diff --git a/AUTHORS b/AUTHORS index 075905f..621bc4e 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -698,6 +698,7 @@ Minchul Kang <tegongkang@gmail.com> Minggang Wang <minggang.wang@intel.com> Mingmin Xie <melvinxie@gmail.com> +Minjeong Kim <deoxyribonucleicacid150@gmail.com> Minjeong Lee <apenr1234@gmail.com> Minseok Koo <kei98301@gmail.com> Minsoo Max Koo <msu.koo@samsung.com>
diff --git a/DEPS b/DEPS index 5f32797..5ffe680 100644 --- a/DEPS +++ b/DEPS
@@ -195,11 +195,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '0baaa2372201e29d68dcb83b7454e2dedf6d4b5e', + 'skia_revision': '578215be44d00af16d431bc277b0d0d429fbf53d', # 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': '48246bebcd061568b0168fedee68e7d0e9f02217', + 'v8_revision': 'bccf9d557196688f8cc91c00db6526f8f493124c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -215,7 +215,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'e8bde89026d67ec34c1fbc729899b67aced3e93d', + 'pdfium_revision': '42aaf8bd7f23e39e85c843d36f5a041870726279', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -302,7 +302,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. - 'spv_tools_revision': '4dd122392f3ad757e70951a1198479bf233d4cd8', + 'spv_tools_revision': '12df3cafeee0ce84861d93b7ea4c939429453644', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -1542,7 +1542,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d32b1bc30216606b7707c93d994f1ad921da2354', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@25e9f126d8c331c5a72893d07c11f95a23acae3b', 'condition': 'checkout_src_internal', },
diff --git a/ash/system/network/network_list_view.cc b/ash/system/network/network_list_view.cc index 47a6688..93c2ada0 100644 --- a/ash/system/network/network_list_view.cc +++ b/ash/system/network/network_list_view.cc
@@ -258,8 +258,8 @@ int index = 0; const NetworkStateProperties* default_network = model()->default_network(); - bool using_proxy = default_network && - default_network->proxy_mode == ProxyMode::kFixedServers; + bool using_proxy = + default_network && default_network->proxy_mode != ProxyMode::kDirect; // Show a warning that the connection might be monitored if connected to a VPN // or if the default network has a proxy installed. if (vpn_connected_ || using_proxy) {
diff --git a/base/base_paths_posix.cc b/base/base_paths_posix.cc index 5b9f34b..11cbe73 100644 --- a/base/base_paths_posix.cc +++ b/base/base_paths_posix.cc
@@ -38,7 +38,7 @@ switch (key) { case FILE_EXE: case FILE_MODULE: { // TODO(evanm): is this correct? -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) FilePath bin_dir; if (!ReadSymbolicLink(FilePath(kProcSelfExe), &bin_dir)) { NOTREACHED() << "Unable to resolve " << kProcSelfExe << ".";
diff --git a/base/base_switches.cc b/base/base_switches.cc index 88401ce..8c8563e5 100644 --- a/base/base_switches.cc +++ b/base/base_switches.cc
@@ -152,7 +152,7 @@ #endif -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // Controls whether or not retired instruction counts are surfaced for threads // in trace events on Linux. //
diff --git a/base/base_switches.h b/base/base_switches.h index 5c3e961..e650b6a3 100644 --- a/base/base_switches.h +++ b/base/base_switches.h
@@ -55,7 +55,7 @@ extern const char kForceFieldTrialParams[]; #endif -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) extern const char kEnableThreadInstructionCount[]; #endif
diff --git a/base/cpu.cc b/base/cpu.cc index d0448de..6590dde 100644 --- a/base/cpu.cc +++ b/base/cpu.cc
@@ -16,7 +16,8 @@ #include "base/stl_util.h" -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ + defined(OS_AIX) #include "base/containers/flat_set.h" #include "base/files/file_util.h" #include "base/no_destructor.h" @@ -29,7 +30,8 @@ #include "base/threading/thread_restrictions.h" #endif -#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX)) +#if defined(ARCH_CPU_ARM_FAMILY) && \ + (defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS)) #include "base/files/file_util.h" #endif @@ -150,7 +152,8 @@ #endif // ARCH_CPU_X86_FAMILY -#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX)) +#if defined(ARCH_CPU_ARM_FAMILY) && \ + (defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS)) std::string* CpuInfoBrand() { static std::string* brand = []() { // This function finds the value from /proc/cpuinfo under the key "model @@ -180,7 +183,7 @@ return brand; } #endif // defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || - // defined(OS_LINUX)) + // defined(OS_LINUX) || defined(OS_CHROMEOS)) } // namespace @@ -302,7 +305,7 @@ } } #elif defined(ARCH_CPU_ARM_FAMILY) -#if (defined(OS_ANDROID) || defined(OS_LINUX)) +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) cpu_brand_ = *CpuInfoBrand(); #elif defined(OS_WIN) // Windows makes high-resolution thread timing information available in @@ -324,7 +327,8 @@ return PENTIUM; } -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ + defined(OS_AIX) namespace { constexpr char kTimeInStatePath[] = @@ -520,6 +524,7 @@ return true; } -#endif // defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || + // defined(OS_AIX) } // namespace base
diff --git a/base/cpu.h b/base/cpu.h index 8de7486..b79cc464 100644 --- a/base/cpu.h +++ b/base/cpu.h
@@ -73,7 +73,8 @@ IntelMicroArchitecture GetIntelMicroArchitecture() const; const std::string& cpu_brand() const { return cpu_brand_; } -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ + defined(OS_AIX) enum class CoreType { kUnknown = 0, kOther, @@ -113,7 +114,8 @@ // NOTE: Currently only supported on Linux/Android, and only on kernels with // cpufreq-stats driver. static bool GetTimeInState(TimeInState&); -#endif // defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || + // defined(OS_AIX) private: // Query the processor for CPUID information.
diff --git a/base/debug/debugger_posix.cc b/base/debug/debugger_posix.cc index 1d3101e..b2e8ae3 100644 --- a/base/debug/debugger_posix.cc +++ b/base/debug/debugger_posix.cc
@@ -153,7 +153,8 @@ #endif } -#elif defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ + defined(OS_AIX) // We can look in /proc/self/status for TracerPid. We are likely used in crash // handling, so we are careful not to use the heap or have side effects.
diff --git a/base/debug/proc_maps_linux.cc b/base/debug/proc_maps_linux.cc index e38a5f9..c150bb5 100644 --- a/base/debug/proc_maps_linux.cc +++ b/base/debug/proc_maps_linux.cc
@@ -13,7 +13,7 @@ #include "base/strings/string_split.h" #include "build/build_config.h" -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) #include <inttypes.h> #endif
diff --git a/base/debug/stack_trace.cc b/base/debug/stack_trace.cc index fef9c2c..1daf640 100644 --- a/base/debug/stack_trace.cc +++ b/base/debug/stack_trace.cc
@@ -14,7 +14,7 @@ #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) #include <pthread.h> #include "base/process/process_handle.h" #include "base/threading/platform_thread.h" @@ -24,7 +24,7 @@ #include <pthread.h> #endif -#if defined(OS_LINUX) && defined(__GLIBC__) +#if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(__GLIBC__) extern "C" void* __libc_stack_end; #endif @@ -105,7 +105,7 @@ // ScanStackForNextFrame() returns 0 if it couldn't find a valid frame // (or if stack scanning is not supported on the current platform). uintptr_t ScanStackForNextFrame(uintptr_t fp, uintptr_t stack_end) { -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // Enough to resume almost all prematurely terminated traces. constexpr size_t kMaxStackScanArea = 8192; @@ -130,7 +130,7 @@ } } } -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) return 0; } @@ -182,7 +182,7 @@ } return stack_end; // 0 in case of error -#elif defined(OS_LINUX) && defined(__GLIBC__) +#elif (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(__GLIBC__) if (GetCurrentProcId() == PlatformThread::CurrentId()) { // For the main thread we have a shortcut.
diff --git a/base/debug/stack_trace_posix.cc b/base/debug/stack_trace_posix.cc index e009de3a..6a1531e1 100644 --- a/base/debug/stack_trace_posix.cc +++ b/base/debug/stack_trace_posix.cc
@@ -35,7 +35,7 @@ #include <AvailabilityMacros.h> #endif -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #include "base/debug/proc_maps_linux.h" #endif @@ -344,7 +344,7 @@ debug::StackTrace().Print(); -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #if ARCH_CPU_X86_FAMILY ucontext_t* context = reinterpret_cast<ucontext_t*>(void_context); const struct { @@ -415,7 +415,7 @@ } PrintToStderr("\n"); #endif // ARCH_CPU_X86_FAMILY -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) PrintToStderr("[end of stack trace]\n"); @@ -800,9 +800,9 @@ success &= (sigaction(SIGBUS, &action, nullptr) == 0); success &= (sigaction(SIGSEGV, &action, nullptr) == 0); // On Linux, SIGSYS is reserved by the kernel for seccomp-bpf sandboxing. -#if !defined(OS_LINUX) +#if !defined(OS_LINUX) && !defined(OS_CHROMEOS) success &= (sigaction(SIGSYS, &action, nullptr) == 0); -#endif // !defined(OS_LINUX) +#endif // !defined(OS_LINUX) && !defined(OS_CHROMEOS) return success; }
diff --git a/base/files/dir_reader_posix.h b/base/files/dir_reader_posix.h index 15fc744f..d68b9c47 100644 --- a/base/files/dir_reader_posix.h +++ b/base/files/dir_reader_posix.h
@@ -17,7 +17,7 @@ // seems worse than falling back to enumerating all file descriptors so we will // probably never implement this on the Mac. -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) #include "base/files/dir_reader_linux.h" #else #include "base/files/dir_reader_fallback.h" @@ -25,7 +25,7 @@ namespace base { -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) typedef DirReaderLinux DirReaderPosix; #else typedef DirReaderFallback DirReaderPosix;
diff --git a/base/files/file_path_unittest.cc b/base/files/file_path_unittest.cc index 8de24ca..c7a617fe 100644 --- a/base/files/file_path_unittest.cc +++ b/base/files/file_path_unittest.cc
@@ -1149,7 +1149,7 @@ "\xEF\xBC\xA1\xEF\xBC\xA2\xEF\xBC\xA3.txt" }, }; -#if !defined(SYSTEM_NATIVE_UTF8) && defined(OS_LINUX) +#if !defined(SYSTEM_NATIVE_UTF8) && (defined(OS_LINUX) || defined(OS_CHROMEOS)) ScopedLocale locale("en_US.UTF-8"); #endif
diff --git a/base/files/file_path_watcher.cc b/base/files/file_path_watcher.cc index b37a167..7b42482 100644 --- a/base/files/file_path_watcher.cc +++ b/base/files/file_path_watcher.cc
@@ -20,7 +20,7 @@ // static bool FilePathWatcher::RecursiveWatchAvailable() { #if defined(OS_MAC) || defined(OS_WIN) || defined(OS_LINUX) || \ - defined(OS_ANDROID) || defined(OS_AIX) + defined(OS_CHROMEOS) || defined(OS_ANDROID) || defined(OS_AIX) return true; #else // FSEvents isn't available on iOS.
diff --git a/base/files/file_path_watcher_unittest.cc b/base/files/file_path_watcher_unittest.cc index f1a37747..6829f06 100644 --- a/base/files/file_path_watcher_unittest.cc +++ b/base/files/file_path_watcher_unittest.cc
@@ -632,7 +632,7 @@ ASSERT_TRUE(WaitForEvents()); } -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // Verify that creating a symlink is caught. TEST_F(FilePathWatcherTest, CreateLink) { @@ -790,7 +790,7 @@ ASSERT_TRUE(WaitForEvents()); } -#endif // OS_LINUX +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) enum Permission { Read,
diff --git a/base/files/file_posix.cc b/base/files/file_posix.cc index 5e344a53..2e22630 100644 --- a/base/files/file_posix.cc +++ b/base/files/file_posix.cc
@@ -125,7 +125,7 @@ // creation time. However, other than on Mac & iOS where the actual file // creation time is included as st_birthtime, the rest of POSIX platforms have // no portable way to get the creation time. -#if defined(OS_LINUX) || defined(OS_FUCHSIA) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_FUCHSIA) time_t last_modified_sec = stat_info.st_mtim.tv_sec; int64_t last_modified_nsec = stat_info.st_mtim.tv_nsec; time_t last_accessed_sec = stat_info.st_atim.tv_sec; @@ -549,7 +549,7 @@ #if defined(OS_NACL) NOTIMPLEMENTED(); // NaCl doesn't implement fsync. return true; -#elif defined(OS_LINUX) || defined(OS_ANDROID) +#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) return !HANDLE_EINTR(fdatasync(file_.get())); #elif defined(OS_APPLE) // On macOS and iOS, fsync() is guaranteed to send the file's data to the
diff --git a/base/files/file_util.h b/base/files/file_util.h index 6b8623c..f5fbea0 100644 --- a/base/files/file_util.h +++ b/base/files/file_util.h
@@ -275,14 +275,14 @@ BASE_EXPORT bool ExecutableExistsInPath(Environment* env, const FilePath::StringType& executable); -#if defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) // Determine if files under a given |path| can be mapped and then mprotect'd // PROT_EXEC. This depends on the mount options used for |path|, which vary // among different Linux distributions and possibly local configuration. It also // depends on details of kernel--ChromeOS uses the noexec option for /dev/shm // but its kernel allows mprotect with PROT_EXEC anyway. BASE_EXPORT bool IsPathExecutable(const FilePath& path); -#endif // OS_LINUX || OS_AIX +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) #endif // OS_POSIX @@ -589,7 +589,7 @@ // the directory |path|, in the number of FilePath::CharType, or -1 on failure. BASE_EXPORT int GetMaximumPathComponentLength(const base::FilePath& path); -#if defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) // Broad categories of file systems as returned by statfs() on Linux. enum FileSystemType { FILE_SYSTEM_UNKNOWN, // statfs failed.
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc index c487f67..1b9cc141 100644 --- a/base/files/file_util_posix.cc +++ b/base/files/file_util_posix.cc
@@ -412,7 +412,7 @@ } bool CreateLocalNonBlockingPipe(int fds[2]) { -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) return pipe2(fds, O_CLOEXEC | O_NONBLOCK) == 0; #else int raw_fds[2]; @@ -940,7 +940,7 @@ // space. It can fail because the filesystem doesn't support it. In that case, // use the manual method below. -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) if (HANDLE_EINTR(fallocate(file->GetPlatformFile(), 0, offset, size)) != -1) return true; DPLOG(ERROR) << "fallocate"; @@ -1111,7 +1111,7 @@ #if !defined(OS_ANDROID) // This is implemented in file_util_android.cc for that platform. bool GetShmemTempDir(bool executable, FilePath* path) { -#if defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) bool disable_dev_shm = false; #if !defined(OS_CHROMEOS) && !BUILDFLAG(IS_LACROS) disable_dev_shm = CommandLine::ForCurrentProcess()->HasSwitch( @@ -1127,7 +1127,7 @@ *path = FilePath("/dev/shm"); return true; } -#endif // defined(OS_LINUX) || defined(OS_AIX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) return GetTempDir(path); } #endif // !defined(OS_ANDROID) @@ -1162,11 +1162,11 @@ int64_t max_bytes) { DCHECK_GE(max_bytes, 0); - // ChromeOS is also covered by OS_LINUX. // posix_fadvise() is only available in the Android NDK in API 21+. Older // versions may have the required kernel support, but don't have enough usage // to justify backporting. -#if defined(OS_LINUX) || (defined(OS_ANDROID) && __ANDROID_API__ >= 21) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || \ + (defined(OS_ANDROID) && __ANDROID_API__ >= 21) File file(file_path, File::FLAG_OPEN | File::FLAG_READ); if (!file.IsValid()) return PrefetchResult{PrefetchResultCode::kInvalidFile}; @@ -1186,7 +1186,8 @@ return internal::PreReadFileSlow(file_path, max_bytes) ? PrefetchResult{PrefetchResultCode::kSlowSuccess} : PrefetchResult{PrefetchResultCode::kSlowFailed}; -#endif // defined(OS_LINUX) || (defined(OS_ANDROID) && __ANDROID_API__ >= 21) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || (defined(OS_ANDROID) && + // __ANDROID_API__ >= 21) } // ----------------------------------------------------------------------------- @@ -1220,7 +1221,7 @@ #endif // !defined(OS_NACL_NONSFI) -#if defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) BASE_EXPORT bool IsPathExecutable(const FilePath& path) { bool result = false; FilePath tmp_file_path; @@ -1241,6 +1242,6 @@ } return result; } -#endif // defined(OS_LINUX) || defined(OS_AIX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) } // namespace base
diff --git a/base/files/file_util_unittest.cc b/base/files/file_util_unittest.cc index a2ef63dd..54cd5b9 100644 --- a/base/files/file_util_unittest.cc +++ b/base/files/file_util_unittest.cc
@@ -66,7 +66,7 @@ #include <unistd.h> #endif -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #include <linux/fs.h> #endif @@ -1603,7 +1603,7 @@ File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE); ASSERT_TRUE(PathExists(file_name3)); -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // On Windows, holding the file open in sufficient to make it un-deletable. // The POSIX code is verifiable on Linux by creating an "immutable" file but // this is best-effort because it's not supported by all file systems. Both @@ -1624,7 +1624,7 @@ DeletePathRecursively(test_subdir); EXPECT_FALSE(PathExists(file_name2)); -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // Make sure that the test can clean up after itself. if (file_attrs_supported) { flags &= ~FS_IMMUTABLE_FL; @@ -1634,7 +1634,7 @@ #endif } -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // This test will validate that files which would block when read result in a // failure on a call to ReadFileToStringNonBlocking. To accomplish this we will // use a named pipe because it appears as a file on disk and we can control how @@ -1667,7 +1667,7 @@ ASSERT_EQ(result.size(), 1u); EXPECT_EQ(result[0], 'a'); } -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) TEST_F(FileUtilTest, MoveFileNew) { // Create a file
diff --git a/base/files/scoped_file.cc b/base/files/scoped_file.cc index 7b6c057..a2e1e6b 100644 --- a/base/files/scoped_file.cc +++ b/base/files/scoped_file.cc
@@ -30,8 +30,8 @@ // a single open directory would bypass the entire security model. int ret = IGNORE_EINTR(close(fd)); -#if defined(OS_LINUX) || defined(OS_APPLE) || defined(OS_FUCHSIA) || \ - defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_APPLE) || \ + defined(OS_FUCHSIA) || defined(OS_ANDROID) // NB: Some file descriptors can return errors from close() e.g. network // filesystems such as NFS and Linux input devices. On Linux, macOS, and // Fuchsia's POSIX layer, errors from close other than EBADF do not indicate
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc index 5f4c0c9..bb2b3f0 100644 --- a/base/logging_unittest.cc +++ b/base/logging_unittest.cc
@@ -28,7 +28,7 @@ #include "base/posix/eintr_wrapper.h" #endif // OS_POSIX -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) #include <ucontext.h> #endif
diff --git a/base/memory/discardable_memory.cc b/base/memory/discardable_memory.cc index b41c27e..6ef3f1f 100644 --- a/base/memory/discardable_memory.cc +++ b/base/memory/discardable_memory.cc
@@ -23,7 +23,7 @@ "MadvFreeDiscardableMemory", base::FEATURE_DISABLED_BY_DEFAULT}; #endif // defined(OS_POSIX) -#if defined(OS_ANDROID) || defined(OS_LINUX) +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) const base::Feature kDiscardableMemoryBackingTrial{ "DiscardableMemoryBackingTrial", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -41,13 +41,13 @@ DiscardableMemoryTrialGroup::kEmulatedSharedMemory, &kDiscardableMemoryBackingParamOptions}; -#endif // defined(OS_ANDROID) || defined(OS_LINUX) +#endif // defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) } // namespace features namespace { -#if defined(OS_ANDROID) || defined(OS_LINUX) +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) DiscardableMemoryBacking GetBackingForFieldTrial() { DiscardableMemoryTrialGroup trial_group = @@ -61,11 +61,11 @@ } NOTREACHED(); } -#endif // defined(OS_ANDROID) || defined(OS_LINUX) +#endif // defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) } // namespace -#if defined(OS_ANDROID) || defined(OS_LINUX) +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) // Probe capabilities of this device to determine whether we should participate // in the discardable memory backing trial. @@ -87,18 +87,18 @@ DCHECK(DiscardableMemoryBackingFieldTrialIsEnabled()); return features::kDiscardableMemoryBackingParam.Get(); } -#endif // defined(OS_ANDROID) || defined(OS_LINUX) +#endif // defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) DiscardableMemory::DiscardableMemory() = default; DiscardableMemory::~DiscardableMemory() = default; DiscardableMemoryBacking GetDiscardableMemoryBacking() { -#if defined(OS_ANDROID) || defined(OS_LINUX) +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) if (DiscardableMemoryBackingFieldTrialIsEnabled()) { return GetBackingForFieldTrial(); } -#endif // defined(OS_ANDROID) || defined(OS_LINUX) +#endif // defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) #if defined(OS_ANDROID) if (ashmem_device_is_supported())
diff --git a/base/memory/discardable_memory_backing_field_trial_unittest.cc b/base/memory/discardable_memory_backing_field_trial_unittest.cc index 64e5177..23bb639b 100644 --- a/base/memory/discardable_memory_backing_field_trial_unittest.cc +++ b/base/memory/discardable_memory_backing_field_trial_unittest.cc
@@ -15,7 +15,7 @@ #include "base/memory/madv_free_discardable_memory_posix.h" #endif // defined(OS_POSIX) -#if defined(OS_ANDROID) || defined(OS_LINUX) +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) namespace base { class DiscardableMemoryBackingFieldTrialTest : public ::testing::Test { @@ -88,4 +88,4 @@ } // namespace base -#endif // defined(OS_ANDROID) || defined(OS_LINUX) +#endif // defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS)
diff --git a/base/memory/discardable_memory_internal.h b/base/memory/discardable_memory_internal.h index 9487a8c..eccf20bd 100644 --- a/base/memory/discardable_memory_internal.h +++ b/base/memory/discardable_memory_internal.h
@@ -10,7 +10,7 @@ #include "base/metrics/field_trial_params.h" #include "build/build_config.h" -#if defined(OS_ANDROID) || defined(OS_LINUX) +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) namespace base { @@ -47,6 +47,6 @@ } // namespace base -#endif // defined(OS_LINUX) || defined(OS_ANDROID) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) #endif // BASE_MEMORY_DISCARDABLE_MEMORY_INTERNAL_H_
diff --git a/base/message_loop/message_pump_for_ui.h b/base/message_loop/message_pump_for_ui.h index 27f18db..1eb7da0 100644 --- a/base/message_loop/message_pump_for_ui.h +++ b/base/message_loop/message_pump_for_ui.h
@@ -20,7 +20,7 @@ // No MessagePumpForUI, see below. #elif defined(USE_GLIB) #include "base/message_loop/message_pump_glib.h" -#elif defined(OS_LINUX) || defined(OS_BSD) +#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD) #include "base/message_loop/message_pump_libevent.h" #elif defined(OS_FUCHSIA) #include "base/message_loop/message_pump_fuchsia.h" @@ -44,7 +44,7 @@ // TODO(abarth): Figure out if we need this. #elif defined(USE_GLIB) using MessagePumpForUI = MessagePumpGlib; -#elif defined(OS_LINUX) || defined(OS_BSD) +#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD) using MessagePumpForUI = MessagePumpLibevent; #elif defined(OS_FUCHSIA) using MessagePumpForUI = MessagePumpFuchsia;
diff --git a/base/path_service_unittest.cc b/base/path_service_unittest.cc index b8594f5..1e9f679f 100644 --- a/base/path_service_unittest.cc +++ b/base/path_service_unittest.cc
@@ -38,7 +38,7 @@ if (dir_type == DIR_CACHE) check_path_exists = false; #endif -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // On the linux try-bots: a path is returned (e.g. /home/chrome-bot/Desktop), // but it doesn't exist. if (dir_type == DIR_USER_DESKTOP)
diff --git a/base/process/kill.h b/base/process/kill.h index b955870f..ee99313e 100644 --- a/base/process/kill.h +++ b/base/process/kill.h
@@ -113,11 +113,11 @@ BASE_EXPORT TerminationStatus GetKnownDeadTerminationStatus( ProcessHandle handle, int* exit_code); -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // Spawns a thread to wait asynchronously for the child |process| to exit // and then reaps it. BASE_EXPORT void EnsureProcessGetsReaped(Process process); -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) #endif // defined(OS_POSIX) // Registers |process| to be asynchronously monitored for termination, forcibly
diff --git a/base/process/kill_posix.cc b/base/process/kill_posix.cc index 0750d9a..29db8b2 100644 --- a/base/process/kill_posix.cc +++ b/base/process/kill_posix.cc
@@ -160,7 +160,7 @@ 0, new BackgroundReaper(std::move(process), TimeDelta::FromSeconds(2))); } -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) void EnsureProcessGetsReaped(Process process) { DCHECK(!process.is_current()); @@ -171,7 +171,7 @@ PlatformThread::CreateNonJoinable( 0, new BackgroundReaper(std::move(process), TimeDelta())); } -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) #endif // !defined(OS_APPLE) #endif // !defined(OS_NACL_NONSFI)
diff --git a/base/process/launch.cc b/base/process/launch.cc index c03e1a7..a643828 100644 --- a/base/process/launch.cc +++ b/base/process/launch.cc
@@ -15,7 +15,7 @@ LaunchOptions LaunchOptionsForTest() { LaunchOptions options; -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // To prevent accidental privilege sharing to an untrusted child, processes // are started with PR_SET_NO_NEW_PRIVS. Do not set that here, since this // new child will be used for testing only.
diff --git a/base/process/launch.h b/base/process/launch.h index 5d4b205..f0d76540 100644 --- a/base/process/launch.h +++ b/base/process/launch.h
@@ -180,7 +180,7 @@ bool clear_environment = false; #endif // OS_WIN || OS_POSIX || OS_FUCHSIA -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // If non-zero, start the process using clone(), using flags as provided. // Unlike in clone, clone_flags may not contain a custom termination signal // that is sent to the parent when the child dies. The termination signal will @@ -193,7 +193,7 @@ // Sets parent process death signal to SIGKILL. bool kill_on_parent_death = false; -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) #if defined(OS_MAC) // Mach ports that will be accessible to the child process. These are not @@ -401,7 +401,7 @@ // binary. This should not be called in production/released code. BASE_EXPORT LaunchOptions LaunchOptionsForTest(); -#if defined(OS_LINUX) || defined(OS_NACL_NONSFI) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_NACL_NONSFI) // A wrapper for clone with fork-like behavior, meaning that it returns the // child's pid in the parent and 0 in the child. |flags|, |ptid|, and |ctid| are // as in the clone system call (the CLONE_VM flag is not supported).
diff --git a/base/process/launch_posix.cc b/base/process/launch_posix.cc index e0e9009..a8b1f0bd 100644 --- a/base/process/launch_posix.cc +++ b/base/process/launch_posix.cc
@@ -48,7 +48,7 @@ #include "base/trace_event/base_tracing.h" #include "build/build_config.h" -#if defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) #include <sys/prctl.h> #endif @@ -108,7 +108,7 @@ return old_sigmask; } -#if (!defined(OS_LINUX) && !defined(OS_AIX)) || \ +#if (!defined(OS_LINUX) && !defined(OS_AIX) && !defined(OS_CHROMEOS)) || \ (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__)) void ResetChildSignalHandlersToDefaults() { // The previous signal handlers are likely to be meaningless in the child's @@ -206,7 +206,7 @@ // Automatically closes |DIR*|s. typedef std::unique_ptr<DIR, ScopedDIRClose> ScopedDIR; -#if defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) static const char kFDDir[] = "/proc/self/fd"; #elif defined(OS_SOLARIS) static const char kFDDir[] = "/dev/fd"; @@ -317,7 +317,7 @@ pid_t pid; base::TimeTicks before_fork = TimeTicks::Now(); -#if defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) if (options.clone_flags) { // Signal handling in this function assumes the creation of a new // process, so we check that a thread is not being created by mistake @@ -451,7 +451,7 @@ // Set NO_NEW_PRIVS by default. Since NO_NEW_PRIVS only exists in kernel // 3.5+, do not check the return value of prctl here. -#if defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) #ifndef PR_SET_NO_NEW_PRIVS #define PR_SET_NO_NEW_PRIVS 38 #endif @@ -666,7 +666,8 @@ #endif // !defined(OS_NACL_NONSFI) -#if defined(OS_LINUX) || defined(OS_NACL_NONSFI) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_NACL_NONSFI) || \ + defined(OS_AIX) namespace { // This function runs on the stack specified on the clone call. It uses longjmp @@ -732,15 +733,15 @@ return CloneAndLongjmpInChild(flags, ptid, ctid, &env); } -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // Since we use clone() directly, it does not call any pthread_aftork() // callbacks, we explicitly clear tid cache here (normally this call is // done as pthread_aftork() callback). See crbug.com/902514. base::internal::ClearTidCache(); -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) return 0; } -#endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_NACL_NONSFI) } // namespace base
diff --git a/base/process/memory.h b/base/process/memory.h index 0e0cc5b..2d313ed 100644 --- a/base/process/memory.h +++ b/base/process/memory.h
@@ -24,7 +24,8 @@ // Crash reporting classifies such crashes as OOM. BASE_EXPORT void TerminateBecauseOutOfMemory(size_t size); -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ + defined(OS_AIX) BASE_EXPORT extern size_t g_oom_size; // The maximum allowed value for the OOM score.
diff --git a/base/process/memory_unittest.cc b/base/process/memory_unittest.cc index c030cfb..43b626f 100644 --- a/base/process/memory_unittest.cc +++ b/base/process/memory_unittest.cc
@@ -34,7 +34,7 @@ #include "base/allocator/buildflags.h" #include "base/process/memory_unittest_mac.h" #endif -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #include <malloc.h> #include "base/test/malloc_wrapper.h" #endif @@ -297,7 +297,7 @@ #endif // defined(OS_WIN) #endif // !defined(OS_MAC) && !defined(OS_ANDROID) -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) TEST_F(OutOfMemoryDeathTest, Valloc) { ASSERT_OOM_DEATH({ @@ -343,7 +343,7 @@ value_ = MallocWrapper(test_size_); }); } -#endif // OS_LINUX +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) // Android doesn't implement posix_memalign(). #if defined(OS_POSIX) && !defined(OS_ANDROID) @@ -507,7 +507,8 @@ } #endif // OS_WIN -#if defined(ARCH_CPU_32_BITS) && (defined(OS_WIN) || defined(OS_LINUX)) +#if defined(ARCH_CPU_32_BITS) && \ + (defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)) void TestAllocationsReleaseReservation(void* (*alloc_fn)(size_t), void (*free_fn)(void*)) { @@ -565,7 +566,8 @@ [](size_t size) { return static_cast<void*>(new char[size]); }, [](void* ptr) { delete[] static_cast<char*>(ptr); }); } -#endif // defined(ARCH_CPU_32_BITS) && (defined(OS_WIN) || defined(OS_LINUX)) +#endif // defined(ARCH_CPU_32_BITS) && (defined(OS_WIN) || defined(OS_LINUX) || + // defined(OS_CHROMEOS)) // See the comment in |UncheckedMalloc()|, it behaves as malloc() in these // cases.
diff --git a/base/process/process_handle.cc b/base/process/process_handle.cc index fcaa129..7212a49 100644 --- a/base/process/process_handle.cc +++ b/base/process/process_handle.cc
@@ -30,7 +30,7 @@ : UniqueProcId(GetCurrentProcId()); } -#if defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) void InitUniqueIdForProcessInPidNamespace(ProcessId pid_outside_of_namespace) { DCHECK(pid_outside_of_namespace != kNullProcessId);
diff --git a/base/process/process_handle.h b/base/process/process_handle.h index 94f7006..3640351 100644 --- a/base/process/process_handle.h +++ b/base/process/process_handle.h
@@ -103,7 +103,7 @@ // processes may be reused. BASE_EXPORT UniqueProcId GetUniqueIdForProcess(); -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // When a process is started in a different PID namespace from the browser // process, this function must be called with the process's PID in the browser's // PID namespace in order to initialize its unique ID. Not thread safe.
diff --git a/base/process/process_metrics.cc b/base/process/process_metrics.cc index 97c195c2..28ec57b 100644 --- a/base/process/process_metrics.cc +++ b/base/process/process_metrics.cc
@@ -49,7 +49,7 @@ SystemMetrics system_metrics; system_metrics.committed_memory_ = GetSystemCommitCharge(); -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) GetSystemMemoryInfo(&system_metrics.memory_info_); GetVmStatInfo(&system_metrics.vmstat_info_); GetSystemDiskInfo(&system_metrics.disk_info_); @@ -67,7 +67,7 @@ std::unique_ptr<DictionaryValue> res(new DictionaryValue()); res->SetIntKey("committed_memory", static_cast<int>(committed_memory_)); -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) std::unique_ptr<DictionaryValue> meminfo = memory_info_.ToValue(); std::unique_ptr<DictionaryValue> vmstat = vmstat_info_.ToValue(); meminfo->MergeDictionary(vmstat.get()); @@ -117,7 +117,8 @@ } #endif -#if defined(OS_APPLE) || defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_APPLE) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ + defined(OS_AIX) int ProcessMetrics::CalculateIdleWakeupsPerSecond( uint64_t absolute_idle_wakeups) { return CalculateEventsPerSecond(absolute_idle_wakeups, @@ -129,7 +130,8 @@ NOTIMPLEMENTED(); // http://crbug.com/120488 return 0; } -#endif // defined(OS_APPLE) || defined(OS_LINUX) || defined(OS_AIX) +#endif // defined(OS_APPLE) || defined(OS_LINUX) || defined(OS_CHROMEOS) || + // defined(OS_AIX) #if defined(OS_APPLE) int ProcessMetrics::CalculatePackageIdleWakeupsPerSecond(
diff --git a/base/process/process_metrics.h b/base/process/process_metrics.h index 834230ae..a2a26f4 100644 --- a/base/process/process_metrics.h +++ b/base/process/process_metrics.h
@@ -47,7 +47,7 @@ // Full declaration is in process_metrics_iocounters.h. struct IoCounters; -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) // Minor and major page fault counts since the process creation. // Both counts are process-wide, and exclude child processes. // @@ -57,7 +57,7 @@ int64_t minor; int64_t major; }; -#endif // defined(OS_LINUX) || defined(OS_ANDROID) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) // Convert a POSIX timeval to microseconds. BASE_EXPORT int64_t TimeValToMicroseconds(const struct timeval& tv); @@ -98,7 +98,7 @@ // convenience wrapper for CreateProcessMetrics(). static std::unique_ptr<ProcessMetrics> CreateCurrentProcessMetrics(); -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) // Resident Set Size is a Linux/Android specific memory concept. Do not // attempt to extend this to other platforms. BASE_EXPORT size_t GetResidentSetSize() const; @@ -124,7 +124,8 @@ // will result in a time delta of 2 seconds/per 1 wall-clock second. TimeDelta GetCumulativeCPUUsage(); -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ + defined(OS_AIX) // Emits the cumulative CPU usage for all currently active threads since they // were started into the output parameter (replacing its current contents). // Threads that have already terminated will not be reported. Thus, the sum of @@ -158,7 +159,8 @@ bool ParseProcTimeInState(const std::string& content, PlatformThreadId tid, TimeInStatePerThread& time_in_state_per_thread); -#endif // defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || + // defined(OS_AIX) // Returns the number of average idle cpu wakeups per second since the last // call. @@ -214,14 +216,14 @@ int GetOpenFdSoftLimit() const; #endif // defined(OS_POSIX) -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) // Bytes of swap as reported by /proc/[pid]/status. uint64_t GetVmSwapBytes() const; // Minor and major page fault count as reported by /proc/[pid]/stat. // Returns true for success. bool GetPageFaultCounts(PageFaultCounts* counts) const; -#endif // defined(OS_LINUX) || defined(OS_ANDROID) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) // Returns total memory usage of malloc. size_t GetMallocUsage(); @@ -233,7 +235,8 @@ ProcessMetrics(ProcessHandle process, PortProvider* port_provider); #endif // !defined(OS_MAC) -#if defined(OS_APPLE) || defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_APPLE) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ + defined(OS_AIX) int CalculateIdleWakeupsPerSecond(uint64_t absolute_idle_wakeups); #endif #if defined(OS_APPLE) @@ -243,12 +246,14 @@ uint64_t absolute_package_idle_wakeups); #endif -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ + defined(OS_AIX) CPU::CoreType GetCoreType(int core_index); // Initialized on the first call to GetCoreType(). base::Optional<std::vector<CPU::CoreType>> core_index_to_type_; -#endif // defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || + // defined(OS_AIX) #if defined(OS_WIN) win::ScopedHandle process_; @@ -269,7 +274,8 @@ // Number of bytes transferred to/from disk in bytes. uint64_t last_cumulative_disk_usage_ = 0; -#if defined(OS_APPLE) || defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_APPLE) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ + defined(OS_AIX) // Same thing for idle wakeups. TimeTicks last_idle_wakeups_time_; uint64_t last_absolute_idle_wakeups_; @@ -320,8 +326,9 @@ BASE_EXPORT void IncreaseFdLimitTo(unsigned int max_descriptors); #endif // defined(OS_POSIX) -#if defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) || \ - defined(OS_ANDROID) || defined(OS_AIX) || defined(OS_FUCHSIA) +#if defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) || \ + defined(OS_CHROMEOS) || defined(OS_ANDROID) || defined(OS_AIX) || \ + defined(OS_FUCHSIA) // Data about system-wide memory consumption. Values are in KB. Available on // Windows, Mac, Linux, Android and Chrome OS. // @@ -354,7 +361,8 @@ int avail_phys = 0; #endif -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ + defined(OS_AIX) // This provides an estimate of available memory as described here: // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773 // NOTE: this is ONLY valid in kernels 3.14 and up. Its value will always @@ -368,8 +376,8 @@ int swap_free = 0; #endif -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_AIX) || \ - defined(OS_FUCHSIA) +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ + defined(OS_AIX) || defined(OS_FUCHSIA) int buffers = 0; int cached = 0; int active_anon = 0; @@ -378,8 +386,8 @@ int inactive_file = 0; int dirty = 0; int reclaimable = 0; -#endif // defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_AIX) || - // defined(OS_FUCHSIA) +#endif // defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) || + // defined(OS_AIX) defined(OS_FUCHSIA) #if defined(OS_CHROMEOS) || BUILDFLAG(IS_LACROS) int shmem = 0; @@ -405,9 +413,11 @@ BASE_EXPORT bool GetSystemMemoryInfo(SystemMemoryInfoKB* meminfo); #endif // defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) || - // defined(OS_ANDROID) || defined(OS_AIX) || defined(OS_FUCHSIA) + // defined(OS_CHROMEOS) defined(OS_ANDROID) || defined(OS_AIX) || + // defined(OS_FUCHSIA) -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ + defined(OS_AIX) // Parse the data found in /proc/<pid>/stat and return the sum of the // CPU-related ticks. Returns -1 on parse error. // Exposed for testing. @@ -480,7 +490,8 @@ // Returns the amount of time spent in user space since boot across all CPUs. BASE_EXPORT TimeDelta GetUserCpuTimeSinceBoot(); -#endif // defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || + // defined(OS_AIX) #if defined(OS_CHROMEOS) || BUILDFLAG(IS_LACROS) // Data from files in directory /sys/block/zram0 about ZRAM usage. @@ -575,7 +586,7 @@ FRIEND_TEST_ALL_PREFIXES(SystemMetricsTest, SystemMetrics); size_t committed_memory_; -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) SystemMemoryInfoKB memory_info_; VmStatInfo vmstat_info_; SystemDiskInfo disk_info_;
diff --git a/base/process/process_metrics_linux.cc b/base/process/process_metrics_linux.cc index d69737a..f8920f3 100644 --- a/base/process/process_metrics_linux.cc +++ b/base/process/process_metrics_linux.cc
@@ -103,7 +103,7 @@ return 0; } -#if defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) // Read /proc/<pid>/status and look for |field|. On success, return true and // write the value for |field| into |result|. // Only works for fields in the form of "field : uint_value" @@ -128,7 +128,7 @@ } return false; } -#endif // defined(OS_LINUX) || defined(OS_AIX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) // Get the total CPU from a proc stat buffer. Return value is number of jiffies // on success or 0 if parsing failed. @@ -297,13 +297,11 @@ return true; } -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) uint64_t ProcessMetrics::GetVmSwapBytes() const { return ReadProcStatusAndGetFieldAsSizeT(process_, "VmSwap") * 1024; } -#endif // defined(OS_LINUX) || defined(OS_ANDROID) -#if defined(OS_LINUX) || defined(OS_ANDROID) bool ProcessMetrics::GetPageFaultCounts(PageFaultCounts* counts) const { // We are not using internal::ReadStatsFileAndGetFieldAsInt64(), since it // would read the file twice, and return inconsistent numbers. @@ -320,7 +318,7 @@ internal::GetProcStatsFieldAsInt64(proc_stats, internal::VM_MAJFLT); return true; } -#endif // defined(OS_LINUX) || defined(OS_ANDROID) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) int ProcessMetrics::GetOpenFdCount() const { // Use /proc/<pid>/fd to count the number of entries there. @@ -365,7 +363,7 @@ return -1; } -#if defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) ProcessMetrics::ProcessMetrics(ProcessHandle process) : process_(process), last_absolute_idle_wakeups_(0) {} #else @@ -1043,7 +1041,7 @@ } #endif // defined(OS_CHROMEOS) || BUILDFLAG(IS_LACROS) -#if defined(OS_LINUX) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) int ProcessMetrics::GetIdleWakeupsPerSecond() { uint64_t num_switches; static const char kSwitchStat[] = "voluntary_ctxt_switches"; @@ -1051,6 +1049,6 @@ ? CalculateIdleWakeupsPerSecond(num_switches) : 0; } -#endif // defined(OS_LINUX) || defined(OS_AIX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_AIX) } // namespace base
diff --git a/base/process/process_metrics_posix.cc b/base/process/process_metrics_posix.cc index d7aafd3..9d12c42 100644 --- a/base/process/process_metrics_posix.cc +++ b/base/process/process_metrics_posix.cc
@@ -37,7 +37,7 @@ #if !defined(OS_FUCHSIA) -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) static const rlim_t kSystemDefaultMaxFds = 8192; #elif defined(OS_APPLE) static const rlim_t kSystemDefaultMaxFds = 256; @@ -119,7 +119,7 @@ malloc_statistics_t stats = {0}; malloc_zone_statistics(nullptr, &stats); return stats.size_in_use; -#elif defined(OS_LINUX) || defined(OS_ANDROID) +#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) struct mallinfo minfo = mallinfo(); #if BUILDFLAG(USE_TCMALLOC) return minfo.uordblks;
diff --git a/base/process/process_metrics_unittest.cc b/base/process/process_metrics_unittest.cc index 15fb978..a52a4a64 100644 --- a/base/process/process_metrics_unittest.cc +++ b/base/process/process_metrics_unittest.cc
@@ -34,7 +34,7 @@ #include <sys/mman.h> #endif -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) #include "base/process/internal_linux.h" #endif @@ -67,7 +67,7 @@ DISALLOW_COPY_AND_ASSIGN(SystemMetricsTest); }; -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) TEST_F(SystemMetricsTest, IsValidDiskName) { const char invalid_input1[] = ""; const char invalid_input2[] = "s"; @@ -329,7 +329,7 @@ const char empty_input[] = ""; EXPECT_FALSE(ParseProcVmstat(empty_input, &vmstat)); } -#endif // defined(OS_LINUX) || defined(OS_ANDROID) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) #if defined(OS_LINUX) || defined(OS_CHROMEOS) || BUILDFLAG(IS_LACROS) || \ defined(OS_WIN) @@ -426,7 +426,7 @@ #endif // defined(OS_CHROMEOS) || BUILDFLAG(IS_LACROS) #if defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) || \ - defined(OS_ANDROID) + defined(OS_CHROMEOS) || defined(OS_ANDROID) TEST(SystemMetrics2Test, GetSystemMemoryInfo) { SystemMemoryInfoKB info; EXPECT_TRUE(GetSystemMemoryInfo(&info)); @@ -438,26 +438,26 @@ #else EXPECT_GT(info.free, 0); #endif -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) EXPECT_GT(info.buffers, 0); EXPECT_GT(info.cached, 0); EXPECT_GT(info.active_anon + info.inactive_anon, 0); EXPECT_GT(info.active_file + info.inactive_file, 0); -#endif // defined(OS_LINUX) || defined(OS_ANDROID) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) // All the values should be less than the total amount of memory. #if !defined(OS_WIN) && !defined(OS_IOS) // TODO(crbug.com/711450): re-enable the following assertion on iOS. EXPECT_LT(info.free, info.total); #endif -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) EXPECT_LT(info.buffers, info.total); EXPECT_LT(info.cached, info.total); EXPECT_LT(info.active_anon, info.total); EXPECT_LT(info.inactive_anon, info.total); EXPECT_LT(info.active_file, info.total); EXPECT_LT(info.inactive_file, info.total); -#endif // defined(OS_LINUX) || defined(OS_ANDROID) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) #if defined(OS_APPLE) EXPECT_GT(info.file_backed, 0); @@ -472,9 +472,9 @@ #endif } #endif // defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) || - // defined(OS_ANDROID) + // defined(OS_CHROMEOS) || defined(OS_ANDROID) -#if defined(OS_LINUX) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) TEST(ProcessMetricsTest, ParseProcStatCPU) { // /proc/self/stat for a process running "top". const char kTopStat[] = "960 (top) S 16230 960 16230 34818 960 " @@ -581,11 +581,11 @@ "invalid334 4\n", // invalid header / line 123, time_in_state)); } -#endif // defined(OS_LINUX) || defined(OS_ANDROID) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) // Disable on Android because base_unittests runs inside a Dalvik VM that // starts and stop threads (crbug.com/175563). -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // http://crbug.com/396455 TEST(ProcessMetricsTest, DISABLED_GetNumberOfThreads) { const ProcessHandle current = GetCurrentProcessHandle(); @@ -603,9 +603,9 @@ // The Thread destructor will stop them. ASSERT_EQ(initial_threads, GetNumberOfThreads(current)); } -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) -#if defined(OS_LINUX) || defined(OS_MAC) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) namespace { // Keep these in sync so the GetChildOpenFdCount test can refer to correct test @@ -729,9 +729,9 @@ EXPECT_EQ(new_fd_count, fd_count + 1); } -#endif // defined(OS_LINUX) || defined(OS_MAC) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) -#if defined(OS_ANDROID) || defined(OS_LINUX) +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) TEST(ProcessMetricsTestLinux, GetPageFaultCounts) { std::unique_ptr<base::ProcessMetrics> process_metrics( @@ -875,7 +875,7 @@ } } -#endif // defined(OS_ANDROID) || defined(OS_LINUX) +#endif // defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) #if defined(OS_WIN) TEST(ProcessMetricsTest, GetDiskUsageBytesPerSecond) {
diff --git a/base/process/process_posix.cc b/base/process/process_posix.cc index 4dc7663a..fc771b34 100644 --- a/base/process/process_posix.cc +++ b/base/process/process_posix.cc
@@ -267,12 +267,14 @@ return Process(handle); } -#if !defined(OS_LINUX) && !defined(OS_MAC) && !defined(OS_AIX) +#if !defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_MAC) && \ + !defined(OS_AIX) // static bool Process::CanBackgroundProcesses() { return false; } -#endif // !defined(OS_LINUX) && !defined(OS_MAC) && !defined(OS_AIX) +#endif // !defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_MAC) && + // !defined(OS_AIX) // static void Process::TerminateCurrentProcessImmediately(int exit_code) { @@ -362,7 +364,8 @@ void Process::Exited(int exit_code) const {} -#if !defined(OS_LINUX) && !defined(OS_MAC) && !defined(OS_AIX) +#if !defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_MAC) && \ + !defined(OS_AIX) bool Process::IsProcessBackgrounded() const { // See SetProcessBackgrounded(). DCHECK(IsValid()); @@ -376,7 +379,8 @@ NOTIMPLEMENTED(); return false; } -#endif // !defined(OS_LINUX) && !defined(OS_MAC) && !defined(OS_AIX) +#endif // !defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_MAC) && + // !defined(OS_AIX) int Process::GetPriority() const { DCHECK(IsValid());
diff --git a/base/process/process_unittest.cc b/base/process/process_unittest.cc index 262cd11..e512a67f 100644 --- a/base/process/process_unittest.cc +++ b/base/process/process_unittest.cc
@@ -154,7 +154,7 @@ // was spawned and a time recorded after it was spawned. However, since the // base::Time and process creation clocks don't match, tolerate some error. constexpr base::TimeDelta kTolerance = -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // On Linux, process creation time is relative to boot time which has a // 1-second resolution. Tolerate 1 second for the imprecise boot time and // 100 ms for the imprecise clock.
diff --git a/base/process/process_util_unittest.cc b/base/process/process_util_unittest.cc index 3fc3faf..da83d2580 100644 --- a/base/process/process_util_unittest.cc +++ b/base/process/process_util_unittest.cc
@@ -40,7 +40,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/multiprocess_func_list.h" -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #include <malloc.h> #include <sched.h> #include <sys/syscall.h> @@ -1307,11 +1307,11 @@ options.fds_to_remap.emplace_back(fds[1], STDOUT_FILENO); #endif // defined(OS_WIN) -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) options.clone_flags = clone_flags; #else CHECK_EQ(0, clone_flags); -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) EXPECT_TRUE(LaunchProcess(cmdline, options).IsValid()); write_pipe.Close(); @@ -1377,11 +1377,11 @@ EXPECT_EQ("wibble", TestLaunchProcess(kPrintEnvCommand, env_changes, no_clear_environ, no_clone_flags)); -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // Test a non-trival value for clone_flags. EXPECT_EQ("wibble", TestLaunchProcess(kPrintEnvCommand, env_changes, no_clear_environ, CLONE_FS)); -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) EXPECT_EQ("wibble", TestLaunchProcess(kPrintEnvCommand, env_changes, @@ -1391,7 +1391,7 @@ true /* clear_environ */, no_clone_flags)); } -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) MULTIPROCESS_TEST_MAIN(CheckPidProcess) { const pid_t kInitPid = 1; const pid_t pid = syscall(__NR_getpid); @@ -1452,6 +1452,6 @@ EXPECT_TRUE(process.WaitForExit(&exit_code)); EXPECT_NE(kSuccess, exit_code); } -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) } // namespace base
diff --git a/base/security_unittest.cc b/base/security_unittest.cc index 786c6f7a..785bc94b 100644 --- a/base/security_unittest.cc +++ b/base/security_unittest.cc
@@ -76,18 +76,23 @@ #if defined(OS_FUCHSIA) || defined(OS_APPLE) || defined(ADDRESS_SANITIZER) || \ defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \ - BUILDFLAG(IS_HWASAN) + BUILDFLAG(IS_HWASAN) || BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) #define MAYBE_NewOverflow DISABLED_NewOverflow #else #define MAYBE_NewOverflow NewOverflow #endif -// Test array[TooBig][X] and array[X][TooBig] allocations for int -// overflows. IOS doesn't honor nothrow, so disable the test there. +// Test that array[TooBig][X] and array[X][TooBig] allocations fail and not +// succeed with the wrong size allocation in case of size_t overflow. This +// test is disabled on environments that operator new (nothrow) crashes in +// case of size_t overflow. +// +// - iOS doesn't honor nothrow. +// - XSan aborts when operator new returns nullptr. +// - PartitionAlloc crashes by design when size_t overflows. +// // TODO(https://crbug.com/828229): Fuchsia SDK exports an incorrect // new[] that gets picked up in Debug/component builds, breaking this -// test. Disabled on Mac for the same reason. Disabled under XSan -// because asan aborts when new returns nullptr, -// https://bugs.chromium.org/p/chromium/issues/detail?id=690271#c15 +// test. Disabled on Mac for the same reason. TEST(SecurityTest, MAYBE_NewOverflow) { const size_t kArraySize = 4096; // We want something "dynamic" here, so that the compiler doesn't
diff --git a/base/strings/sys_string_conversions_unittest.cc b/base/strings/sys_string_conversions_unittest.cc index c2e93e6..2bd868c 100644 --- a/base/strings/sys_string_conversions_unittest.cc +++ b/base/strings/sys_string_conversions_unittest.cc
@@ -75,8 +75,8 @@ EXPECT_EQ(expected_null, SysUTF8ToWide(utf8_null)); } -#if defined(OS_LINUX) // Tests depend on setting a specific Linux locale. - +// Tests depend on setting a specific Linux locale. +#if defined(OS_LINUX) || defined(OS_CHROMEOS) TEST(SysStrings, SysWideToNativeMB) { #if !defined(SYSTEM_NATIVE_UTF8) ScopedLocale locale("en_US.UTF-8"); @@ -191,6 +191,6 @@ EXPECT_EQ(wide, trip); } } -#endif // OS_LINUX +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) } // namespace base
diff --git a/base/syslog_logging.cc b/base/syslog_logging.cc index df9b6d10..1334927 100644 --- a/base/syslog_logging.cc +++ b/base/syslog_logging.cc
@@ -13,7 +13,7 @@ #include "base/strings/string_util.h" #include "base/win/scoped_handle.h" #include "base/win/win_util.h" -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) || defined(OS_CHROMEOS) // <syslog.h> defines LOG_INFO, LOG_WARNING macros that could conflict with // base::LOG_INFO, base::LOG_WARNING. #include <syslog.h> @@ -134,7 +134,7 @@ if (user_sid != nullptr) ::LocalFree(user_sid); -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) || defined(OS_CHROMEOS) const char kEventSource[] = "chrome"; openlog(kEventSource, LOG_NOWAIT | LOG_PID, LOG_USER); // We can't use the defined names for the logging severity from syslog.h
diff --git a/base/system/sys_info.cc b/base/system/sys_info.cc index 4c5340d0..d1aa830 100644 --- a/base/system/sys_info.cc +++ b/base/system/sys_info.cc
@@ -104,7 +104,7 @@ #elif defined(OS_ANDROID) || defined(OS_APPLE) base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {}, base::BindOnce(&GetHardwareInfoSync), std::move(callback)); -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) || defined(OS_CHROMEOS) base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock()}, base::BindOnce(&GetHardwareInfoSync), std::move(callback));
diff --git a/base/system/sys_info.h b/base/system/sys_info.h index 4f39c00f..fe737010d 100644 --- a/base/system/sys_info.h +++ b/base/system/sys_info.h
@@ -211,7 +211,8 @@ static bool IsLowEndDeviceImpl(); static HardwareInfo GetHardwareInfoSync(); -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_AIX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ + defined(OS_AIX) static int64_t AmountOfAvailablePhysicalMemory( const SystemMemoryInfoKB& meminfo); #endif
diff --git a/base/system/sys_info_posix.cc b/base/system/sys_info_posix.cc index 32e72d7..381ed36 100644 --- a/base/system/sys_info_posix.cc +++ b/base/system/sys_info_posix.cc
@@ -29,7 +29,7 @@ #include <sys/statvfs.h> #endif -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #include <linux/magic.h> #include <sys/vfs.h> #endif @@ -78,7 +78,7 @@ base::internal::LazySysInfoValue<int64_t, AmountOfVirtualMemory>>::Leaky g_lazy_virtual_memory = LAZY_INSTANCE_INITIALIZER; -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) bool IsStatsZeroIfUnlimited(const base::FilePath& path) { struct statfs stats; @@ -93,7 +93,7 @@ } return false; } -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) bool GetDiskSpaceInfo(const base::FilePath& path, int64_t* available_bytes, @@ -102,7 +102,7 @@ if (HANDLE_EINTR(statvfs(path.value().c_str(), &stats)) != 0) return false; -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) const bool zero_size_means_unlimited = stats.f_blocks == 0 && IsStatsZeroIfUnlimited(path); #else
diff --git a/base/system/sys_info_unittest.cc b/base/system/sys_info_unittest.cc index 4ff9a9a..c1bf352 100644 --- a/base/system/sys_info_unittest.cc +++ b/base/system/sys_info_unittest.cc
@@ -50,13 +50,13 @@ EXPECT_GE(SysInfo::AmountOfVirtualMemory(), 0); } -#if defined(OS_LINUX) || defined(OS_ANDROID) -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #define MAYBE_AmountOfAvailablePhysicalMemory \ DISABLED_AmountOfAvailablePhysicalMemory #else #define MAYBE_AmountOfAvailablePhysicalMemory AmountOfAvailablePhysicalMemory -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) TEST_F(SysInfoTest, MAYBE_AmountOfAvailablePhysicalMemory) { // Note: info is in _K_bytes. SystemMemoryInfoKB info; @@ -87,7 +87,7 @@ EXPECT_GT(amount, static_cast<int64_t>(info.free) * 1024); EXPECT_LT(amount / 1024, info.total); } -#endif // defined(OS_LINUX) || defined(OS_ANDROID) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) #if defined(OS_FUCHSIA) // TODO(crbug.com/851734): Implementation depends on statvfs, which is not @@ -118,7 +118,7 @@ } #if defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) || \ - defined(OS_FUCHSIA) + defined(OS_CHROMEOS) || defined(OS_FUCHSIA) TEST_F(SysInfoTest, OperatingSystemVersionNumbers) { int32_t os_major_version = -1; int32_t os_minor_version = -1; @@ -178,7 +178,7 @@ EXPECT_TRUE(IsStringUTF8(hardware_info->model)); bool empty_result_expected = #if defined(OS_ANDROID) || defined(OS_APPLE) || defined(OS_WIN) || \ - defined(OS_LINUX) + defined(OS_LINUX) || defined(OS_CHROMEOS) false; #else true;
diff --git a/base/test/test_file_util_posix.cc b/base/test/test_file_util_posix.cc index d31e89c7..add3174 100644 --- a/base/test/test_file_util_posix.cc +++ b/base/test/test_file_util_posix.cc
@@ -87,7 +87,8 @@ sync(); } -#if !defined(OS_LINUX) && !defined(OS_APPLE) && !defined(OS_ANDROID) +#if !defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_APPLE) && \ + !defined(OS_ANDROID) bool EvictFileFromSystemCache(const FilePath& file) { // There doesn't seem to be a POSIX way to cool the disk cache. NOTIMPLEMENTED();
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index 8e5f102c..4406928 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc
@@ -66,7 +66,7 @@ #include "base/test/test_support_android.h" #endif -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #include "base/test/fontconfig_util_linux.h" #endif @@ -382,14 +382,14 @@ testing::GTEST_FLAG(catch_exceptions) = false; #endif EnableTerminationOnHeapCorruption(); -#if defined(OS_LINUX) && defined(USE_AURA) +#if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(USE_AURA) // When calling native char conversion functions (e.g wrctomb) we need to // have the locale set. In the absence of such a call the "C" locale is the // default. In the gtk code (below) gtk_init() implicitly sets a locale. setlocale(LC_ALL, ""); // We still need number to string conversions to be locale insensitive. setlocale(LC_NUMERIC, "C"); -#endif // defined(OS_LINUX) && defined(USE_AURA) +#endif // (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(USE_AURA) // On Android, AtExitManager is created in // testing/android/native_test_wrapper.cc before main() is called. @@ -650,7 +650,7 @@ // TODO(jshin): Should we set the locale via an OS X locale API here? i18n::SetICUDefaultLocale("en_US"); -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) SetUpFontconfig(); #endif
diff --git a/base/threading/platform_thread.h b/base/threading/platform_thread.h index ab7e8da..39baf182 100644 --- a/base/threading/platform_thread.h +++ b/base/threading/platform_thread.h
@@ -221,7 +221,7 @@ static ThreadPriority GetCurrentThreadPriority(); -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // Toggles a specific thread's priority at runtime. This can be used to // change the priority of a thread in a different process and will fail // if the calling process does not have proper permissions. The
diff --git a/base/threading/platform_thread_internal_posix.h b/base/threading/platform_thread_internal_posix.h index d248fa9..ef907352 100644 --- a/base/threading/platform_thread_internal_posix.h +++ b/base/threading/platform_thread_internal_posix.h
@@ -47,13 +47,13 @@ // of CanIncreaseThreadPriority(). Optional<ThreadPriority> GetCurrentThreadPriorityForPlatform(); -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // Current thread id is cached in thread local storage for performance reasons. // In some rare cases it's important to clear that cache explicitly (e.g. after // going through clone() syscall which does not call pthread_atfork() // handlers). BASE_EXPORT void ClearTidCache(); -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) } // namespace internal
diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc index 3e5d666..403b91d 100644 --- a/base/threading/platform_thread_posix.cc +++ b/base/threading/platform_thread_posix.cc
@@ -28,7 +28,7 @@ #include "base/posix/can_lower_nice_to.h" #endif -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #include <sys/syscall.h> #endif @@ -135,7 +135,7 @@ return success; } -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // Store the thread ids in local storage since calling the SWI can // expensive and PlatformThread::CurrentId is used liberally. Clear @@ -153,11 +153,11 @@ InitAtFork() { pthread_atfork(nullptr, nullptr, internal::ClearTidCache); } }; -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) } // namespace -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) namespace internal { @@ -167,7 +167,7 @@ } // namespace internal -#endif // defined(OS_LINUX) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) // static PlatformThreadId PlatformThread::CurrentId() { @@ -175,7 +175,7 @@ // into the kernel. #if defined(OS_APPLE) return pthread_mach_thread_np(pthread_self()); -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) || defined(OS_CHROMEOS) static NoDestructor<InitAtFork> init_at_fork; if (g_thread_id == -1) { g_thread_id = syscall(__NR_gettid);
diff --git a/base/threading/platform_thread_unittest.cc b/base/threading/platform_thread_unittest.cc index 8144665a..376b7bc 100644 --- a/base/threading/platform_thread_unittest.cc +++ b/base/threading/platform_thread_unittest.cc
@@ -302,7 +302,7 @@ // and hardcodes what we know. Please inform scheduler-dev@chromium.org if this // proprerty changes for a given platform. TEST(PlatformThreadTest, CanIncreaseThreadPriority) { -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) // On Ubuntu, RLIMIT_NICE and RLIMIT_RTPRIO are 0 by default, so we won't be // able to increase priority to any level. constexpr bool kCanIncreasePriority = false; @@ -397,7 +397,8 @@ TEST(PlatformThreadTest, GetDefaultThreadStackSize) { size_t stack_size = PlatformThread::GetDefaultThreadStackSize(); #if defined(OS_WIN) || defined(OS_IOS) || defined(OS_FUCHSIA) || \ - (defined(OS_LINUX) && !defined(THREAD_SANITIZER)) || \ + ((defined(OS_LINUX) || defined(OS_CHROMEOS)) && \ + !defined(THREAD_SANITIZER)) || \ (defined(OS_ANDROID) && !defined(ADDRESS_SANITIZER)) EXPECT_EQ(0u, stack_size); #else
diff --git a/base/trace_event/traced_value.cc b/base/trace_event/traced_value.cc index e4cb0067..a5fba8e 100644 --- a/base/trace_event/traced_value.cc +++ b/base/trace_event/traced_value.cc
@@ -882,5 +882,50 @@ return str; } +TracedValue::ArrayScope::ArrayScope(TracedValue* value) : value_(value) { + value_->BeginArray(); +} + +TracedValue::ArrayScope::ArrayScope(TracedValue* value, const char* name) + : value_(value) { + value_->BeginArray(name); +} + +TracedValue::ArrayScope::~ArrayScope() { + value_->EndArray(); +} + +TracedValue::ArrayScope TracedValue::AppendArrayScoped() { + return TracedValue::ArrayScope(this); +} + +TracedValue::ArrayScope TracedValue::BeginArrayScoped(const char* name) { + return TracedValue::ArrayScope(this, name); +} + +TracedValue::DictionaryScope::DictionaryScope(TracedValue* value) + : value_(value) { + value_->BeginDictionary(); +} + +TracedValue::DictionaryScope::DictionaryScope(TracedValue* value, + const char* name) + : value_(value) { + value_->BeginDictionary(name); +} + +TracedValue::DictionaryScope::~DictionaryScope() { + value_->EndDictionary(); +} + +TracedValue::DictionaryScope TracedValue::AppendDictionaryScoped() { + return TracedValue::DictionaryScope(this); +} + +TracedValue::DictionaryScope TracedValue::BeginDictionaryScoped( + const char* name) { + return TracedValue::DictionaryScope(this, name); +} + } // namespace trace_event } // namespace base
diff --git a/base/trace_event/traced_value.h b/base/trace_event/traced_value.h index 58fc2f3..f7f2c09 100644 --- a/base/trace_event/traced_value.h +++ b/base/trace_event/traced_value.h
@@ -67,6 +67,73 @@ void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead) override; + // Helper to open / close an array. The ctor of |ArrayScope| opens the array, + // the dtor closes. To be used via |TracedValue::AppendArrayScoped| and + // |TracedValue::BeginArrayScoped|. + // + // |ArrayScope| holds a |TracedValue| pointer which should remain a valid + // pointer at the time |ArrayScope::~ArrayScope| is called. + // + // |ArrayScope::ArrayScope| calls |TracedValue::BeginArray| + // |ArrayScope::~ArrayScope| calls |TracedValue::EndArray| (which checks if + // the held |TracedValue*| is in array state). + // + // Example: + // std::unique_ptr<TracedValue> value(new TracedValue()); + // { + // auto scope = value->BeginArrayScoped("array_name"); + // value->AppendBoolean(false); + // } + class BASE_EXPORT ArrayScope { + public: + ~ArrayScope(); + + private: + explicit ArrayScope(TracedValue* value); + explicit ArrayScope(TracedValue* value, const char* name); + + TracedValue* value_; + + friend class TracedValue; + }; + + ArrayScope AppendArrayScoped(); + ArrayScope BeginArrayScoped(const char* name); + + // Helper to open / close a dictionary. The ctor of |DictionaryScope| opens + // the dictionary, the dtor closes. To be used via + // |TracedValue::AppendDictionaryScoped| and + // |TracedValue::BeginDictionaryScoped|. + // + // |DictionaryScope| holds a |TracedValue| pointer which should remain a valid + // pointer at the time |DictionaryScope::~DictionaryScope| is called. + // + // |DictionaryScope::DictionaryScope| calls |TracedValue::BeginDictionary| + // |DictionaryScope::~DictionaryScope| calls |TracedValue::EndDictionary| + // (which checks if the held |TracedValue*| is in dictionary state). + // + // Example: + // std::unique_ptr<TracedValue> value(new TracedValue()); + // { + // auto scope = value->BeginDictionaryScoped("dictionary_name"); + // value->SetBoolean("my_boolean", false); + // } + class BASE_EXPORT DictionaryScope { + public: + ~DictionaryScope(); + + private: + explicit DictionaryScope(TracedValue* value); + explicit DictionaryScope(TracedValue* value, const char* name); + + TracedValue* value_; + + friend class TracedValue; + }; + + DictionaryScope AppendDictionaryScoped(); + DictionaryScope BeginDictionaryScoped(const char* name); + class BASE_EXPORT Array; class BASE_EXPORT Dictionary; class BASE_EXPORT ValueHolder;
diff --git a/base/trace_event/traced_value_unittest.cc b/base/trace_event/traced_value_unittest.cc index 24238a78..e06faf00 100644 --- a/base/trace_event/traced_value_unittest.cc +++ b/base/trace_event/traced_value_unittest.cc
@@ -53,6 +53,54 @@ json); } +TEST(TraceEventArgumentTest, ArrayAndDictionaryScope) { + std::unique_ptr<TracedValue> value(new TracedValue()); + { + auto dictionary = value->BeginDictionaryScoped("dictionary_name"); + value->SetInteger("my_int", 1); + } + { + auto array = value->BeginArrayScoped("array_name"); + value->AppendInteger(2); + } + { + auto surround_dictionary = + value->BeginDictionaryScoped("outside_dictionary"); + value->SetBoolean("my_bool:", true); + { + auto inside_array = value->BeginArrayScoped("inside_array"); + value->AppendBoolean(false); + } + { + auto inside_array = value->BeginDictionaryScoped("inside_dictionary"); + value->SetBoolean("inner_bool", false); + } + } + { + auto surround_array = value->BeginArrayScoped("outside_array"); + value->AppendBoolean(false); + { + auto inside_dictionary = value->AppendDictionaryScoped(); + value->SetBoolean("my_bool:", true); + } + { + auto inside_array = value->AppendArrayScoped(); + value->AppendBoolean(false); + } + } + std::string json; + value->AppendAsTraceFormat(&json); + EXPECT_EQ( + "{" + "\"dictionary_name\":{\"my_int\":1}," + "\"array_name\":[2]," + "\"outside_dictionary\":{\"my_bool:\":true,\"inside_array\":[false]," + "\"inside_dictionary\":{\"inner_bool\":false}}," + "\"outside_array\":[false,{\"my_bool:\":true},[false]]" + "}", + json); +} + std::string SayHello() { // Create a string by concatenating two strings, so that there is no literal // corresponding to the result.
diff --git a/build/args/headless.gn b/build/args/headless.gn index d941799..6936b258 100644 --- a/build/args/headless.gn +++ b/build/args/headless.gn
@@ -44,3 +44,4 @@ v8_enable_lazy_source_positions = false use_glib = false use_gtk = false +use_pangocairo = false
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 9de62d2..6ecdbc0 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -2317,10 +2317,12 @@ swiftflags = [ "-g" ] } - if (use_debug_fission && !is_nacl && !is_android) { + if (use_debug_fission && !is_nacl && + (!is_android || target_os == "android")) { # NOTE: Some Chrome OS builds globally set |use_debug_fission| to true, - # but they also build some targets against Android toolchains which aren't - # compatible with it. + # but they also build some targets whose toolchains aren't + # compatible with it. In particular don't turn it on for Android + # toolchain if not building for Android OS. # # TODO(https://crbug.com/837032): See if we can clean this up by e.g. not # setting use_debug_fission globally. @@ -2329,6 +2331,16 @@ asmflags = cflags ldflags = [] + if (use_debug_fission && is_android && target_os == "android") { + # NOTE: This flag is for use by the link wrapper scripts. They are also + # expected to remove it before sending the rest of ldflags to the actual + # linker. Only expect Android Chrome build on Android OS to need this. + ldflags += [ + "--generate-dwp", + "-gsplit-dwarf", + ] + } + # TODO(thakis): Figure out if there's a way to make this go for 32-bit, # currently we get "warning: # obj/native_client/src/trusted/service_runtime/sel_asm/nacl_switch_32.o:
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index 3eff75f5..918712d 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni
@@ -194,8 +194,8 @@ !use_lld && !(is_chromecast && is_linux && (current_cpu == "arm" || current_cpu == "mipsel")) && ((is_linux && (current_cpu == "x64" || current_cpu == "x86" || - current_cpu == "arm" || current_cpu == "arm64" || - current_cpu == "mipsel" || current_cpu == "mips64el")) || + current_cpu == "arm" || current_cpu == "arm64" || + current_cpu == "mipsel" || current_cpu == "mips64el")) || (is_android && (current_cpu == "x86" || current_cpu == "x64" || current_cpu == "arm" || current_cpu == "arm64"))) } @@ -210,8 +210,8 @@ # deterministic builds to reduce compile times, so this is less relevant for # official builders. strip_absolute_paths_from_debug_symbols_default = - is_android || is_fuchsia || is_nacl || (is_win && use_lld) || is_linux || is_chromeos || - (is_mac && !enable_dsyms) || ios_use_goma_rbe + is_android || is_fuchsia || is_nacl || (is_win && use_lld) || is_linux || + is_chromeos || (is_mac && !enable_dsyms) || ios_use_goma_rbe # If the platform uses stripped absolute paths by default, then we don't expose # it as a configuration option. If this is causing problems, please file a bug. @@ -226,7 +226,8 @@ # If it wasn't manually set, set to an appropriate default. assert(symbol_level >= -1 && symbol_level <= 2, "Invalid symbol_level") if (symbol_level == -1) { - if (is_android && !is_component_build) { + if (is_android && !is_component_build && + !(use_debug_fission != "default" && use_debug_fission)) { # Reduce symbol level when it will cause invalid elf files to be created # (due to file size). https://crbug.com/648948. symbol_level = 1 @@ -247,8 +248,9 @@ # info or variable info, so we can leave that out to speed up the build. # Sanitizers also require symbols for filename suppressions to work. symbol_level = 1 - } else if ((!is_nacl && !is_linux && !is_chromeos && !is_fuchsia && current_os != "aix") || - is_debug || is_official_build || is_chromecast) { + } else if ((!is_nacl && !is_linux && !is_chromeos && !is_fuchsia && + current_os != "aix") || is_debug || is_official_build || + is_chromecast) { # Linux builds slower by having symbols as part of the target binary, # whereas Mac and Windows have them separate, so in Release Linux, default # them off, but keep them on for Official builds and Chromecast builds. @@ -273,9 +275,11 @@ # Assert that the configuration isn't going to hit https://crbug.com/648948. # An exception is made when target_os == "chromeos" as we only use the Android # toolchain there to build relatively small binaries. -assert(ignore_elf32_limitations || !is_android || target_os == "chromeos" || - is_component_build || symbol_level < 2, - "Android 32-bit non-component builds cannot have symbol_level=2 " + - "due to 4GiB file size limit, see https://crbug.com/648948. " + - "If you really want to try this out, " + - "set ignore_elf32_limitations=true.") +assert( + ignore_elf32_limitations || !is_android || target_os == "chromeos" || + is_component_build || symbol_level < 2 || + (use_debug_fission != "default" && use_debug_fission), + "Android 32-bit non-component builds without DWARF Fission cannot " + + "have symbol_level=2 due to 4GiB file size limit, see " + + "https://crbug.com/648948. " + "If you really want to try this out, " + + "set ignore_elf32_limitations=true.")
diff --git a/build/extract_partition.py b/build/extract_partition.py index 52607c8..7ee93cb 100755 --- a/build/extract_partition.py +++ b/build/extract_partition.py
@@ -30,6 +30,7 @@ required=True, help='Stripped output file', metavar='FILE') + parser.add_argument('--dwp', help='Path to dwp binary', metavar='FILE') parser.add_argument('input', help='Input file') args = parser.parse_args() @@ -46,6 +47,13 @@ ] subprocess.check_call(objcopy_args) + if args.dwp: + dwp_args = [ + args.dwp, '-e', args.unstripped_output, '-o', + args.stripped_output + '.dwp' + ] + subprocess.check_call(dwp_args) + if __name__ == '__main__': sys.exit(main())
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 0d80c57..9fcd918 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20200824.3.1 +0.20200825.0.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 0d80c57..9fcd918 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20200824.3.1 +0.20200825.0.1
diff --git a/build/partitioned_shared_library.gni b/build/partitioned_shared_library.gni index bb2cefb..ef7408c2 100644 --- a/build/partitioned_shared_library.gni +++ b/build/partitioned_shared_library.gni
@@ -3,7 +3,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/android/config.gni") import("//build/config/clang/clang.gni") +import("//build/config/compiler/compiler.gni") # This template creates a set of shared libraries, by linking a single # "partitioned" shared library, then splitting it into multiple pieces. @@ -97,6 +99,16 @@ "${invoker.partition}", ] } + + # Restrict to Android OS because ChromeOS uses the Android toolchain with + # use_debug_fission set globally, which isn't reliable across all + # possible build configs with Android. + if (is_android && target_os == "android" && + use_debug_fission != "default" && use_debug_fission) { + dwp = rebase_path("${android_tool_prefix}dwp", root_build_dir) + args += [ "--dwp=${dwp}" ] + outputs += [ invoker.stripped_output + ".dwp" ] + } args += [ rebase_path(sources[0], root_build_dir) ] } }
diff --git a/build/toolchain/android/BUILD.gn b/build/toolchain/android/BUILD.gn index ceca1a4..075dcad 100644 --- a/build/toolchain/android/BUILD.gn +++ b/build/toolchain/android/BUILD.gn
@@ -42,6 +42,7 @@ ld = cxx readelf = _tool_prefix + "readelf" nm = _tool_prefix + "nm" + dwp = _tool_prefix + "dwp" strip = rebase_path("//buildtools/third_party/eu-strip/bin/eu-strip", root_build_dir) use_unstripped_as_runtime_outputs = android_unstripped_runtime_outputs
diff --git a/build/toolchain/gcc_link_wrapper.py b/build/toolchain/gcc_link_wrapper.py index 8892f14b..f73221e 100755 --- a/build/toolchain/gcc_link_wrapper.py +++ b/build/toolchain/gcc_link_wrapper.py
@@ -45,6 +45,7 @@ help=('Use --Wl,-Map to generate a map file. Will be ' 'gzipped if extension ends with .gz'), metavar='FILE') + parser.add_argument('--dwp', help=('The dwp binary to run'), metavar='FILE') parser.add_argument('--output', required=True, help='Final output executable file', @@ -53,6 +54,10 @@ help='Linking command') args = parser.parse_args() + generate_dwp = '--generate-dwp' in args.command + if generate_dwp: + args.command.remove('--generate-dwp') + # Work-around for gold being slow-by-default. http://crbug.com/632230 fast_env = dict(os.environ) fast_env['LC_ALL'] = 'C' @@ -61,12 +66,29 @@ if result != 0: return result + # If dwp is set, then package debug info for this exe. + dwp_proc = None + if generate_dwp: + if not args.dwp: + parser.error('--generate-dwp requireds --dwp') + exe_file = args.output + if args.unstripped_file: + exe_file = args.unstripped_file + dwp_proc = subprocess.Popen( + wrapper_utils.CommandToRun( + [args.dwp, '-e', exe_file, '-o', args.output + '.dwp'])) + # Finally, strip the linked executable (if desired). if args.strip: result = subprocess.call(CommandToRun([ args.strip, '-o', args.output, args.unstripped_file ])) + if dwp_proc: + dwp_result = dwp_proc.wait() + if dwp_result != 0: + return dwp_result + return result
diff --git a/build/toolchain/gcc_solink_wrapper.py b/build/toolchain/gcc_solink_wrapper.py index 66b7f0c..0c034bf9 100755 --- a/build/toolchain/gcc_solink_wrapper.py +++ b/build/toolchain/gcc_solink_wrapper.py
@@ -93,6 +93,7 @@ parser.add_argument('--strip', help='The strip binary to run', metavar='PATH') + parser.add_argument('--dwp', help='The dwp binary to run', metavar='PATH') parser.add_argument('--sofile', required=True, help='Shared object file produced by linking command', @@ -121,6 +122,16 @@ # https://crbug.com/954311 tracks finding a better way to plumb these. link_only = InterceptFlag('--link-only', args.command) collect_inputs_only = InterceptFlag('--collect-inputs-only', args.command) + generate_dwp = InterceptFlag('--generate-dwp', args.command) + + # First, run the actual link. + command = wrapper_utils.CommandToRun(args.command) + result = wrapper_utils.RunLinkWithOptionalMapFile(command, + env=fast_env, + map_file=args.map_file) + + if result != 0: + return result # If only linking, we are likely generating a partitioned .so that will be # split apart later. In that case: @@ -158,6 +169,15 @@ if result != 0 or link_only: return result + # If dwp is set, then package debug info for this SO. + dwp_proc = None + if generate_dwp: + if not args.dwp: + parser.error('--generate-dwp requireds --dwp') + dwp_proc = subprocess.Popen( + wrapper_utils.CommandToRun( + [args.dwp, '-e', args.sofile, '-o', args.output + '.dwp'])) + # Next, generate the contents of the TOC file. result, toc = CollectTOC(args) if result != 0: @@ -172,6 +192,11 @@ result = subprocess.call(wrapper_utils.CommandToRun( [args.strip, '-o', args.output, args.sofile])) + if dwp_proc: + dwp_result = dwp_proc.wait() + if dwp_result != 0: + return dwp_result + return result
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni index 06854b7..4710fd5 100644 --- a/build/toolchain/gcc_toolchain.gni +++ b/build/toolchain/gcc_toolchain.gni
@@ -237,6 +237,11 @@ } else { nm = "nm" } + if (defined(invoker.dwp)) { + dwp = invoker.dwp + } else { + dwp = "dwp" + } if (defined(invoker.shlib_extension)) { default_shlib_extension = invoker.shlib_extension @@ -398,7 +403,7 @@ # The host might not have a POSIX shell and utilities (e.g. Windows). solink_wrapper = rebase_path("//build/toolchain/gcc_solink_wrapper.py", root_build_dir) - command = "$python_path \"$solink_wrapper\" --readelf=\"$readelf\" --nm=\"$nm\" $strip_switch--sofile=\"$unstripped_sofile\" --tocfile=\"$tocfile\"$map_switch --output=\"$sofile\" -- $link_command" + command = "$python_path \"$solink_wrapper\" --readelf=\"$readelf\" --nm=\"$nm\" $strip_switch--dwp=\"${dwp}\" --sofile=\"$unstripped_sofile\" --tocfile=\"$tocfile\"$map_switch --output=\"$sofile\" -- $link_command" if (target_cpu == "mipsel" && is_component_build && is_android) { rspfile_content = "-Wl,--start-group -Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}} -Wl,--end-group" @@ -528,13 +533,9 @@ strip_switch = " --strip=\"${invoker.strip}\" --unstripped-file=\"$unstripped_outfile\"" } - if (strip_switch != "" || map_switch != "") { - link_wrapper = - rebase_path("//build/toolchain/gcc_link_wrapper.py", root_build_dir) - command = "$python_path \"$link_wrapper\" --output=\"$outfile\"$strip_switch$map_switch -- $link_command" - } else { - command = link_command - } + link_wrapper = + rebase_path("//build/toolchain/gcc_link_wrapper.py", root_build_dir) + command = "$python_path \"$link_wrapper\" --output=\"$outfile\"$strip_switch$map_switch --dwp=\"${dwp}\" -- $link_command" description = "LINK $outfile" rspfile_content = "{{inputs}}" @@ -596,6 +597,7 @@ readelf = "${toolprefix}readelf" ar = "${prefix}/llvm-ar" nm = "${toolprefix}nm" + dwp = "${toolprefix}dwp" forward_variables_from(invoker, [
diff --git a/build/toolchain/win/setup_toolchain.py b/build/toolchain/win/setup_toolchain.py index d9cd612..58bf3e8c 100644 --- a/build/toolchain/win/setup_toolchain.py +++ b/build/toolchain/win/setup_toolchain.py
@@ -102,9 +102,15 @@ # Load environment from json file. env = os.path.normpath(os.path.join(sdk_dir, 'bin/SetEnv.%s.json' % cpu)) env = json.load(open(env))['env'] + if env['VSINSTALLDIR'] == [["..", "..\\"]]: + # Old-style paths were relative to the win_sdk\bin directory. + json_relative_dir = os.path.join(sdk_dir, 'bin') + else: + # New-style paths are relative to the toolchain directory, which is the + # parent of the SDK directory. + json_relative_dir = os.path.split(sdk_dir)[0] for k in env: - entries = [os.path.join(*([os.path.join(sdk_dir, 'bin')] + e)) - for e in env[k]] + entries = [os.path.join(*([json_relative_dir] + e)) for e in env[k]] # clang-cl wants INCLUDE to be ;-separated even on non-Windows, # lld-link wants LIB to be ;-separated even on non-Windows. Path gets :. # The separator for INCLUDE here must match the one used in main() below.
diff --git a/chrome/VERSION b/chrome/VERSION index a11996f7..e35c032 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=87 MINOR=0 -BUILD=4244 +BUILD=4245 PATCH=0
diff --git a/chrome/android/features/tab_ui/java/res/layout/tab_grid_dialog_layout.xml b/chrome/android/features/tab_ui/java/res/layout/tab_grid_dialog_layout.xml index 6af12dff..757ed3d 100644 --- a/chrome/android/features/tab_ui/java/res/layout/tab_grid_dialog_layout.xml +++ b/chrome/android/features/tab_ui/java/res/layout/tab_grid_dialog_layout.xml
@@ -17,10 +17,6 @@ android:focusable="true" android:focusableInTouchMode="true" android:background="@drawable/tab_grid_dialog_background"> - <!-- Ignore useless parents here for two reasons: - 1. Content recyclerView and toolbar view will be added programmatically later. - 2. We need to keep the LinearLayout so that we can animate the ungroup textView and shadow - imageView together. --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" @@ -28,8 +24,7 @@ android:orientation="vertical" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" - android:visibility="invisible" - tools:ignore="UselessParent"> + android:visibility="invisible"> <ImageView android:layout_width="match_parent" android:layout_height="@dimen/toolbar_shadow_height" @@ -46,6 +41,13 @@ android:background="@drawable/ungroup_bar_background" android:gravity="center" /> </LinearLayout> + <FrameLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:id="@+id/dialog_snack_bar_container_view" + android:layout_alignParentBottom="true" + android:layout_centerHorizontal="true"> + </FrameLayout> </RelativeLayout> <View android:layout_width="match_parent"
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java index 6c797b1..51fe015 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.tasks.tab_management; +import android.app.Activity; import android.content.Context; import android.graphics.Rect; import android.view.LayoutInflater; @@ -20,6 +21,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.tab_ui.R; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; import org.chromium.ui.modelutil.PropertyModel; @@ -63,10 +65,13 @@ mDialogView = containerView.findViewById(R.id.dialog_parent_view); mDialogView.setupScrimCoordinator(scrimCoordinator); } + Activity activity = (Activity) context; + SnackbarManager snackbarManager = + new SnackbarManager(activity, mDialogView.getSnackBarContainer(), null); mMediator = new TabGridDialogMediator(context, this, mModel, tabModelSelector, tabCreatorManager, resetHandler, animationSourceViewProvider, shareDelegateSupplier, - mComponentName); + snackbarManager, mComponentName); // TODO(crbug.com/1031349) : Remove the inline mode logic here, make the constructor to take // in a mode parameter instead.
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java index 87ee66c..bcafcf7 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java
@@ -35,6 +35,8 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; +import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; +import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.tab_ui.R; import org.chromium.components.browser_ui.share.ShareParams; import org.chromium.components.embedder_support.util.UrlConstants; @@ -49,7 +51,7 @@ * with the components' coordinator as well as managing the business logic * for dialog show/hide. */ -public class TabGridDialogMediator { +public class TabGridDialogMediator implements SnackbarManager.SnackbarController { /** * Defines an interface for a {@link TabGridDialogMediator} to control dialog. */ @@ -115,7 +117,8 @@ TabModelSelector tabModelSelector, TabCreatorManager tabCreatorManager, TabSwitcherMediator.ResetHandler tabSwitcherResetHandler, AnimationSourceViewProvider animationSourceViewProvider, - ObservableSupplier<ShareDelegate> shareDelegateSupplier, String componentName) { + ObservableSupplier<ShareDelegate> shareDelegateSupplier, + SnackbarManager snackbarManager, String componentName) { mContext = context; mModel = model; mTabModelSelector = tabModelSelector; @@ -142,6 +145,7 @@ public void tabClosureUndone(Tab tab) { updateDialog(); updateGridTabSwitcher(); + snackbarManager.dismissSnackbars(TabGridDialogMediator.this, tab.getId()); } @Override @@ -168,6 +172,22 @@ updateDialog(); updateGridTabSwitcher(); } + + @Override + public void tabPendingClosure(Tab tab) { + if (!mModel.get(TabGridPanelProperties.IS_DIALOG_VISIBLE)) return; + snackbarManager.showSnackbar( + Snackbar.make(tab.getTitle(), TabGridDialogMediator.this, + Snackbar.TYPE_ACTION, Snackbar.UMA_TAB_CLOSE_UNDO) + .setTemplateText( + mContext.getString(R.string.undo_bar_close_message)) + .setAction(mContext.getString(R.string.undo), tab.getId())); + } + + @Override + public void tabClosureCommitted(Tab tab) { + snackbarManager.dismissSnackbars(TabGridDialogMediator.this, tab.getId()); + } }; mTabModelSelectorObserver = new EmptyTabModelSelectorObserver() { @@ -504,6 +524,25 @@ return mTabGridDialogHandler; } + // SnackbarManager.SnackbarController implementation. + @Override + public void onAction(Object actionData) { + int tabId = (int) actionData; + TabModel model = mTabModelSelector.getModelForTabId(tabId); + if (model != null) { + model.cancelTabClosure(tabId); + } + } + + @Override + public void onDismissNoAction(Object actionData) { + int tabId = (int) actionData; + TabModel model = mTabModelSelector.getModelForTabId(tabId); + if (model != null) { + model.commitTabClosure(tabId); + } + } + /** * A handler that handles TabGridDialog related changes originated from {@link TabListMediator} * and {@link TabGridItemTouchHelperCallback}.
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java index 45f4f5f..bc8a7775 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java
@@ -74,6 +74,7 @@ private View mAnimationCardView; private View mItemView; private View mUngroupBar; + private ViewGroup mSnackBarContainer; private ViewGroup mParent; private TextView mUngroupBarTextView; private RelativeLayout mDialogContainerView; @@ -157,6 +158,7 @@ mBackgroundFrame = findViewById(R.id.dialog_frame); mBackgroundFrame.setLayoutParams(mContainerParams); mAnimationCardView = findViewById(R.id.dialog_animation_card_view); + mSnackBarContainer = findViewById(R.id.dialog_snack_bar_container_view); updateDialogWithOrientation(mContext.getResources().getConfiguration().orientation); prepareAnimation(); @@ -674,6 +676,7 @@ mDialogContainerView.addView(toolbarView); mDialogContainerView.addView(recyclerView); mDialogContainerView.addView(mUngroupBar); + mDialogContainerView.addView(mSnackBarContainer); RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) recyclerView.getLayoutParams(); params.setMargins(0, mToolbarHeight, 0, 0); @@ -804,6 +807,13 @@ mUngroupBarTextAppearance = textAppearance; } + /** + * Return the container view for undo closure snack bar. + */ + ViewGroup getSnackBarContainer() { + return mSnackBarContainer; + } + @VisibleForTesting Animator getCurrentDialogAnimatorForTesting() { return mCurrentDialogAnimator;
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java index 0caa5fc..1152fc2 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
@@ -52,6 +52,7 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.verifyTabSwitcherCardCount; import static org.chromium.chrome.features.start_surface.InstantStartTest.createTabStateFile; import static org.chromium.chrome.features.start_surface.InstantStartTest.createThumbnailBitmapAndWriteToFile; +import static org.chromium.chrome.test.util.ViewUtils.onViewWaiting; import static org.chromium.chrome.test.util.ViewUtils.waitForView; import android.content.Intent; @@ -82,6 +83,7 @@ import org.chromium.base.test.params.ParameterAnnotations; import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.FlakyTest; @@ -352,7 +354,10 @@ // Exit dialog, wait for the undo bar showing and undo the closure. clickScrimToExitDialog(cta); waitForDialogHidingAnimationInTabSwitcher(cta); - CriteriaHelper.pollInstrumentationThread(TabUiTestHelper::verifyUndoBarShowingAndClickUndo); + onViewWaiting( + allOf(withId(R.id.snackbar_button), isDescendantOfA(withId(R.id.bottom_container)), + isCompletelyDisplayed())) + .perform(click()); // Verify the undo has happened. verifyFirstCardTitle("2 tabs"); @@ -386,7 +391,10 @@ // Exit dialog, wait for the undo bar showing and undo the closure. clickScrimToExitDialog(cta); waitForDialogHidingAnimation(cta); - CriteriaHelper.pollInstrumentationThread(TabUiTestHelper::verifyUndoBarShowingAndClickUndo); + onViewWaiting( + allOf(withId(R.id.snackbar_button), isDescendantOfA(withId(R.id.bottom_container)), + isCompletelyDisplayed())) + .perform(click()); // Verify the undo has happened. verifyTabStripFaviconCount(cta, 2); @@ -395,6 +403,41 @@ @Test @MediumTest + @DisableIf.Build(supported_abis_includes = "x86", message = "https://crbug.com/1121363") + public void testUndoClosureInDialog_DialogUndoBar() throws ExecutionException { + final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); + createTabs(cta, false, 2); + enterTabSwitcher(cta); + verifyTabSwitcherCardCount(cta, 2); + mergeAllNormalTabsToAGroup(cta); + verifyTabSwitcherCardCount(cta, 1); + openDialogFromTabSwitcherAndVerify(cta, 2, null); + + // Verify close and undo in dialog from tab switcher. + closeFirstTabInDialog(); + verifyShowingDialog(cta, 1, null); + onViewWaiting(allOf(withId(R.id.snackbar_button), + isDescendantOfA(withId(R.id.dialog_snack_bar_container_view)), + isCompletelyDisplayed())) + .perform(click()); + verifyShowingDialog(cta, 2, null); + + // Verify close and undo in dialog from tab strip. + clickFirstTabInDialog(cta); + openDialogFromStripAndVerify(cta, 2, null); + closeFirstTabInDialog(); + verifyShowingDialog(cta, 1, null); + onViewWaiting(allOf(withId(R.id.snackbar_button), + isDescendantOfA(withId(R.id.dialog_snack_bar_container_view)), + isCompletelyDisplayed())) + .perform(click()); + verifyShowingDialog(cta, 2, null); + clickScrimToExitDialog(cta); + verifyTabStripFaviconCount(cta, 2); + } + + @Test + @MediumTest @Features.EnableFeatures(ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID) public void testDialogToolbarMenuShareGroup() { final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogViewTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogViewTest.java index 504664c..faad408 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogViewTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogViewTest.java
@@ -131,8 +131,9 @@ mTabGridDialogView.resetDialog(toolbarView, recyclerView); - // It should contain three child views: top tool bar, recyclerview and ungroup bar. - Assert.assertEquals(3, mTabGridDialogContainer.getChildCount()); + // It should contain four child views: top tool bar, recyclerview, ungroup bar and undo bar + // container. + Assert.assertEquals(4, mTabGridDialogContainer.getChildCount()); Assert.assertEquals(View.VISIBLE, recyclerView.getVisibility()); RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) recyclerView.getLayoutParams();
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java index 94771d17f..5be4e08 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java
@@ -57,6 +57,8 @@ import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl; import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; +import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; +import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.tab_ui.R; import org.chromium.chrome.test.util.browser.Features; import org.chromium.content_public.browser.LoadUrlParams; @@ -128,6 +130,8 @@ Editable mEditable; @Mock ObservableSupplier<ShareDelegate> mShareDelegateSupplier; + @Mock + SnackbarManager mSnackbarManager; @Captor ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor; @@ -192,7 +196,7 @@ mModel = new PropertyModel(TabGridPanelProperties.ALL_KEYS); mMediator = new TabGridDialogMediator(mContext, mDialogController, mModel, mTabModelSelector, mTabCreatorManager, mTabSwitcherResetHandler, - mAnimationSourceViewProvider, mShareDelegateSupplier, ""); + mAnimationSourceViewProvider, mShareDelegateSupplier, mSnackbarManager, ""); // TabModelObserver is registered when native is ready. assertThat(mTabModelObserverCaptor.getAllValues().isEmpty(), equalTo(true)); @@ -601,6 +605,7 @@ assertThat(mModel.get(TabGridPanelProperties.HEADER_TITLE), equalTo(DIALOG_TITLE1)); verify(mTabSwitcherResetHandler).resetWithTabList(mTabGroupModelFilter, false, false); + verify(mSnackbarManager).dismissSnackbars(eq(mMediator), eq(TAB1_ID)); } @Test @@ -623,6 +628,7 @@ assertThat( mModel.get(TabGridPanelProperties.HEADER_TITLE), equalTo(CUSTOMIZED_DIALOG_TITLE)); verify(mTabSwitcherResetHandler).resetWithTabList(mTabGroupModelFilter, false, false); + verify(mSnackbarManager).dismissSnackbars(eq(mMediator), eq(TAB2_ID)); } @Test @@ -639,6 +645,32 @@ assertThat(mModel.get(TabGridPanelProperties.IS_DIALOG_VISIBLE), equalTo(false)); verify(mTabSwitcherResetHandler, never()) .resetWithTabList(mTabGroupModelFilter, false, false); + verify(mSnackbarManager).dismissSnackbars(eq(mMediator), eq(TAB1_ID)); + } + + @Test + public void tabClosureCommitted() { + mTabModelObserverCaptor.getValue().tabClosureCommitted(mTab1); + + verify(mSnackbarManager).dismissSnackbars(eq(mMediator), eq(TAB1_ID)); + } + + @Test + public void tabPendingClosure_DialogVisible() { + mModel.set(TabGridPanelProperties.IS_DIALOG_VISIBLE, true); + + mTabModelObserverCaptor.getValue().tabPendingClosure(mTab1); + + verify(mSnackbarManager).showSnackbar(any(Snackbar.class)); + } + + @Test + public void tabPendingClosure_DialogInVisible() { + mModel.set(TabGridPanelProperties.IS_DIALOG_VISIBLE, false); + + mTabModelObserverCaptor.getValue().tabPendingClosure(mTab1); + + verify(mSnackbarManager, never()).showSnackbar(any(Snackbar.class)); } @Test @@ -882,7 +914,7 @@ // the animationParamsProvider is null. mMediator = new TabGridDialogMediator(mContext, mDialogController, mModel, mTabModelSelector, mTabCreatorManager, mTabSwitcherResetHandler, null, - mShareDelegateSupplier, ""); + mShareDelegateSupplier, mSnackbarManager, ""); mMediator.initWithNative(mTabSelectionEditorController, mTabGroupTitleEditor); // Mock that the dialog is hidden and animation source view, header title and scrim click @@ -913,7 +945,7 @@ // the animationParamsProvider is null. mMediator = new TabGridDialogMediator(mContext, mDialogController, mModel, mTabModelSelector, mTabCreatorManager, mTabSwitcherResetHandler, null, - mShareDelegateSupplier, ""); + mShareDelegateSupplier, mSnackbarManager, ""); mMediator.initWithNative(mTabSelectionEditorController, mTabGroupTitleEditor); // Mock that the dialog is hidden and animation source view, header title and scrim click // runnable are all null. @@ -947,7 +979,7 @@ // the animationParamsProvider is null. mMediator = new TabGridDialogMediator(mContext, mDialogController, mModel, mTabModelSelector, mTabCreatorManager, mTabSwitcherResetHandler, null, - mShareDelegateSupplier, ""); + mShareDelegateSupplier, mSnackbarManager, ""); mMediator.initWithNative(mTabSelectionEditorController, mTabGroupTitleEditor); // Mock that the dialog is hidden and animation source view is set to some mock view for // testing purpose. @@ -1012,6 +1044,24 @@ } @Test + public void testSnackbarController_onAction() { + doReturn(mTabModel).when(mTabModelSelector).getModelForTabId(TAB1_ID); + + mMediator.onAction(TAB1_ID); + + verify(mTabModel).cancelTabClosure(eq(TAB1_ID)); + } + + @Test + public void testSnackbarController_onDismissNoAction() { + doReturn(mTabModel).when(mTabModelSelector).getModelForTabId(TAB1_ID); + + mMediator.onDismissNoAction(TAB1_ID); + + verify(mTabModel).commitTabClosure(eq(TAB1_ID)); + } + + @Test public void destroy() { mMediator.destroy();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java index 6e618cf4..49e2c4f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -194,6 +194,7 @@ } public void destroy() { + stopAutocomplete(true); mDropdownViewInfoListBuilder.destroy(); if (mTabObserver != null) { mTabObserver.destroy();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetView.java index 7c1a82b..0e11489 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerBottomSheetView.java
@@ -152,11 +152,12 @@ */ void setUpSignInGeneralErrorView() { mAccountPickerTitle.setText(R.string.signin_account_picker_bottom_sheet_error_title); + mAccountPickerSubtitle.setText(R.string.signin_account_picker_general_error_subtitle); mAccountPickerSubtitle.setVisibility(View.VISIBLE); mContentView.findViewById(R.id.account_picker_signin_spinner_view) .setVisibility(View.INVISIBLE); - mContinueAsButton.setVisibility(View.VISIBLE); mContinueAsButton.setText(R.string.signin_account_picker_general_error_button); + mContinueAsButton.setVisibility(View.VISIBLE); mContentView.findViewById(R.id.account_picker_horizontal_divider).setVisibility(View.GONE); mSelectedAccountView.setVisibility(View.GONE); @@ -164,13 +165,14 @@ /** * Sets up the view for sign-in auth error. - * TODO(https://crbug.com/1116952): Add strings for subtitle and button for sign-in auth error */ void setUpSignInAuthErrorView() { mAccountPickerTitle.setText(R.string.signin_account_picker_bottom_sheet_error_title); + mAccountPickerSubtitle.setText(R.string.signin_account_picker_auth_error_subtitle); mAccountPickerSubtitle.setVisibility(View.VISIBLE); mContentView.findViewById(R.id.account_picker_signin_spinner_view) .setVisibility(View.INVISIBLE); + mContinueAsButton.setText(R.string.auth_error_card_button); mContinueAsButton.setVisibility(View.VISIBLE); mContentView.findViewById(R.id.account_picker_horizontal_divider).setVisibility(View.GONE);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetTest.java index 65a88e2..efb1f3f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountPickerBottomSheetTest.java
@@ -334,6 +334,9 @@ }); onView(withText(R.string.signin_account_picker_bottom_sheet_error_title)) .check(matches(isDisplayed())); + onView(withText(R.string.signin_account_picker_auth_error_subtitle)) + .check(matches(isDisplayed())); + onView(withText(R.string.auth_error_card_button)).check(matches(isDisplayed())); onView(withId(R.id.account_picker_horizontal_divider)).check(matches(not(isDisplayed()))); onView(withId(R.id.account_picker_selected_account)).check(matches(not(isDisplayed()))); onView(withId(R.id.account_picker_signin_spinner_view)).check(matches(not(isDisplayed())));
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index 25423aa..540adb2 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//build/config/locales.gni") import("//build/config/ui.gni") import("//chrome/common/features.gni") @@ -115,6 +116,7 @@ deps = [ "//base", + "//build:lacros_buildflags", "//chrome/app:shutdown_signal_handlers", "//chrome/browser", "//chrome/browser/policy:path_parser", @@ -170,6 +172,10 @@ ] } + if (chromeos_is_browser_only) { + deps += [ "//chromeos/lacros" ] + } + if (enable_plugins && enable_nacl) { deps += [ "//components/nacl/browser",
diff --git a/chrome/app/DEPS b/chrome/app/DEPS index 019e17c9..d04cc41d7 100644 --- a/chrome/app/DEPS +++ b/chrome/app/DEPS
@@ -11,6 +11,7 @@ "+chrome/utility/chrome_content_utility_client.h", "+chromeos/constants", "+chromeos/hugepage_text/hugepage_text.h", + "+chromeos/lacros", "+chromeos/memory", "+components/browser_watcher", "+components/component_updater",
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index 313975f4..e8121085 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc
@@ -175,6 +175,11 @@ #include "components/gwp_asan/client/gwp_asan.h" // nogncheck #endif +#if BUILDFLAG(IS_LACROS) +#include "chrome/browser/lacros/lacros_chrome_service_delegate_impl.h" +#include "chromeos/lacros/lacros_chrome_service_impl.h" +#endif + base::LazyInstance<ChromeContentGpuClient>::DestructorAtExit g_chrome_content_gpu_client = LAZY_INSTANCE_INITIALIZER; base::LazyInstance<ChromeContentRendererClient>::DestructorAtExit @@ -548,6 +553,13 @@ chromeos::InitializeFeatureListDependentDBus(); #endif +#if BUILDFLAG(IS_LACROS) + // LacrosChromeServiceImpl instance is needs the sequence of the main thread, + // and needs to be created earlier than incoming Mojo invitation handling. + lacros_chrome_service_ = std::make_unique<chromeos::LacrosChromeServiceImpl>( + std::make_unique<LacrosChromeServiceDelegateImpl>()); +#endif + #if defined(OS_ANDROID) startup_data_->CreateProfilePrefService(); net::NetworkChangeNotifier::SetFactory(
diff --git a/chrome/app/chrome_main_delegate.h b/chrome/app/chrome_main_delegate.h index 06529ad..3f1bc5cf 100644 --- a/chrome/app/chrome_main_delegate.h +++ b/chrome/app/chrome_main_delegate.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/time/time.h" #include "build/build_config.h" +#include "build/lacros_buildflags.h" #include "chrome/browser/startup_data.h" #include "chrome/common/chrome_content_client.h" #include "content/public/app/content_main_delegate.h" @@ -19,6 +20,10 @@ class CommandLine; } +namespace chromeos { +class LacrosChromeServiceImpl; +} + namespace tracing { class TracingSamplerProfiler; } @@ -83,6 +88,10 @@ // the reporting pipeline. std::unique_ptr<HeapProfilerController> heap_profiler_controller_; +#if BUILDFLAG(IS_LACROS) + std::unique_ptr<chromeos::LacrosChromeServiceImpl> lacros_chrome_service_; +#endif + DISALLOW_COPY_AND_ASSIGN(ChromeMainDelegate); };
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index f318fd00..2c2d794 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -4106,8 +4106,6 @@ if (chromeos_is_browser_only) { assert(enable_native_notifications) sources += [ - "chrome_browser_main_extra_parts_lacros.cc", - "chrome_browser_main_extra_parts_lacros.h", "lacros/lacros_chrome_service_delegate_impl.cc", "lacros/lacros_chrome_service_delegate_impl.h", "metrics/lacros_metrics_provider.cc",
diff --git a/chrome/browser/OWNERS b/chrome/browser/OWNERS index eb6b3ea..e286c6f 100644 --- a/chrome/browser/OWNERS +++ b/chrome/browser/OWNERS
@@ -85,5 +85,9 @@ per-file chrome_back_forward_cache_browsertest.cc=altimin@chromium.org per-file chrome_back_forward_cache_browsertest.cc=file://content/OWNERS +# Cross-Origin-Opener-Policy: +per-file chrome_cross_origin_opener_policy_browsertest.cc=file://content/OWNERS +per-file chrome_cross_origin_opener_policy_browsertest.cc=arthursonzogni@chromium.org + # COMPONENT: UI>Browser # TEAM: chromium-reviews@chromium.org
diff --git a/chrome/browser/apps/app_service/app_icon_factory.cc b/chrome/browser/apps/app_service/app_icon_factory.cc index ef8c2034..9fe6c4fd 100644 --- a/chrome/browser/apps/app_service/app_icon_factory.cc +++ b/chrome/browser/apps/app_service/app_icon_factory.cc
@@ -670,6 +670,13 @@ void IconLoadingPipeline::LoadCompressedIconFromFile( const base::FilePath& path) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + // For the compressed icon, MaybeApplyEffectsAndComplete() uses + // |icon_scale_for_compressed_response_| to apps::EncodeImageToPngBytes(). So + // set |icon_scale_for_compressed_response_| to match |icon_scale_|, which is + // used to decode the icon. + icon_scale_for_compressed_response_ = icon_scale_; + base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, base::BindOnce(&ReadFileAsCompressedData, path),
diff --git a/chrome/browser/chrome_browser_main_extra_parts_lacros.cc b/chrome/browser/chrome_browser_main_extra_parts_lacros.cc deleted file mode 100644 index 93a429d..0000000 --- a/chrome/browser/chrome_browser_main_extra_parts_lacros.cc +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chrome_browser_main_extra_parts_lacros.h" - -#include "chrome/browser/lacros/lacros_chrome_service_delegate_impl.h" -#include "chromeos/lacros/lacros_chrome_service_impl.h" - -ChromeBrowserMainExtraPartsLacros::ChromeBrowserMainExtraPartsLacros() = - default; - -ChromeBrowserMainExtraPartsLacros::~ChromeBrowserMainExtraPartsLacros() = - default; - -void ChromeBrowserMainExtraPartsLacros::PostCreateThreads() { - lacros_chrome_service_ = std::make_unique<chromeos::LacrosChromeServiceImpl>( - std::make_unique<LacrosChromeServiceDelegateImpl>()); -}
diff --git a/chrome/browser/chrome_browser_main_extra_parts_lacros.h b/chrome/browser/chrome_browser_main_extra_parts_lacros.h deleted file mode 100644 index e8217fd2..0000000 --- a/chrome/browser/chrome_browser_main_extra_parts_lacros.h +++ /dev/null
@@ -1,33 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROME_BROWSER_MAIN_EXTRA_PARTS_LACROS_H_ -#define CHROME_BROWSER_CHROME_BROWSER_MAIN_EXTRA_PARTS_LACROS_H_ - -#include <memory> - -#include "chrome/browser/chrome_browser_main_extra_parts.h" - -namespace chromeos { -class LacrosChromeServiceImpl; -} - -// Startup and shutdown code for lacros-chrome. -class ChromeBrowserMainExtraPartsLacros : public ChromeBrowserMainExtraParts { - public: - ChromeBrowserMainExtraPartsLacros(); - ChromeBrowserMainExtraPartsLacros(const ChromeBrowserMainExtraPartsLacros&) = - delete; - ChromeBrowserMainExtraPartsLacros& operator=( - const ChromeBrowserMainExtraPartsLacros&) = delete; - ~ChromeBrowserMainExtraPartsLacros() override; - - private: - // ChromeBrowserMainExtraParts: - void PostCreateThreads() override; - - std::unique_ptr<chromeos::LacrosChromeServiceImpl> lacros_chrome_service_; -}; - -#endif // CHROME_BROWSER_CHROME_BROWSER_MAIN_EXTRA_PARTS_LACROS_H_
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 6dec4a8..814294f 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -632,7 +632,6 @@ #endif #if BUILDFLAG(IS_LACROS) -#include "chrome/browser/chrome_browser_main_extra_parts_lacros.h" #include "chromeos/lacros/lacros_chrome_service_impl.h" #endif @@ -1380,10 +1379,6 @@ main_parts->AddParts(std::make_unique<ChromeBrowserMainExtraPartsAsh>()); #endif -#if BUILDFLAG(IS_LACROS) - main_parts->AddParts(std::make_unique<ChromeBrowserMainExtraPartsLacros>()); -#endif - #if defined(USE_X11) || defined(USE_OZONE) main_parts->AddParts(std::make_unique<ChromeBrowserMainExtraPartsOzone>()); #endif @@ -5816,11 +5811,11 @@ } void ChromeContentBrowserClient::BindBrowserControlInterface( - mojo::GenericPendingReceiver receiver) { + mojo::ScopedMessagePipeHandle pipe) { #if BUILDFLAG(IS_LACROS) - if (auto r = receiver.As<crosapi::mojom::LacrosChromeService>()) { - chromeos::LacrosChromeServiceImpl::Get()->BindReceiver(std::move(r)); - } + chromeos::LacrosChromeServiceImpl::Get()->BindReceiver( + mojo::PendingReceiver<crosapi::mojom::LacrosChromeService>( + std::move(pipe))); #endif }
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index a635cc3..c8fec14e 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -683,8 +683,7 @@ bool IsOriginTrialRequiredForAppCache( content::BrowserContext* browser_context) override; - void BindBrowserControlInterface( - mojo::GenericPendingReceiver receiver) override; + void BindBrowserControlInterface(mojo::ScopedMessagePipeHandle pipe) override; bool ShouldInheritCrossOriginEmbedderPolicyImplicitly( const GURL& url) override; bool ShouldAllowInsecurePrivateNetworkRequests(
diff --git a/chrome/browser/chrome_cross_origin_opener_policy_browsertest.cc b/chrome/browser/chrome_cross_origin_opener_policy_browsertest.cc new file mode 100644 index 0000000..8ec9cb5 --- /dev/null +++ b/chrome/browser/chrome_cross_origin_opener_policy_browsertest.cc
@@ -0,0 +1,185 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/command_line.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "components/network_session_configurator/common/network_switches.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/content_browser_test_utils.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "services/network/public/cpp/features.h" +#include "services/network/public/mojom/cross_origin_opener_policy.mojom.h" + +#include "content/public/browser/web_contents.h" +// Cross-Origin-Opener-Policy is a web platform feature implemented by content/. +// However, since ContentBrowserClientImpl::LogWebFeatureForCurrentPage() is +// currently left blank in content/, it can't be tested from content/. So it is +// tested from chrome/ instead. +class ChromeCrossOriginOpenerPolicyBrowserTest : public InProcessBrowserTest { + public: + ChromeCrossOriginOpenerPolicyBrowserTest() { + features_.InitWithFeatures( + { + // Enabled: + network::features::kCrossOriginOpenerPolicy, + network::features::kCrossOriginEmbedderPolicy, + network::features::kCrossOriginOpenerPolicyReporting, + }, + {}); + } + + content::WebContents* web_contents() const { + return browser()->tab_strip_model()->GetActiveWebContents(); + } + + private: + void SetUpOnMainThread() final { host_resolver()->AddRule("*", "127.0.0.1"); } + + void SetUpCommandLine(base::CommandLine* command_line) final { + InProcessBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitch(switches::kIgnoreCertificateErrors); + } + + base::test::ScopedFeatureList features_; +}; + +// Check the kCrossOriginOpenerPolicyReporting feature usage. +IN_PROC_BROWSER_TEST_F(ChromeCrossOriginOpenerPolicyBrowserTest, + ReportingUsage) { + net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); + net::EmbeddedTestServer http_server(net::EmbeddedTestServer::TYPE_HTTP); + https_server.AddDefaultHandlers(GetChromeTestDataDir()); + http_server.AddDefaultHandlers(GetChromeTestDataDir()); + https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK); + ASSERT_TRUE(https_server.Start()); + ASSERT_TRUE(http_server.Start()); + + int expected_count = 0; + base::HistogramTester histogram; + + auto expect_histogram_increased_by = [&](int count) { + expected_count += count; + histogram.ExpectBucketCount( + "Blink.UseCounter.Features", + blink::mojom::WebFeature::kCrossOriginOpenerPolicyReporting, + expected_count); + }; + + // No header => 0 count. + { + GURL url = https_server.GetURL("a.com", "/title1.html"); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + expect_histogram_increased_by(0); + } + + // COOP-Report-Only + HTTP => 0 count. + { + GURL url = http_server.GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy-Report-Only: " + "same-origin; report-to%3d\"a\""); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + expect_histogram_increased_by(0); + } + + // COOP-Report-Only + HTTPS => 1 count. + { + GURL url = https_server.GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy-Report-Only: " + "same-origin; report-to%3d\"a\""); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + expect_histogram_increased_by(1); + } + + // COOP + HTPS => 1 count. + { + GURL url = https_server.GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy: " + "same-origin; report-to%3d\"a\""); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + expect_histogram_increased_by(1); + } + + // COOP + COOP-RO + HTTPS => 1 count. + { + GURL url = https_server.GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy: " + "same-origin; report-to%3d\"a\"&" + "Cross-Origin-Opener-Policy-Report-Only: " + "same-origin; report-to%3d\"a\""); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + expect_histogram_increased_by(1); + } + // No report endpoints defined => 0 count. + { + GURL url = https_server.GetURL( + "a.com", + "/set-header?" + "Cross-Origin-Opener-Policy: same-origin&" + "Cross-Origin-Opener-Policy-Report-Only: same-origin"); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + expect_histogram_increased_by(0); + } + + // Main frame (COOP-RO), subframe (COOP-RO) => 1 count. + { + GURL url = https_server.GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy-Report-Only: " + "same-origin; report-to%3d\"a\""); + EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); + EXPECT_TRUE(content::ExecJs(web_contents(), content::JsReplace(R"( + new Promise(resolve => { + let iframe = document.createElement("iframe"); + iframe.src = $1; + iframe.onload = resolve; + document.body.appendChild(iframe); + }); + )", + url))); + expect_histogram_increased_by(1); + } + + // Main frame (no-headers), subframe (COOP-RO) => 0 count. + { + GURL main_document_url = https_server.GetURL("a.com", "/title1.html"); + GURL sub_document_url = + https_server.GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy-Report-Only: " + "same-origin; report-to%3d\"a\""); + EXPECT_TRUE(content::NavigateToURL(web_contents(), main_document_url)); + EXPECT_TRUE( + content::ExecJs(web_contents(), content::JsReplace(R"( + new Promise(resolve => { + let iframe = document.createElement("iframe"); + iframe.src = $1; + iframe.onload = resolve; + document.body.appendChild(iframe); + }); + )", + sub_document_url))); + expect_histogram_increased_by(0); + } +} + +// TODO(arthursonzogni): Add basic test(s) for the WebFeatures: +// - CrossOriginOpenerPolicySameOrigin +// - CrossOriginOpenerPolicySameOriginAllowPopups +// - CrossOriginEmbedderPolicyRequireCorp +// - CoopAndCoepIsolated +// +// Added by: +// https://chromium-review.googlesource.com/c/chromium/src/+/2122140 +// +// In particular, it would be interesting knowing what happens with iframes? +// Are CoopCoepOriginIsolated nested document counted as CoopAndCoepIsolated? +// Not doing it would underestimate the usage metric.
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_data.cc b/chrome/browser/chromeos/app_mode/kiosk_app_data.cc index ff52281..a1b164e 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_data.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_data.cc
@@ -107,8 +107,8 @@ std::unique_ptr<base::DictionaryValue> original_manifest, const extensions::Extension* extension, const SkBitmap& install_icon, - extensions::declarative_net_request::RulesetChecksums - ruleset_checksums) override { + extensions::declarative_net_request::RulesetInstallPrefs + ruleset_install_prefs) override { DCHECK(task_runner_->RunsTasksInCurrentSequence()); const extensions::KioskModeInfo* info =
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.cc b/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.cc index 83cc0f56..2a18085 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.cc
@@ -56,7 +56,8 @@ std::unique_ptr<base::DictionaryValue> original_manifest, const extensions::Extension* extension, const SkBitmap& install_icon, - extensions::declarative_net_request::RulesetChecksums ruleset_checksums) { + extensions::declarative_net_request::RulesetInstallPrefs + ruleset_install_prefs) { DCHECK(crx_file_.extension_id == extension->id()); std::string minimum_browser_version;
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.h b/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.h index ac0abbc..c36d1d2 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.h +++ b/chrome/browser/chromeos/app_mode/kiosk_external_update_validator.h
@@ -58,8 +58,8 @@ std::unique_ptr<base::DictionaryValue> original_manifest, const extensions::Extension* extension, const SkBitmap& install_icon, - extensions::declarative_net_request::RulesetChecksums - ruleset_checksums) override; + extensions::declarative_net_request::RulesetInstallPrefs + ruleset_install_prefs) override; // Task runner for executing file I/O tasks. const scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
diff --git a/chrome/browser/chromeos/crosapi/browser_manager.cc b/chrome/browser/chromeos/crosapi/browser_manager.cc index 109e1fec..dff0173 100644 --- a/chrome/browser/chromeos/crosapi/browser_manager.cc +++ b/chrome/browser/chromeos/crosapi/browser_manager.cc
@@ -35,7 +35,6 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/platform/platform_channel.h" #include "mojo/public/cpp/system/invitation.h" -#include "mojo/public/mojom/base/binder.mojom.h" // TODO(crbug.com/1101667): Currently, this source has log spamming // by LOG(WARNING) for non critical errors to make it easy @@ -223,6 +222,21 @@ mojo::PlatformChannel channel; channel.PrepareToPassRemoteEndpoint(&options, &command_line); + // Queue messages to establish the mojo connection, + // so that the passed IPC is available already when lacros-chrome accepts + // the invitation. + // TODO(crbug.com/1115092): Pass the initialization parameter over + // mojo connection. + mojo::OutgoingInvitation invitation; + lacros_chrome_service_.Bind( + mojo::PendingRemote<crosapi::mojom::LacrosChromeService>( + invitation.AttachMessagePipe(0), /*version=*/0)); + lacros_chrome_service_.set_disconnect_handler(base::BindOnce( + &BrowserManager::OnMojoDisconnected, weak_factory_.GetWeakPtr())); + lacros_chrome_service_->RequestAshChromeServiceReceiver( + base::BindOnce(&BrowserManager::OnAshChromeServiceReceiverReceived, + weak_factory_.GetWeakPtr())); + // Create the lacros-chrome subprocess. base::RecordAction(base::UserMetricsAction("Lacros.Launch")); // If lacros_process_ already exists, because it does not call waitpid(2), @@ -235,22 +249,11 @@ state_ = State::STARTING; LOG(WARNING) << "Launched lacros-chrome with pid " << lacros_process_.Pid(); - // Invite the lacros-chrome to the mojo universe, and bind - // LacrosChromeService and AshChromeService interfaces to each other. + // Invite the lacros-chrome to the mojo universe. channel.RemoteProcessLaunchAttempted(); - mojo::OutgoingInvitation invitation; - mojo::Remote<mojo_base::mojom::Binder> binder( - mojo::PendingRemote<mojo_base::mojom::Binder>( - invitation.AttachMessagePipe(0), /*version=*/0)); mojo::OutgoingInvitation::Send(std::move(invitation), lacros_process_.Handle(), channel.TakeLocalEndpoint()); - binder->Bind(lacros_chrome_service_.BindNewPipeAndPassReceiver()); - lacros_chrome_service_.set_disconnect_handler(base::BindOnce( - &BrowserManager::OnMojoDisconnected, weak_factory_.GetWeakPtr())); - lacros_chrome_service_->RequestAshChromeServiceReceiver( - base::BindOnce(&BrowserManager::OnAshChromeServiceReceiverReceived, - weak_factory_.GetWeakPtr())); return true; }
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index ca34ee6..f135f13 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -326,6 +326,30 @@ return api::autotest_private::AppType::APP_TYPE_NONE; } +api::autotest_private::AppInstallSource GetAppInstallSource( + apps::mojom::InstallSource source) { + switch (source) { + case apps::mojom::InstallSource::kUnknown: + return api::autotest_private::AppInstallSource:: + APP_INSTALL_SOURCE_UNKNOWN; + case apps::mojom::InstallSource::kSystem: + return api::autotest_private::AppInstallSource::APP_INSTALL_SOURCE_SYSTEM; + case apps::mojom::InstallSource::kPolicy: + return api::autotest_private::AppInstallSource::APP_INSTALL_SOURCE_POLICY; + case apps::mojom::InstallSource::kOem: + return api::autotest_private::AppInstallSource::APP_INSTALL_SOURCE_OEM; + case apps::mojom::InstallSource::kDefault: + return api::autotest_private::AppInstallSource:: + APP_INSTALL_SOURCE_DEFAULT; + case apps::mojom::InstallSource::kSync: + return api::autotest_private::AppInstallSource::APP_INSTALL_SOURCE_SYNC; + case apps::mojom::InstallSource::kUser: + return api::autotest_private::AppInstallSource::APP_INSTALL_SOURCE_USER; + } + NOTREACHED(); + return api::autotest_private::AppInstallSource::APP_INSTALL_SOURCE_NONE; +} + api::autotest_private::AppWindowType GetAppWindowType(ash::AppType type) { switch (type) { case ash::AppType::ARC_APP: @@ -2864,6 +2888,7 @@ app.short_name = update.ShortName(); app.additional_search_terms = update.AdditionalSearchTerms(); app.type = GetAppType(update.AppType()); + app.install_source = GetAppInstallSource(update.InstallSource()); app.readiness = GetAppReadiness(update.Readiness()); app.show_in_launcher = ConvertMojomOptionalBool(update.ShowInLauncher()); app.show_in_search = ConvertMojomOptionalBool(update.ShowInSearch());
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_media_parser.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_media_parser.cc index cffa8f3..ae8704d 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_media_parser.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_media_parser.cc
@@ -91,17 +91,11 @@ return RespondNow(Error("fileEntry.file() blob error.")); } - bool include_images = false; - if (params->type == - api::file_manager_private::CONTENT_METADATA_TYPE_METADATATAGSIMAGES) { - include_images = true; - } - content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce( &FileManagerPrivateInternalGetContentMetadataFunction::ReadBlobSize, - this, params->blob_uuid, params->mime_type, include_images)); + this, params->blob_uuid, params->mime_type, params->include_images)); return RespondLater(); }
diff --git a/chrome/browser/chromeos/input_method/OWNERS b/chrome/browser/chromeos/input_method/OWNERS index f084c17..41944314 100644 --- a/chrome/browser/chromeos/input_method/OWNERS +++ b/chrome/browser/chromeos/input_method/OWNERS
@@ -3,6 +3,8 @@ shend@chromium.org shuchen@chromium.org yhanada@chromium.org +jiwan@chromium.org +myy@chromium.org # backup reviewers yukishiino@chromium.org
diff --git a/chrome/browser/chromeos/kerberos/kerberos_credentials_manager_test.cc b/chrome/browser/chromeos/kerberos/kerberos_credentials_manager_test.cc index 3140b8c..feac3de2 100644 --- a/chrome/browser/chromeos/kerberos/kerberos_credentials_manager_test.cc +++ b/chrome/browser/chromeos/kerberos/kerberos_credentials_manager_test.cc
@@ -1123,7 +1123,8 @@ // UpdateAccountsFromPref retries to add account if addition fails for network // related errors. -TEST_F(KerberosCredentialsManagerTest, UpdateAccountsFromPrefRetry) { +// TODO(https://crbug.com/1121383): Disabled due to flakiness. +TEST_F(KerberosCredentialsManagerTest, DISABLED_UpdateAccountsFromPrefRetry) { // Starting with Kerberos enabled. SetPref(prefs::kKerberosEnabled, base::Value(true));
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_setup_browsertest.cc b/chrome/browser/chromeos/login/demo_mode/demo_setup_browsertest.cc index 3281753..ff76b74 100644 --- a/chrome/browser/chromeos/login/demo_mode/demo_setup_browsertest.cc +++ b/chrome/browser/chromeos/login/demo_mode/demo_setup_browsertest.cc
@@ -1108,7 +1108,13 @@ EXPECT_TRUE(IsScreenShown(EulaView::kScreenId)); } -IN_PROC_BROWSER_TEST_F(DemoSetupArcSupportedTest, BackOnNetworkScreen) { +// TODO(https://crbug.com/1121422): Flaky on ChromeOS ASAN. +#if defined(OS_CHROMEOS) +#define MAYBE_BackOnNetworkScreen DISABLED_BackOnNetworkScreen +#else +#define MAYBE_BackOnNetworkScreen BackOnNetworkScreen +#endif +IN_PROC_BROWSER_TEST_F(DemoSetupArcSupportedTest, MAYBE_BackOnNetworkScreen) { SimulateNetworkConnected(); SkipToScreen(NetworkScreenView::kScreenId);
diff --git a/chrome/browser/chromeos/net/network_pref_state_observer_unittest.cc b/chrome/browser/chromeos/net/network_pref_state_observer_unittest.cc index 5ac2141..58c7b872 100644 --- a/chrome/browser/chromeos/net/network_pref_state_observer_unittest.cc +++ b/chrome/browser/chromeos/net/network_pref_state_observer_unittest.cc
@@ -86,7 +86,7 @@ TEST_F(NetworkPrefStateObserverTest, LoginUser) { // UIProxyConfigService should exist with device PrefService. UIProxyConfigService* device_ui_proxy_config_service = - NetworkHandler::Get()->ui_proxy_config_service(); + NetworkHandler::GetUiProxyConfigService(); ASSERT_TRUE(device_ui_proxy_config_service); // There should be no proxy config available. base::Value ui_proxy_config(base::Value::Type::DICTIONARY); @@ -97,7 +97,7 @@ // New UIProxyConfigService should be created with a profile PrefService. UIProxyConfigService* profile_ui_proxy_config_service = - NetworkHandler::Get()->ui_proxy_config_service(); + NetworkHandler::GetUiProxyConfigService(); ASSERT_TRUE(profile_ui_proxy_config_service); ASSERT_NE(device_ui_proxy_config_service, profile_ui_proxy_config_service); ui_proxy_config = base::Value(base::Value::Type::DICTIONARY); @@ -114,9 +114,9 @@ // Mode should now be MODE_PAC_SCRIPT. ui_proxy_config = base::Value(base::Value::Type::DICTIONARY); - EXPECT_TRUE(NetworkHandler::Get() - ->ui_proxy_config_service() - ->MergeEnforcedProxyConfig(kNetworkId, &ui_proxy_config)); + EXPECT_TRUE( + NetworkHandler::GetUiProxyConfigService()->MergeEnforcedProxyConfig( + kNetworkId, &ui_proxy_config)); base::Value* mode = ui_proxy_config.FindPath( {::onc::network_config::kType, ::onc::kAugmentationActiveSetting}); ASSERT_TRUE(mode);
diff --git a/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc b/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc index 599e2a6..23fae522 100644 --- a/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc +++ b/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc
@@ -230,8 +230,8 @@ const std::vector<const api::events::Rule*>& api_rules) { EvaluationScope evaluation_scope(this); const Extension* extension = ExtensionRegistry::Get(browser_context()) - ->GetInstalledExtension(extension_id); - DCHECK(extension); + ->enabled_extensions().GetByID(extension_id); + CHECK(extension); std::string error; RulesMap new_rules;
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc index 97bfd89..1f079f0 100644 --- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_unittest.cc
@@ -21,6 +21,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/test/scoped_run_loop_timeout.h" #include "base/test/test_timeouts.h" #include "base/values.h" @@ -41,6 +42,7 @@ #include "extensions/browser/api/declarative_net_request/utils.h" #include "extensions/browser/api_test_utils.h" #include "extensions/browser/disable_reason.h" +#include "extensions/browser/extension_prefs.h" #include "extensions/browser/test_extension_registry_observer.h" #include "extensions/common/api/declarative_net_request.h" #include "extensions/common/api/declarative_net_request/constants.h" @@ -148,13 +150,15 @@ EXPECT_TRUE(error_reporter()->GetErrors()->empty()); // The histograms below are not logged for unpacked extensions. - if (GetParam() == ExtensionLoadType::PACKED && expect_rulesets_indexed) { + if (GetParam() == ExtensionLoadType::PACKED) { + int expected_samples = expect_rulesets_indexed ? 1 : 0; + tester.ExpectTotalCount(kIndexAndPersistRulesTimeHistogram, - 1 /* count */); + expected_samples); tester.ExpectUniqueSample(kManifestRulesCountHistogram, - expected_rules_count, 1 /* count */); + expected_rules_count, expected_samples); tester.ExpectUniqueSample(kManifestEnabledRulesCountHistogram, - expected_enabled_rules_count, 1 /* count */); + expected_enabled_rules_count, expected_samples); } } @@ -692,6 +696,101 @@ } } +// Ensure that we can add up to the |dnr_api::GUARANTEED_MINIMUM_STATIC_RULES| + +// |kMaxStaticRulesPerProfile| rules if the global rules feature is enabled. +TEST_P(SingleRulesetTest, RuleCountLimitMatched_GlobalRules) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(kDeclarativeNetRequestGlobalRules); + + // Override the API rule limit to prevent a timeout on loading the extension. + base::AutoReset<int> rule_limit_override = + CreateScopedStaticRuleLimitOverrideForTesting(100); + + // Similarly, override the global limit to prevent a timeout. + base::AutoReset<int> global_limit_override = + CreateScopedGlobalStaticRuleLimitOverrideForTesting(200); + + // Sanity check that the extension can index and enable up to + // |rule_limit_override| + |global_limit_override| rules. + ASSERT_EQ(300, GetStaticRuleLimit()); + + TestRule rule = CreateGenericRule(); + for (int i = 0; i < GetStaticRuleLimit(); ++i) { + rule.id = kMinValidID + i; + rule.condition->url_filter = std::to_string(i); + AddRule(rule); + } + + extension_loader()->set_ignore_manifest_warnings(true); + LoadAndExpectSuccess(300); + + std::vector<RulesetSource> static_sources = + RulesetSource::CreateStatic(*extension()); + + ASSERT_EQ(1u, static_sources.size()); + EXPECT_TRUE(base::PathExists(static_sources[0].indexed_path())); + + // The ruleset's ID should not be marked as ignored in prefs. + ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context()); + EXPECT_FALSE( + prefs->ShouldIgnoreDNRRuleset(extension()->id(), static_sources[0].id())); +} + +// Ensure that we get an install warning on exceeding the rule count limit and +// that no rules are indexed. +TEST_P(SingleRulesetTest, RuleCountLimitExceeded_GlobalRules) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(kDeclarativeNetRequestGlobalRules); + + // Override the API rule limit to prevent a timeout on loading the extension. + base::AutoReset<int> rule_limit_override = + CreateScopedStaticRuleLimitOverrideForTesting(100); + + // Similarly, override the global limit to prevent a timeout. + base::AutoReset<int> global_limit_override = + CreateScopedGlobalStaticRuleLimitOverrideForTesting(200); + + ASSERT_EQ(300, GetStaticRuleLimit()); + + TestRule rule = CreateGenericRule(); + for (int i = 1; i <= GetStaticRuleLimit() + 1; ++i) { + rule.id = kMinValidID + i; + rule.condition->url_filter = std::to_string(i); + AddRule(rule); + } + + extension_loader()->set_ignore_manifest_warnings(true); + DeclarativeNetRequestUnittest::LoadAndExpectSuccess( + 0, 0, false /* expect_rulesets_indexed */); + + std::vector<RulesetSource> static_sources = + RulesetSource::CreateStatic(*extension()); + + // Since the ruleset was ignored and not indexed, it should not be persisted + // to a file. + ASSERT_EQ(1u, static_sources.size()); + EXPECT_FALSE(base::PathExists(static_sources[0].indexed_path())); + + // TODO(crbug.com/879355): CrxInstaller reloads the extension after moving it, + // which causes it to lose the install warning. This should be fixed. + if (GetParam() != ExtensionLoadType::PACKED) { + ASSERT_EQ(1u, extension()->install_warnings().size()); + InstallWarning expected_warning = + InstallWarning(GetErrorWithFilename(ErrorUtils::FormatErrorMessage( + kIndexingRuleLimitExceeded, + std::to_string(static_sources[0].id().value()))), + dnr_api::ManifestKeys::kDeclarativeNetRequest, + dnr_api::DNRInfo::kRuleResources); + + EXPECT_EQ(expected_warning, extension()->install_warnings()[0]); + } + + // The ruleset's ID should be persisted in the ignored rulesets pref. + ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context()); + EXPECT_TRUE( + prefs->ShouldIgnoreDNRRuleset(extension()->id(), static_sources[0].id())); +} + // Ensure that regex rules which exceed the per rule memory limit are ignored // and raise an install warning. TEST_P(SingleRulesetTest, LargeRegexIgnored) { @@ -1215,6 +1314,79 @@ Pointee(Property(&RulesetMatcher::GetRulesCount, 20 + 20)))); } +// Ensure that only rulesets which exceed the rules count limit will not have +// their rules indexed and will raise an install warning. +TEST_P(MultipleRulesetsTest, StaticRuleCountExceeded_GlobalRules) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(kDeclarativeNetRequestGlobalRules); + + // Override the API rule limit to prevent a timeout on loading the extension. + base::AutoReset<int> rule_limit_override = + CreateScopedStaticRuleLimitOverrideForTesting(100); + + // Similarly, override the global limit to prevent a timeout. + base::AutoReset<int> global_limit_override = + CreateScopedGlobalStaticRuleLimitOverrideForTesting(200); + + ASSERT_EQ(300, GetStaticRuleLimit()); + + // Ruleset should not be indexed as it exceeds the limit. + AddRuleset(CreateRuleset(kId1, 301, 0, true)); + + // Ruleset should be indexed as it is within the limit. + AddRuleset(CreateRuleset(kId2, 250, 0, true)); + + RulesetManagerObserver ruleset_waiter(manager()); + extension_loader()->set_ignore_manifest_warnings(true); + + DeclarativeNetRequestUnittest::LoadAndExpectSuccess( + 250, 250, true /* expect_rulesets_indexed */); + + ruleset_waiter.WaitForExtensionsWithRulesetsCount(1); + CompositeMatcher* composite_matcher = + manager()->GetMatcherForExtension(extension()->id()); + ASSERT_TRUE(composite_matcher); + + VerifyPublicRulesetIDs(*extension(), {kId2}); + + EXPECT_THAT(composite_matcher->matchers(), + UnorderedElementsAre( + Pointee(Property(&RulesetMatcher::GetRulesCount, 250)))); + + std::vector<RulesetSource> static_sources = + RulesetSource::CreateStatic(*extension()); + ASSERT_EQ(2u, static_sources.size()); + + if (GetParam() != ExtensionLoadType::PACKED) { + std::string expected_warning = GetErrorWithFilename( + ErrorUtils::FormatErrorMessage( + kIndexingRuleLimitExceeded, + std::to_string(static_sources[0].id().value())), + kId1); + + EXPECT_THAT(extension()->install_warnings(), + UnorderedElementsAre( + Field(&InstallWarning::message, expected_warning))); + } + + // Since the first ruleset was ignored and not indexed, it should not be + // persisted to a file. + EXPECT_FALSE(base::PathExists(static_sources[0].indexed_path())); + + // The second ruleset was indexed and it should be persisted. + EXPECT_TRUE(base::PathExists(static_sources[1].indexed_path())); + + ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context()); + + // The first ruleset's ID should be persisted in the ignored rulesets pref. + EXPECT_TRUE( + prefs->ShouldIgnoreDNRRuleset(extension()->id(), static_sources[0].id())); + + // The second ruleset's ID should not be marked as ignored in prefs. + EXPECT_FALSE( + prefs->ShouldIgnoreDNRRuleset(extension()->id(), static_sources[1].id())); +} + TEST_P(MultipleRulesetsTest, UpdateEnabledRulesets_InvalidRulesetID) { AddRuleset(CreateRuleset(kId1, 10, 10, true)); AddRuleset(CreateRuleset(kId2, 10, 10, false));
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc b/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc index 67a4611..a6c30ff 100644 --- a/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc +++ b/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc
@@ -277,7 +277,7 @@ frame_observer.Wait(); // Non-Aura Linux uses a singleton for the popup, so it looks like all windows // have popups if there is any popup open. -#if !(defined(OS_LINUX) && !defined(USE_AURA)) +#if !((defined(OS_LINUX) || defined(OS_CHROMEOS)) && !defined(USE_AURA)) // Starting window does not have a popup. EXPECT_FALSE(ExtensionActionTestHelper::Create(browser())->HasPopup()); #endif
diff --git a/chrome/browser/extensions/api/notifications/notifications_apitest.cc b/chrome/browser/extensions/api/notifications/notifications_apitest.cc index 23d02a8e..0b48607c 100644 --- a/chrome/browser/extensions/api/notifications/notifications_apitest.cc +++ b/chrome/browser/extensions/api/notifications/notifications_apitest.cc
@@ -222,7 +222,8 @@ } // namespace // http://crbug.com/691913 -#if (defined(OS_LINUX) || defined(OS_WIN)) && !defined(NDEBUG) +#if (defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN)) && \ + !defined(NDEBUG) #define MAYBE_TestBasicUsage DISABLED_TestBasicUsage #else #define MAYBE_TestBasicUsage TestBasicUsage
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index e97b1ba..ca7886a 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc
@@ -248,7 +248,7 @@ OnUnpackSuccessOnSharedFileThread(extension->path(), extension->path(), nullptr, extension, SkBitmap(), - {} /* ruleset_checksums */); + {} /* ruleset_install_prefs */); } void CrxInstaller::InstallWebApp(const WebApplicationInfo& web_app) { @@ -319,7 +319,7 @@ OnUnpackSuccessOnSharedFileThread(extension->path(), extension->path(), nullptr, extension, SkBitmap(), - {} /* ruleset_checksums */); + {} /* ruleset_install_prefs */); } base::Optional<CrxInstallError> CrxInstaller::CheckExpectations( @@ -527,14 +527,14 @@ std::unique_ptr<base::DictionaryValue> original_manifest, const Extension* extension, const SkBitmap& install_icon, - declarative_net_request::RulesetChecksums ruleset_checksums) { + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs) { DCHECK(unpacker_task_runner_->RunsTasksInCurrentSequence()); shared_file_task_runner_->PostTask( FROM_HERE, base::BindOnce(&CrxInstaller::OnUnpackSuccessOnSharedFileThread, this, temp_dir, extension_dir, std::move(original_manifest), scoped_refptr<const Extension>(extension), install_icon, - std::move(ruleset_checksums))); + std::move(ruleset_install_prefs))); } void CrxInstaller::OnUnpackSuccessOnSharedFileThread( @@ -543,12 +543,12 @@ std::unique_ptr<base::DictionaryValue> original_manifest, scoped_refptr<const Extension> extension, SkBitmap install_icon, - declarative_net_request::RulesetChecksums ruleset_checksums) { + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs) { DCHECK(shared_file_task_runner_->RunsTasksInCurrentSequence()); extension_ = extension; temp_dir_ = temp_dir; - ruleset_checksums_ = std::move(ruleset_checksums); + ruleset_install_prefs_ = std::move(ruleset_install_prefs); ReportInstallationStage(InstallationStage::kCheckingExpectations); if (!install_icon.empty()) @@ -1040,7 +1040,7 @@ } service_weak_->OnExtensionInstalled(extension(), page_ordinal_, - install_flags_, ruleset_checksums_); + install_flags_, ruleset_install_prefs_); NotifyCrxInstallComplete(base::nullopt); }
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index ed2a875..8e9a427 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h
@@ -22,7 +22,7 @@ #include "chrome/browser/extensions/webstore_installer.h" #include "chrome/common/extensions/extension_constants.h" #include "components/sync/model/string_ordinal.h" -#include "extensions/browser/api/declarative_net_request/ruleset_checksum.h" +#include "extensions/browser/api/declarative_net_request/ruleset_install_pref.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/install_flag.h" #include "extensions/browser/preload_check.h" @@ -291,13 +291,13 @@ scoped_refptr<const Extension> extension, base::OnceCallback<void(bool)> callback) override; void OnUnpackFailure(const CrxInstallError& error) override; - void OnUnpackSuccess( - const base::FilePath& temp_dir, - const base::FilePath& extension_dir, - std::unique_ptr<base::DictionaryValue> original_manifest, - const Extension* extension, - const SkBitmap& install_icon, - declarative_net_request::RulesetChecksums ruleset_checksums) override; + void OnUnpackSuccess(const base::FilePath& temp_dir, + const base::FilePath& extension_dir, + std::unique_ptr<base::DictionaryValue> original_manifest, + const Extension* extension, + const SkBitmap& install_icon, + declarative_net_request::RulesetInstallPrefs + ruleset_install_prefs) override; void OnStageChanged(InstallationStage stage) override; // Called on the UI thread to start the requirements, policy and blocklist @@ -352,7 +352,7 @@ std::unique_ptr<base::DictionaryValue> original_manifest, scoped_refptr<const Extension> extension, SkBitmap install_icon, - declarative_net_request::RulesetChecksums ruleset_checksums); + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs); void set_install_flag(int flag, bool val) { if (val) @@ -521,9 +521,8 @@ // The flags for ExtensionService::OnExtensionInstalled. int install_flags_; - // The checksums for the indexed rulesets corresponding to the Declarative Net - // Request API. - declarative_net_request::RulesetChecksums ruleset_checksums_; + // Install prefs needed for the Declarative Net Request API. + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs_; // Checks that may run before installing the extension. std::unique_ptr<PreloadCheck> policy_check_;
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index de6f44c..e61bbc4 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -1404,10 +1404,10 @@ << extension->version().GetString(); // TODO(crbug.com/696822): If needed, add support for Declarative Net - // Request to component extensions and pass the ruleset checksum here. + // Request to component extensions and pass the ruleset install prefs here. AddNewOrUpdatedExtension(extension, Extension::ENABLED, kInstallFlagNone, syncer::StringOrdinal(), std::string(), - {} /* ruleset_checksums */); + {} /* ruleset_install_prefs */); return; } @@ -1547,7 +1547,7 @@ const Extension* extension, const syncer::StringOrdinal& page_ordinal, int install_flags, - const declarative_net_request::RulesetChecksums& ruleset_checksums) { + const declarative_net_request::RulesetInstallPrefs& ruleset_install_prefs) { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); const std::string& id = extension->id(); @@ -1651,12 +1651,12 @@ case InstallGate::INSTALL: AddNewOrUpdatedExtension(extension, initial_state, install_flags, page_ordinal, install_parameter, - ruleset_checksums); + ruleset_install_prefs); return; case InstallGate::DELAY: extension_prefs_->SetDelayedInstallInfo( extension, initial_state, install_flags, delay_reason, page_ordinal, - install_parameter, ruleset_checksums); + install_parameter, ruleset_install_prefs); // Transfer ownership of |extension|. delayed_installs_.Insert(extension); @@ -1705,11 +1705,11 @@ int install_flags, const syncer::StringOrdinal& page_ordinal, const std::string& install_parameter, - const declarative_net_request::RulesetChecksums& ruleset_checksums) { + const declarative_net_request::RulesetInstallPrefs& ruleset_install_prefs) { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); extension_prefs_->OnExtensionInstalled(extension, initial_state, page_ordinal, install_flags, install_parameter, - ruleset_checksums); + ruleset_install_prefs); delayed_installs_.Remove(extension->id()); if (InstallVerifier::NeedsVerification(*extension)) InstallVerifier::Get(GetBrowserContext())->VerifyExtension(extension->id());
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index fdd2211f..d8a9e122 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h
@@ -32,7 +32,7 @@ #include "components/sync/model/string_ordinal.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" -#include "extensions/browser/api/declarative_net_request/ruleset_checksum.h" +#include "extensions/browser/api/declarative_net_request/ruleset_install_pref.h" #include "extensions/browser/crx_file_info.h" #include "extensions/browser/disable_reason.h" #include "extensions/browser/extension_prefs.h" @@ -313,16 +313,17 @@ // Informs the service that an extension's files are in place for loading. // - // |extension| the extension - // |page_ordinal| the location of the extension in the app launcher - // |install_flags| a bitmask of InstallFlags - // |ruleset_checksums| Checksums of the indexed rulesets for the - // Declarative Net Request API. - void OnExtensionInstalled( - const Extension* extension, - const syncer::StringOrdinal& page_ordinal, - int install_flags, - const declarative_net_request::RulesetChecksums& ruleset_checksums = {}); + // |extension| the extension + // |page_ordinal| the location of the extension in the app + // launcher + // |install_flags| a bitmask of InstallFlags + // |ruleset_install_prefs| Install prefs needed for the Declarative Net + // Request API. + void OnExtensionInstalled(const Extension* extension, + const syncer::StringOrdinal& page_ordinal, + int install_flags, + const declarative_net_request::RulesetInstallPrefs& + ruleset_install_prefs = {}); void OnExtensionInstalled(const Extension* extension, const syncer::StringOrdinal& page_ordinal) { OnExtensionInstalled(extension, page_ordinal, @@ -515,7 +516,8 @@ int install_flags, const syncer::StringOrdinal& page_ordinal, const std::string& install_parameter, - const declarative_net_request::RulesetChecksums& ruleset_checksums); + const declarative_net_request::RulesetInstallPrefs& + ruleset_install_prefs); // Common helper to finish installing the given extension. void FinishInstallation(const Extension* extension);
diff --git a/chrome/browser/extensions/process_manager_browsertest.cc b/chrome/browser/extensions/process_manager_browsertest.cc index d84302d9..ee42f67 100644 --- a/chrome/browser/extensions/process_manager_browsertest.cc +++ b/chrome/browser/extensions/process_manager_browsertest.cc
@@ -679,7 +679,7 @@ // Verify correct keepalive count behavior on network request events. // Regression test for http://crbug.com/535716. // Disabled on Linux for flakiness: http://crbug.com/1030435. -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #define MAYBE_KeepaliveOnNetworkRequest DISABLED_KeepaliveOnNetworkRequest #else #define MAYBE_KeepaliveOnNetworkRequest KeepaliveOnNetworkRequest
diff --git a/chrome/browser/extensions/startup_helper.cc b/chrome/browser/extensions/startup_helper.cc index 8221acc5..984ae18b 100644 --- a/chrome/browser/extensions/startup_helper.cc +++ b/chrome/browser/extensions/startup_helper.cc
@@ -99,13 +99,13 @@ protected: ~ValidateCrxHelper() override {} - void OnUnpackSuccess( - const base::FilePath& temp_dir, - const base::FilePath& extension_root, - std::unique_ptr<base::DictionaryValue> original_manifest, - const Extension* extension, - const SkBitmap& install_icon, - declarative_net_request::RulesetChecksums ruleset_checksums) override { + void OnUnpackSuccess(const base::FilePath& temp_dir, + const base::FilePath& extension_root, + std::unique_ptr<base::DictionaryValue> original_manifest, + const Extension* extension, + const SkBitmap& install_icon, + declarative_net_request::RulesetInstallPrefs + ruleset_install_prefs) override { DCHECK(GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence()); success_ = true; content::GetUIThreadTaskRunner({})->PostTask(
diff --git a/chrome/browser/extensions/unpacked_installer.cc b/chrome/browser/extensions/unpacked_installer.cc index 9024d95..4533622 100644 --- a/chrome/browser/extensions/unpacked_installer.cc +++ b/chrome/browser/extensions/unpacked_installer.cc
@@ -277,7 +277,7 @@ return false; } - ruleset_checksums_ = std::move(result.ruleset_checksums); + ruleset_install_prefs_ = std::move(result.ruleset_install_prefs); if (!result.warnings.empty()) extension_->AddInstallWarnings(std::move(result.warnings)); @@ -362,7 +362,7 @@ service_weak_->OnExtensionInstalled(extension(), syncer::StringOrdinal(), kInstallFlagInstallImmediately, - ruleset_checksums_); + ruleset_install_prefs_); if (!callback_.is_null()) std::move(callback_).Run(extension(), extension_path_, std::string());
diff --git a/chrome/browser/extensions/unpacked_installer.h b/chrome/browser/extensions/unpacked_installer.h index a73a05d..2a70c07 100644 --- a/chrome/browser/extensions/unpacked_installer.h +++ b/chrome/browser/extensions/unpacked_installer.h
@@ -16,7 +16,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" -#include "extensions/browser/api/declarative_net_request/ruleset_checksum.h" +#include "extensions/browser/api/declarative_net_request/ruleset_install_pref.h" #include "extensions/browser/preload_check.h" #include "extensions/common/manifest.h" @@ -160,9 +160,8 @@ // Runs the above checks. std::unique_ptr<PreloadCheckGroup> check_group_; - // The checksums for the indexed rulesets corresponding to the Declarative Net - // Request API. - declarative_net_request::RulesetChecksums ruleset_checksums_; + // Install prefs needed for the Declarative Net Request API. + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs_; CompletionCallback callback_;
diff --git a/chrome/browser/extensions/updater/parallel_unpacker.cc b/chrome/browser/extensions/updater/parallel_unpacker.cc index b497214e..cfb0342 100644 --- a/chrome/browser/extensions/updater/parallel_unpacker.cc +++ b/chrome/browser/extensions/updater/parallel_unpacker.cc
@@ -26,14 +26,14 @@ std::unique_ptr<base::DictionaryValue> original_manifest, scoped_refptr<const Extension> extension, const SkBitmap& install_icon, - declarative_net_request::RulesetChecksums ruleset_checksums) + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs) : fetch_info(std::move(fetch_info)), temp_dir(temp_dir), extension_root(extension_root), original_manifest(std::move(original_manifest)), extension(extension), install_icon(install_icon), - ruleset_checksums(std::move(ruleset_checksums)) {} + ruleset_install_prefs(std::move(ruleset_install_prefs)) {} ParallelUnpacker::UnpackedExtension::UnpackedExtension(UnpackedExtension&&) = default; @@ -118,12 +118,12 @@ std::unique_ptr<base::DictionaryValue> original_manifest, const Extension* extension, const SkBitmap& install_icon, - declarative_net_request::RulesetChecksums ruleset_checksums) { + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs) { DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); UnpackedExtension unpacked_extension( std::move(fetch_info_), temp_dir, extension_root, std::move(original_manifest), extension, install_icon, - std::move(ruleset_checksums)); + std::move(ruleset_install_prefs)); base::PostTask(FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(&ParallelUnpacker::ReportSuccessOnUIThread, unpacker_, std::move(unpacked_extension)));
diff --git a/chrome/browser/extensions/updater/parallel_unpacker.h b/chrome/browser/extensions/updater/parallel_unpacker.h index 94438be9..39f23ffb 100644 --- a/chrome/browser/extensions/updater/parallel_unpacker.h +++ b/chrome/browser/extensions/updater/parallel_unpacker.h
@@ -11,7 +11,7 @@ #include "base/files/file_path.h" #include "base/memory/scoped_refptr.h" #include "chrome/browser/extensions/updater/fetched_crx_file.h" -#include "extensions/browser/api/declarative_net_request/ruleset_checksum.h" +#include "extensions/browser/api/declarative_net_request/ruleset_install_pref.h" #include "extensions/browser/crx_file_info.h" #include "extensions/browser/install/crx_install_error.h" #include "extensions/browser/sandboxed_unpacker.h" @@ -42,7 +42,7 @@ std::unique_ptr<base::DictionaryValue> original_manifest, scoped_refptr<const Extension> extension, const SkBitmap& install_icon, - declarative_net_request::RulesetChecksums ruleset_checksums); + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs); UnpackedExtension(UnpackedExtension&& other); UnpackedExtension& operator=(UnpackedExtension&&); ~UnpackedExtension(); @@ -69,9 +69,8 @@ scoped_refptr<const Extension> extension; // The icon we will display in the installation UI, if any. SkBitmap install_icon; - // Checksums for the indexed rulesets corresponding to the Declarative Net - // Request API. - declarative_net_request::RulesetChecksums ruleset_checksums; + // Install prefs needed for the Declarative Net Request API. + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs; }; class Delegate { @@ -120,7 +119,8 @@ std::unique_ptr<base::DictionaryValue> original_manifest, const Extension* extension, const SkBitmap& install_icon, - declarative_net_request::RulesetChecksums ruleset_checksums) override; + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs) + override; void OnUnpackFailure(const CrxInstallError& error) override; FetchedCRXFile& fetch_info() { return fetch_info_; }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index ed7bf01c..7574e36 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -719,17 +719,17 @@ { "name": "cryptauth-v2-device-activity-status", "owners": [ "khorimoto", "nohle", "themaxli" ], - "expiry_milestone": 86 + "expiry_milestone": 89 }, { "name": "cryptauth-v2-devicesync", "owners": [ "khorimoto", "nohle" ], - "expiry_milestone": 86 + "expiry_milestone": 89 }, { "name": "cryptauth-v2-enrollment", "owners": [ "khorimoto", "nohle" ], - "expiry_milestone": 86 + "expiry_milestone": 89 }, { "name": "cups-ipp-printing-backend", @@ -854,7 +854,7 @@ { "name": "disable-cryptauth-v1-devicesync", "owners": [ "khorimoto", "nohle" ], - "expiry_milestone": 87 + "expiry_milestone": 90 }, { "name": "disable-experimental-accessibility-chromevox-language-switching", @@ -3358,7 +3358,7 @@ { "name": "omnibox-on-focus-suggestions", "owners": [ "chrome-omnibox-team@google.com" ], - "expiry_milestone": 86 + "expiry_milestone": 90 }, { "name": "omnibox-on-focus-suggestions-contextual-web", @@ -4256,12 +4256,12 @@ { "name": "tab-hover-card-images", "owners": [ "dfried", "corising", "//chrome/browser/ui/views/tabs/OWNERS" ], - "expiry_milestone": 86 + "expiry_milestone": 88 }, { "name": "tab-hover-cards", "owners": [ "corising", "//chrome/browser/ui/views/tabs/OWNERS" ], - "expiry_milestone": 86 + "expiry_milestone": 88 }, { "name": "tab-outlines-in-low-contrast-themes",
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.cc b/chrome/browser/media/router/mojo/media_router_desktop.cc index ae06b14..5eb3ef26 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop.cc
@@ -50,7 +50,7 @@ MediaRouterMojoImpl::OnUserGesture(); // Allow MRPM to intelligently update sinks and observers by passing in a // media source. - UpdateMediaSinks(MediaSource::ForDesktop().id()); + UpdateMediaSinks(MediaSource::ForUnchosenDesktop().id()); media_sink_service_->BindLogger(GetLogger()); media_sink_service_->OnUserGesture();
diff --git a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc index 7f9276f..56005bd 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc
@@ -114,7 +114,7 @@ TEST_F(MediaRouterDesktopTest, OnUserGesture) { EXPECT_CALL(mock_extension_provider_, - UpdateMediaSinks(MediaSource::ForDesktop().id())); + UpdateMediaSinks(MediaSource::ForUnchosenDesktop().id())); router()->OnUserGesture(); base::RunLoop().RunUntilIdle(); }
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc index df0ebcb..59350c9c 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
@@ -146,6 +146,9 @@ params.app_name = l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME); params.target_name = params.app_name; params.select_only_screen = true; + params.request_audio = true; + params.approve_audio_by_default = true; + return params; } @@ -1132,8 +1135,8 @@ media_id, "ChromeMediaRouter", content::kRegistryStreamTypeDesktop); media_route_providers_[provider_id]->CreateRoute( - MediaSource::ForDesktop(request.stream_id).id(), sink_id, presentation_id, - origin, -1, timeout, off_the_record, + MediaSource::ForDesktop(request.stream_id, media_id.audio_share).id(), + sink_id, presentation_id, origin, -1, timeout, off_the_record, base::BindOnce( [](mojom::MediaRouteProvider::CreateRouteCallback inner_callback, base::WeakPtr<MediaRouterMojoImpl> self,
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_metrics.cc b/chrome/browser/media/router/mojo/media_router_mojo_metrics.cc index 64e0f58..3c5c50c3 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_metrics.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_metrics.cc
@@ -147,7 +147,7 @@ auto cast_source = CastMediaSource::FromMediaSource(media_source); if (cast_source) { ukm::builders::MediaRouter_SiteInitiatedMirroringStarted(source_id) - .SetAllowAudioCapture(cast_source->allow_audio_capture()) + .SetAllowAudioCapture(cast_source->site_requested_audio_capture()) .Record(ukm::UkmRecorder::Get()); } }
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc index cf193c69..6353c14 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc +++ b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
@@ -187,7 +187,7 @@ if (IsSiteInitiatedMirroringSource(cast_source.source_id())) { base::UmaHistogramBoolean(kHistogramAudioSender, - cast_source.allow_audio_capture()); + cast_source.site_requested_audio_capture()); } RecordLaunchSessionRequestSupportedAppTypes( cast_source.supported_app_types());
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity.cc b/chrome/browser/media/router/providers/cast/mirroring_activity.cc index 0b1dc73..21f1bfbf 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity.cc +++ b/chrome/browser/media/router/providers/cast/mirroring_activity.cc
@@ -323,13 +323,16 @@ auto cast_source = CastMediaSource::FromMediaSource(route_.media_source()); DCHECK(cast_source); - // Derive session type from capabilities and media source. + // Derive session type by intersecting the sink capabilities with what the + // media source can provide. const bool has_audio = (cast_data_.capabilities & static_cast<uint8_t>(cast_channel::AUDIO_OUT)) != 0 && - cast_source->allow_audio_capture(); + cast_source->ProvidesStreamingAudioCapture(); const bool has_video = (cast_data_.capabilities & static_cast<uint8_t>(cast_channel::VIDEO_OUT)) != 0; - DCHECK(has_audio || has_video); + if (!has_audio && !has_video) { + return; + } const SessionType session_type = has_audio && has_video ? SessionType::AUDIO_AND_VIDEO
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc b/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc index db1e084..4681c60 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc +++ b/chrome/browser/media/router/providers/cast/mirroring_activity_unittest.cc
@@ -132,7 +132,7 @@ base::HistogramTester uma_recorder; EXPECT_CALL(media_router_, GetMirroringServiceHostForDesktop(_, kDesktopMediaId, _)); - MediaSource source = MediaSource::ForDesktop(kDesktopMediaId); + MediaSource source = MediaSource::ForDesktop(kDesktopMediaId, true); ASSERT_TRUE(source.IsDesktopMirroringSource()); MakeActivity(source);
diff --git a/chrome/browser/media/webrtc/desktop_media_picker_controller.cc b/chrome/browser/media/webrtc/desktop_media_picker_controller.cc index 74462a8..239bf79 100644 --- a/chrome/browser/media/webrtc/desktop_media_picker_controller.cc +++ b/chrome/browser/media/webrtc/desktop_media_picker_controller.cc
@@ -81,7 +81,19 @@ DCHECK(source_lists_.size() == 1); auto* source_list = source_lists_[0].get(); if (source_list->GetSourceCount() == 1) { - OnPickerDialogResults({}, source_list->GetSource(0).id); + // With only one possible source, the picker dialog is being bypassed. Apply + // the default value of the "audio checkbox" here for desktop screen share. + // Only two platform configurations support desktop audio capture (i.e., + // system-wide audio loopback) at this time. + content::DesktopMediaID media_id = source_list->GetSource(0).id; + DCHECK_EQ(media_id.type, content::DesktopMediaID::TYPE_SCREEN); +#if defined(USE_CRAS) || defined(OS_WIN) + media_id.audio_share = + params_.request_audio && params_.approve_audio_by_default; +#else + media_id.audio_share = false; +#endif + OnPickerDialogResults({}, media_id); return; }
diff --git a/chrome/browser/notifications/notification_display_service_impl.cc b/chrome/browser/notifications/notification_display_service_impl.cc index 73ad8453..88ffe9b 100644 --- a/chrome/browser/notifications/notification_display_service_impl.cc +++ b/chrome/browser/notifications/notification_display_service_impl.cc
@@ -37,7 +37,8 @@ #include "chrome/browser/notifications/notification_platform_bridge_message_center.h" #endif -#if defined(OS_LINUX) || defined(OS_MAC) || defined(OS_WIN) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || \ + defined(OS_WIN) #include "chrome/browser/nearby_sharing/nearby_notification_handler.h" #include "chrome/browser/send_tab_to_self/desktop_notification_handler.h" #include "chrome/browser/sharing/sharing_notification_handler.h" @@ -52,7 +53,7 @@ #if !defined(OS_CHROMEOS) bool NativeNotificationsEnabled(Profile* profile) { -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) if (profile) { PrefService* prefs = profile->GetPrefs(); if (!prefs->GetBoolean(prefs::kAllowNativeNotifications)) @@ -151,7 +152,8 @@ AddNotificationHandler(NotificationHandler::Type::WEB_PERSISTENT, std::make_unique<PersistentNotificationHandler>()); -#if defined(OS_LINUX) || defined(OS_MAC) || defined(OS_WIN) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || \ + defined(OS_WIN) AddNotificationHandler( NotificationHandler::Type::SEND_TAB_TO_SELF, std::make_unique<send_tab_to_self::DesktopNotificationHandler>(
diff --git a/chrome/browser/notifications/notification_interactive_uitest.cc b/chrome/browser/notifications/notification_interactive_uitest.cc index 8c4b443..2adc8c6 100644 --- a/chrome/browser/notifications/notification_interactive_uitest.cc +++ b/chrome/browser/notifications/notification_interactive_uitest.cc
@@ -442,7 +442,7 @@ } // See crbug.com/248470 -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) #define MAYBE_TestCrashRendererNotificationRemain \ DISABLED_TestCrashRendererNotificationRemain #else
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 c8be3fca..72f4cce 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
@@ -425,6 +425,13 @@ // Creates a frame with display:none styling and verifies that it has an // empty intersection with the main frame. +#if defined(OS_WIN) +#define MAYBE_PageAdDensityIgnoreDisplayNoneFrame \ + DISABLED_PageAdDensityIgnoreDisplayNoneFrame +#else +#define MAYBE_PageAdDensityIgnoreDisplayNoneFrame \ + PageAdDensityIgnoreDisplayNoneFrame +#endif IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, PageAdDensityIgnoreDisplayNoneFrame) { base::HistogramTester histogram_tester;
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc index 9ea29677..97349258 100644 --- a/chrome/browser/printing/print_view_manager.cc +++ b/chrome/browser/printing/print_view_manager.cc
@@ -216,9 +216,11 @@ return true; } -void PrintViewManager::OnDidShowPrintDialog(content::RenderFrameHost* rfh) { - if (rfh != print_preview_rfh_) +void PrintViewManager::DidShowPrintDialog() { + if (print_manager_host_receivers_.GetCurrentTargetFrame() != + print_preview_rfh_) { return; + } if (on_print_dialog_shown_callback_) std::move(on_print_dialog_shown_callback_).Run(); @@ -302,7 +304,6 @@ FrameDispatchHelper helper = {this, render_frame_host}; bool handled = true; IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(PrintViewManager, message, render_frame_host) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog) IPC_MESSAGE_FORWARD_DELAY_REPLY( PrintHostMsg_SetupScriptedPrintPreview, &helper, FrameDispatchHelper::OnSetupScriptedPrintPreview)
diff --git a/chrome/browser/printing/print_view_manager.h b/chrome/browser/printing/print_view_manager.h index 4030f94..dfb02cb 100644 --- a/chrome/browser/printing/print_view_manager.h +++ b/chrome/browser/printing/print_view_manager.h
@@ -58,6 +58,9 @@ // renderer in the case of scripted print preview if needed. void PrintPreviewDone(); + // mojom::PrintManagerHost: + void DidShowPrintDialog() override; + // content::WebContentsObserver implementation. void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; @@ -91,7 +94,6 @@ bool has_selection); // IPC Message handlers. - void OnDidShowPrintDialog(content::RenderFrameHost* rfh); void OnSetupScriptedPrintPreview(content::RenderFrameHost* rfh, IPC::Message* reply_msg); void OnShowScriptedPrintPreview(content::RenderFrameHost* rfh,
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access/nodes/node_wrapper.js b/chrome/browser/resources/chromeos/accessibility/switch_access/nodes/node_wrapper.js index f87d286..82ca1f61 100644 --- a/chrome/browser/resources/chromeos/accessibility/switch_access/nodes/node_wrapper.js +++ b/chrome/browser/resources/chromeos/accessibility/switch_access/nodes/node_wrapper.js
@@ -356,12 +356,12 @@ * @return {!RootNodeWrapper} */ static buildTree(rootNode) { - if (SwitchAccessPredicate.isWindow(rootNode)) { - return WindowRootNode.buildTree(rootNode); - } if (rootNode.role === chrome.automation.RoleType.KEYBOARD) { return KeyboardRootNode.buildTree(); } + if (SwitchAccessPredicate.isWindow(rootNode)) { + return WindowRootNode.buildTree(rootNode); + } const root = new RootNodeWrapper(rootNode); const childConstructor = (node) => NodeWrapper.create(node, root);
diff --git a/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js b/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js index 13dbc68..5434483 100644 --- a/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js +++ b/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js
@@ -19,7 +19,7 @@ * url: string, * }} */ -let RegulatoryInfo; +/* #export */ let RegulatoryInfo; /** * @typedef {{ @@ -28,7 +28,7 @@ * isLts: boolean, * }} */ -let ChannelInfo; +/* #export */ let ChannelInfo; /** * @typedef {{ @@ -37,7 +37,7 @@ * osVersion: string, * }} */ -let VersionInfo; +/* #export */ let VersionInfo; /** * @typedef {{ @@ -45,7 +45,7 @@ * size: (string|undefined), * }} */ -let AboutPageUpdateInfo; +/* #export */ let AboutPageUpdateInfo; /** * @typedef {{ @@ -59,7 +59,7 @@ * Enumeration of all possible browser channels. * @enum {string} */ -const BrowserChannel = { +/* #export */ const BrowserChannel = { BETA: 'beta-channel', CANARY: 'canary-channel', DEV: 'dev-channel', @@ -71,7 +71,7 @@ * updateAvailable: boolean, * }} */ -let TPMFirmwareUpdateStatusChangedEvent; +/* #export */ let TPMFirmwareUpdateStatusChangedEvent; // </if> /** @@ -124,7 +124,7 @@ * @param {boolean} isLts * @return {string} */ - function browserChannelToI18nId(channel, isLts) { + /* #export */ function browserChannelToI18nId(channel, isLts) { if (isLts) { return 'aboutChannelLongTermStable'; } @@ -149,7 +149,8 @@ * @return {boolean} Whether the target channel is more stable than the * current channel. */ - function isTargetChannelMoreStable(currentChannel, targetChannel) { + /* #export */ function isTargetChannelMoreStable( + currentChannel, targetChannel) { // List of channels in increasing stability order. const channelList = [ BrowserChannel.CANARY,
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 6fa5962..c08dce7 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -272,7 +272,8 @@ "multidevice_page:closure_compile_module", #"os_a11y_page:closure_compile_module", - #"os_about_page:closure_compile_module", + "os_about_page:closure_compile_module", + #"os_apps_page:closure_compile_module", #"os_apps_page/app_management_page/plugin_vm_page:closure_compile_module", "os_files_page:closure_compile_module", @@ -435,10 +436,13 @@ "..:modulize", "..:settings_shared_css_module", "..:settings_vars_css_module", + "../../settings:settings_page_css_module", + "../about_page:modulize", "../nearby_share_page:polymer3_elements", "../prefs:modulize", "../prefs:prefs_module", "../settings_page:settings_animated_pages_module", + "../settings_page:settings_section_module", "../settings_page:settings_subpage_module", ] }
diff --git a/chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.m.js b/chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.m.js index 18ce583..65544f6 100644 --- a/chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.m.js +++ b/chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.m.js
@@ -5,7 +5,7 @@ let lazyLoadPromise = null; /** @return {!Promise<void>} Resolves when the lazy load module is imported. */ -export function ensureLazyLoadedOs() { +export function ensureLazyLoaded() { if (!lazyLoadPromise) { const script = document.createElement('script'); script.type = 'module';
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn index e34ecfe8..651d75c2 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("../os_settings.gni") js_type_check("closure_compile") { deps = [ @@ -47,21 +48,23 @@ ] } -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":channel_switcher_dialog.m", -# ":detailed_build_info.m", -# ":os_about_page.m", -# ":update_warning_dialog.m" -# ] -#} +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ + ":channel_switcher_dialog.m", + ":detailed_build_info.m", + ":os_about_page.m", + ":update_warning_dialog.m", + ] +} js_library("channel_switcher_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_about_page/channel_switcher_dialog.m.js" ] deps = [ - # TODO: Fill those in. + "../../about_page:about_page_browser_proxy.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:load_time_data.m", ] extra_deps = [ ":channel_switcher_dialog_module" ] } @@ -69,7 +72,10 @@ js_library("detailed_build_info.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.m.js" ] deps = [ - # TODO: Fill those in. + "../../about_page:about_page_browser_proxy.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/policy:cr_policy_indicator_behavior.m", + "//ui/webui/resources/js:i18n_behavior.m", ] extra_deps = [ ":detailed_build_info_module" ] } @@ -77,7 +83,17 @@ js_library("os_about_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.m.js" ] deps = [ - # TODO: Fill those in. + "..:os_route.m", + "../..:i18n_setup", + "../..:lifetime_browser_proxy.m", + "../..:router.m", + "../../about_page:about_page_browser_proxy.m", + "../os_settings_page:main_page_behavior.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:load_time_data.m", + "//ui/webui/resources/js:parse_html_subset.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", ] extra_deps = [ ":os_about_page_module" ] } @@ -85,7 +101,9 @@ js_library("update_warning_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_about_page/update_warning_dialog.m.js" ] deps = [ - # TODO: Fill those in. + "../../about_page:about_page_browser_proxy.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:i18n_behavior.m", ] extra_deps = [ ":update_warning_dialog_module" ] } @@ -105,22 +123,34 @@ js_file = "channel_switcher_dialog.js" html_file = "channel_switcher_dialog.html" html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("detailed_build_info") { js_file = "detailed_build_info.js" html_file = "detailed_build_info.html" html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("os_about_page") { js_file = "os_about_page.js" html_file = "os_about_page.html" html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("update_warning_dialog") { js_file = "update_warning_dialog.js" html_file = "update_warning_dialog.html" html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports }
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/channel_switcher_dialog.html b/chrome/browser/resources/settings/chromeos/os_about_page/channel_switcher_dialog.html index 153da20..36ccecd55 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/channel_switcher_dialog.html +++ b/chrome/browser/resources/settings/chromeos/os_about_page/channel_switcher_dialog.html
@@ -7,6 +7,8 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-selector/iron-selector.html"> <link rel="import" href="../../about_page/about_page_browser_proxy.html"> <link rel="import" href="../../settings_shared_css.html"> +<link rel="import" href="chrome://resources/html/assert.html"> +<link rel="import" href="chrome://resources/html/load_time_data.html"> <dom-module id="settings-channel-switcher-dialog"> <template>
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.html b/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.html index f1673ac..9bea07dd 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.html +++ b/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.html
@@ -9,6 +9,7 @@ <link rel="import" href="../localized_link/localized_link.html"> <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator_behavior.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <dom-module id="settings-detailed-build-info">
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html index 7f1600b..d528dc9 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html +++ b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html
@@ -1,8 +1,8 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/html/parse_html_subset.html"> <link rel="import" href="../../about_page/about_page_browser_proxy.html"> <link rel="import" href="../../i18n_setup.html"> -<!-- TODO(crbug.com/986596): Don't use browser icons here. Fork them. --> <link rel="import" href="../../icons.html"> <link rel="import" href="../../lifetime_browser_proxy.html"> <link rel="import" href="../../prefs/prefs.html"> @@ -62,6 +62,7 @@ text-align: center; } + /* TODO(crbug.com/986596): Don't use browser icons here. Fork them. */ iron-icon[icon='settings:check-circle'] { fill: var(--cros-icon-color-prominent); } @@ -102,6 +103,7 @@ when update is done) or set the src (when it's updating). --> <div class="icon-container" hidden="[[!shouldShowIcons_(showUpdateStatus_)]]"> + <!-- TODO(crbug.com/986596): Don't use browser icons here. Fork them. --> <iron-icon icon$="[[getUpdateStatusIcon_( hasEndOfLife_, currentUpdateStatusEvent_)]]"
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.js b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.js index fc6961af..8d48bf7 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.js +++ b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.js
@@ -400,6 +400,7 @@ return 'cr:error'; case UpdateStatus.UPDATED: case UpdateStatus.NEARLY_UPDATED: + // TODO(crbug.com/986596): Don't use browser icons here. Fork them. return 'settings:check-circle'; default: return null; @@ -464,6 +465,7 @@ return this.i18nAdvanced('aboutRelaunch'); } } + return ''; }, /** @private */
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/update_warning_dialog.js b/chrome/browser/resources/settings/chromeos/os_about_page/update_warning_dialog.js index 42cddca..e679770 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/update_warning_dialog.js +++ b/chrome/browser/resources/settings/chromeos/os_about_page/update_warning_dialog.js
@@ -40,8 +40,13 @@ /** @private */ onContinueTap_() { + if (!this.updateInfo || !this.updateInfo.version || !this.updateInfo.size){ + console.log('ERROR: requestUpdateOverCellular arguments are undefined'); + return; + } this.browserProxy_.requestUpdateOverCellular( - this.updateInfo.version, this.updateInfo.size); + /** @type {!string} */ (this.updateInfo.version), + /** @type {!string} */ (this.updateInfo.size)); this.$.dialog.close(); },
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index ac39b77..8f867c8f 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -74,6 +74,9 @@ "settings.printing.isNameAndAddressValid|isNameAndAddressValid", "settings.printing.isPPDInfoValid|isPPDInfoValid", "settings.printing.getPrintServerErrorText|getPrintServerErrorText", + "settings.AboutPageBrowserProxyImpl|AboutPageBrowserProxyImpl", + "settings.browserChannelToI18nId|browserChannelToI18nId", + "settings.isTargetChannelMoreStable|isTargetChannelMoreStable", ] os_settings_auto_imports = settings_auto_imports + @@ -120,6 +123,9 @@ "ui/webui/resources/html/web_ui_listener_behavior.html|WebUIListenerBehavior", "ui/webui/resources/cr_components/chromeos/network/network_listener_behavior.html|NetworkListenerBehavior", "chrome/browser/resources/settings/chromeos/os_printing_page/cups_printer_types.html|PrinterListEntry,PrinterType", + "chrome/browser/resources/settings/about_page/about_page_browser_proxy.html|AboutPageBrowserProxyImpl,AboutPageUpdateInfo,AboutPageBrowserProxy,browserChannelToI18nId,VersionInfo,ChannelInfo,BrowserChannel,isTargetChannelMoreStable,UpdateStatus,UpdateStatusChangedEvent,RegulatoryInfo,TPMFirmwareUpdateStatusChangedEvent", + "chrome/browser/resources/settings/chromeos/os_settings_page/main_page_behavior.html|MainPageBehavior", + "ui/webui/resources/html/parse_html_subset.html|parseHtmlSubset", ] os_settings_migrated_imports = settings_migrated_imports
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.js b/chrome/browser/resources/settings/chromeos/os_settings.js index 66ea8fb..7939ed10 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.js +++ b/chrome/browser/resources/settings/chromeos/os_settings.js
@@ -16,7 +16,12 @@ import './os_people_page/kerberos_accounts.m.js'; import './parental_controls_page/parental_controls_page.m.js'; import './os_people_page/os_people_page.m.js'; +import './os_about_page/os_about_page.m.js'; +import './os_about_page/channel_switcher_dialog.m.js'; +import './os_about_page/detailed_build_info.m.js'; +import './os_about_page/update_warning_dialog.m.js'; +export {AboutPageBrowserProxyImpl, BrowserChannel, UpdateStatus} from '../about_page/about_page_browser_proxy.m.js'; export {LifetimeBrowserProxy, LifetimeBrowserProxyImpl} from '../lifetime_browser_proxy.m.js'; export {dataUsageStringToEnum, NearbyShareDataUsage} from '../nearby_share_page/types.m.js'; export {pageVisibility} from '../page_visibility.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp b/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp index b760be5c..21ac725 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp +++ b/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp
@@ -406,6 +406,49 @@ use_base_dir="false" compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_OS_ABOUT_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.m.js" + use_base_dir="false" + compress="false" + preprocess="true" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CHANNEL_SWITCHER_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_about_page/channel_switcher_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_DETAILED_BUILD_INFO_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_UPDATE_WARNING_DIALOG_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_about_page/update_warning_dialog.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_SETTINGS_PAGE_MAIN_PAGE_BEHAVIOR_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_settings_page/main_page_behavior.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_SETTINGS_ABOUT_PAGE_ABOUT_PAGE_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/about_page/about_page_browser_proxy.m.js" + use_base_dir="false" + compress="false" + preprocess="true" + type="BINDATA" /> + <include name="IDR_SETTINGS_SETTINGS_PAGE_SETTINGS_SECTION_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/settings_page/settings_section.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_SETTINGS_SETTINGS_PAGE_CSS_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/settings_page_css.m.js" + use_base_dir="false" + compress="false" + preprocess="true" + type="BINDATA" /> <include name="IDR_OS_SETTINGS_OS_FILES_PAGE_OS_FILES_PAGE_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.m.js" use_base_dir="false"
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index 2e310a0..f1a2ce5 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -22,6 +22,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "base/test/simple_test_clock.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" @@ -2072,8 +2073,21 @@ IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest, KeyPress_WarningShown) { + constexpr int kTimeOnPage = 10; base::HistogramTester histograms; NavigateAndAssertNoInterstitial(); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + // Inject a test clock to test the histogram that records the time on the + // delayed warning page before the warning shows or the user leaves the page. + base::SimpleTestClock clock; + SafeBrowsingUserInteractionObserver* observer = + SafeBrowsingUserInteractionObserver::FromWebContents(web_contents); + ASSERT_TRUE(observer); + clock.SetNow(observer->GetCreationTimeForTesting()); + observer->SetClockForTesting(&clock); + clock.Advance(base::TimeDelta::FromSeconds(kTimeOnPage)); // Type something. An interstitial should be shown. EXPECT_TRUE(TypeAndWaitForInterstitial(browser())); @@ -2088,17 +2102,33 @@ DelayedWarningEvent::kPageLoaded, 1); histograms.ExpectBucketCount(kDelayedWarningsHistogram, DelayedWarningEvent::kWarningShownOnKeypress, 1); + histograms.ExpectUniqueTimeSample(kDelayedWarningsTimeOnPageHistogram, + base::TimeDelta::FromSeconds(kTimeOnPage), + 1); } // Same as KeyPress_WarningShown, but user disabled URL elision by enabling // "Always Show Full URLs" option. A separate histogram must be recorded. IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageDelayedWarningBrowserTest, KeyPress_WarningShown_UrlElisionDisabled) { + constexpr int kTimeOnPage = 10; browser()->profile()->GetPrefs()->SetBoolean( omnibox::kPreventUrlElisionsInOmnibox, true); base::HistogramTester histograms; NavigateAndAssertNoInterstitial(); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + // Inject a test clock to test the histogram that records the time on the + // delayed warning page before the warning shows or the user leaves the page. + base::SimpleTestClock clock; + SafeBrowsingUserInteractionObserver* observer = + SafeBrowsingUserInteractionObserver::FromWebContents(web_contents); + ASSERT_TRUE(observer); + clock.SetNow(observer->GetCreationTimeForTesting()); + observer->SetClockForTesting(&clock); + clock.Advance(base::TimeDelta::FromSeconds(kTimeOnPage)); // Type something. An interstitial should be shown. EXPECT_TRUE(TypeAndWaitForInterstitial(browser())); @@ -2106,13 +2136,16 @@ EXPECT_TRUE(ClickAndWaitForDetach(browser(), "primary-button")); AssertNoInterstitial(browser(), false); // Assert the interstitial is gone EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank" - browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); + web_contents->GetURL()); histograms.ExpectTotalCount(kDelayedWarningsWithElisionDisabledHistogram, 2); histograms.ExpectBucketCount(kDelayedWarningsWithElisionDisabledHistogram, DelayedWarningEvent::kPageLoaded, 1); histograms.ExpectBucketCount(kDelayedWarningsWithElisionDisabledHistogram, DelayedWarningEvent::kWarningShownOnKeypress, 1); + histograms.ExpectUniqueTimeSample( + kDelayedWarningsTimeOnPageWithElisionDisabledHistogram, + base::TimeDelta::FromSeconds(kTimeOnPage), 1); } // Same as KeyPress_WarningShown_UrlElisionDisabled, but user disabled URL
diff --git a/chrome/browser/safe_browsing/user_interaction_observer.cc b/chrome/browser/safe_browsing/user_interaction_observer.cc index 00cc6fd..23182ce4 100644 --- a/chrome/browser/safe_browsing/user_interaction_observer.cc +++ b/chrome/browser/safe_browsing/user_interaction_observer.cc
@@ -29,9 +29,13 @@ namespace safe_browsing { const char kDelayedWarningsHistogram[] = "SafeBrowsing.DelayedWarnings.Event"; +const char kDelayedWarningsTimeOnPageHistogram[] = + "SafeBrowsing.DelayedWarnings.TimeOnPage"; const char kDelayedWarningsWithElisionDisabledHistogram[] = "SafeBrowsing.DelayedWarnings.Event_UrlElisionDisabled"; +const char kDelayedWarningsTimeOnPageWithElisionDisabledHistogram[] = + "SafeBrowsing.DelayedWarnings.TimeOnPage_UrlElisionDisabled"; namespace { const char kWebContentsUserDataKey[] = @@ -68,7 +72,9 @@ : content::WebContentsObserver(web_contents), web_contents_(web_contents), resource_(resource), - ui_manager_(ui_manager) { + ui_manager_(ui_manager), + creation_time_(base::Time::Now()), + clock_(base::DefaultClock::GetInstance()) { DCHECK(base::FeatureList::IsEnabled(kDelayedWarnings)); key_press_callback_ = base::BindRepeating(&SafeBrowsingUserInteractionObserver::HandleKeyPress, @@ -105,9 +111,6 @@ key_press_callback_); web_contents_->GetRenderViewHost()->GetWidget()->RemoveMouseEventCallback( mouse_event_callback_); - if (!interstitial_shown_) { - RecordUMA(DelayedWarningEvent::kWarningNotShown); - } } // static @@ -188,7 +191,21 @@ } void SafeBrowsingUserInteractionObserver::Detach() { + if (!interstitial_shown_) { + RecordUMA(DelayedWarningEvent::kWarningNotShown); + } + base::TimeDelta time_on_page = clock_->Now() - creation_time_; + if (IsUrlElisionDisabled( + Profile::FromBrowserContext(web_contents()->GetBrowserContext()), + suspicious_site_reporter_extension_id_)) { + base::UmaHistogramLongTimes( + kDelayedWarningsTimeOnPageWithElisionDisabledHistogram, time_on_page); + } else { + base::UmaHistogramLongTimes(kDelayedWarningsTimeOnPageHistogram, + time_on_page); + } web_contents()->RemoveUserData(kWebContentsUserDataKey); + // DO NOT add code past this point. |this| is destroyed. } void SafeBrowsingUserInteractionObserver::DidToggleFullscreenModeForTab( @@ -262,6 +279,16 @@ suspicious_site_reporter_extension_id_ = kPreventElisionExtensionId; } +void SafeBrowsingUserInteractionObserver::SetClockForTesting( + base::Clock* clock) { + clock_ = clock; +} + +base::Time SafeBrowsingUserInteractionObserver::GetCreationTimeForTesting() + const { + return creation_time_; +} + void SafeBrowsingUserInteractionObserver::RecordUMA(DelayedWarningEvent event) { Profile* profile = Profile::FromBrowserContext(web_contents()->GetBrowserContext());
diff --git a/chrome/browser/safe_browsing/user_interaction_observer.h b/chrome/browser/safe_browsing/user_interaction_observer.h index c3c250f3..c71c255d 100644 --- a/chrome/browser/safe_browsing/user_interaction_observer.h +++ b/chrome/browser/safe_browsing/user_interaction_observer.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_SAFE_BROWSING_USER_INTERACTION_OBSERVER_H_ #define CHROME_BROWSER_SAFE_BROWSING_USER_INTERACTION_OBSERVER_H_ +#include "base/time/default_clock.h" #include "chrome/browser/safe_browsing/ui_manager.h" #include "components/permissions/permission_request_manager.h" #include "components/security_interstitials/core/unsafe_resource.h" @@ -57,14 +58,15 @@ kMaxValue = kWarningShownOnPaste, }; -// Name of the recorded histogram when the user did not disable URL elision via +// Name of the recorded histograms when the user did not disable URL elision via // "Always Show Full URLs" menu option or by installing Suspicious Site Reporter // extension. extern const char kDelayedWarningsHistogram[]; +extern const char kDelayedWarningsTimeOnPageHistogram[]; -// Same as kDelayedWarningsHistogram but only recorded if the user disabled -// URL elision. +// Same as above but only recorded if the user disabled URL elision. extern const char kDelayedWarningsWithElisionDisabledHistogram[]; +extern const char kDelayedWarningsTimeOnPageWithElisionDisabledHistogram[]; // Observes user interactions and shows an interstitial if necessary. // Only created when an interstitial was about to be displayed but was delayed @@ -124,6 +126,9 @@ const char* extension_id); static void ResetSuspiciousSiteReporterExtensionIdForTesting(); + void SetClockForTesting(base::Clock* clock); + base::Time GetCreationTimeForTesting() const; + private: void RecordUMA(DelayedWarningEvent event); @@ -152,6 +157,12 @@ // Id of the Suspicious Site Reporter extension. Only set in tests. static const char* suspicious_site_reporter_extension_id_; + + // The time that this observer was created. Used for recording histograms. + base::Time creation_time_; + // This clock is used to record the delta from |creation_time_| when the + // observer is detached, and can be injected by tests. + base::Clock* clock_; }; } // namespace safe_browsing
diff --git a/chrome/browser/speech/speech_recognition_service.cc b/chrome/browser/speech/speech_recognition_service.cc index 7fc7b75d..acc8a787 100644 --- a/chrome/browser/speech/speech_recognition_service.cc +++ b/chrome/browser/speech/speech_recognition_service.cc
@@ -59,6 +59,17 @@ if (speech_recognition_service_.is_bound()) return; + PrefService* prefs = user_prefs::UserPrefs::Get(context_); + DCHECK(prefs); +#if BUILDFLAG(ENABLE_SODA) + auto binary_path = prefs->GetFilePath(prefs::kSodaBinaryPath); + auto config_path = SpeechRecognitionService::GetSodaConfigPath(prefs); + if (binary_path.empty() || config_path.empty()) { + LOG(ERROR) << "Unable to find SODA files on the device."; + return; + } +#endif + content::ServiceProcessHost::Launch( speech_recognition_service_.BindNewPipeAndPassReceiver(), content::ServiceProcessHost::Options() @@ -74,12 +85,9 @@ speech_recognition_service_.reset_on_idle_timeout(kIdleProcessTimeout); speech_recognition_service_client_.reset(); - - PrefService* prefs = user_prefs::UserPrefs::Get(context_); - DCHECK(prefs); - speech_recognition_service_->SetSodaPath( - prefs->GetFilePath(prefs::kSodaBinaryPath), - prefs->GetFilePath(prefs::kSodaEnUsConfigPath)); +#if BUILDFLAG(ENABLE_SODA) + speech_recognition_service_->SetSodaPath(binary_path, config_path); +#endif speech_recognition_service_->BindSpeechRecognitionServiceClient( speech_recognition_service_client_.BindNewPipeAndPassRemote()); OnNetworkServiceDisconnect(); @@ -89,12 +97,13 @@ speech::LanguageCode language = speech::GetLanguageCode( prefs->GetString(prefs::kLiveCaptionLanguageCode)); switch (language) { + case speech::LanguageCode::kNone: + NOTREACHED(); + return base::FilePath(); case speech::LanguageCode::kEnUs: return prefs->GetFilePath(prefs::kSodaEnUsConfigPath); case speech::LanguageCode::kJaJp: return prefs->GetFilePath(prefs::kSodaJaJpConfigPath); - default: - NOTREACHED(); } return base::FilePath();
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 3f8b77e..229c781 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -3918,8 +3918,6 @@ "views/toolbar/home_button.h", "views/toolbar/reload_button.cc", "views/toolbar/reload_button.h", - "views/toolbar/sharesheet_button.cc", - "views/toolbar/sharesheet_button.h", "views/toolbar/toolbar_account_icon_container_view.cc", "views/toolbar/toolbar_account_icon_container_view.h", "views/toolbar/toolbar_action_view.cc",
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 135787bc..cde5036 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -2446,6 +2446,9 @@ <message name="IDS_SIGNIN_ACCOUNT_PICKER_GENERAL_ERROR_SUBTITLE" desc="The subtitle of the account picker bottom sheet when something went wrong in the sign-in process"> Chrome couldn’t verify your information </message> + <message name="IDS_SIGNIN_ACCOUNT_PICKER_AUTH_ERROR_SUBTITLE" desc="The subtitle of the account picker bottom sheet when there is an authentication error with the credentials of the account selected."> + Sorry, we couldn’t validate your credentials + </message> <message name="IDS_SIGNIN_ACCOUNT_PICKER_GENERAL_ERROR_BUTTON" desc="Button text of the account picker bottom sheet when something went wrong in the sign-in process. User can try again if they click it."> Try again </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SIGNIN_ACCOUNT_PICKER_AUTH_ERROR_SUBTITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SIGNIN_ACCOUNT_PICKER_AUTH_ERROR_SUBTITLE.png.sha1 new file mode 100644 index 0000000..0886194 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SIGNIN_ACCOUNT_PICKER_AUTH_ERROR_SUBTITLE.png.sha1
@@ -0,0 +1 @@ +0891305cb2dc15b6b5962c0ab5ba7b2de43c7470 \ No newline at end of file
diff --git a/chrome/browser/ui/ash/cast_config_controller_media_router.cc b/chrome/browser/ui/ash/cast_config_controller_media_router.cc index 7c9f73fa..a40794475 100644 --- a/chrome/browser/ui/ash/cast_config_controller_media_router.cc +++ b/chrome/browser/ui/ash/cast_config_controller_media_router.cc
@@ -101,7 +101,7 @@ const base::RepeatingClosure& update_devices_callback) : MediaRoutesObserver(GetMediaRouter()), MediaSinksObserver(GetMediaRouter(), - media_router::MediaSource::ForDesktop(), + media_router::MediaSource::ForUnchosenDesktop(), url::Origin()), update_devices_callback_(update_devices_callback) {} @@ -245,7 +245,7 @@ void CastConfigControllerMediaRouter::CastToSink(const std::string& sink_id) { // TODO(imcheng): Pass in tab casting timeout. GetMediaRouter()->CreateRoute( - media_router::MediaSource::ForDesktop().id(), sink_id, + media_router::MediaSource::ForUnchosenDesktop().id(), sink_id, url::Origin::Create(GURL("http://cros-cast-origin/")), nullptr, base::DoNothing(), base::TimeDelta(), false); }
diff --git a/chrome/browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc b/chrome/browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc index 75a0a87..2045e1b 100644 --- a/chrome/browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc +++ b/chrome/browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc
@@ -38,8 +38,8 @@ const std::string& sink_id, bool is_local) { return media_router::MediaRoute( - route_id, media_router::MediaSource::ForDesktop(), sink_id, "description", - is_local, true /*for_display*/); + route_id, media_router::MediaSource::ForUnchosenDesktop(), sink_id, + "description", is_local, true /*for_display*/); } class SystemTrayTrayCastMediaRouterChromeOSTest : public InProcessBrowserTest {
diff --git a/chrome/browser/ui/views/media_router/media_router_views_ui.cc b/chrome/browser/ui/views/media_router/media_router_views_ui.cc index 63edd3b8..fbef89d4 100644 --- a/chrome/browser/ui/views/media_router/media_router_views_ui.cc +++ b/chrome/browser/ui/views/media_router/media_router_views_ui.cc
@@ -614,7 +614,8 @@ // Desktop mirror mode is always available. query_result_manager_->SetSourcesForCastMode( - MediaCastMode::DESKTOP_MIRROR, {MediaSource::ForDesktop()}, origin); + MediaCastMode::DESKTOP_MIRROR, {MediaSource::ForUnchosenDesktop()}, + origin); // File mirroring is always available. query_result_manager_->SetSourcesForCastMode(
diff --git a/chrome/browser/ui/views/toolbar/sharesheet_button.cc b/chrome/browser/ui/views/toolbar/sharesheet_button.cc deleted file mode 100644 index 432a446..0000000 --- a/chrome/browser/ui/views/toolbar/sharesheet_button.cc +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/views/toolbar/sharesheet_button.h" - -#include <memory> - -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/sharesheet/sharesheet_service.h" -#include "chrome/browser/sharesheet/sharesheet_service_factory.h" -#include "chrome/browser/themes/theme_properties.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_finder.h" -#include "components/vector_icons/vector_icons.h" -#include "ui/base/pointer/touch_ui_controller.h" -#include "ui/gfx/paint_vector_icon.h" - -SharesheetButton::SharesheetButton(Browser* browser) - : ToolbarButton(this), browser_(browser) {} - -SharesheetButton::~SharesheetButton() = default; - -void SharesheetButton::UpdateIcon() { - SetImageModel(views::Button::STATE_NORMAL, - ui::ImageModel::FromVectorIcon( - vector_icons::kHelpIcon, - GetThemeProvider()->GetColor( - ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON), - GetIconSize())); -} - -void SharesheetButton::ButtonPressed(views::Button* sender, - const ui::Event& event) { - // On button press show sharesheet bubble. - auto* profile = Profile::FromBrowserContext( - browser_->tab_strip_model()->GetActiveWebContents()->GetBrowserContext()); - auto* sharesheet_service = - sharesheet::SharesheetServiceFactory::GetForProfile(profile); - sharesheet_service->ShowBubble(/* bubble_anchor_view */ this, - /* intent */ nullptr); -} - -int SharesheetButton::GetIconSize() const { - const bool touch_ui = ui::TouchUiController::Get()->touch_ui(); - return (touch_ui && !browser_->app_controller()) ? kDefaultTouchableIconSize - : kDefaultIconSize; -}
diff --git a/chrome/browser/ui/views/toolbar/sharesheet_button.h b/chrome/browser/ui/views/toolbar/sharesheet_button.h deleted file mode 100644 index 5e4eefe..0000000 --- a/chrome/browser/ui/views/toolbar/sharesheet_button.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_SHARESHEET_BUTTON_H_ -#define CHROME_BROWSER_UI_VIEWS_TOOLBAR_SHARESHEET_BUTTON_H_ - -#include "chrome/browser/ui/views/toolbar/toolbar_button.h" - -class Browser; - -class SharesheetButton : public ToolbarButton, public views::ButtonListener { - public: - explicit SharesheetButton(Browser* browser); - SharesheetButton(const SharesheetButton&) = delete; - SharesheetButton& operator=(const SharesheetButton&) = delete; - ~SharesheetButton() override; - - // ToolbarButton: - void UpdateIcon() override; - - private: - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - - int GetIconSize() const; - - Browser* const browser_; -}; - -#endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_SHARESHEET_BUTTON_H_
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc index 7ccd06a..f69ad82 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -53,7 +53,6 @@ #include "chrome/browser/ui/views/toolbar/browser_app_menu_button.h" #include "chrome/browser/ui/views/toolbar/home_button.h" #include "chrome/browser/ui/views/toolbar/reload_button.h" -#include "chrome/browser/ui/views/toolbar/sharesheet_button.h" #include "chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_button.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" @@ -232,13 +231,6 @@ media_button = std::make_unique<MediaToolbarButtonView>(browser_); } - std::unique_ptr<SharesheetButton> sharesheet_button; -#if defined(OS_CHROMEOS) - if (base::FeatureList::IsEnabled(features::kSharesheet)) { - sharesheet_button = std::make_unique<SharesheetButton>(browser_); - } -#endif - std::unique_ptr<ToolbarAccountIconContainerView> toolbar_account_icon_container; bool show_avatar_toolbar_button = true; @@ -276,9 +268,6 @@ if (media_button) media_button_ = AddChildView(std::move(media_button)); - if (sharesheet_button) - sharesheet_button_ = AddChildView(std::move(sharesheet_button)); - if (toolbar_account_icon_container) { toolbar_account_icon_container_ = AddChildView(std::move(toolbar_account_icon_container));
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.h b/chrome/browser/ui/views/toolbar/toolbar_view.h index f4af66f..21510da 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.h +++ b/chrome/browser/ui/views/toolbar/toolbar_view.h
@@ -49,7 +49,6 @@ class HomeButton; class MediaToolbarButtonView; class ReloadButton; -class SharesheetButton; class ToolbarButton; class ToolbarAccountIconContainerView; @@ -273,7 +272,6 @@ media_router::CastToolbarButton* cast_ = nullptr; ToolbarAccountIconContainerView* toolbar_account_icon_container_ = nullptr; AvatarToolbarButton* avatar_ = nullptr; - SharesheetButton* sharesheet_button_ = nullptr; MediaToolbarButtonView* media_button_ = nullptr; BrowserAppMenuButton* app_menu_button_ = nullptr;
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.cc b/chrome/browser/ui/web_applications/app_browser_controller.cc index 4a336a14..21859266 100644 --- a/chrome/browser/ui/web_applications/app_browser_controller.cc +++ b/chrome/browser/ui/web_applications/app_browser_controller.cc
@@ -100,6 +100,8 @@ gfx::Size(652, 484)); constexpr gfx::Size TERMINAL_SETTINGS_DEFAULT_SIZE(768, 512); constexpr gfx::Size HELP_DEFAULT_SIZE(960, 600); +// The height of camera app window includes the top bar height which is 32. +constexpr gfx::Size CAMERA_WINDOW_DEFAULT_SIZE(864, 486 + 32); } // namespace // static @@ -361,6 +363,11 @@ display::Screen::GetScreen()->GetDisplayForNewWindows().work_area(); bounds.ClampToCenteredSize(HELP_DEFAULT_SIZE); return bounds; + } else if (system_app_type_ == SystemAppType::CAMERA) { + gfx::Rect bounds = + display::Screen::GetScreen()->GetDisplayForNewWindows().work_area(); + bounds.ClampToCenteredSize(CAMERA_WINDOW_DEFAULT_SIZE); + return bounds; } return gfx::Rect(); }
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc index a56d684..99d470a 100644 --- a/chrome/browser/ui/web_applications/web_app_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -115,6 +115,39 @@ chrome::SetAutoAcceptPWAInstallConfirmationForTesting(false); return app_id; } + + bool HasMinimalUiButtons(DisplayMode display_mode, + base::Optional<DisplayMode> display_override_mode, + bool open_as_window) { + static int index = 0; + + base::HistogramTester tester; + const std::string base_url = "https://example.com/path"; + auto web_app_info = std::make_unique<WebApplicationInfo>(); + web_app_info->app_url = GURL(base_url + base::NumberToString(index++)); + web_app_info->scope = web_app_info->app_url; + web_app_info->display_mode = display_mode; + web_app_info->open_as_window = open_as_window; + if (display_override_mode) + web_app_info->display_override.push_back(*display_override_mode); + + AppId app_id = InstallWebApp(std::move(web_app_info)); + Browser* app_browser = LaunchWebAppBrowser(app_id); + DCHECK(app_browser->app_controller()); + tester.ExpectUniqueSample( + kLaunchWebAppDisplayModeHistogram, + display_override_mode ? *display_override_mode : display_mode, 1); + + bool matches; + EXPECT_TRUE(ExecuteScriptAndExtractBool( + app_browser->tab_strip_model()->GetActiveWebContents(), + "window.domAutomationController.send(window.matchMedia('(display-mode: " + "minimal-ui)').matches)", + &matches)); + EXPECT_EQ(app_browser->app_controller()->HasMinimalUiButtons(), matches); + + return matches; + } }; // A dedicated test fixture for DisplayOverride, which is supported @@ -261,51 +294,28 @@ before_launch); } -IN_PROC_BROWSER_TEST_P(WebAppBrowserTest, HasMinimalUiButtons) { - int index = 0; - auto has_buttons = [this, &index](DisplayMode display_mode, - bool open_as_window) -> bool { - base::HistogramTester tester; - const std::string base_url = "https://example.com/path"; - auto web_app_info = std::make_unique<WebApplicationInfo>(); - web_app_info->app_url = GURL(base_url + base::NumberToString(index++)); - web_app_info->scope = web_app_info->app_url; - web_app_info->display_mode = display_mode; - web_app_info->open_as_window = open_as_window; - AppId app_id = InstallWebApp(std::move(web_app_info)); - Browser* app_browser = LaunchWebAppBrowser(app_id); - DCHECK(app_browser->app_controller()); - tester.ExpectUniqueSample(kLaunchWebAppDisplayModeHistogram, display_mode, - 1); +IN_PROC_BROWSER_TEST_P(WebAppBrowserTest, WithMinimalUiButtons) { + EXPECT_TRUE(HasMinimalUiButtons(DisplayMode::kBrowser, base::nullopt, + /*open_as_window=*/true)); + EXPECT_TRUE(HasMinimalUiButtons(DisplayMode::kMinimalUi, base::nullopt, + /*open_as_window=*/true)); - bool matches; - EXPECT_TRUE(ExecuteScriptAndExtractBool( - app_browser->tab_strip_model()->GetActiveWebContents(), - "window.domAutomationController.send(window.matchMedia('(display-mode: " - "minimal-ui)').matches)", - &matches)); - EXPECT_EQ(app_browser->app_controller()->HasMinimalUiButtons(), matches); + EXPECT_TRUE(HasMinimalUiButtons(DisplayMode::kBrowser, base::nullopt, + /*open_as_window=*/false)); + EXPECT_TRUE(HasMinimalUiButtons(DisplayMode::kMinimalUi, base::nullopt, + /*open_as_window=*/false)); +} - return matches; - }; +IN_PROC_BROWSER_TEST_P(WebAppBrowserTest, WithoutMinimalUiButtons) { + EXPECT_FALSE(HasMinimalUiButtons(DisplayMode::kStandalone, base::nullopt, + /*open_as_window=*/true)); + EXPECT_FALSE(HasMinimalUiButtons(DisplayMode::kFullscreen, base::nullopt, + /*open_as_window=*/true)); - EXPECT_TRUE(has_buttons(DisplayMode::kBrowser, - /*open_as_window=*/true)); - EXPECT_TRUE(has_buttons(DisplayMode::kMinimalUi, - /*open_as_window=*/true)); - EXPECT_FALSE(has_buttons(DisplayMode::kStandalone, - /*open_as_window=*/true)); - EXPECT_FALSE(has_buttons(DisplayMode::kFullscreen, - /*open_as_window=*/true)); - - EXPECT_TRUE(has_buttons(DisplayMode::kBrowser, - /*open_as_window=*/false)); - EXPECT_TRUE(has_buttons(DisplayMode::kMinimalUi, - /*open_as_window=*/false)); - EXPECT_FALSE(has_buttons(DisplayMode::kStandalone, - /*open_as_window=*/false)); - EXPECT_FALSE(has_buttons(DisplayMode::kFullscreen, - /*open_as_window=*/false)); + EXPECT_FALSE(HasMinimalUiButtons(DisplayMode::kStandalone, base::nullopt, + /*open_as_window=*/false)); + EXPECT_FALSE(HasMinimalUiButtons(DisplayMode::kFullscreen, base::nullopt, + /*open_as_window=*/false)); } IN_PROC_BROWSER_TEST_P(WebAppBrowserTest_DisplayOverride, DisplayOverride) { @@ -325,61 +335,38 @@ EXPECT_EQ(DisplayMode::kStandalone, app_display_mode_override[1]); } -IN_PROC_BROWSER_TEST_P(WebAppBrowserTest_DisplayOverride, HasMinimalUiButtons) { - int index = 0; - auto has_buttons = [this, &index](DisplayMode display_override_mode, - bool open_as_window) -> bool { - base::HistogramTester tester; - const std::string base_url = "https://example.com/path"; - auto web_app_info = std::make_unique<WebApplicationInfo>(); - web_app_info->app_url = GURL(base_url + base::NumberToString(index++)); - web_app_info->scope = web_app_info->app_url; +IN_PROC_BROWSER_TEST_P(WebAppBrowserTest_DisplayOverride, + WithMinimalUiButtons) { + EXPECT_TRUE(HasMinimalUiButtons(DisplayMode::kStandalone, + DisplayMode::kBrowser, + /*open_as_window=*/true)); + EXPECT_TRUE(HasMinimalUiButtons(DisplayMode::kStandalone, + DisplayMode::kMinimalUi, + /*open_as_window=*/true)); - DisplayMode display_mode = DisplayMode::kStandalone; + EXPECT_TRUE(HasMinimalUiButtons(DisplayMode::kStandalone, + DisplayMode::kBrowser, + /*open_as_window=*/false)); + EXPECT_TRUE(HasMinimalUiButtons(DisplayMode::kStandalone, + DisplayMode::kMinimalUi, + /*open_as_window=*/false)); +} - if (display_override_mode == DisplayMode::kFullscreen || - display_override_mode == DisplayMode::kStandalone) { - display_mode = DisplayMode::kMinimalUi; - } +IN_PROC_BROWSER_TEST_P(WebAppBrowserTest_DisplayOverride, + WithoutMinimalUiButtons) { + EXPECT_FALSE(HasMinimalUiButtons(DisplayMode::kMinimalUi, + DisplayMode::kStandalone, + /*open_as_window=*/true)); + EXPECT_FALSE(HasMinimalUiButtons(DisplayMode::kMinimalUi, + DisplayMode::kFullscreen, + /*open_as_window=*/true)); - web_app_info->display_mode = display_mode; - web_app_info->open_as_window = open_as_window; - web_app_info->display_override.push_back(display_override_mode); - - AppId app_id = InstallWebApp(std::move(web_app_info)); - Browser* app_browser = LaunchWebAppBrowser(app_id); - DCHECK(app_browser->app_controller()); - tester.ExpectUniqueSample(kLaunchWebAppDisplayModeHistogram, - display_override_mode, 1); - - bool matches; - EXPECT_TRUE(ExecuteScriptAndExtractBool( - app_browser->tab_strip_model()->GetActiveWebContents(), - "window.domAutomationController.send(window.matchMedia('(display-mode: " - "minimal-ui)').matches)", - &matches)); - EXPECT_EQ(app_browser->app_controller()->HasMinimalUiButtons(), matches); - - return matches; - }; - - EXPECT_TRUE(has_buttons(DisplayMode::kBrowser, - /*open_as_window=*/true)); - EXPECT_TRUE(has_buttons(DisplayMode::kMinimalUi, - /*open_as_window=*/true)); - EXPECT_FALSE(has_buttons(DisplayMode::kStandalone, - /*open_as_window=*/true)); - EXPECT_FALSE(has_buttons(DisplayMode::kFullscreen, - /*open_as_window=*/true)); - - EXPECT_TRUE(has_buttons(DisplayMode::kBrowser, - /*open_as_window=*/false)); - EXPECT_TRUE(has_buttons(DisplayMode::kMinimalUi, - /*open_as_window=*/false)); - EXPECT_FALSE(has_buttons(DisplayMode::kStandalone, - /*open_as_window=*/false)); - EXPECT_FALSE(has_buttons(DisplayMode::kFullscreen, - /*open_as_window=*/false)); + EXPECT_FALSE(HasMinimalUiButtons(DisplayMode::kMinimalUi, + DisplayMode::kStandalone, + /*open_as_window=*/false)); + EXPECT_FALSE(HasMinimalUiButtons(DisplayMode::kMinimalUi, + DisplayMode::kFullscreen, + /*open_as_window=*/false)); } // Tests that desktop PWAs open links in the browser.
diff --git a/chrome/browser/ui/webui/chromeos/login/network_state_informer.cc b/chrome/browser/ui/webui/chromeos/login/network_state_informer.cc index 2271d77..0a95a8c 100644 --- a/chrome/browser/ui/webui/chromeos/login/network_state_informer.cc +++ b/chrome/browser/ui/webui/chromeos/login/network_state_informer.cc
@@ -48,16 +48,14 @@ // NetworkPortalDetector's state of current network is unknown. if (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE || (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN && - !NetworkHandler::Get() - ->ui_proxy_config_service() + !NetworkHandler::GetUiProxyConfigService() ->HasDefaultNetworkProxyConfigured() && network->connection_state() == shill::kStateOnline)) { return NetworkStateInformer::ONLINE; } if (status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED && - NetworkHandler::Get() - ->ui_proxy_config_service() + NetworkHandler::GetUiProxyConfigService() ->HasDefaultNetworkProxyConfigured()) { return NetworkStateInformer::PROXY_AUTH_REQUIRED; }
diff --git a/chrome/browser/ui/webui/management_ui_handler.cc b/chrome/browser/ui/webui/management_ui_handler.cc index d3fc82f..518f0baa 100644 --- a/chrome/browser/ui/webui/management_ui_handler.cc +++ b/chrome/browser/ui/webui/management_ui_handler.cc
@@ -640,13 +640,14 @@ base::Value proxy_settings(base::Value::Type::DICTIONARY); // |ui_proxy_config_service| may be missing in tests. If the device is offline // (no network connected) the |DefaultNetwork| is null. - if (network_handler->has_ui_proxy_config_service() && + if (chromeos::NetworkHandler::HasUiProxyConfigService() && network_handler->network_state_handler()->DefaultNetwork()) { // Check if proxy is enforced by user policy, a forced install extension or // ONC policies. This will only read managed settings. - network_handler->ui_proxy_config_service()->MergeEnforcedProxyConfig( - network_handler->network_state_handler()->DefaultNetwork()->guid(), - &proxy_settings); + chromeos::NetworkHandler::GetUiProxyConfigService() + ->MergeEnforcedProxyConfig( + network_handler->network_state_handler()->DefaultNetwork()->guid(), + &proxy_settings); } if (!proxy_settings.DictEmpty()) { // Proxies can be specified by web server url, via a PAC script or via the
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_install_finalizer_unittest.cc b/chrome/browser/web_applications/extensions/bookmark_app_install_finalizer_unittest.cc index 8e866392..4504ccd5 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_install_finalizer_unittest.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_install_finalizer_unittest.cc
@@ -78,7 +78,8 @@ std::unique_ptr<base::DictionaryValue> original_manifest, scoped_refptr<const Extension> extension, SkBitmap install_icon, - declarative_net_request::RulesetChecksums ruleset_checksums) override { + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs) + override { run_loop_.Quit(); }
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 5edf455..35f58c2 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1598270291-b801bf78b6b55c941ccf8675be0d44cb7bb468ce.profdata +chrome-mac-master-1598313565-08e05b737624bbbe76926e73b436a35f99d64175.profdata
diff --git a/chrome/common/extensions/api/autotest_private.idl b/chrome/common/extensions/api/autotest_private.idl index 8c0dc32..27084a6 100644 --- a/chrome/common/extensions/api/autotest_private.idl +++ b/chrome/common/extensions/api/autotest_private.idl
@@ -42,6 +42,17 @@ Borealis }; + // A mapping of apps::mojom::InstallSource + enum AppInstallSource { + Unknown, + System, + Policy, + Oem, + Default, + Sync, + User + }; + // A mapping of apps::mojom::Readiness enum AppReadiness { Ready, @@ -308,6 +319,7 @@ DOMString name; DOMString shortName; AppType? type; + AppInstallSource? installSource; AppReadiness? readiness; DOMString[] additionalSearchTerms; boolean? showInLauncher;
diff --git a/chrome/common/extensions/api/file_manager_private.idl b/chrome/common/extensions/api/file_manager_private.idl index 5bcd169..ffb0b4ff 100644 --- a/chrome/common/extensions/api/file_manager_private.idl +++ b/chrome/common/extensions/api/file_manager_private.idl
@@ -249,14 +249,6 @@ unshare }; -// Metadata extraction types for getContentMetadata(). -enum ContentMetadataType { - // Extract metadata tags and images. - metadataTagsImages, - // Extract metadata tags only. - metadataTags -}; - // A file task represents an action that the file manager can perform over the // currently selected files. See // chrome/browser/chromeos/extensions/file_manager/file_tasks.h for details @@ -959,12 +951,13 @@ // Gets metadata from an Audio or Video file. // |fileEntry| The file entry to be checked. // |mimeType| Content sniffed mimeType of the file. - // |type| Content metadata type to extact. + // |includeImages| False returns metadata tags only. True returns + // metadata tags and metadata (thumbnail) images. // |callback| [nocompile] static void getContentMetadata([instanceof=FileEntry] object fileEntry, DOMString mimeType, - ContentMetadataType type, + boolean includeImages, GetContentMetadataCallback callback); // Gets localized strings and initialization data.
diff --git a/chrome/common/extensions/api/file_manager_private_internal.idl b/chrome/common/extensions/api/file_manager_private_internal.idl index 09589188a..0197800 100644 --- a/chrome/common/extensions/api/file_manager_private_internal.idl +++ b/chrome/common/extensions/api/file_manager_private_internal.idl
@@ -70,7 +70,7 @@ GetContentMimeTypeCallback callback); static void getContentMetadata(DOMString blobUUID, DOMString mimeType, - fileManagerPrivate.ContentMetadataType type, + boolean includeImages, GetContentMetadataCallback callback); static void pinDriveFile(DOMString url, boolean pin,
diff --git a/chrome/common/extensions/docs/templates/articles/devtools.html b/chrome/common/extensions/docs/templates/articles/devtools.html index 02236e5..9b970acd 100644 --- a/chrome/common/extensions/docs/templates/articles/devtools.html +++ b/chrome/common/extensions/docs/templates/articles/devtools.html
@@ -212,7 +212,7 @@ devToolsConnection.onDisconnect.addListener(function() { devToolsConnection.onMessage.removeListener(devToolsListener); }); -} +}); </pre> <h3 id="evaluating-js">Evaluating JavaScript in the Inspected Window</h3>
diff --git a/chrome/installer/mini_installer/mini_installer.cc b/chrome/installer/mini_installer/mini_installer.cc index eed99a9..1c94fd3 100644 --- a/chrome/installer/mini_installer/mini_installer.cc +++ b/chrome/installer/mini_installer/mini_installer.cc
@@ -103,14 +103,12 @@ } } -// Writes the value |installer_error| into InstallerError for reporting by -// Omaha. -void WriteInstallerError(const Configuration& configuration, - DWORD installer_error) { - // Write the value in Chrome's ClientState key. +// Writes the value |extra_code_1| into ExtraCode1 for reporting by Omaha. +void WriteExtraCode1(const Configuration& configuration, DWORD extra_code_1) { + // Write the value in Chrome ClientState key. RegKey key; if (OpenInstallStateKey(configuration, &key)) - key.WriteDWValue(kInstallerErrorRegistryValue, installer_error); + key.WriteDWValue(kInstallerExtraCode1RegistryValue, extra_code_1); } // This function sets the flag in registry to indicate that Google Update @@ -918,21 +916,19 @@ #if BUILDFLAG(GOOGLE_CHROME_BRANDING) if (exit_code.IsSuccess()) { - // Send up a signal in InstallerError upon successful install where the - // fallback work dir location was used. This means that GetWorkDir failed to - // create a temporary directory next to the executable (in a directory owned - // by Omaha) then succeeded to create one in %TMP% and ultimately resulted - // in a successful install/update. If we ~never see this signal, then we - // know that it's safe to remove the fallback code and associated - // cleanup. See https://crbug.com/516207 for more info. Pick two arbitrary - // success HRESULT values that should stand out obviously in queries. - constexpr HRESULT kSucceededWithFallback = - MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_ITF, 0x4001); - constexpr HRESULT kSucceededWithoutFallback = - MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_ITF, 0x4002); - WriteInstallerError(configuration, work_dir_in_fallback - ? kSucceededWithFallback - : kSucceededWithoutFallback); + // Send up a signal in ExtraCode1 upon successful install where the fallback + // work dir location was used. This means that GetWorkDir failed to create a + // temporary directory next to the executable (in a directory owned by + // Omaha) then succeeded to create one in %TMP% and ultimately resulted in + // a successful install/update. If we ~never see this signal, then we know + // that it's safe to remove the fallback code and associated cleanup. See + // https://crbug.com/516207 for more info. + // Pick two arbitrary values that should stand out obviously in queries. + constexpr DWORD kSucceededWithFallback = 0x1U << 16; + constexpr DWORD kSucceededWithoutFallback = 0x2U << 16; + WriteExtraCode1(configuration, work_dir_in_fallback + ? kSucceededWithFallback + : kSucceededWithoutFallback); } else { WriteInstallResults(configuration, exit_code); }
diff --git a/chrome/renderer/resources/extensions/file_manager_private_custom_bindings.js b/chrome/renderer/resources/extensions/file_manager_private_custom_bindings.js index b27f6ff5..29a37a8c 100644 --- a/chrome/renderer/resources/extensions/file_manager_private_custom_bindings.js +++ b/chrome/renderer/resources/extensions/file_manager_private_custom_bindings.js
@@ -148,7 +148,7 @@ }); apiFunctions.setHandleRequest('getContentMetadata', - function(fileEntry, mimeType, type, callback) { + function(fileEntry, mimeType, includeImages, callback) { fileEntry.file(blob => { var blobUUID = blobNatives.GetBlobUuid(blob); @@ -162,7 +162,7 @@ }.bind(this, blob); // Bind a blob reference: crbug.com/415792#c12 fileManagerPrivateInternal.getContentMetadata( - blobUUID, mimeType, type, onGetContentMetadata); + blobUUID, mimeType, !!includeImages, onGetContentMetadata); }, (error) => { var errorUUID = ''; @@ -172,7 +172,7 @@ }.bind(this); fileManagerPrivateInternal.getContentMetadata( - errorUUID, mimeType, type, onGetContentMetadata); + errorUUID, mimeType, false, onGetContentMetadata); }); });
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 1a508b2..07d4b69c 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -913,6 +913,7 @@ "../browser/browsing_data/navigation_entry_remover_browsertest.cc", "../browser/chrome_back_forward_cache_browsertest.cc", "../browser/chrome_content_browser_client_browsertest.cc", + "../browser/chrome_cross_origin_opener_policy_browsertest.cc", "../browser/chrome_do_not_track_browsertest.cc", "../browser/chrome_find_request_manager_browsertest.cc", "../browser/chrome_main_browsertest.cc",
diff --git a/chrome/test/data/extensions/api_test/autotest_private/test.js b/chrome/test/data/extensions/api_test/autotest_private/test.js index ab8bf13..21982c7 100644 --- a/chrome/test/data/extensions/api_test/autotest_private/test.js +++ b/chrome/test/data/extensions/api_test/autotest_private/test.js
@@ -471,6 +471,7 @@ chrome.test.assertEq(chromium.showInLauncher, true); chrome.test.assertEq(chromium.showInSearch, true); chrome.test.assertEq(chromium.type, 'Extension'); + chrome.test.assertEq(chromium.installSource, 'System'); })); }, // This test verifies that only Chromium is available by default.
diff --git a/chrome/test/data/extensions/api_test/file_browser/media_metadata/test.js b/chrome/test/data/extensions/api_test/file_browser/media_metadata/test.js index aeb29a82..ffd4bd02 100644 --- a/chrome/test/data/extensions/api_test/file_browser/media_metadata/test.js +++ b/chrome/test/data/extensions/api_test/file_browser/media_metadata/test.js
@@ -121,7 +121,7 @@ const entry = emptyEntry; chrome.fileManagerPrivate.getContentMetadata( - entry, 'audio/mpeg', 'metadataTags', (metadata) => { + entry, 'audio/mpeg', false, (metadata) => { chrome.test.assertEq(undefined, metadata); chrome.test.assertNoLastError(); chrome.test.succeed(); @@ -129,13 +129,13 @@ } /* - * getContentMetadata 'metadataTags' returns tags only. + * getContentMetadata can return metadata tags only. */ function testGetContentMetadataAudioTags() { const entry = audioEntry; chrome.fileManagerPrivate.getContentMetadata( - entry, 'audio/mpeg', 'metadataTags', (metadata) => { + entry, 'audio/mpeg', false, (metadata) => { chrome.test.assertEq('audio/mpeg', metadata.mimeType); chrome.test.assertNoLastError(); @@ -147,13 +147,13 @@ } /* - * getContentMetadata 'metadataTagsImages' returns tags and images. + * getContentMetadata can return metadata tags and metadata images. */ function testGetContentMetadataAudioTagsImages() { const entry = audioEntry; chrome.fileManagerPrivate.getContentMetadata( - entry, 'audio/mpeg', 'metadataTagsImages', (metadata) => { + entry, 'audio/mpeg', true, (metadata) => { chrome.test.assertEq('audio/mpeg', metadata.mimeType); chrome.test.assertNoLastError(); @@ -217,7 +217,7 @@ const entry = videoEntry; chrome.fileManagerPrivate.getContentMetadata( - entry, 'video/mp4', 'metadataTagsImages', (metadata) => { + entry, 'video/mp4', true, (metadata) => { chrome.test.assertEq('video/mp4', metadata.mimeType); chrome.test.assertNoLastError(); @@ -235,7 +235,7 @@ const entry = audioEntry; chrome.fileManagerPrivate.getContentMetadata( - entry, 'audio/input-type', 'metadataTags', (metadata) => { + entry, 'audio/input-type', false, (metadata) => { chrome.test.assertEq('audio/input-type', metadata.mimeType); chrome.test.assertNoLastError(); chrome.test.succeed(); @@ -250,7 +250,7 @@ const entry = videoEntry; chrome.fileManagerPrivate.getContentMetadata( - entry, 'audio/input-type', 'metadataTagsImages', (metadata) => { + entry, 'audio/input-type', true, (metadata) => { chrome.test.assertEq('video/input-type', metadata.mimeType); chrome.test.assertNoLastError(); @@ -269,7 +269,7 @@ const entry = imageEntry; chrome.fileManagerPrivate.getContentMetadata( - entry, 'image/jpeg', 'metadataTags', (metadata) => { + entry, 'image/jpeg', false, (metadata) => { chrome.test.assertEq(undefined, metadata); if (!chrome.runtime.lastError) {
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index 7d0e4c0783b..238e946 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -300,6 +300,8 @@ "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cups_printer_test_utils.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cups_printer_landing_page_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/cups_printer_entry_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_about_page_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.m.js", ] } defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index 45e0470..75319aa0f 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -75,6 +75,8 @@ "cups_printer_test_utils.js", "cups_printer_landing_page_tests.js", "cups_printer_entry_tests.js", + "os_about_page_tests.js", + "test_about_page_browser_proxy_chromeos.js", ] namespace_rewrites = os_settings_namespace_rewrites + os_test_namespace_rewrites
diff --git a/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js b/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js index e4300eaf..10e6f55f 100644 --- a/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js
@@ -2,8 +2,41 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// clang-format off +// #import {TestAboutPageBrowserProxyChromeOS} from './test_about_page_browser_proxy_chromeos.m.js'; +// #import {BrowserChannel,UpdateStatus,AboutPageBrowserProxyImpl,LifetimeBrowserProxyImpl,Router, routes} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; +// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {TestLifetimeBrowserProxy} from './test_os_lifetime_browser_proxy.m.js'; +// #import {eventToPromise,flushTasks} from 'chrome://test/test_util.m.js'; +// clang-format on + cr.define('settings_about_page', function() { - function registerAboutPageTests() { + suite('AboutPageTest', function() { + let page = null; + + /** @type {?settings.TestAboutPageBrowserProxyChromeOS} */ + let aboutBrowserProxy = null; + + /** @type {?settings.TestLifetimeBrowserProxy} */ + let lifetimeBrowserProxy = null; + + const SPINNER_ICON = 'chrome://resources/images/throbber_small.svg'; + + setup(function() { + lifetimeBrowserProxy = new settings.TestLifetimeBrowserProxy(); + settings.LifetimeBrowserProxyImpl.instance_ = lifetimeBrowserProxy; + + aboutBrowserProxy = new TestAboutPageBrowserProxyChromeOS(); + settings.AboutPageBrowserProxyImpl.instance_ = aboutBrowserProxy; + return initNewPage(); + }); + + teardown(function() { + page.remove(); + page = null; + }); + /** * @param {!UpdateStatus} status * @param {{ @@ -24,698 +57,659 @@ }); } - suite('AboutPageTest', function() { - let page = null; + /** @return {!Promise} */ + function initNewPage() { + aboutBrowserProxy.reset(); + lifetimeBrowserProxy.reset(); + PolymerTest.clearBody(); + page = document.createElement('os-settings-about-page'); + settings.Router.getInstance().navigateTo(settings.routes.ABOUT); + document.body.appendChild(page); + return Promise.all([ + aboutBrowserProxy.whenCalled('getChannelInfo'), + aboutBrowserProxy.whenCalled('refreshUpdateStatus'), + aboutBrowserProxy.whenCalled('refreshTPMFirmwareUpdateStatus'), + aboutBrowserProxy.whenCalled('getEnabledReleaseNotes'), + aboutBrowserProxy.whenCalled('checkInternetConnection'), + ]); + } - /** @type {?settings.TestAboutPageBrowserProxyChromeOS} */ - let aboutBrowserProxy = null; + /** + * Test that the status icon and status message update according to + * incoming 'update-status-changed' events. + */ + test('IconAndMessageUpdates', function() { + const icon = page.$$('iron-icon'); + assertTrue(!!icon); + const statusMessageEl = page.$$('#updateStatusMessage div'); + let previousMessageText = statusMessageEl.textContent; - /** @type {?settings.TestLifetimeBrowserProxy} */ - let lifetimeBrowserProxy = null; + fireStatusChanged(UpdateStatus.CHECKING); + assertEquals(SPINNER_ICON, icon.src); + assertEquals(null, icon.getAttribute('icon')); + assertNotEquals(previousMessageText, statusMessageEl.textContent); + previousMessageText = statusMessageEl.textContent; - const SPINNER_ICON = 'chrome://resources/images/throbber_small.svg'; + fireStatusChanged(UpdateStatus.UPDATING, {progress: 0}); + assertEquals(SPINNER_ICON, icon.src); + assertEquals(null, icon.getAttribute('icon')); + assertFalse(statusMessageEl.textContent.includes('%')); + assertNotEquals(previousMessageText, statusMessageEl.textContent); + previousMessageText = statusMessageEl.textContent; - setup(function() { - lifetimeBrowserProxy = new settings.TestLifetimeBrowserProxy(); - settings.LifetimeBrowserProxyImpl.instance_ = lifetimeBrowserProxy; + fireStatusChanged(UpdateStatus.UPDATING, {progress: 1}); + assertNotEquals(previousMessageText, statusMessageEl.textContent); + assertTrue(statusMessageEl.textContent.includes('%')); + previousMessageText = statusMessageEl.textContent; - aboutBrowserProxy = new TestAboutPageBrowserProxyChromeOS(); - settings.AboutPageBrowserProxyImpl.instance_ = aboutBrowserProxy; - return initNewPage(); - }); + fireStatusChanged(UpdateStatus.NEARLY_UPDATED); + assertEquals(null, icon.src); + assertEquals('settings:check-circle', icon.icon); + assertNotEquals(previousMessageText, statusMessageEl.textContent); + previousMessageText = statusMessageEl.textContent; - teardown(function() { - page.remove(); - page = null; - }); + fireStatusChanged(UpdateStatus.DISABLED_BY_ADMIN); + assertEquals(null, icon.src); + assertEquals('cr20:domain', icon.icon); + assertEquals(0, statusMessageEl.textContent.trim().length); - /** @return {!Promise} */ - function initNewPage() { - aboutBrowserProxy.reset(); - lifetimeBrowserProxy.reset(); - PolymerTest.clearBody(); - page = document.createElement('os-settings-about-page'); - settings.Router.getInstance().navigateTo(settings.routes.ABOUT); - document.body.appendChild(page); - return Promise.all([ - aboutBrowserProxy.whenCalled('getChannelInfo'), - aboutBrowserProxy.whenCalled('refreshUpdateStatus'), - aboutBrowserProxy.whenCalled('refreshTPMFirmwareUpdateStatus'), - aboutBrowserProxy.whenCalled('getEnabledReleaseNotes'), - aboutBrowserProxy.whenCalled('checkInternetConnection'), - ]); + fireStatusChanged(UpdateStatus.FAILED); + assertEquals(null, icon.src); + assertEquals('cr:error', icon.icon); + assertEquals(0, statusMessageEl.textContent.trim().length); + + fireStatusChanged(UpdateStatus.DISABLED); + assertEquals(null, icon.src); + assertEquals(null, icon.getAttribute('icon')); + assertEquals(0, statusMessageEl.textContent.trim().length); + }); + + test('ErrorMessageWithHtml', function() { + const htmlError = 'hello<br>there<br>was<pre>an</pre>error'; + fireStatusChanged(UpdateStatus.FAILED, {message: htmlError}); + const statusMessageEl = page.$$('#updateStatusMessage div'); + assertEquals(htmlError, statusMessageEl.innerHTML); + }); + + test('FailedLearnMoreLink', function() { + // Check that link is shown when update failed. + fireStatusChanged(UpdateStatus.FAILED, {message: 'foo'}); + assertTrue(!!page.$$('#updateStatusMessage a:not([hidden])')); + + // Check that link is hidden when update hasn't failed. + fireStatusChanged(UpdateStatus.UPDATED, {message: ''}); + assertTrue(!!page.$$('#updateStatusMessage a[hidden]')); + }); + + test('Relaunch', function() { + const {relaunch} = page.$; + assertTrue(!!relaunch); + assertTrue(relaunch.hidden); + + fireStatusChanged(UpdateStatus.NEARLY_UPDATED); + assertFalse(relaunch.hidden); + relaunch.click(); + return lifetimeBrowserProxy.whenCalled('relaunch'); + }); + + test('NoInternet', function() { + assertTrue(page.$.updateStatusMessage.hidden); + aboutBrowserProxy.sendStatusNoInternet(); + Polymer.dom.flush(); + assertFalse(page.$.updateStatusMessage.hidden); + assertNotEquals( + page.$.updateStatusMessage.innerHTML.includes('no internet')); + }); + + /** + * Test that all buttons update according to incoming + * 'update-status-changed' events for the case where target and current + * channel are the same. + */ + test('ButtonsUpdate_SameChannel', function() { + const {checkForUpdates, relaunch} = page.$; + + assertTrue(!!relaunch); + assertTrue(!!checkForUpdates); + + function assertAllHidden() { + assertTrue(checkForUpdates.hidden); + assertTrue(relaunch.hidden); + // Ensure that when all buttons are hidden, the container is also + // hidden. + assertTrue(page.$.buttonContainer.hidden); } - /** - * Test that the status icon and status message update according to - * incoming 'update-status-changed' events. - */ - test('IconAndMessageUpdates', function() { - const icon = page.$$('iron-icon'); - assertTrue(!!icon); - const statusMessageEl = page.$$('#updateStatusMessage div'); - let previousMessageText = statusMessageEl.textContent; + // Check that |UPDATED| status is ignored if the user has not + // explicitly checked for updates yet. + fireStatusChanged(UpdateStatus.UPDATED); + assertFalse(checkForUpdates.hidden); + assertTrue(relaunch.hidden); - fireStatusChanged(UpdateStatus.CHECKING); - assertEquals(SPINNER_ICON, icon.src); - assertEquals(null, icon.getAttribute('icon')); - assertNotEquals(previousMessageText, statusMessageEl.textContent); - previousMessageText = statusMessageEl.textContent; + // Check that the "Check for updates" button gets hidden for certain + // UpdateStatus values, even if the CHECKING state was never + // encountered (for example triggering update from crosh command + // line). + fireStatusChanged(UpdateStatus.UPDATING); + assertAllHidden(); + fireStatusChanged(UpdateStatus.NEARLY_UPDATED); + assertTrue(checkForUpdates.hidden); + assertFalse(relaunch.hidden); - fireStatusChanged(UpdateStatus.UPDATING, {progress: 0}); - assertEquals(SPINNER_ICON, icon.src); - assertEquals(null, icon.getAttribute('icon')); - assertFalse(statusMessageEl.textContent.includes('%')); - assertNotEquals(previousMessageText, statusMessageEl.textContent); - previousMessageText = statusMessageEl.textContent; + fireStatusChanged(UpdateStatus.CHECKING); + assertAllHidden(); - fireStatusChanged(UpdateStatus.UPDATING, {progress: 1}); - assertNotEquals(previousMessageText, statusMessageEl.textContent); - assertTrue(statusMessageEl.textContent.includes('%')); - previousMessageText = statusMessageEl.textContent; + fireStatusChanged(UpdateStatus.UPDATING); + assertAllHidden(); - fireStatusChanged(UpdateStatus.NEARLY_UPDATED); - assertEquals(null, icon.src); - assertEquals('settings:check-circle', icon.icon); - assertNotEquals(previousMessageText, statusMessageEl.textContent); - previousMessageText = statusMessageEl.textContent; + fireStatusChanged(UpdateStatus.NEARLY_UPDATED); + assertTrue(checkForUpdates.hidden); + assertFalse(relaunch.hidden); - fireStatusChanged(UpdateStatus.DISABLED_BY_ADMIN); - assertEquals(null, icon.src); - assertEquals('cr20:domain', icon.icon); - assertEquals(0, statusMessageEl.textContent.trim().length); + fireStatusChanged(UpdateStatus.UPDATED); + assertAllHidden(); - fireStatusChanged(UpdateStatus.FAILED); - assertEquals(null, icon.src); - assertEquals('cr:error', icon.icon); - assertEquals(0, statusMessageEl.textContent.trim().length); + fireStatusChanged(UpdateStatus.FAILED); + assertFalse(checkForUpdates.hidden); + assertTrue(relaunch.hidden); - fireStatusChanged(UpdateStatus.DISABLED); - assertEquals(null, icon.src); - assertEquals(null, icon.getAttribute('icon')); - assertEquals(0, statusMessageEl.textContent.trim().length); - }); + fireStatusChanged(UpdateStatus.DISABLED); + assertAllHidden(); - test('ErrorMessageWithHtml', function() { - const htmlError = 'hello<br>there<br>was<pre>an</pre>error'; - fireStatusChanged(UpdateStatus.FAILED, {message: htmlError}); - const statusMessageEl = page.$$('#updateStatusMessage div'); - assertEquals(htmlError, statusMessageEl.innerHTML); - }); - - test('FailedLearnMoreLink', function() { - // Check that link is shown when update failed. - fireStatusChanged(UpdateStatus.FAILED, {message: 'foo'}); - assertTrue(!!page.$$('#updateStatusMessage a:not([hidden])')); - - // Check that link is hidden when update hasn't failed. - fireStatusChanged(UpdateStatus.UPDATED, {message: ''}); - assertTrue(!!page.$$('#updateStatusMessage a[hidden]')); - }); - - test('Relaunch', function() { - const {relaunch} = page.$; - assertTrue(!!relaunch); - assertTrue(relaunch.hidden); - - fireStatusChanged(UpdateStatus.NEARLY_UPDATED); - assertFalse(relaunch.hidden); - relaunch.click(); - return lifetimeBrowserProxy.whenCalled('relaunch'); - }); - - test('NoInternet', function() { - assertTrue(page.$.updateStatusMessage.hidden); - aboutBrowserProxy.sendStatusNoInternet(); - Polymer.dom.flush(); - assertFalse(page.$.updateStatusMessage.hidden); - assertNotEquals( - page.$.updateStatusMessage.innerHTML.includes('no internet')); - }); - - /** - * Test that all buttons update according to incoming - * 'update-status-changed' events for the case where target and current - * channel are the same. - */ - test('ButtonsUpdate_SameChannel', function() { - const {checkForUpdates, relaunch} = page.$; - - assertTrue(!!relaunch); - assertTrue(!!checkForUpdates); - - function assertAllHidden() { - assertTrue(checkForUpdates.hidden); - assertTrue(relaunch.hidden); - // Ensure that when all buttons are hidden, the container is also - // hidden. - assertTrue(page.$.buttonContainer.hidden); - } - - // Check that |UPDATED| status is ignored if the user has not - // explicitly checked for updates yet. - fireStatusChanged(UpdateStatus.UPDATED); - assertFalse(checkForUpdates.hidden); - assertTrue(relaunch.hidden); - - // Check that the "Check for updates" button gets hidden for certain - // UpdateStatus values, even if the CHECKING state was never - // encountered (for example triggering update from crosh command - // line). - fireStatusChanged(UpdateStatus.UPDATING); - assertAllHidden(); - fireStatusChanged(UpdateStatus.NEARLY_UPDATED); - assertTrue(checkForUpdates.hidden); - assertFalse(relaunch.hidden); - - fireStatusChanged(UpdateStatus.CHECKING); - assertAllHidden(); - - fireStatusChanged(UpdateStatus.UPDATING); - assertAllHidden(); - - fireStatusChanged(UpdateStatus.NEARLY_UPDATED); - assertTrue(checkForUpdates.hidden); - assertFalse(relaunch.hidden); - - fireStatusChanged(UpdateStatus.UPDATED); - assertAllHidden(); - - fireStatusChanged(UpdateStatus.FAILED); - assertFalse(checkForUpdates.hidden); - assertTrue(relaunch.hidden); - - fireStatusChanged(UpdateStatus.DISABLED); - assertAllHidden(); - - fireStatusChanged(UpdateStatus.DISABLED_BY_ADMIN); - assertAllHidden(); - }); - - /** - * Test that buttons update according to incoming - * 'update-status-changed' events for the case where the target channel - * is more stable than current channel and update will powerwash. - */ - test('ButtonsUpdate_BetaToStable', async () => { - aboutBrowserProxy.setChannels( - BrowserChannel.BETA, BrowserChannel.STABLE); - await initNewPage(); - - fireStatusChanged(UpdateStatus.NEARLY_UPDATED, {powerwash: true}); - - assertTrue(!!page.$.relaunch); - assertFalse(page.$.relaunch.hidden); - - assertEquals( - page.$.relaunch.innerText, - loadTimeData.getString('aboutRelaunchAndPowerwash')); - - page.$.relaunch.click(); - await lifetimeBrowserProxy.whenCalled('relaunch'); - }); - - /** - * Test that buttons update according to incoming - * 'update-status-changed' events for the case where the target channel - * is less stable than current channel. - */ - test('ButtonsUpdate_StableToBeta', async () => { - aboutBrowserProxy.setChannels( - BrowserChannel.STABLE, BrowserChannel.BETA); - await initNewPage(); - - fireStatusChanged(UpdateStatus.NEARLY_UPDATED, {powerwash: false}); - - assertTrue(!!page.$.relaunch); - assertFalse(page.$.relaunch.hidden); - - assertEquals( - page.$.relaunch.innerText, loadTimeData.getString('aboutRelaunch')); - - page.$.relaunch.click(); - await lifetimeBrowserProxy.whenCalled('relaunch'); - }); - - /** - * The relaunch and powerwash button is shown if the powerwash flag is set - * in the update status. - */ - test('ButtonsUpdate_Powerwash', async () => { - await initNewPage(); - - fireStatusChanged(UpdateStatus.NEARLY_UPDATED, {powerwash: true}); - - assertTrue(!!page.$.relaunch); - assertFalse(page.$.relaunch.hidden); - - assertEquals( - page.$.relaunch.innerText, - loadTimeData.getString('aboutRelaunchAndPowerwash')); - - page.$.relaunch.click(); - await lifetimeBrowserProxy.whenCalled('relaunch'); - }); - - /** - * Test that release notes button can toggled by feature flags. - * Test that release notes button handles offline/online mode properly. - * page.$$("#") is used to access items inside dom-if. - */ - test('ReleaseNotes', async () => { - const releaseNotes = null; - - /** - * Checks the visibility of the "release notes" section when online. - * @param {boolean} isShowing Whether the section is expected to be - * visible. - * @return {!Promise} - */ - async function checkReleaseNotesOnline(isShowing) { - await aboutBrowserProxy.whenCalled('getEnabledReleaseNotes'); - const releaseNotesOnlineEl = page.$$('#releaseNotesOnline'); - assertTrue(!!releaseNotesOnlineEl); - assertEquals(isShowing, !releaseNotesOnlineEl.hidden); - } - - /** - * Checks the visibility of the "release notes" for offline mode. - * @param {boolean} isShowing Whether the section is expected to be - * visible. - * @return {!Promise} - */ - async function checkReleaseNotesOffline(isShowing) { - await aboutBrowserProxy.whenCalled('getEnabledReleaseNotes'); - const releaseNotesOfflineEl = page.$$('#releaseNotesOffline'); - assertTrue(!!releaseNotesOfflineEl); - assertEquals(isShowing, !releaseNotesOfflineEl.hidden); - } - - /** - * Checks the visibility of the "release notes" section when disabled. - * @return {!Promise} - */ - async function checkReleaseNotesDisabled() { - await aboutBrowserProxy.whenCalled('getEnabledReleaseNotes'); - const releaseNotesOnlineEl = page.$$('#releaseNotesOnline'); - assertTrue(!releaseNotesOnlineEl); - const releaseNotesOfflineEl = page.$$('#releaseNotesOffline'); - assertTrue(!releaseNotesOfflineEl); - } - - aboutBrowserProxy.setReleaseNotes(false); - aboutBrowserProxy.setInternetConnection(false); - await initNewPage(); - await checkReleaseNotesDisabled(); - - aboutBrowserProxy.setReleaseNotes(false); - aboutBrowserProxy.setInternetConnection(true); - await initNewPage(); - await checkReleaseNotesDisabled(); - - aboutBrowserProxy.setReleaseNotes(true); - aboutBrowserProxy.setInternetConnection(false); - await initNewPage(); - await checkReleaseNotesOnline(false); - await checkReleaseNotesOffline(true); - - aboutBrowserProxy.setReleaseNotes(true); - aboutBrowserProxy.setInternetConnection(true); - await initNewPage(); - await checkReleaseNotesOnline(true); - await checkReleaseNotesOffline(false); - - page.$$('#releaseNotesOnline').click(); - return aboutBrowserProxy.whenCalled('launchReleaseNotes'); - }); - - test('RegulatoryInfo', async () => { - const regulatoryInfo = {text: 'foo', url: 'bar'}; - - /** - * Checks the visibility of the "regulatory info" section. - * @param {boolean} isShowing Whether the section is expected to be - * visible. - * @return {!Promise} - */ - async function checkRegulatoryInfo(isShowing) { - await aboutBrowserProxy.whenCalled('getRegulatoryInfo'); - const regulatoryInfoEl = page.$.regulatoryInfo; - assertTrue(!!regulatoryInfoEl); - assertEquals(isShowing, !regulatoryInfoEl.hidden); - - if (isShowing) { - const img = regulatoryInfoEl.querySelector('img'); - assertTrue(!!img); - assertEquals(regulatoryInfo.text, img.getAttribute('alt')); - assertEquals(regulatoryInfo.url, img.getAttribute('src')); - } - } - - await checkRegulatoryInfo(false); - aboutBrowserProxy.setRegulatoryInfo(regulatoryInfo); - await initNewPage(); - await checkRegulatoryInfo(true); - }); - - test('TPMFirmwareUpdate', async () => { - assertTrue(page.$.aboutTPMFirmwareUpdate.hidden); - aboutBrowserProxy.setTPMFirmwareUpdateStatus({updateAvailable: true}); - aboutBrowserProxy.refreshTPMFirmwareUpdateStatus(); - assertFalse(page.$.aboutTPMFirmwareUpdate.hidden); - page.$.aboutTPMFirmwareUpdate.click(); - await test_util.flushTasks(); - const dialog = page.$$('os-settings-powerwash-dialog'); - assertTrue(!!dialog); - assertTrue(dialog.$.dialog.open); - dialog.$$('#powerwash').click(); - const requestTpmFirmwareUpdate = - await lifetimeBrowserProxy.whenCalled('factoryReset'); - assertTrue(requestTpmFirmwareUpdate); - }); - - test('DeviceEndOfLife', async () => { - /** - * Checks the visibility of the end of life message and icon. - * @param {boolean} isShowing Whether the end of life UI is expected - * to be visible. - * @return {!Promise} - */ - async function checkHasEndOfLife(isShowing) { - await aboutBrowserProxy.whenCalled('getEndOfLifeInfo'); - const {endOfLifeMessageContainer} = page.$; - assertTrue(!!endOfLifeMessageContainer); - - assertEquals(isShowing, !endOfLifeMessageContainer.hidden); - - // Update status message should be hidden before user has - // checked for updates. - assertTrue(page.$.updateStatusMessage.hidden); - - fireStatusChanged(UpdateStatus.CHECKING); - assertEquals(isShowing, page.$.updateStatusMessage.hidden); - - if (isShowing) { - const icon = page.$$('iron-icon'); - assertTrue(!!icon); - assertEquals(null, icon.src); - assertEquals('os-settings:end-of-life', icon.icon); - - const {checkForUpdates} = page.$; - assertTrue(!!checkForUpdates); - assertTrue(checkForUpdates.hidden); - } - } - - // Force test proxy to not respond to JS requests. - // End of life message should still be hidden in this case. - aboutBrowserProxy.setEndOfLifeInfo(new Promise(function(res, rej) {})); - await initNewPage(); - await checkHasEndOfLife(false); - aboutBrowserProxy.setEndOfLifeInfo({ - hasEndOfLife: true, - endOfLifeAboutMessage: '', - }); - await initNewPage(); - await checkHasEndOfLife(true); - aboutBrowserProxy.setEndOfLifeInfo({ - hasEndOfLife: false, - endOfLifeAboutMessage: '', - }); - await initNewPage(); - await checkHasEndOfLife(false); - }); - - test('detailed build info page', async () => { - async function checkEndOfLifeSection() { - await aboutBrowserProxy.whenCalled('getEndOfLifeInfo'); - const buildInfoPage = page.$$('settings-detailed-build-info'); - assertTrue(!!buildInfoPage.$['endOfLifeSectionContainer']); - assertFalse(buildInfoPage.$['endOfLifeSectionContainer'].hidden); - } - - aboutBrowserProxy.setEndOfLifeInfo({ - hasEndOfLife: true, - aboutPageEndOfLifeMessage: '', - }); - await initNewPage(); - page.scroller = page.offsetParent; - assertTrue(!!page.$['detailed-build-info-trigger']); - page.$['detailed-build-info-trigger'].click(); - const buildInfoPage = page.$$('settings-detailed-build-info'); - assertTrue(!!buildInfoPage); - assertTrue(!!buildInfoPage.$['endOfLifeSectionContainer']); - assertTrue(buildInfoPage.$['endOfLifeSectionContainer'].hidden); - - aboutBrowserProxy.setEndOfLifeInfo({ - hasEndOfLife: true, - aboutPageEndOfLifeMessage: 'message', - }); - await initNewPage(); - page.scroller = page.offsetParent; - assertTrue(!!page.$['detailed-build-info-trigger']); - page.$['detailed-build-info-trigger'].click(); - checkEndOfLifeSection(); - }); - - test('GetHelp', function() { - assertTrue(!!page.$.help); - page.$.help.click(); - return aboutBrowserProxy.whenCalled('openOsHelpPage'); - }); + fireStatusChanged(UpdateStatus.DISABLED_BY_ADMIN); + assertAllHidden(); }); - } - function registerOfficialBuildTests() { - suite('AboutPageTest_OfficialBuild', function() { - test('ReportAnIssue', function() { - const browserProxy = new TestAboutPageBrowserProxyChromeOS(); - settings.AboutPageBrowserProxyImpl.instance_ = browserProxy; - PolymerTest.clearBody(); - const page = document.createElement('os-settings-about-page'); - document.body.appendChild(page); + /** + * Test that buttons update according to incoming + * 'update-status-changed' events for the case where the target channel + * is more stable than current channel and update will powerwash. + */ + test('ButtonsUpdate_BetaToStable', async () => { + aboutBrowserProxy.setChannels(BrowserChannel.BETA, BrowserChannel.STABLE); + await initNewPage(); - assertTrue(!!page.$.reportIssue); - page.$.reportIssue.click(); - return browserProxy.whenCalled('openFeedbackDialog'); - }); + fireStatusChanged(UpdateStatus.NEARLY_UPDATED, {powerwash: true}); + + assertTrue(!!page.$.relaunch); + assertFalse(page.$.relaunch.hidden); + + assertEquals( + page.$.relaunch.innerText, + loadTimeData.getString('aboutRelaunchAndPowerwash')); + + page.$.relaunch.click(); + await lifetimeBrowserProxy.whenCalled('relaunch'); }); - } - function registerDetailedBuildInfoTests() { - suite('DetailedBuildInfoTest', function() { - let page = null; - let browserProxy = null; + /** + * Test that buttons update according to incoming + * 'update-status-changed' events for the case where the target channel + * is less stable than current channel. + */ + test('ButtonsUpdate_StableToBeta', async () => { + aboutBrowserProxy.setChannels(BrowserChannel.STABLE, BrowserChannel.BETA); + await initNewPage(); - setup(function() { - browserProxy = new TestAboutPageBrowserProxyChromeOS(); - settings.AboutPageBrowserProxyImpl.instance_ = browserProxy; - PolymerTest.clearBody(); - }); + fireStatusChanged(UpdateStatus.NEARLY_UPDATED, {powerwash: false}); - teardown(function() { - page.remove(); - page = null; - }); + assertTrue(!!page.$.relaunch); + assertFalse(page.$.relaunch.hidden); - test('Initialization', async () => { - page = document.createElement('settings-detailed-build-info'); - document.body.appendChild(page); + assertEquals( + page.$.relaunch.innerText, loadTimeData.getString('aboutRelaunch')); - await Promise.all([ - browserProxy.whenCalled('pageReady'), - browserProxy.whenCalled('canChangeChannel'), - browserProxy.whenCalled('getChannelInfo'), - browserProxy.whenCalled('getVersionInfo'), - ]); - }); + page.$.relaunch.click(); + await lifetimeBrowserProxy.whenCalled('relaunch'); + }); + + /** + * The relaunch and powerwash button is shown if the powerwash flag is set + * in the update status. + */ + test('ButtonsUpdate_Powerwash', async () => { + await initNewPage(); + + fireStatusChanged(UpdateStatus.NEARLY_UPDATED, {powerwash: true}); + + assertTrue(!!page.$.relaunch); + assertFalse(page.$.relaunch.hidden); + + assertEquals( + page.$.relaunch.innerText, + loadTimeData.getString('aboutRelaunchAndPowerwash')); + + page.$.relaunch.click(); + await lifetimeBrowserProxy.whenCalled('relaunch'); + }); + + /** + * Test that release notes button can toggled by feature flags. + * Test that release notes button handles offline/online mode properly. + * page.$$("#") is used to access items inside dom-if. + */ + test('ReleaseNotes', async () => { + const releaseNotes = null; /** - * Checks whether the "change channel" button state (enabled/disabled) - * correctly reflects whether the user is allowed to change channel (as - * dictated by the browser via loadTimeData boolean). - * @param {boolean} canChangeChannel Whether to simulate the case where - * changing channels is allowed. + * Checks the visibility of the "release notes" section when online. + * @param {boolean} isShowing Whether the section is expected to be + * visible. * @return {!Promise} */ - async function checkChangeChannelButton(canChangeChannel) { - browserProxy.setCanChangeChannel(canChangeChannel); - page = document.createElement('settings-detailed-build-info'); - document.body.appendChild(page); - await browserProxy.whenCalled('canChangeChannel'); - const changeChannelButton = page.$$('cr-button'); - assertTrue(!!changeChannelButton); - assertEquals(canChangeChannel, !changeChannelButton.disabled); + async function checkReleaseNotesOnline(isShowing) { + await aboutBrowserProxy.whenCalled('getEnabledReleaseNotes'); + const releaseNotesOnlineEl = page.$$('#releaseNotesOnline'); + assertTrue(!!releaseNotesOnlineEl); + assertEquals(isShowing, !releaseNotesOnlineEl.hidden); } - test('ChangeChannel_Enabled', function() { - return checkChangeChannelButton(true); - }); - - test('ChangeChannel_Disabled', function() { - return checkChangeChannelButton(false); - }); - /** - * Checks whether the "change channel" button state (enabled/disabled) - * is correct before getChannelInfo() returns - * (see https://crbug.com/848750). Here, getChannelInfo() is blocked - * manually until after the button check. + * Checks the visibility of the "release notes" for offline mode. + * @param {boolean} isShowing Whether the section is expected to be + * visible. + * @return {!Promise} */ - async function checkChangeChannelButtonWithDelayedChannelState( - canChangeChannel) { - const resolver = new PromiseResolver(); - browserProxy.getChannelInfo = async function() { - await resolver.promise; - this.methodCalled('getChannelInfo'); - return Promise.resolve(this.channelInfo_); - }; - const result = await checkChangeChannelButton(canChangeChannel); - resolver.resolve(); - return result; + async function checkReleaseNotesOffline(isShowing) { + await aboutBrowserProxy.whenCalled('getEnabledReleaseNotes'); + const releaseNotesOfflineEl = page.$$('#releaseNotesOffline'); + assertTrue(!!releaseNotesOfflineEl); + assertEquals(isShowing, !releaseNotesOfflineEl.hidden); } - test('ChangeChannel_EnabledWithDelayedChannelState', function() { - return checkChangeChannelButtonWithDelayedChannelState(true); - }); - - test('ChangeChannel_DisabledWithDelayedChannelState', function() { - return checkChangeChannelButtonWithDelayedChannelState(false); - }); - - async function checkCopyBuildDetailsButton() { - page = document.createElement('settings-detailed-build-info'); - document.body.appendChild(page); - const copyBuildDetailsButton = page.$$('cr-icon-button'); - await browserProxy.whenCalled('getVersionInfo'); - await browserProxy.whenCalled('getChannelInfo'); - await browserProxy.whenCalled('canChangeChannel'); - - const expectedClipBoardText = - `${loadTimeData.getString('application_label')}: ` + - `${loadTimeData.getString('aboutBrowserVersion')}\n` + - `Platform: ${browserProxy.versionInfo_.osVersion}\n` + - `Channel: ${browserProxy.channelInfo_.targetChannel}\n` + - `Firmware Version: ${browserProxy.versionInfo_.osFirmware}\n` + - `ARC Enabled: ${loadTimeData.getBoolean('aboutIsArcEnabled')}\n` + - `ARC: ${browserProxy.versionInfo_.arcVersion}\n` + - `Enterprise Enrolled: ` + - `${loadTimeData.getBoolean('aboutEnterpriseManaged')}\n` + - `Developer Mode: ` + - `${loadTimeData.getBoolean('aboutIsDeveloperMode')}`; - - assertTrue(!!copyBuildDetailsButton); - await navigator.clipboard.readText().then(text => assertFalse(!!text)); - copyBuildDetailsButton.click(); - await navigator.clipboard.readText().then( - text => assertEquals(text, expectedClipBoardText)); + /** + * Checks the visibility of the "release notes" section when disabled. + * @return {!Promise} + */ + async function checkReleaseNotesDisabled() { + await aboutBrowserProxy.whenCalled('getEnabledReleaseNotes'); + const releaseNotesOnlineEl = page.$$('#releaseNotesOnline'); + assertTrue(!releaseNotesOnlineEl); + const releaseNotesOfflineEl = page.$$('#releaseNotesOffline'); + assertTrue(!releaseNotesOfflineEl); } - test('CheckCopyBuildDetails', function() { - checkCopyBuildDetailsButton(); - }); + aboutBrowserProxy.setReleaseNotes(false); + aboutBrowserProxy.setInternetConnection(false); + await initNewPage(); + await checkReleaseNotesDisabled(); + + aboutBrowserProxy.setReleaseNotes(false); + aboutBrowserProxy.setInternetConnection(true); + await initNewPage(); + await checkReleaseNotesDisabled(); + + aboutBrowserProxy.setReleaseNotes(true); + aboutBrowserProxy.setInternetConnection(false); + await initNewPage(); + await checkReleaseNotesOnline(false); + await checkReleaseNotesOffline(true); + + aboutBrowserProxy.setReleaseNotes(true); + aboutBrowserProxy.setInternetConnection(true); + await initNewPage(); + await checkReleaseNotesOnline(true); + await checkReleaseNotesOffline(false); + + page.$$('#releaseNotesOnline').click(); + return aboutBrowserProxy.whenCalled('launchReleaseNotes'); }); - } - function registerChannelSwitcherDialogTests() { - suite('ChannelSwitcherDialogTest', function() { - let dialog = null; - let radioButtons = null; - let browserProxy = null; - const currentChannel = BrowserChannel.BETA; + test('RegulatoryInfo', async () => { + const regulatoryInfo = {text: 'foo', url: 'bar'}; - setup(function() { - browserProxy = new TestAboutPageBrowserProxyChromeOS(); - browserProxy.setChannels(currentChannel, currentChannel); - settings.AboutPageBrowserProxyImpl.instance_ = browserProxy; - PolymerTest.clearBody(); - dialog = document.createElement('settings-channel-switcher-dialog'); - document.body.appendChild(dialog); + /** + * Checks the visibility of the "regulatory info" section. + * @param {boolean} isShowing Whether the section is expected to be + * visible. + * @return {!Promise} + */ + async function checkRegulatoryInfo(isShowing) { + await aboutBrowserProxy.whenCalled('getRegulatoryInfo'); + const regulatoryInfoEl = page.$.regulatoryInfo; + assertTrue(!!regulatoryInfoEl); + assertEquals(isShowing, !regulatoryInfoEl.hidden); - radioButtons = dialog.shadowRoot.querySelectorAll('cr-radio-button'); - assertEquals(3, radioButtons.length); - return browserProxy.whenCalled('getChannelInfo'); - }); + if (isShowing) { + const img = regulatoryInfoEl.querySelector('img'); + assertTrue(!!img); + assertEquals(regulatoryInfo.text, img.getAttribute('alt')); + assertEquals(regulatoryInfo.url, img.getAttribute('src')); + } + } - teardown(function() { - dialog.remove(); - }); - - test('Initialization', function() { - const radioGroup = dialog.$$('cr-radio-group'); - assertTrue(!!radioGroup); - assertTrue(!!dialog.$.warningSelector); - assertTrue(!!dialog.$.changeChannel); - assertTrue(!!dialog.$.changeChannelAndPowerwash); - - // Check that upon initialization the radio button corresponding to - // the current release channel is pre-selected. - assertEquals(currentChannel, radioGroup.selected); - assertEquals(dialog.$.warningSelector.selected, -1); - - // Check that action buttons are hidden when current and target - // channel are the same. - assertTrue(dialog.$.changeChannel.hidden); - assertTrue(dialog.$.changeChannelAndPowerwash.hidden); - }); - - // Test case where user switches to a less stable channel. - test('ChangeChannel_LessStable', async () => { - assertEquals(BrowserChannel.DEV, radioButtons.item(2).name); - radioButtons.item(2).click(); - Polymer.dom.flush(); - - await browserProxy.whenCalled('getChannelInfo'); - assertEquals(dialog.$.warningSelector.selected, 2); - // Check that only the "Change channel" button becomes visible. - assertTrue(dialog.$.changeChannelAndPowerwash.hidden); - assertFalse(dialog.$.changeChannel.hidden); - - const whenTargetChannelChangedFired = - test_util.eventToPromise('target-channel-changed', dialog); - - dialog.$.changeChannel.click(); - const [channel, isPowerwashAllowed] = - await browserProxy.whenCalled('setChannel'); - assertEquals(BrowserChannel.DEV, channel); - assertFalse(isPowerwashAllowed); - const {detail} = await whenTargetChannelChangedFired; - assertEquals(BrowserChannel.DEV, detail); - }); - - // Test case where user switches to a more stable channel. - test('ChangeChannel_MoreStable', async () => { - assertEquals(BrowserChannel.STABLE, radioButtons.item(0).name); - radioButtons.item(0).click(); - Polymer.dom.flush(); - - await browserProxy.whenCalled('getChannelInfo'); - assertEquals(dialog.$.warningSelector.selected, 1); - // Check that only the "Change channel and Powerwash" button becomes - // visible. - assertFalse(dialog.$.changeChannelAndPowerwash.hidden); - assertTrue(dialog.$.changeChannel.hidden); - - const whenTargetChannelChangedFired = - test_util.eventToPromise('target-channel-changed', dialog); - - dialog.$.changeChannelAndPowerwash.click(); - const [channel, isPowerwashAllowed] = - await browserProxy.whenCalled('setChannel'); - assertEquals(BrowserChannel.STABLE, channel); - assertTrue(isPowerwashAllowed); - const {detail} = await whenTargetChannelChangedFired; - assertEquals(BrowserChannel.STABLE, detail); - }); + await checkRegulatoryInfo(false); + aboutBrowserProxy.setRegulatoryInfo(regulatoryInfo); + await initNewPage(); + await checkRegulatoryInfo(true); }); - } - return { - registerTests: function() { - registerDetailedBuildInfoTests(); - registerChannelSwitcherDialogTests(); - registerAboutPageTests(); - }, - registerOfficialBuildTests: registerOfficialBuildTests, - }; + test('TPMFirmwareUpdate', async () => { + assertTrue(page.$.aboutTPMFirmwareUpdate.hidden); + aboutBrowserProxy.setTPMFirmwareUpdateStatus({updateAvailable: true}); + aboutBrowserProxy.refreshTPMFirmwareUpdateStatus(); + assertFalse(page.$.aboutTPMFirmwareUpdate.hidden); + page.$.aboutTPMFirmwareUpdate.click(); + await test_util.flushTasks(); + const dialog = page.$$('os-settings-powerwash-dialog'); + assertTrue(!!dialog); + assertTrue(dialog.$.dialog.open); + dialog.$$('#powerwash').click(); + const requestTpmFirmwareUpdate = + await lifetimeBrowserProxy.whenCalled('factoryReset'); + assertTrue(requestTpmFirmwareUpdate); + }); + + test('DeviceEndOfLife', async () => { + /** + * Checks the visibility of the end of life message and icon. + * @param {boolean} isShowing Whether the end of life UI is expected + * to be visible. + * @return {!Promise} + */ + async function checkHasEndOfLife(isShowing) { + await aboutBrowserProxy.whenCalled('getEndOfLifeInfo'); + const {endOfLifeMessageContainer} = page.$; + assertTrue(!!endOfLifeMessageContainer); + + assertEquals(isShowing, !endOfLifeMessageContainer.hidden); + + // Update status message should be hidden before user has + // checked for updates. + assertTrue(page.$.updateStatusMessage.hidden); + + fireStatusChanged(UpdateStatus.CHECKING); + assertEquals(isShowing, page.$.updateStatusMessage.hidden); + + if (isShowing) { + const icon = page.$$('iron-icon'); + assertTrue(!!icon); + assertEquals(null, icon.src); + assertEquals('os-settings:end-of-life', icon.icon); + + const {checkForUpdates} = page.$; + assertTrue(!!checkForUpdates); + assertTrue(checkForUpdates.hidden); + } + } + + // Force test proxy to not respond to JS requests. + // End of life message should still be hidden in this case. + aboutBrowserProxy.setEndOfLifeInfo(new Promise(function(res, rej) {})); + await initNewPage(); + await checkHasEndOfLife(false); + aboutBrowserProxy.setEndOfLifeInfo({ + hasEndOfLife: true, + endOfLifeAboutMessage: '', + }); + await initNewPage(); + await checkHasEndOfLife(true); + aboutBrowserProxy.setEndOfLifeInfo({ + hasEndOfLife: false, + endOfLifeAboutMessage: '', + }); + await initNewPage(); + await checkHasEndOfLife(false); + }); + + test('detailed build info page', async () => { + async function checkEndOfLifeSection() { + await aboutBrowserProxy.whenCalled('getEndOfLifeInfo'); + const buildInfoPage = page.$$('settings-detailed-build-info'); + assertTrue(!!buildInfoPage.$['endOfLifeSectionContainer']); + assertFalse(buildInfoPage.$['endOfLifeSectionContainer'].hidden); + } + + aboutBrowserProxy.setEndOfLifeInfo({ + hasEndOfLife: true, + aboutPageEndOfLifeMessage: '', + }); + await initNewPage(); + page.scroller = page.offsetParent; + assertTrue(!!page.$['detailed-build-info-trigger']); + page.$['detailed-build-info-trigger'].click(); + const buildInfoPage = page.$$('settings-detailed-build-info'); + assertTrue(!!buildInfoPage); + assertTrue(!!buildInfoPage.$['endOfLifeSectionContainer']); + assertTrue(buildInfoPage.$['endOfLifeSectionContainer'].hidden); + + aboutBrowserProxy.setEndOfLifeInfo({ + hasEndOfLife: true, + aboutPageEndOfLifeMessage: 'message', + }); + await initNewPage(); + page.scroller = page.offsetParent; + assertTrue(!!page.$['detailed-build-info-trigger']); + page.$['detailed-build-info-trigger'].click(); + checkEndOfLifeSection(); + }); + + test('GetHelp', function() { + assertTrue(!!page.$.help); + page.$.help.click(); + return aboutBrowserProxy.whenCalled('openOsHelpPage'); + }); + }); + + suite('DetailedBuildInfoTest', function() { + let page = null; + let browserProxy = null; + + setup(function() { + browserProxy = new TestAboutPageBrowserProxyChromeOS(); + settings.AboutPageBrowserProxyImpl.instance_ = browserProxy; + PolymerTest.clearBody(); + }); + + teardown(function() { + page.remove(); + page = null; + }); + + test('Initialization', async () => { + page = document.createElement('settings-detailed-build-info'); + document.body.appendChild(page); + + await Promise.all([ + browserProxy.whenCalled('pageReady'), + browserProxy.whenCalled('canChangeChannel'), + browserProxy.whenCalled('getChannelInfo'), + browserProxy.whenCalled('getVersionInfo'), + ]); + }); + + /** + * Checks whether the "change channel" button state (enabled/disabled) + * correctly reflects whether the user is allowed to change channel (as + * dictated by the browser via loadTimeData boolean). + * @param {boolean} canChangeChannel Whether to simulate the case where + * changing channels is allowed. + * @return {!Promise} + */ + async function checkChangeChannelButton(canChangeChannel) { + browserProxy.setCanChangeChannel(canChangeChannel); + page = document.createElement('settings-detailed-build-info'); + document.body.appendChild(page); + await browserProxy.whenCalled('canChangeChannel'); + const changeChannelButton = page.$$('cr-button'); + assertTrue(!!changeChannelButton); + assertEquals(canChangeChannel, !changeChannelButton.disabled); + } + + test('ChangeChannel_Enabled', function() { + return checkChangeChannelButton(true); + }); + + test('ChangeChannel_Disabled', function() { + return checkChangeChannelButton(false); + }); + + /** + * Checks whether the "change channel" button state (enabled/disabled) + * is correct before getChannelInfo() returns + * (see https://crbug.com/848750). Here, getChannelInfo() is blocked + * manually until after the button check. + */ + async function checkChangeChannelButtonWithDelayedChannelState( + canChangeChannel) { + const resolver = new PromiseResolver(); + browserProxy.getChannelInfo = async function() { + await resolver.promise; + this.methodCalled('getChannelInfo'); + return Promise.resolve(this.channelInfo_); + }; + const result = await checkChangeChannelButton(canChangeChannel); + resolver.resolve(); + return result; + } + + test('ChangeChannel_EnabledWithDelayedChannelState', function() { + return checkChangeChannelButtonWithDelayedChannelState(true); + }); + + test('ChangeChannel_DisabledWithDelayedChannelState', function() { + return checkChangeChannelButtonWithDelayedChannelState(false); + }); + + async function checkCopyBuildDetailsButton() { + page = document.createElement('settings-detailed-build-info'); + document.body.appendChild(page); + const copyBuildDetailsButton = page.$$('cr-icon-button'); + await browserProxy.whenCalled('getVersionInfo'); + await browserProxy.whenCalled('getChannelInfo'); + await browserProxy.whenCalled('canChangeChannel'); + + const expectedClipBoardText = + `${loadTimeData.getString('application_label')}: ` + + `${loadTimeData.getString('aboutBrowserVersion')}\n` + + `Platform: ${browserProxy.versionInfo_.osVersion}\n` + + `Channel: ${browserProxy.channelInfo_.targetChannel}\n` + + `Firmware Version: ${browserProxy.versionInfo_.osFirmware}\n` + + `ARC Enabled: ${loadTimeData.getBoolean('aboutIsArcEnabled')}\n` + + `ARC: ${browserProxy.versionInfo_.arcVersion}\n` + + `Enterprise Enrolled: ` + + `${loadTimeData.getBoolean('aboutEnterpriseManaged')}\n` + + `Developer Mode: ` + + `${loadTimeData.getBoolean('aboutIsDeveloperMode')}`; + + assertTrue(!!copyBuildDetailsButton); + await navigator.clipboard.readText().then(text => assertFalse(!!text)); + copyBuildDetailsButton.click(); + await navigator.clipboard.readText().then( + text => assertEquals(text, expectedClipBoardText)); + } + + test('CheckCopyBuildDetails', function() { + checkCopyBuildDetailsButton(); + }); + }); + + suite('ChannelSwitcherDialogTest', function() { + let dialog = null; + let radioButtons = null; + let browserProxy = null; + let currentChannel; + + setup(function() { + currentChannel = BrowserChannel.BETA; + browserProxy = new TestAboutPageBrowserProxyChromeOS(); + browserProxy.setChannels(currentChannel, currentChannel); + settings.AboutPageBrowserProxyImpl.instance_ = browserProxy; + PolymerTest.clearBody(); + dialog = document.createElement('settings-channel-switcher-dialog'); + document.body.appendChild(dialog); + + radioButtons = dialog.shadowRoot.querySelectorAll('cr-radio-button'); + assertEquals(3, radioButtons.length); + return browserProxy.whenCalled('getChannelInfo'); + }); + + teardown(function() { + dialog.remove(); + }); + + test('Initialization', function() { + const radioGroup = dialog.$$('cr-radio-group'); + assertTrue(!!radioGroup); + assertTrue(!!dialog.$.warningSelector); + assertTrue(!!dialog.$.changeChannel); + assertTrue(!!dialog.$.changeChannelAndPowerwash); + + // Check that upon initialization the radio button corresponding to + // the current release channel is pre-selected. + assertEquals(currentChannel, radioGroup.selected); + assertEquals(dialog.$.warningSelector.selected, -1); + + // Check that action buttons are hidden when current and target + // channel are the same. + assertTrue(dialog.$.changeChannel.hidden); + assertTrue(dialog.$.changeChannelAndPowerwash.hidden); + }); + + // Test case where user switches to a less stable channel. + test('ChangeChannel_LessStable', async () => { + assertEquals(BrowserChannel.DEV, radioButtons.item(2).name); + radioButtons.item(2).click(); + Polymer.dom.flush(); + + await browserProxy.whenCalled('getChannelInfo'); + assertEquals(dialog.$.warningSelector.selected, 2); + // Check that only the "Change channel" button becomes visible. + assertTrue(dialog.$.changeChannelAndPowerwash.hidden); + assertFalse(dialog.$.changeChannel.hidden); + + const whenTargetChannelChangedFired = + test_util.eventToPromise('target-channel-changed', dialog); + + dialog.$.changeChannel.click(); + const [channel, isPowerwashAllowed] = + await browserProxy.whenCalled('setChannel'); + assertEquals(BrowserChannel.DEV, channel); + assertFalse(isPowerwashAllowed); + const {detail} = await whenTargetChannelChangedFired; + assertEquals(BrowserChannel.DEV, detail); + }); + + // Test case where user switches to a more stable channel. + test('ChangeChannel_MoreStable', async () => { + assertEquals(BrowserChannel.STABLE, radioButtons.item(0).name); + radioButtons.item(0).click(); + Polymer.dom.flush(); + + await browserProxy.whenCalled('getChannelInfo'); + assertEquals(dialog.$.warningSelector.selected, 1); + // Check that only the "Change channel and Powerwash" button becomes + // visible. + assertFalse(dialog.$.changeChannelAndPowerwash.hidden); + assertTrue(dialog.$.changeChannel.hidden); + + const whenTargetChannelChangedFired = + test_util.eventToPromise('target-channel-changed', dialog); + + dialog.$.changeChannelAndPowerwash.click(); + const [channel, isPowerwashAllowed] = + await browserProxy.whenCalled('setChannel'); + assertEquals(BrowserChannel.STABLE, channel); + assertTrue(isPowerwashAllowed); + const {detail} = await whenTargetChannelChangedFired; + assertEquals(BrowserChannel.STABLE, detail); + }); + }); + + suite('AboutPageTest_OfficialBuild', function() { + test('ReportAnIssue', function() { + const browserProxy = new TestAboutPageBrowserProxyChromeOS(); + settings.AboutPageBrowserProxyImpl.instance_ = browserProxy; + PolymerTest.clearBody(); + const page = document.createElement('os-settings-about-page'); + document.body.appendChild(page); + + assertTrue(!!page.$.reportIssue); + page.$.reportIssue.click(); + return browserProxy.whenCalled('openFeedbackDialog'); + }); + }); + + // #cr_define_end + return {}; });
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index 5f757355..d9f35c4 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -82,15 +82,13 @@ } }; -TEST_F('OSSettingsAboutPageTest', 'AboutPage', () => { - settings_about_page.registerTests(); - mocha.run(); +TEST_F('OSSettingsAboutPageTest', 'AllBuilds', () => { + mocha.grep('/^(?!AboutPageTest_OfficialBuild).*$/').run(); }); GEN('#if BUILDFLAG(GOOGLE_CHROME_BRANDING)'); TEST_F('OSSettingsAboutPageTest', 'AboutPage_OfficialBuild', () => { - settings_about_page.registerOfficialBuildTests(); - mocha.run(); + mocha.grep('AboutPageTest_OfficialBuild').run(); }); GEN('#endif');
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js index 549aafc..66d09ac7 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -6,6 +6,7 @@ // Polymer BrowserTest fixture. GEN_INCLUDE(['//chrome/test/data/webui/polymer_browser_test_base.js']); GEN('#include "chrome/common/buildflags.h"'); +GEN('#include "build/branding_buildflags.h"'); GEN('#include "content/public/test/browser_test.h"'); GEN('#include "chromeos/constants/chromeos_features.h"'); @@ -65,6 +66,7 @@ ['CupsPrinterPage', 'cups_printer_page_tests.m.js'], ['CupsPrinterLandingPage', 'cups_printer_landing_page_tests.m.js'], ['CupsPrinterEntry', 'cups_printer_entry_tests.m.js'], + ['AboutPage', 'os_about_page_tests.m.js'], ].forEach(test => registerTest(...test)); function registerTest(testName, module, caseName) { @@ -76,5 +78,19 @@ } }; - TEST_F(className, caseName || 'All', () => mocha.run()); + // AboutPage has a test suite that can only succeed on official builds where + // the is_chrome_branded build flag is enabled + if (testName === 'AboutPage') { + TEST_F(className, 'AllBuilds' || 'All', () => { + mocha.grep('/^(?!AboutPageTest_OfficialBuild).*$/').run(); + }); + + GEN('#if BUILDFLAG(GOOGLE_CHROME_BRANDING)'); + TEST_F(className, 'OfficialBuild' || 'All', () => { + mocha.grep('AboutPageTest_OfficialBuild').run(); + }); + GEN('#endif'); + } else { + TEST_F(className, caseName || 'All', () => mocha.run()); + } }
diff --git a/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.js b/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.js index a2ccc28..75c5fa5 100644 --- a/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.js +++ b/chrome/test/data/webui/settings/chromeos/test_about_page_browser_proxy_chromeos.js
@@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// #import {TestBrowserProxy} from 'chrome://test/test_browser_proxy.m.js'; -// #import {BrowserChannel, UpdateStatus} from 'chrome://settings/settings.js'; +// clang-format off +// #import {TestBrowserProxy} from '../../test_browser_proxy.m.js'; +// #import {BrowserChannel,UpdateStatus} from 'chrome://os-settings/chromeos/os_settings.js'; +// clang-format on /** @implements {settings.AboutPageBrowserProxy} */ /* #export */ class TestAboutPageBrowserProxyChromeOS extends TestBrowserProxy {
diff --git a/chromeos/memory/pressure/system_memory_pressure_evaluator.cc b/chromeos/memory/pressure/system_memory_pressure_evaluator.cc index d101e18..acd11c40 100644 --- a/chromeos/memory/pressure/system_memory_pressure_evaluator.cc +++ b/chromeos/memory/pressure/system_memory_pressure_evaluator.cc
@@ -29,7 +29,7 @@ namespace memory { const base::Feature kCrOSUserSpaceLowMemoryNotification{ - "CrOSUserSpaceLowMemoryNotification", base::FEATURE_DISABLED_BY_DEFAULT}; + "CrOSUserSpaceLowMemoryNotification", base::FEATURE_ENABLED_BY_DEFAULT}; namespace { // Pointer to the SystemMemoryPressureEvaluator used by TabManagerDelegate for
diff --git a/chromeos/network/network_handler.cc b/chromeos/network/network_handler.cc index b0cf31a4..21dfc3a 100644 --- a/chromeos/network/network_handler.cc +++ b/chromeos/network/network_handler.cc
@@ -135,6 +135,15 @@ network_metadata_store_.reset(); } +bool NetworkHandler::HasUiProxyConfigService() { + return IsInitialized() && Get()->ui_proxy_config_service_.get(); +} + +UIProxyConfigService* NetworkHandler::GetUiProxyConfigService() { + DCHECK(HasUiProxyConfigService()); + return Get()->ui_proxy_config_service_.get(); +} + NetworkStateHandler* NetworkHandler::network_state_handler() { return network_state_handler_.get(); } @@ -189,9 +198,4 @@ return prohibited_technologies_handler_.get(); } -UIProxyConfigService* NetworkHandler::ui_proxy_config_service() { - CHECK(ui_proxy_config_service_.get()); - return ui_proxy_config_service_.get(); -} - } // namespace chromeos
diff --git a/chromeos/network/network_handler.h b/chromeos/network/network_handler.h index 706ad6f98..50b27e0 100644 --- a/chromeos/network/network_handler.h +++ b/chromeos/network/network_handler.h
@@ -64,6 +64,10 @@ // Must be called before pref services are shut down. void ShutdownPrefServices(); + // Global network configuration services. + static bool HasUiProxyConfigService(); + static UIProxyConfigService* GetUiProxyConfigService(); + // Returns the task runner for posting NetworkHandler calls from other // threads. base::SingleThreadTaskRunner* task_runner() { return task_runner_.get(); } @@ -85,10 +89,6 @@ GeolocationHandler* geolocation_handler(); ProhibitedTechnologiesHandler* prohibited_technologies_handler(); - // Global network configuration services. - UIProxyConfigService* ui_proxy_config_service(); - bool has_ui_proxy_config_service() { return ui_proxy_config_service_.get(); } - void set_is_enterprise_managed(bool is_enterprise_managed) { is_enterprise_managed_ = is_enterprise_managed; }
diff --git a/chromeos/network/proxy/ui_proxy_config_service.cc b/chromeos/network/proxy/ui_proxy_config_service.cc index 1256b05f..21e089e 100644 --- a/chromeos/network/proxy/ui_proxy_config_service.cc +++ b/chromeos/network/proxy/ui_proxy_config_service.cc
@@ -17,8 +17,10 @@ #include "chromeos/network/proxy/proxy_config_handler.h" #include "chromeos/network/proxy/proxy_config_service_impl.h" #include "chromeos/network/tether_constants.h" +#include "components/prefs/pref_service.h" #include "components/proxy_config/pref_proxy_config_tracker_impl.h" #include "components/proxy_config/proxy_config_pref_names.h" +#include "components/proxy_config/proxy_prefs.h" #include "net/proxy_resolution/proxy_config.h" namespace chromeos { @@ -179,6 +181,19 @@ return base::Value(); } +ProxyPrefs::ProxyMode OncStringToProxyMode(const std::string& onc_proxy_type) { + if (onc_proxy_type == ::onc::proxy::kDirect) + return ProxyPrefs::ProxyMode::MODE_DIRECT; + if (onc_proxy_type == ::onc::proxy::kWPAD) + return ProxyPrefs::ProxyMode::MODE_AUTO_DETECT; + if (onc_proxy_type == ::onc::proxy::kPAC) + return ProxyPrefs::ProxyMode::MODE_PAC_SCRIPT; + if (onc_proxy_type == ::onc::proxy::kManual) + return ProxyPrefs::ProxyMode::MODE_FIXED_SERVERS; + NOTREACHED() << "Unsupported ONC proxy type: " << onc_proxy_type; + return ProxyPrefs::ProxyMode::MODE_DIRECT; +} + } // namespace UIProxyConfigService::UIProxyConfigService( @@ -291,16 +306,35 @@ ProxyPrefs::ProxyMode UIProxyConfigService::ProxyModeForNetwork( const NetworkState* network) { - // TODO(919691): Include proxies set by an extension and per-user proxies. onc::ONCSource onc_source = onc::ONC_SOURCE_NONE; std::unique_ptr<ProxyConfigDictionary> proxy_dict = proxy_config::GetProxyConfigForNetwork(nullptr, local_state_prefs_, *network, network_profile_handler_, &onc_source); - ProxyPrefs::ProxyMode mode; - if (!proxy_dict || !proxy_dict->GetMode(&mode)) - return ProxyPrefs::MODE_DIRECT; - return mode; + base::Value proxy_settings(base::Value::Type::DICTIONARY); + if (proxy_dict) + proxy_settings = proxy_dict->GetDictionary().Clone(); + + PrefService* top_pref_service = + profile_prefs_ ? profile_prefs_ : local_state_prefs_; + + // On the OOBE screen and/or tests. + if (!network->IsInProfile() || + !top_pref_service->HasPrefPath(::proxy_config::prefs::kProxy)) { + ProxyPrefs::ProxyMode mode; + if (!proxy_dict || !proxy_dict->GetMode(&mode)) + return ProxyPrefs::MODE_DIRECT; + return mode; + } + + MergeEnforcedProxyConfig(network->guid(), &proxy_settings); + if (!proxy_settings.DictEmpty()) { + base::Value* proxy_specification_mode = proxy_settings.FindPath( + {::onc::network_config::kType, ::onc::kAugmentationActiveSetting}); + if (proxy_specification_mode) + return OncStringToProxyMode(proxy_specification_mode->GetString()); + } + return ProxyPrefs::ProxyMode::MODE_DIRECT; } void UIProxyConfigService::OnPreferenceChanged(const std::string& pref_name) {
diff --git a/chromeos/network/proxy/ui_proxy_config_service.h b/chromeos/network/proxy/ui_proxy_config_service.h index 5732c4d..03fe1c65 100644 --- a/chromeos/network/proxy/ui_proxy_config_service.h +++ b/chromeos/network/proxy/ui_proxy_config_service.h
@@ -64,7 +64,9 @@ // with mode == MODE_FIXED_SERVERS. bool HasDefaultNetworkProxyConfigured(); - // Returns the ProxyMode for |network| using |local_state_prefs_| + // Returns the ProxyMode for |network| by merging proxy configurations from + // different sources, including user set, policy and extensions. See + // |MergeEnforcedProxyConfig| for order of preference. ProxyPrefs::ProxyMode ProxyModeForNetwork(const NetworkState* network); private:
diff --git a/chromeos/services/device_sync/proto/enum_util.cc b/chromeos/services/device_sync/proto/enum_util.cc index 9ecda47f..212255ed 100644 --- a/chromeos/services/device_sync/proto/enum_util.cc +++ b/chromeos/services/device_sync/proto/enum_util.cc
@@ -85,6 +85,12 @@ case cryptauth::SoftwareFeature::SMS_CONNECT_CLIENT: stream << "[SMS Connect client]"; break; + case cryptauth::SoftwareFeature::PHONE_HUB_HOST: + stream << "[Phone Hub host]"; + break; + case cryptauth::SoftwareFeature::PHONE_HUB_CLIENT: + stream << "[Phone Hub client]"; + break; default: stream << "[unknown software feature]"; break; @@ -110,6 +116,10 @@ return cryptauth::SoftwareFeature::SMS_CONNECT_HOST; if (software_feature_as_string == "smsConnectClient") return cryptauth::SoftwareFeature::SMS_CONNECT_CLIENT; + if (software_feature_as_string == "phoneHubHost") + return cryptauth::SoftwareFeature::PHONE_HUB_HOST; + if (software_feature_as_string == "phoneHubClient") + return cryptauth::SoftwareFeature::PHONE_HUB_CLIENT; return cryptauth::SoftwareFeature::UNKNOWN_FEATURE; } @@ -133,6 +143,10 @@ return "smsConnectHost"; case cryptauth::SoftwareFeature::SMS_CONNECT_CLIENT: return "smsConnectClient"; + case cryptauth::SoftwareFeature::PHONE_HUB_HOST: + return "phoneHubHost"; + case cryptauth::SoftwareFeature::PHONE_HUB_CLIENT: + return "phoneHubClient"; default: return "unknownFeature"; } @@ -157,6 +171,10 @@ return "SMS_CONNECT_HOST"; case cryptauth::SoftwareFeature::SMS_CONNECT_CLIENT: return "SMS_CONNECT_CLIENT"; + case cryptauth::SoftwareFeature::PHONE_HUB_HOST: + return "PHONE_HUB_HOST"; + case cryptauth::SoftwareFeature::PHONE_HUB_CLIENT: + return "PHONE_HUB_CLIENT"; default: return "UNKNOWN_FEATURE"; }
diff --git a/chromeos/services/network_config/cros_network_config.cc b/chromeos/services/network_config/cros_network_config.cc index d40c112b..b3bba59 100644 --- a/chromeos/services/network_config/cros_network_config.cc +++ b/chromeos/services/network_config/cros_network_config.cc
@@ -312,17 +312,11 @@ result->priority = network->priority(); result->prohibited_by_policy = network->blocked_by_policy(); result->source = GetMojoOncSource(network); - - // NetworkHandler and UIProxyConfigService may not exist in tests. - UIProxyConfigService* ui_proxy_config_service = - NetworkHandler::IsInitialized() && - NetworkHandler::Get()->has_ui_proxy_config_service() - ? NetworkHandler::Get()->ui_proxy_config_service() - : nullptr; result->proxy_mode = - ui_proxy_config_service + NetworkHandler::HasUiProxyConfigService() ? mojom::ProxyMode( - ui_proxy_config_service->ProxyModeForNetwork(network)) + NetworkHandler::GetUiProxyConfigService()->ProxyModeForNetwork( + network)) : mojom::ProxyMode::kDirect; const NetworkState::CaptivePortalProviderInfo* captive_portal_provider =
diff --git a/chromeos/services/network_config/cros_network_config_unittest.cc b/chromeos/services/network_config/cros_network_config_unittest.cc index 29eb069..68223fb 100644 --- a/chromeos/services/network_config/cros_network_config_unittest.cc +++ b/chromeos/services/network_config/cros_network_config_unittest.cc
@@ -457,6 +457,9 @@ } std::string wifi1_path() { return wifi1_path_; } + protected: + sync_preferences::TestingPrefServiceSyncable user_prefs_; + private: base::test::SingleThreadTaskEnvironment task_environment_; NetworkStateTestHelper helper_{false /* use_default_devices_and_services */}; @@ -468,7 +471,6 @@ managed_network_configuration_handler_; std::unique_ptr<NetworkConnectionHandler> network_connection_handler_; std::unique_ptr<chromeos::UIProxyConfigService> ui_proxy_config_service_; - sync_preferences::TestingPrefServiceSyncable user_prefs_; TestingPrefServiceSimple local_state_; std::unique_ptr<CrosNetworkConfig> cros_network_config_; std::unique_ptr<CrosNetworkConfigTestObserver> observer_; @@ -1249,5 +1251,18 @@ EXPECT_EQ(0, observer()->GetNetworkChangedCount("wifi2_guid")); } +TEST_F(CrosNetworkConfigTest, PolicyEnforcedProxyMode) { + // Proxies enforced by policy and/or extension are set in the kProxy + // preference. + base::Value policy_prefs_config = ProxyConfigDictionary::CreateAutoDetect(); + user_prefs_.SetUserPref( + proxy_config::prefs::kProxy, + base::Value::ToUniquePtrValue(std::move(policy_prefs_config))); + + mojom::NetworkStatePropertiesPtr network = GetNetworkState("wifi2_guid"); + ASSERT_TRUE(network); + EXPECT_EQ(network->proxy_mode, mojom::ProxyMode::kAutoDetect); +} + } // namespace network_config } // namespace chromeos
diff --git a/components/autofill_assistant/browser/devtools/devtools_client.cc b/components/autofill_assistant/browser/devtools/devtools_client.cc index 8f7af50..6698d95 100644 --- a/components/autofill_assistant/browser/devtools/devtools_client.cc +++ b/components/autofill_assistant/browser/devtools/devtools_client.cc
@@ -30,7 +30,7 @@ next_message_id_(0), frame_tracker_(this) { browser_main_thread_ = content::GetUIThreadTaskRunner({}); - agent_host_->AttachClient(this); + agent_host_->AttachClientWithoutWakeLock(this); frame_tracker_.Start(); }
diff --git a/components/dbus/menu/BUILD.gn b/components/dbus/menu/BUILD.gn index 9c0d113..6712968 100644 --- a/components/dbus/menu/BUILD.gn +++ b/components/dbus/menu/BUILD.gn
@@ -24,7 +24,7 @@ "//ui/gfx", ] if (use_x11) { - configs += [ "//build/config/linux:x11" ] + deps += [ "//ui/gfx/x" ] } }
diff --git a/components/dbus/menu/DEPS b/components/dbus/menu/DEPS index 0d3f0e9..9b41b13 100644 --- a/components/dbus/menu/DEPS +++ b/components/dbus/menu/DEPS
@@ -3,4 +3,5 @@ "+ui/base", "+ui/events/keycodes", "+ui/gfx/image", + "+ui/gfx/x", ]
diff --git a/components/dbus/menu/menu_property_list.cc b/components/dbus/menu/menu_property_list.cc index 7939625..f87141fc 100644 --- a/components/dbus/menu/menu_property_list.cc +++ b/components/dbus/menu/menu_property_list.cc
@@ -14,10 +14,9 @@ #include "ui/gfx/image/image.h" #if defined(USE_X11) -#include <X11/Xlib.h> - #include "ui/base/ui_base_features.h" #include "ui/events/keycodes/keyboard_code_conversion_x.h" // nogncheck +#include "ui/gfx/x/x11.h" // nogncheck #endif MenuItemProperties ComputeMenuPropertiesForMenuItem(ui::MenuModel* menu,
diff --git a/components/domain_reliability/monitor.cc b/components/domain_reliability/monitor.cc index 788b22d..2d9125f 100644 --- a/components/domain_reliability/monitor.cc +++ b/components/domain_reliability/monitor.cc
@@ -188,7 +188,9 @@ : url(request.url()), net_error(net_error), response_info(request.response_info()), - load_flags(request.load_flags()), + // This ignores cookie blocking by the NetworkDelegate, but probably + // should not. Unclear if it's worth fixing. + allow_credentials(request.allow_credentials()), upload_depth( DomainReliabilityUploader::GetURLRequestUploadDepth(request)) { request.GetLoadTimingInfo(&load_timing_info); @@ -206,15 +208,14 @@ // static bool DomainReliabilityMonitor::RequestInfo::ShouldReportRequest( const DomainReliabilityMonitor::RequestInfo& request) { - // Always report DR upload requests, even though they have - // DO_NOT_SEND_COOKIES. + // Always report DR upload requests, even though they don't allow credentials. // Note: They are reported (i.e. generate a beacon) but do not necessarily // trigger an upload by themselves. if (request.upload_depth > 0) return true; - // Don't report requests that weren't supposed to send cookies. - if (request.load_flags & net::LOAD_DO_NOT_SEND_COOKIES) + // Don't report requests that weren't supposed to send credentials. + if (!request.allow_credentials) return false; // Report requests that accessed the network or failed with an error code
diff --git a/components/domain_reliability/monitor.h b/components/domain_reliability/monitor.h index 47e6c4c3..9306877 100644 --- a/components/domain_reliability/monitor.h +++ b/components/domain_reliability/monitor.h
@@ -60,7 +60,7 @@ GURL url; int net_error; net::HttpResponseInfo response_info; - int load_flags; + bool allow_credentials; net::LoadTimingInfo load_timing_info; net::ConnectionAttempts connection_attempts; net::IPEndPoint remote_endpoint;
diff --git a/components/domain_reliability/monitor_unittest.cc b/components/domain_reliability/monitor_unittest.cc index bfaa18a..628c417 100644 --- a/components/domain_reliability/monitor_unittest.cc +++ b/components/domain_reliability/monitor_unittest.cc
@@ -21,7 +21,6 @@ #include "components/domain_reliability/config.h" #include "components/domain_reliability/google_configs.h" #include "components/domain_reliability/test_util.h" -#include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/http/http_response_headers.h" #include "net/http/http_util.h" @@ -75,7 +74,7 @@ request.response_info.was_cached = false; request.response_info.network_accessed = true; request.response_info.was_fetched_via_proxy = false; - request.load_flags = 0; + request.allow_credentials = true; request.upload_depth = 0; return request; } @@ -174,13 +173,13 @@ EXPECT_EQ(0u, CountQueuedBeacons(context)); } -// Make sure the monitor does not log requests that don't send cookies. +// Make sure the monitor does not log requests that don't send credentials. TEST_F(DomainReliabilityMonitorTest, DoNotSendCookies) { const DomainReliabilityContext* context = CreateAndAddContext(); RequestInfo request = MakeRequestInfo(); request.url = GURL("http://example/"); - request.load_flags = net::LOAD_DO_NOT_SEND_COOKIES; + request.allow_credentials = false; OnRequestLegComplete(request); EXPECT_EQ(0u, CountQueuedBeacons(context)); @@ -253,15 +252,14 @@ EXPECT_TRUE(beacons[0]->server_ip.empty()); } -// Make sure the monitor does log uploads, even though they have -// LOAD_DO_NOT_SEND_COOKIES. +// Make sure the monitor does log uploads, even when credentials are not +// allowed. TEST_F(DomainReliabilityMonitorTest, Upload) { const DomainReliabilityContext* context = CreateAndAddContext(); RequestInfo request = MakeRequestInfo(); request.url = GURL("http://example/"); - request.load_flags = - net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES; + request.allow_credentials = false; request.net_error = net::ERR_CONNECTION_RESET; request.upload_depth = 1; OnRequestLegComplete(request);
diff --git a/components/domain_reliability/uploader_unittest.cc b/components/domain_reliability/uploader_unittest.cc index 8c918c2..65c34e4b 100644 --- a/components/domain_reliability/uploader_unittest.cc +++ b/components/domain_reliability/uploader_unittest.cc
@@ -45,9 +45,8 @@ : net::URLRequestJob(request, network_delegate), upload_stream_(nullptr), result_(result) { - int load_flags = request->load_flags(); - EXPECT_TRUE(load_flags & net::LOAD_DO_NOT_SEND_COOKIES); - EXPECT_TRUE(load_flags & net::LOAD_DO_NOT_SAVE_COOKIES); + EXPECT_FALSE(request->allow_credentials()); + EXPECT_TRUE(request->load_flags() & net::LOAD_DO_NOT_SAVE_COOKIES); } protected:
diff --git a/components/media_router/common/media_source.cc b/components/media_router/common/media_source.cc index 5f3374c..2f4b560 100644 --- a/components/media_router/common/media_source.cc +++ b/components/media_router/common/media_source.cc
@@ -25,7 +25,10 @@ constexpr char kTabMediaUrnFormat[] = "urn:x-org.chromium.media:source:tab:%d"; constexpr base::StringPiece kDesktopMediaUrnPrefix = "urn:x-org.chromium.media:source:desktop:"; -constexpr base::StringPiece kUnknownDesktopMediaUrn = +// WARNING: If more desktop URN parameters are added in the future, the parsing +// code will have to be smarter! +constexpr base::StringPiece kDesktopMediaUrnAudioParam = "?with_audio=true"; +constexpr base::StringPiece kUnchosenDesktopMediaUrn = "urn:x-org.chromium.media:source:desktop"; // List of non-http(s) schemes that are allowed in a Presentation URL. @@ -98,14 +101,21 @@ } // static -MediaSource MediaSource::ForDesktop(const std::string& desktop_media_id) { - DCHECK(!desktop_media_id.empty()); - return MediaSource(kDesktopMediaUrnPrefix.as_string() + desktop_media_id); +MediaSource MediaSource::ForDesktop( + const std::string& registered_desktop_stream_id, + bool with_audio) { + DCHECK(!registered_desktop_stream_id.empty()); + std::string id = + kDesktopMediaUrnPrefix.as_string() + registered_desktop_stream_id; + if (with_audio) { + id += kDesktopMediaUrnAudioParam.as_string(); + } + return MediaSource(id); } // static -MediaSource MediaSource::ForDesktop() { - return MediaSource(kUnknownDesktopMediaUrn.as_string()); +MediaSource MediaSource::ForUnchosenDesktop() { + return MediaSource(kUnchosenDesktopMediaUrn.as_string()); } // static @@ -118,7 +128,7 @@ } bool MediaSource::IsDesktopMirroringSource() const { - return id() == kUnknownDesktopMediaUrn || + return id() == kUnchosenDesktopMediaUrn || base::StartsWith(id(), kDesktopMediaUrnPrefix, base::CompareCase::SENSITIVE); } @@ -142,11 +152,24 @@ base::Optional<std::string> MediaSource::DesktopStreamId() const { if (base::StartsWith(id_, kDesktopMediaUrnPrefix, base::CompareCase::SENSITIVE)) { - return std::string(id_.begin() + kDesktopMediaUrnPrefix.size(), id_.end()); + const auto begin = id_.begin() + kDesktopMediaUrnPrefix.size(); + auto end = id_.end(); + if (base::EndsWith(id_, kDesktopMediaUrnAudioParam, + base::CompareCase::SENSITIVE)) { + end -= kDesktopMediaUrnAudioParam.size(); + } + return std::string(begin, end); } return base::nullopt; } +bool MediaSource::IsDesktopSourceWithAudio() const { + return base::StartsWith(id_, kDesktopMediaUrnPrefix, + base::CompareCase::SENSITIVE) && + base::EndsWith(id_, kDesktopMediaUrnAudioParam, + base::CompareCase::SENSITIVE); +} + bool MediaSource::IsDialSource() const { return url_.SchemeIs(kCastDialPresentationUrlScheme); }
diff --git a/components/media_router/common/media_source.h b/components/media_router/common/media_source.h index e8af36d..61b55df8 100644 --- a/components/media_router/common/media_source.h +++ b/components/media_router/common/media_source.h
@@ -96,18 +96,17 @@ static MediaSource ForPresentationUrl(const GURL& presentation_url); // Creates a media source for a specific desktop. - static MediaSource ForDesktop(const std::string& desktop_media_id); + // |registered_desktop_stream_id| is the string returned by + // content::DesktopStreamsRegistry::RegisterStream(). + static MediaSource ForDesktop(const std::string& registered_desktop_stream_id, + bool with_audio); - // Creates a media source representing "the" desktop. When possible, prefer - // the form with an argument instead. This type of source is used to - // represent using a desktop as a media source at a point where, in the case - // of multiple desktops, the actual desktop to use cannot be determined. - // Before a route can be created using the source, the desktop picker must be - // invoked to choose a specific desktop. - // - // TODO(crbug.com/809249): See if this method can be removed after the - // extension-based Cast MRP is removed. - static MediaSource ForDesktop(); + // Creates a media source representing a yet-to-be-chosen desktop, screen or + // window. This must never be passed to a mojom::MediaRouteProvider + // implementation's CreateRoute(). This is just a placeholder for the media + // router UI until the moment the user initiates capture and picks a specific + // desktop/screen/window. + static MediaSource ForUnchosenDesktop(); // Returns true if source outputs its content via tab mirroring and isn't a // local file. @@ -128,12 +127,15 @@ // source and -1 for non-tab sources or the ForAnyTab() source. int TabId() const; - // When this source was created by ForDesktop(string), returns a stream ID - // suitable for passing to - // content::DesktopStreamsRegistry::RequestMediaForStreamId(). Otherwise + // When this source was created by ForDesktop(), returns the stream ID to pass + // to content::DesktopStreamsRegistry::RequestMediaForStreamId(). Otherwise, // returns base::nullopt. base::Optional<std::string> DesktopStreamId() const; + // Returns true if this source represents desktop capture that also provides + // audio loopback capture. Returns false otherwise. + bool IsDesktopSourceWithAudio() const; + // Returns true this source outputs its content via DIAL. // TODO(crbug.com/804419): Move this to in-browser DIAL/Cast MRP when we have // one.
diff --git a/components/media_router/common/media_source_unittest.cc b/components/media_router/common/media_source_unittest.cc index ff8b53f..f2b8cd4 100644 --- a/components/media_router/common/media_source_unittest.cc +++ b/components/media_router/common/media_source_unittest.cc
@@ -86,11 +86,28 @@ EXPECT_FALSE(source.IsDialSource()); } -TEST(MediaSourceTest, ForDesktop) { +TEST(MediaSourceTest, ForDesktopWithoutAudio) { std::string media_id = "fakeMediaId"; - auto source = MediaSource::ForDesktop(media_id); + auto source = MediaSource::ForDesktop(media_id, false); EXPECT_EQ("urn:x-org.chromium.media:source:desktop:" + media_id, source.id()); EXPECT_TRUE(source.IsDesktopMirroringSource()); + EXPECT_EQ(media_id, source.DesktopStreamId()); + EXPECT_FALSE(source.IsDesktopSourceWithAudio()); + EXPECT_FALSE(source.IsTabMirroringSource()); + EXPECT_FALSE(source.IsLocalFileSource()); + EXPECT_FALSE(source.IsCastPresentationUrl()); + EXPECT_FALSE(source.IsDialSource()); +} + +TEST(MediaSourceTest, ForDesktopWithAudio) { + std::string media_id = "fakeMediaId"; + auto source = MediaSource::ForDesktop(media_id, true); + EXPECT_EQ("urn:x-org.chromium.media:source:desktop:" + media_id + + "?with_audio=true", + source.id()); + EXPECT_TRUE(source.IsDesktopMirroringSource()); + EXPECT_EQ(media_id, source.DesktopStreamId()); + EXPECT_TRUE(source.IsDesktopSourceWithAudio()); EXPECT_FALSE(source.IsTabMirroringSource()); EXPECT_FALSE(source.IsLocalFileSource()); EXPECT_FALSE(source.IsCastPresentationUrl());
diff --git a/components/media_router/common/providers/cast/cast_media_source.cc b/components/media_router/common/providers/cast/cast_media_source.cc index 6987a56..8507205a 100644 --- a/components/media_router/common/providers/cast/cast_media_source.cc +++ b/components/media_router/common/providers/cast/cast_media_source.cc
@@ -197,11 +197,16 @@ } std::unique_ptr<CastMediaSource> CastMediaSourceForDesktopMirroring( - const MediaSource::Id& source_id) { + const MediaSource& source) { // TODO(https://crbug.com/849335): Add back audio-only devices for desktop // mirroring when proper support is implemented. - return std::make_unique<CastMediaSource>( - source_id, std::vector<CastAppInfo>({CastAppInfo::ForCastStreaming()})); + CastAppInfo info = CastAppInfo::ForCastStreaming(); + if (info.required_capabilities.Has(CastDeviceCapability::AUDIO_OUT) && + !source.IsDesktopSourceWithAudio()) { + info.required_capabilities.Remove(CastDeviceCapability::AUDIO_OUT); + } + return std::make_unique<CastMediaSource>(source.id(), + std::vector<CastAppInfo>({info})); } // The logic shared by ParseCastUrl() and ParseLegacyCastUrl(). @@ -249,7 +254,7 @@ } if (audio_capture_str == "0") - cast_source->set_allow_audio_capture(false); + cast_source->set_site_requested_audio_capture(false); if (!supported_app_types.empty()) cast_source->set_supported_app_types(supported_app_types); @@ -393,7 +398,7 @@ return CastMediaSourceForTabMirroring(source.id()); if (source.IsDesktopMirroringSource()) - return CastMediaSourceForDesktopMirroring(source.id()); + return CastMediaSourceForDesktopMirroring(source); const GURL& url = source.url(); @@ -462,6 +467,20 @@ return app_ids; } +bool CastMediaSource::ProvidesStreamingAudioCapture() const { + if (!site_requested_audio_capture_) { + return false; + } + for (const auto& info : app_infos_) { + if ((info.app_id == kCastStreamingAppId || + info.app_id == kCastStreamingAudioAppId) && + info.required_capabilities.Has(CastDeviceCapability::AUDIO_OUT)) { + return true; + } + } + return false; +} + void CastMediaSource::set_supported_app_types( const std::vector<ReceiverAppType>& types) { DCHECK(!types.empty());
diff --git a/components/media_router/common/providers/cast/cast_media_source.h b/components/media_router/common/providers/cast/cast_media_source.h index cd34d24..84e6e80d 100644 --- a/components/media_router/common/providers/cast/cast_media_source.h +++ b/components/media_router/common/providers/cast/cast_media_source.h
@@ -55,6 +55,7 @@ bool empty() const { return bits_ == 0; } T bits() const { return bits_; } void Add(E value) { bits_ |= Mask(value); } + void Remove(E value) { bits_ &= ~Mask(value); } bool Has(E value) const { return (bits_ & Mask(value)) != 0; } bool HasAll(const BitwiseOr& other) const { return (bits_ & other.bits_) == other.bits_; @@ -168,6 +169,11 @@ // Returns a list of App IDs in this CastMediaSource. std::vector<std::string> GetAppIds() const; + // Returns true iff all of the following are true: this source is a streaming + // source, the site requested audio capture, and the application is capable of + // providing audio capture (and has the user's permission to do so). + bool ProvidesStreamingAudioCapture() const; + const MediaSource::Id& source_id() const { return source_id_; } const std::vector<CastAppInfo>& app_infos() const { return app_infos_; } const std::string& client_id() const { return client_id_; } @@ -194,9 +200,12 @@ const base::Optional<base::TimeDelta>& target_playout_delay) { target_playout_delay_ = target_playout_delay; } - bool allow_audio_capture() const { return allow_audio_capture_; } - void set_allow_audio_capture(bool allow_audio_capture) { - allow_audio_capture_ = allow_audio_capture; + // See also: ProvidesStreamingAudioCapture(). + bool site_requested_audio_capture() const { + return site_requested_audio_capture_; + } + void set_site_requested_audio_capture(bool is_requested) { + site_requested_audio_capture_ = is_requested; } const std::string& app_params() const { return app_params_; } void set_app_params(const std::string& app_params) { @@ -217,7 +226,7 @@ std::string client_id_; base::Optional<cast_channel::BroadcastRequest> broadcast_request_; base::Optional<base::TimeDelta> target_playout_delay_; - bool allow_audio_capture_ = true; + bool site_requested_audio_capture_ = true; std::vector<ReceiverAppType> supported_app_types_ = {ReceiverAppType::kWeb}; std::string app_params_; };
diff --git a/components/media_router/common/providers/cast/cast_media_source_unittest.cc b/components/media_router/common/providers/cast/cast_media_source_unittest.cc index 24cbabc3..5c88d24 100644 --- a/components/media_router/common/providers/cast/cast_media_source_unittest.cc +++ b/components/media_router/common/providers/cast/cast_media_source_unittest.cc
@@ -31,7 +31,7 @@ source->default_action_policy()); EXPECT_EQ(ReceiverAppType::kWeb, source->supported_app_types()[0]); EXPECT_EQ(base::nullopt, source->target_playout_delay()); - EXPECT_EQ(true, source->allow_audio_capture()); + EXPECT_EQ(true, source->site_requested_audio_capture()); } TEST(CastMediaSourceTest, FromCastURL) { @@ -70,7 +70,7 @@ EXPECT_EQ("appParams", source->app_params()); EXPECT_EQ(base::TimeDelta::FromMilliseconds(42), source->target_playout_delay()); - EXPECT_EQ(false, source->allow_audio_capture()); + EXPECT_EQ(false, source->site_requested_audio_capture()); } TEST(CastMediaSourceTest, FromLegacyCastURL) {
diff --git a/components/mirroring/browser/single_client_video_capture_host.cc b/components/mirroring/browser/single_client_video_capture_host.cc index 9ef7096..9aab72b2 100644 --- a/components/mirroring/browser/single_client_video_capture_host.cc +++ b/components/mirroring/browser/single_client_video_capture_host.cc
@@ -113,9 +113,7 @@ for (const auto& entry : buffer_context_map_) buffers_in_use.push_back(entry.first); for (int buffer_id : buffers_in_use) { - OnFinishedConsumingBuffer( - buffer_id, - media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded); + OnFinishedConsumingBuffer(buffer_id, media::VideoFrameFeedback()); } DCHECK(buffer_context_map_.empty()); observer_->OnStateChanged(media::mojom::VideoCaptureState::ENDED); @@ -152,11 +150,11 @@ void SingleClientVideoCaptureHost::ReleaseBuffer( const base::UnguessableToken& device_id, int32_t buffer_id, - double consumer_resource_utilization) { + const media::VideoFrameFeedback& feedback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DVLOG(3) << __func__ << ": buffer_id=" << buffer_id; - OnFinishedConsumingBuffer(buffer_id, consumer_resource_utilization); + OnFinishedConsumingBuffer(buffer_id, feedback); } void SingleClientVideoCaptureHost::GetDeviceSupportedFormats( @@ -297,7 +295,7 @@ void SingleClientVideoCaptureHost::OnFinishedConsumingBuffer( int buffer_context_id, - double consumer_resource_utilization) { + const media::VideoFrameFeedback& feedback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(observer_); const auto buffer_context_iter = buffer_context_map_.find(buffer_context_id); @@ -308,11 +306,9 @@ } VideoFrameConsumerFeedbackObserver* feedback_observer = launched_device_.get(); - if (feedback_observer && - consumer_resource_utilization != - VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded) { + if (feedback_observer && !feedback.Empty()) { feedback_observer->OnUtilizationReport(buffer_context_iter->second.first, - consumer_resource_utilization); + feedback); } buffer_context_map_.erase(buffer_context_iter); const auto retired_iter = retired_buffers_.find(buffer_context_id);
diff --git a/components/mirroring/browser/single_client_video_capture_host.h b/components/mirroring/browser/single_client_video_capture_host.h index 7a212a5..27adfa05 100644 --- a/components/mirroring/browser/single_client_video_capture_host.h +++ b/components/mirroring/browser/single_client_video_capture_host.h
@@ -59,7 +59,7 @@ void RequestRefreshFrame(const base::UnguessableToken& device_id) override; void ReleaseBuffer(const base::UnguessableToken& device_id, int32_t buffer_id, - double consumer_resource_utilization) override; + const media::VideoFrameFeedback& feedback) override; void GetDeviceSupportedFormats( const base::UnguessableToken& device_id, const base::UnguessableToken& session_id, @@ -99,7 +99,7 @@ private: // Reports the |consumer_resource_utilization| and removes the buffer context. void OnFinishedConsumingBuffer(int buffer_context_id, - double consumer_resource_utilization); + const media::VideoFrameFeedback& feedback); const std::string device_id_; const blink::mojom::MediaStreamType type_;
diff --git a/components/mirroring/browser/single_client_video_capture_host_unittest.cc b/components/mirroring/browser/single_client_video_capture_host_unittest.cc index a370fbd..fd92e62 100644 --- a/components/mirroring/browser/single_client_video_capture_host_unittest.cc +++ b/components/mirroring/browser/single_client_video_capture_host_unittest.cc
@@ -38,7 +38,7 @@ MOCK_METHOD0(MaybeSuspendDevice, void()); MOCK_METHOD0(ResumeDevice, void()); MOCK_METHOD0(RequestRefreshFrame, void()); - MOCK_METHOD2(OnUtilizationReport, void(int, double)); + MOCK_METHOD2(OnUtilizationReport, void(int, media::VideoFrameFeedback)); private: DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureDevice); @@ -138,12 +138,13 @@ receiver_.BindNewPipeAndPassRemote()); } - void FinishConsumingBuffer(int32_t buffer_id, double utilization) { + void FinishConsumingBuffer(int32_t buffer_id, + media::VideoFrameFeedback feedback) { EXPECT_TRUE(buffers_.find(buffer_id) != buffers_.end()); const auto iter = frame_infos_.find(buffer_id); EXPECT_TRUE(iter != frame_infos_.end()); frame_infos_.erase(iter); - host_->ReleaseBuffer(device_id_, buffer_id, utilization); + host_->ReleaseBuffer(device_id_, buffer_id, feedback); } void Stop() { host_->Stop(device_id_); } @@ -227,12 +228,11 @@ void FinishConsumingBuffer(int buffer_context_id, int feedback_id, - double utilization) { + const media::VideoFrameFeedback& feedback) { base::RunLoop run_loop; - EXPECT_CALL(*launched_device_, - OnUtilizationReport(feedback_id, utilization)) + EXPECT_CALL(*launched_device_, OnUtilizationReport(feedback_id, feedback)) .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); - consumer_->FinishConsumingBuffer(buffer_context_id, utilization); + consumer_->FinishConsumingBuffer(buffer_context_id, feedback); run_loop.Run(); } @@ -270,7 +270,10 @@ TEST_F(SingleClientVideoCaptureHostTest, Basic) { CreateBuffer(1, 0); FrameReadyInBuffer(1, 0, 5); - FinishConsumingBuffer(0, 5, 1.0); + FinishConsumingBuffer( + 0, 5, + media::VideoFrameFeedback(1.0, std::numeric_limits<float>::infinity(), + base::nullopt)); RetireBuffer(1, 0); } @@ -290,7 +293,10 @@ FrameReadyInBuffer(0, 1, 7); // Finish consuming frame in the retired buffer 0. - FinishConsumingBuffer(0, 3, 1.0); + FinishConsumingBuffer( + 0, 3, + media::VideoFrameFeedback(1.0, std::numeric_limits<float>::infinity(), + base::nullopt)); // The retired buffer is expected to be destroyed since the consumer finished // consuming the frame in that buffer. base::RunLoop run_loop; @@ -298,7 +304,10 @@ .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); run_loop.Run(); - FinishConsumingBuffer(1, 7, 0.5); + FinishConsumingBuffer( + 1, 7, + media::VideoFrameFeedback(0.5, std::numeric_limits<float>::infinity(), + base::nullopt)); RetireBuffer(0, 1); }
diff --git a/components/mirroring/service/fake_video_capture_host.h b/components/mirroring/service/fake_video_capture_host.h index 1f533f7..bcbd14c 100644 --- a/components/mirroring/service/fake_video_capture_host.h +++ b/components/mirroring/service/fake_video_capture_host.h
@@ -25,7 +25,9 @@ // mojom::VideoCaptureHost implementations MOCK_METHOD1(RequestRefreshFrame, void(const base::UnguessableToken&)); MOCK_METHOD3(ReleaseBuffer, - void(const base::UnguessableToken&, int32_t, double)); + void(const base::UnguessableToken&, + int32_t, + const media::VideoFrameFeedback&)); MOCK_METHOD1(Pause, void(const base::UnguessableToken&)); MOCK_METHOD3(Resume, void(const base::UnguessableToken&,
diff --git a/components/mirroring/service/message_dispatcher.cc b/components/mirroring/service/message_dispatcher.cc index 849a9d65..da5de2c0 100644 --- a/components/mirroring/service/message_dispatcher.cc +++ b/components/mirroring/service/message_dispatcher.cc
@@ -69,6 +69,10 @@ } void MessageDispatcher::Send(mojom::CastMessagePtr message) { + // TODO(crbug.com/1117673): Add MR-internals logging: + // VLOG(2) << "Inbound message received: ns=" << message->message_namespace + // << ", data=" << message->json_format_data; + if (message->message_namespace != mojom::kWebRtcNamespace && message->message_namespace != mojom::kRemotingNamespace) { DVLOG(2) << "Ignoring message with unknown namespace = " @@ -126,6 +130,9 @@ } void MessageDispatcher::SendOutboundMessage(mojom::CastMessagePtr message) { + // TODO(crbug.com/1117673): Add MR-internals logging: + // VLOG(2) << "Sending outbound message: ns=" << message->message_namespace + // << ", data=" << message->json_format_data; outbound_channel_->Send(std::move(message)); }
diff --git a/components/mirroring/service/session.cc b/components/mirroring/service/session.cc index e312ef9..8de6bc2 100644 --- a/components/mirroring/service/session.cc +++ b/components/mirroring/service/session.cc
@@ -812,7 +812,8 @@ } void Session::OnResponseParsingError(const std::string& error_message) { - // TODO(crbug.com/1015467): Log the |error_message| in the mirroring logs. + // TODO(crbug.com/1117673): Add MR-internals logging: + // VLOG(2) << "[REJECT] " << error_message; } void Session::CreateAudioStream(
diff --git a/components/mirroring/service/video_capture_client.cc b/components/mirroring/service/video_capture_client.cc index 7385839..01d1e96 100644 --- a/components/mirroring/service/video_capture_client.cc +++ b/components/mirroring/service/video_capture_client.cc
@@ -144,7 +144,8 @@ << VideoPixelFormatToString(info->pixel_format); } if (!consume_buffer) { - video_capture_host_->ReleaseBuffer(DeviceId(), buffer_id, -1.0); + video_capture_host_->ReleaseBuffer(DeviceId(), buffer_id, + media::VideoFrameFeedback()); return; } @@ -189,7 +190,8 @@ mojo::ScopedSharedBufferMapping mapping = buffer_iter->second->get_shared_buffer_handle()->Map(buffer_size); if (!mapping) { - video_capture_host_->ReleaseBuffer(DeviceId(), buffer_id, -1.0); + video_capture_host_->ReleaseBuffer(DeviceId(), buffer_id, + media::VideoFrameFeedback()); return; } mapping_iter = @@ -226,13 +228,14 @@ if (!frame) { LOG(DFATAL) << "Unable to wrap shared memory mapping."; - video_capture_host_->ReleaseBuffer(DeviceId(), buffer_id, -1.0); + video_capture_host_->ReleaseBuffer(DeviceId(), buffer_id, + media::VideoFrameFeedback()); OnStateChanged(media::mojom::VideoCaptureState::FAILED); return; } frame->AddDestructionObserver( base::BindOnce(&VideoCaptureClient::DidFinishConsumingFrame, - frame->metadata(), std::move(buffer_finished_callback))); + frame->feedback(), std::move(buffer_finished_callback))); frame->set_metadata(info->metadata); if (info->color_space.has_value()) @@ -256,7 +259,7 @@ void VideoCaptureClient::OnClientBufferFinished( int buffer_id, base::ReadOnlySharedMemoryMapping mapping, - double consumer_resource_utilization) { + media::VideoFrameFeedback feedback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DVLOG(3) << __func__ << ": buffer_id=" << buffer_id; @@ -266,18 +269,17 @@ return; } - video_capture_host_->ReleaseBuffer(DeviceId(), buffer_id, - consumer_resource_utilization); + video_capture_host_->ReleaseBuffer(DeviceId(), buffer_id, feedback); } // static void VideoCaptureClient::DidFinishConsumingFrame( - const media::VideoFrameMetadata* metadata, + const media::VideoFrameFeedback* feedback, BufferFinishedCallback callback) { // Note: This function may be called on any thread by the VideoFrame - // destructor. |metadata| is still valid for read-access at this point. + // destructor. |feedback| is still valid for read-access at this point. DCHECK(!callback.is_null()); - std::move(callback).Run(metadata->resource_utilization.value_or(-1.0)); + std::move(callback).Run(*feedback); } } // namespace mirroring
diff --git a/components/mirroring/service/video_capture_client.h b/components/mirroring/service/video_capture_client.h index 6a7a734..35d0bc3 100644 --- a/components/mirroring/service/video_capture_client.h +++ b/components/mirroring/service/video_capture_client.h
@@ -20,7 +20,7 @@ namespace media { class VideoFrame; -struct VideoFrameMetadata; +struct VideoFrameFeedback; } // namespace media namespace mirroring { @@ -62,15 +62,15 @@ private: using BufferFinishedCallback = - base::OnceCallback<void(double consumer_resource_utilization)>; + base::OnceCallback<void(media::VideoFrameFeedback)>; // Called by the VideoFrame destructor. - static void DidFinishConsumingFrame(const media::VideoFrameMetadata* metadata, + static void DidFinishConsumingFrame(const media::VideoFrameFeedback* feedback, BufferFinishedCallback callback); // Reports the utilization, unmaps the shared memory, and returns the buffer. void OnClientBufferFinished(int buffer_id, base::ReadOnlySharedMemoryMapping mapping, - double consumer_resource_utilization); + media::VideoFrameFeedback feedback); const media::VideoCaptureParams params_; const mojo::Remote<media::mojom::VideoCaptureHost> video_capture_host_;
diff --git a/components/mirroring/service/video_capture_client_unittest.cc b/components/mirroring/service/video_capture_client_unittest.cc index 2d02465..888dd40 100644 --- a/components/mirroring/service/video_capture_client_unittest.cc +++ b/components/mirroring/service/video_capture_client_unittest.cc
@@ -24,7 +24,7 @@ namespace { -constexpr double kUtilization = 0.6; +const media::VideoFrameFeedback kFeedback(0.6, 30.0, 1000); media::mojom::VideoFrameInfoPtr GetVideoFrameInfo(const gfx::Size& size) { media::VideoFrameMetadata metadata; @@ -61,7 +61,7 @@ MOCK_METHOD1(OnFrameReceived, void(const gfx::Size&)); void OnFrameReady(scoped_refptr<media::VideoFrame> video_frame) { - video_frame->metadata()->resource_utilization = kUtilization; + *video_frame->feedback() = kFeedback; OnFrameReceived(video_frame->coded_size()); } @@ -101,7 +101,7 @@ // Expects to receive one frame. EXPECT_CALL(*this, OnFrameReceived(frame_size)).Times(1); // Expects to return the buffer after the frame is consumed. - EXPECT_CALL(*host_impl_, ReleaseBuffer(_, 0, kUtilization)) + EXPECT_CALL(*host_impl_, ReleaseBuffer(_, 0, kFeedback)) .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); client_->OnBufferReady(buffer_id, GetVideoFrameInfo(frame_size)); run_loop.Run();
diff --git a/components/printing/browser/print_manager.cc b/components/printing/browser/print_manager.cc index 9e73c760..3c8242c6 100644 --- a/components/printing/browser/print_manager.cc +++ b/components/printing/browser/print_manager.cc
@@ -115,6 +115,8 @@ cookie_ = cookie; } +void PrintManager::DidShowPrintDialog() {} + void PrintManager::OnPrintingFailed(int cookie) { if (cookie != cookie_) { NOTREACHED();
diff --git a/components/printing/browser/print_manager.h b/components/printing/browser/print_manager.h index 1ad7f56..9d0d6a0d 100644 --- a/components/printing/browser/print_manager.h +++ b/components/printing/browser/print_manager.h
@@ -42,6 +42,7 @@ // printing::mojom::PrintManager: void DidGetPrintedPagesCount(int32_t cookie, int32_t number_pages) override; void DidGetDocumentCookie(int32_t cookie) override; + void DidShowPrintDialog() override; protected: explicit PrintManager(content::WebContents* contents); @@ -104,6 +105,9 @@ int number_pages_ = 0; // Number of pages to print in the print job. int cookie_ = 0; // The current document cookie. + // Holds WebContents associated mojo receivers. + content::WebContentsFrameReceiverSet<printing::mojom::PrintManagerHost> + print_manager_host_receivers_; #if defined(OS_ANDROID) // Callback to execute when done writing pdf. @@ -117,9 +121,6 @@ std::map<content::RenderFrameHost*, mojo::AssociatedRemote<printing::mojom::PrintRenderFrame>> print_render_frames_; - - content::WebContentsFrameReceiverSet<printing::mojom::PrintManagerHost> - print_manager_host_receivers_; }; } // namespace printing
diff --git a/components/printing/common/print.mojom b/components/printing/common/print.mojom index c5f86c7..177a590 100644 --- a/components/printing/common/print.mojom +++ b/components/printing/common/print.mojom
@@ -261,4 +261,7 @@ // Sends the document cookie of the current printer query to the browser. DidGetDocumentCookie(int32 cookie); + + // Tells the browser that the print dialog has been shown. + DidShowPrintDialog(); };
diff --git a/components/printing/common/print_messages.h b/components/printing/common/print_messages.h index bdbe494..cf04464 100644 --- a/components/printing/common/print_messages.h +++ b/components/printing/common/print_messages.h
@@ -289,9 +289,6 @@ // Messages sent from the renderer to the browser. -// Tells the browser that the print dialog has been shown. -IPC_MESSAGE_ROUTED0(PrintHostMsg_DidShowPrintDialog) - // Sends back to the browser the rendered document that was requested by a // PrintMsg_PrintPages message or from scripted printing. The memory handle in // this message is already valid in the browser process. Waits until the
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc index e17d88e0..a33f555 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -2270,7 +2270,7 @@ params.is_scripted = is_scripted; params.is_modifiable = !IsPrintingNodeOrPdfFrame(frame, node); - Send(new PrintHostMsg_DidShowPrintDialog(routing_id())); + GetPrintManagerHost()->DidShowPrintDialog(); print_pages_params_.reset();
diff --git a/components/printing/test/print_render_frame_helper_browsertest.cc b/components/printing/test/print_render_frame_helper_browsertest.cc index cc24c736a..4b54fa6e 100644 --- a/components/printing/test/print_render_frame_helper_browsertest.cc +++ b/components/printing/test/print_render_frame_helper_browsertest.cc
@@ -229,6 +229,7 @@ printer_->SetPrintedPagesCount(cookie, number_pages); } void DidGetDocumentCookie(int32_t cookie) override {} + void DidShowPrintDialog() override {} void SetExpectedPagesCount(int32_t number_pages) { number_pages_ = number_pages;
diff --git a/components/safe_browsing/core/db/v4_protocol_manager_util.cc b/components/safe_browsing/core/db/v4_protocol_manager_util.cc index 0870dbbc..c4689db1 100644 --- a/components/safe_browsing/core/db/v4_protocol_manager_util.cc +++ b/components/safe_browsing/core/db/v4_protocol_manager_util.cc
@@ -116,7 +116,7 @@ PlatformType GetCurrentPlatformType() { #if defined(OS_WIN) return WINDOWS_PLATFORM; -#elif defined(OS_LINUX) +#elif defined(OS_LINUX) || defined(OS_CHROMEOS) return LINUX_PLATFORM; #elif defined(OS_IOS) return IOS_PLATFORM;
diff --git a/components/services/storage/public/cpp/filesystem/filesystem_impl.cc b/components/services/storage/public/cpp/filesystem/filesystem_impl.cc index 989b11b..ad6230d 100644 --- a/components/services/storage/public/cpp/filesystem/filesystem_impl.cc +++ b/components/services/storage/public/cpp/filesystem/filesystem_impl.cc
@@ -11,6 +11,7 @@ #include "base/files/file.h" #include "base/files/file_enumerator.h" #include "base/files/file_util.h" +#include "base/files/important_file_writer.h" #include "base/no_destructor.h" #include "base/notreached.h" #include "base/stl_util.h" @@ -193,6 +194,13 @@ std::move(callback).Run(error, std::move(file)); } +void FilesystemImpl::WriteFileAtomically(const base::FilePath& path, + const std::string& contents, + WriteFileAtomicallyCallback callback) { + std::move(callback).Run(base::ImportantFileWriter::WriteFileAtomically( + MakeAbsolute(path), std::move(contents))); +} + void FilesystemImpl::RemoveFile(const base::FilePath& path, RemoveFileCallback callback) { std::move(callback).Run(base::DeleteFile(MakeAbsolute(path))); @@ -207,13 +215,13 @@ void FilesystemImpl::RemoveDirectory(const base::FilePath& path, RemoveDirectoryCallback callback) { - const base::FilePath full_path = MakeAbsolute(path); - if (!base::DirectoryExists(full_path)) { - std::move(callback).Run(false); - return; - } + std::move(callback).Run(base::DeleteFile(MakeAbsolute(path))); +} - std::move(callback).Run(base::DeleteFile(full_path)); +void FilesystemImpl::RemoveDirectoryRecursively( + const base::FilePath& path, + RemoveDirectoryRecursivelyCallback callback) { + std::move(callback).Run(base::DeletePathRecursively(MakeAbsolute(path))); } void FilesystemImpl::GetFileInfo(const base::FilePath& path, @@ -230,6 +238,14 @@ std::move(callback).Run(GetPathAccessLocal(MakeAbsolute(path))); } +void FilesystemImpl::GetMaximumPathComponentLength( + const base::FilePath& path, + GetMaximumPathComponentLengthCallback callback) { + int len = base::GetMaximumPathComponentLength(MakeAbsolute(path)); + bool success = len != -1; + return std::move(callback).Run(success, len); +} + void FilesystemImpl::RenameFile(const base::FilePath& old_path, const base::FilePath& new_path, RenameFileCallback callback) {
diff --git a/components/services/storage/public/cpp/filesystem/filesystem_impl.h b/components/services/storage/public/cpp/filesystem/filesystem_impl.h index 281a245..3b7e07b 100644 --- a/components/services/storage/public/cpp/filesystem/filesystem_impl.h +++ b/components/services/storage/public/cpp/filesystem/filesystem_impl.h
@@ -50,16 +50,25 @@ mojom::FileReadAccess read_access, mojom::FileWriteAccess write_access, OpenFileCallback callback) override; + void WriteFileAtomically(const base::FilePath& path, + const std::string& contents, + WriteFileAtomicallyCallback callback) override; void RemoveFile(const base::FilePath& path, RemoveFileCallback callback) override; void CreateDirectory(const base::FilePath& path, CreateDirectoryCallback callback) override; void RemoveDirectory(const base::FilePath& path, RemoveDirectoryCallback callback) override; + void RemoveDirectoryRecursively( + const base::FilePath& path, + RemoveDirectoryRecursivelyCallback callback) override; void GetFileInfo(const base::FilePath& path, GetFileInfoCallback callback) override; void GetPathAccess(const base::FilePath& path, GetPathAccessCallback callback) override; + void GetMaximumPathComponentLength( + const base::FilePath& path, + GetMaximumPathComponentLengthCallback callback) override; void RenameFile(const base::FilePath& old_path, const base::FilePath& new_path, RenameFileCallback callback) override;
diff --git a/components/services/storage/public/cpp/filesystem/filesystem_proxy.cc b/components/services/storage/public/cpp/filesystem/filesystem_proxy.cc index e5c575a..94b89bc 100644 --- a/components/services/storage/public/cpp/filesystem/filesystem_proxy.cc +++ b/components/services/storage/public/cpp/filesystem/filesystem_proxy.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/files/file.h" #include "base/files/file_util.h" +#include "base/files/important_file_writer.h" #include "base/task/post_task.h" #include "base/util/type_safety/pass_key.h" #include "build/build_config.h" @@ -200,6 +201,19 @@ return file; } +bool FilesystemProxy::WriteFileAtomically(const base::FilePath& path, + const std::string& contents) { + if (!remote_directory_) { + return base::ImportantFileWriter::WriteFileAtomically( + MaybeMakeAbsolute(path), contents); + } + + bool success = false; + remote_directory_->WriteFileAtomically(MakeRelative(path), contents, + &success); + return success; +} + bool FilesystemProxy::RemoveFile(const base::FilePath& path) { if (!remote_directory_) return base::DeleteFile(MaybeMakeAbsolute(path)); @@ -224,8 +238,6 @@ bool FilesystemProxy::RemoveDirectory(const base::FilePath& path) { if (!remote_directory_) { const base::FilePath full_path = MaybeMakeAbsolute(path); - if (!base::DirectoryExists(full_path)) - return false; return base::DeleteFile(full_path); } @@ -234,6 +246,17 @@ return success; } +bool FilesystemProxy::RemoveDirectoryRecursively(const base::FilePath& path) { + if (!remote_directory_) { + const base::FilePath full_path = MaybeMakeAbsolute(path); + return base::DeletePathRecursively(full_path); + } + + bool success = false; + remote_directory_->RemoveDirectoryRecursively(MakeRelative(path), &success); + return success; +} + base::Optional<base::File::Info> FilesystemProxy::GetFileInfo( const base::FilePath& path) { if (!remote_directory_) { @@ -262,6 +285,20 @@ return PathAccessInfo{info->can_read, info->can_write}; } +base::Optional<int> FilesystemProxy::GetMaximumPathComponentLength( + const base::FilePath& path) { + if (!remote_directory_) + return base::GetMaximumPathComponentLength(MaybeMakeAbsolute(path)); + + int len = -1; + bool success = false; + remote_directory_->GetMaximumPathComponentLength(MakeRelative(path), &success, + &len); + if (!success) + return base::nullopt; + return len; +} + base::File::Error FilesystemProxy::RenameFile(const base::FilePath& old_path, const base::FilePath& new_path) { base::File::Error error = base::File::FILE_ERROR_IO; @@ -312,6 +349,33 @@ return success; } +// TODO(enne): this could be a lot of sync ipcs. Should this be implemented +// as a Directory API instead? +int64_t FilesystemProxy::ComputeDirectorySize(const base::FilePath& path) { + if (!remote_directory_) + return base::ComputeDirectorySize(MaybeMakeAbsolute(path)); + + int64_t running_size = 0; + + const mojom::GetEntriesMode mode = mojom::GetEntriesMode::kFilesOnly; + base::File::Error error = base::File::FILE_ERROR_IO; + std::vector<base::FilePath> entries; + base::FilePath relative_path = MakeRelative(path); + remote_directory_->GetEntries(relative_path, mode, &error, &entries); + if (error != base::File::FILE_OK) + return running_size; + + for (auto& entry : entries) { + base::Optional<base::File::Info> info; + base::FilePath path = entry; + remote_directory_->GetFileInfo(relative_path.Append(entry), &info); + if (info.has_value()) + running_size += info->size; + } + + return running_size; +} + base::FilePath FilesystemProxy::MakeRelative(const base::FilePath& path) const { DCHECK(remote_directory_); DCHECK(!path.ReferencesParent());
diff --git a/components/services/storage/public/cpp/filesystem/filesystem_proxy.h b/components/services/storage/public/cpp/filesystem/filesystem_proxy.h index 8a41e54..a667fa86 100644 --- a/components/services/storage/public/cpp/filesystem/filesystem_proxy.h +++ b/components/services/storage/public/cpp/filesystem/filesystem_proxy.h
@@ -88,6 +88,10 @@ // base::File::Flags values. FileErrorOr<base::File> OpenFile(const base::FilePath& path, int flags); + // Writes a file atomically using the ImportantFileWriter. + bool WriteFileAtomically(const base::FilePath& path, + const std::string& contents); + // Deletes the file at |path| if it exists and returns true iff successful. bool RemoveFile(const base::FilePath& path); @@ -96,9 +100,14 @@ base::File::Error CreateDirectory(const base::FilePath& path); // Deletes the directory at |path| if it exists and returns true iff - // successful. + // successful. Not recursive. Will fail if there are subdirectories. + // This will return true if |path| does not exist. bool RemoveDirectory(const base::FilePath& path); + // Recursively deletes the directory at |path| if it exists and returns true + // iff successful. This will return true if |path| does not exist. + bool RemoveDirectoryRecursively(const base::FilePath& path); + // Retrieves information about a file or directory at |path|. Returns a valid // base::File::Info value on success, or null on failure. base::Optional<base::File::Info> GetFileInfo(const base::FilePath& path); @@ -111,6 +120,10 @@ }; base::Optional<PathAccessInfo> GetPathAccess(const base::FilePath& path); + // Returns the maximum length of path component on the volume containing the + // directory |path|, in the number of FilePath::CharType, or -1 on failure. + base::Optional<int> GetMaximumPathComponentLength(const base::FilePath& path); + // Renames a file from |old_path| to |new_path|. Must be atomic. base::File::Error RenameFile(const base::FilePath& old_path, const base::FilePath& new_path); @@ -133,6 +146,10 @@ // Sets the length of the given file to |length| bytes. bool SetOpenedFileLength(base::File* file, uint64_t length); + // Returns the total number of bytes used by all the files under |path|. + // If the path does not exist the function returns 0. + int64_t ComputeDirectorySize(const base::FilePath& path); + private: // For restricted FilesystemProxy instances, this returns a FilePath // equivalent to |path| which is strictly relative to |root_|. It is an error
diff --git a/components/services/storage/public/cpp/filesystem/filesystem_proxy_unittest.cc b/components/services/storage/public/cpp/filesystem/filesystem_proxy_unittest.cc index 0c88014e..56ef3de 100644 --- a/components/services/storage/public/cpp/filesystem/filesystem_proxy_unittest.cc +++ b/components/services/storage/public/cpp/filesystem/filesystem_proxy_unittest.cc
@@ -28,6 +28,9 @@ namespace { constexpr char kFile1Contents[] = "Hello, world!"; +constexpr char kFile2Contents[] = "Goodbye, cruel world!"; +constexpr char kDir1File1Contents[] = "asdf"; +constexpr char kDir1File2Contents[] = "qwerty"; using ::testing::UnorderedElementsAre; @@ -62,10 +65,14 @@ CHECK(base::CreateDirectory(root.Append(kDir2))); CHECK(base::WriteFile(root.Append(kFile1), kFile1Contents, base::size(kFile1Contents) - 1)); - CHECK(base::WriteFile(root.Append(kFile2), " ", 1)); - CHECK(base::WriteFile(root.Append(kDir1).Append(kDir1File1), " ", 1)); - CHECK(base::WriteFile(root.Append(kDir1).Append(kDir1File2), " ", 1)); - CHECK(base::WriteFile(root.Append(kDir2).Append(kDir1File2), " ", 1)); + CHECK(base::WriteFile(root.Append(kFile2), kFile2Contents, + base::size(kFile2Contents) - 1)); + CHECK(base::WriteFile(root.Append(kDir1).Append(kDir1File1), + kDir1File1Contents, + base::size(kDir1File1Contents) - 1)); + CHECK(base::WriteFile(root.Append(kDir1).Append(kDir1File2), + kDir1File2Contents, + base::size(kDir1File2Contents) - 1)); if (UseRestrictedFilesystem()) { // Run a remote FilesystemImpl on a background thread to exercise @@ -323,9 +330,38 @@ TEST_P(FilesystemProxyTest, CreateAndRemoveDirectory) { const base::FilePath kNewDirectoryName{FILE_PATH_LITERAL("new_dir")}; - EXPECT_EQ(base::File::FILE_OK, proxy().CreateDirectory(kNewDirectoryName)); + EXPECT_TRUE(proxy().RemoveDirectory(kNewDirectoryName)); - EXPECT_FALSE(proxy().RemoveDirectory(kNewDirectoryName)); + + EXPECT_EQ(base::File::FILE_OK, proxy().CreateDirectory(kNewDirectoryName)); + EXPECT_TRUE(proxy().PathExists(kNewDirectoryName)); + + EXPECT_TRUE(proxy().RemoveDirectory(kNewDirectoryName)); + + EXPECT_FALSE(proxy().PathExists(kNewDirectoryName)); + EXPECT_TRUE(proxy().RemoveDirectory(kNewDirectoryName)); +} + +TEST_P(FilesystemProxyTest, RemoveDirectoryFailsOnSubDirectory) { + // kDir1 has a subdirectory kDir1Dir1, which RemoveDirectory can't remove. + EXPECT_TRUE(proxy().PathExists(kDir1)); + EXPECT_FALSE(proxy().RemoveDirectory(kDir1)); + EXPECT_TRUE(proxy().PathExists(kDir1)); +} + +TEST_P(FilesystemProxyTest, RemoveDirectoryRecursively) { + EXPECT_TRUE(proxy().PathExists(kDir1)); + EXPECT_TRUE(proxy().RemoveDirectoryRecursively(kDir1)); + EXPECT_FALSE(proxy().PathExists(kDir1)); + EXPECT_TRUE(proxy().RemoveDirectoryRecursively(kDir1)); +} + +TEST_P(FilesystemProxyTest, GetMaximumPathComponentLength) { + // This has different values on different platforms, so merely smoke test + // this to make sure it returns a reasonable valid value. + base::Optional<int> max = proxy().GetMaximumPathComponentLength(kDir1); + ASSERT_TRUE(max.has_value()); + EXPECT_GT(*max, 50); } TEST_P(FilesystemProxyTest, GetFileInfo) { @@ -342,7 +378,8 @@ proxy().GetFileInfo(kDir1.Append(kDir1File1)); ASSERT_TRUE(dir1_file1_info.has_value()); EXPECT_FALSE(dir1_file1_info->is_directory); - EXPECT_EQ(1, dir1_file1_info->size); + EXPECT_EQ(static_cast<int>(base::size(kDir1File1Contents) - 1), + dir1_file1_info->size); const base::FilePath kBadFilename{FILE_PATH_LITERAL("bad_file")}; EXPECT_FALSE(proxy().GetFileInfo(kBadFilename).has_value()); @@ -402,6 +439,13 @@ EXPECT_NE(nullptr, result.value()); } +TEST_P(FilesystemProxyTest, ComputeDirectorySize) { + // The file size does not include the null terminator, so subtract 1 per file. + int64_t expected_size = + base::size(kDir1File1Contents) + base::size(kDir1File2Contents) - 2; + EXPECT_EQ(proxy().ComputeDirectorySize(kDir1), expected_size); +} + TEST_P(FilesystemProxyTest, AbsolutePathEqualToRoot) { // Verifies that if a delegate is given an absolute path identical to its // root path, it is correctly resolved to an empty relative path and can @@ -428,6 +472,14 @@ MakeAbsolute(kDir1.Append(kDir1Dir1)))); } +TEST_P(FilesystemProxyTest, WriteFileAtomically) { + const base::FilePath kFile{FILE_PATH_LITERAL("some_new_file")}; + + const std::string kData{"files can have a little data, as a treat"}; + EXPECT_TRUE(proxy().WriteFileAtomically(kFile, kData)); + EXPECT_EQ(kData, ReadFileContentsAtPath(kFile)); +} + INSTANTIATE_TEST_SUITE_P(, FilesystemProxyTest, testing::Bool()); } // namespace storage
diff --git a/components/services/storage/public/mojom/filesystem/directory.mojom b/components/services/storage/public/mojom/filesystem/directory.mojom index c63942cb..82ecfcb 100644 --- a/components/services/storage/public/mojom/filesystem/directory.mojom +++ b/components/services/storage/public/mojom/filesystem/directory.mojom
@@ -4,6 +4,7 @@ module storage.mojom; +import "mojo/public/mojom/base/big_string.mojom"; import "mojo/public/mojom/base/file.mojom"; import "mojo/public/mojom/base/file_error.mojom"; import "mojo/public/mojom/base/file_info.mojom"; @@ -120,6 +121,11 @@ FileWriteAccess write_access) => (mojo_base.mojom.FileError error, mojo_base.mojom.File? file); + // Writes a small file atomically using the ImportantFileWriter. + [Sync] WriteFileAtomically(StrictRelativePath path, + mojo_base.mojom.BigString contents) + => (bool success); + // Deletes a regular file at |path|. [Sync] RemoveFile(StrictRelativePath path) => (bool success); @@ -130,9 +136,18 @@ // Deletes a directory at |path|. Not recursive. If the directory at |path| // contains only files (i.e. no subdirectories), all contents are deleted. + // It is considered successful to remove a directory that does not exist. [Sync] RemoveDirectory(StrictRelativePath path) => (bool success); + // Deletes the given path, whether it's a file or a directory. + // If it's a directory, it's perfectly happy to delete all of the + // directory's contents, including subdirectories and their contents. + // Returns true if successful, false otherwise. It is considered successful + // to attempt to remove a directory that does not exist. + [Sync] + RemoveDirectoryRecursively(StrictRelativePath path) => (bool success); + // Retrieves information about a specific filesystem entry at |path|. Returns // null on failure, or a populated |info| struct on success. [Sync] @@ -143,6 +158,12 @@ [Sync] GetPathAccess(StrictRelativePath path) => (PathAccessInfo? info); + // Returns the maximum length of path component on the volume containing the + // directory |path|, in the number of FilePath::CharType on success. + [Sync] + GetMaximumPathComponentLength(StrictRelativePath path) + => (bool success, int32 length); + // Renames a file from |old_path| to |new_path|. Note that if |new_path| // already exists, it will be overwritten by this call. [Sync]
diff --git a/components/viz/service/frame_sinks/video_capture/in_flight_frame_delivery.cc b/components/viz/service/frame_sinks/video_capture/in_flight_frame_delivery.cc index 511b6649..ec5605e9 100644 --- a/components/viz/service/frame_sinks/video_capture/in_flight_frame_delivery.cc +++ b/components/viz/service/frame_sinks/video_capture/in_flight_frame_delivery.cc
@@ -4,11 +4,14 @@ #include "components/viz/service/frame_sinks/video_capture/in_flight_frame_delivery.h" +#include <utility> + namespace viz { InFlightFrameDelivery::InFlightFrameDelivery( base::OnceClosure post_delivery_callback, - base::OnceCallback<void(double)> feedback_callback) + base::OnceCallback<void(const media::VideoFrameFeedback&)> + feedback_callback) : post_delivery_callback_(std::move(post_delivery_callback)), feedback_callback_(std::move(feedback_callback)) {} @@ -22,9 +25,10 @@ } } -void InFlightFrameDelivery::ProvideFeedback(double utilization) { +void InFlightFrameDelivery::ProvideFeedback( + const media::VideoFrameFeedback& feedback) { if (!feedback_callback_.is_null()) { - std::move(feedback_callback_).Run(utilization); + std::move(feedback_callback_).Run(feedback); } }
diff --git a/components/viz/service/frame_sinks/video_capture/in_flight_frame_delivery.h b/components/viz/service/frame_sinks/video_capture/in_flight_frame_delivery.h index 871f8a4..6aa989f 100644 --- a/components/viz/service/frame_sinks/video_capture/in_flight_frame_delivery.h +++ b/components/viz/service/frame_sinks/video_capture/in_flight_frame_delivery.h
@@ -18,18 +18,20 @@ class VIZ_SERVICE_EXPORT InFlightFrameDelivery : public mojom::FrameSinkVideoConsumerFrameCallbacks { public: - InFlightFrameDelivery(base::OnceClosure post_delivery_callback, - base::OnceCallback<void(double)> feedback_callback); + InFlightFrameDelivery( + base::OnceClosure post_delivery_callback, + base::OnceCallback<void(const media::VideoFrameFeedback&)> + feedback_callback); ~InFlightFrameDelivery() final; // mojom::FrameSinkVideoConsumerFrameCallbacks implementation: void Done() final; - void ProvideFeedback(double utilization) final; + void ProvideFeedback(const media::VideoFrameFeedback&) final; private: base::OnceClosure post_delivery_callback_; - base::OnceCallback<void(double)> feedback_callback_; + base::OnceCallback<void(const media::VideoFrameFeedback&)> feedback_callback_; DISALLOW_COPY_AND_ASSIGN(InFlightFrameDelivery); };
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index 1dec904..35683362 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc
@@ -90,7 +90,7 @@ #include "mojo/public/cpp/platform/platform_channel.h" #include "mojo/public/cpp/system/dynamic_library_support.h" #include "mojo/public/cpp/system/invitation.h" -#include "mojo/public/mojom/base/binder.mojom.h" +#include "mojo/public/cpp/system/message_pipe.h" #include "ppapi/buildflags/buildflags.h" #include "sandbox/policy/sandbox_type.h" #include "sandbox/policy/switches.h" @@ -394,24 +394,6 @@ #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) -class ControlInterfaceBinderImpl : public mojo_base::mojom::Binder { - public: - ControlInterfaceBinderImpl() = default; - ~ControlInterfaceBinderImpl() override = default; - - // mojo_base::mojom::Binder: - void Bind(mojo::GenericPendingReceiver receiver) override { - GetContentClient()->browser()->BindBrowserControlInterface( - std::move(receiver)); - } -}; - -void RunControlInterfaceBinder(mojo::ScopedMessagePipeHandle pipe) { - mojo::MakeSelfOwnedReceiver( - std::make_unique<ControlInterfaceBinderImpl>(), - mojo::PendingReceiver<mojo_base::mojom::Binder>(std::move(pipe))); -} - } // namespace class ContentClientCreator { @@ -969,7 +951,8 @@ mojo::PlatformChannel::RecoverPassedEndpointFromCommandLine( command_line); auto invitation = mojo::IncomingInvitation::Accept(std::move(endpoint)); - RunControlInterfaceBinder(invitation.ExtractMessagePipe(0)); + GetContentClient()->browser()->BindBrowserControlInterface( + invitation.ExtractMessagePipe(0)); } download::SetIOTaskRunner(
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index b1ce130..5d89f5e 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -2361,7 +2361,7 @@ # Ozone/Linux, but requires to use pangocairo. We probably want to continue # using pango on Linux and switch to something else for other systems that # use Ozone. - if (use_ozone && !is_desktop_linux) { + if (use_ozone && (!is_desktop_linux || !use_pangocairo)) { sources += [ "renderer_host/pepper/pepper_truetype_font_list_ozone.cc" ] } else if (use_pangocairo) { sources += [ "renderer_host/pepper/pepper_truetype_font_list_pango.cc" ]
diff --git a/content/browser/cross_origin_opener_policy_browsertest.cc b/content/browser/cross_origin_opener_policy_browsertest.cc index 2c18b5c2..320cb9c 100644 --- a/content/browser/cross_origin_opener_policy_browsertest.cc +++ b/content/browser/cross_origin_opener_policy_browsertest.cc
@@ -1015,6 +1015,60 @@ } } +// Try to host into the same cross-origin isolated process, two cross-origin +// documents. The second's response sets CSP:sandbox, so its origin is opaque +// and derived from the first. +IN_PROC_BROWSER_TEST_P(CrossOriginOpenerPolicyBrowserTest, + CrossOriginIsolatedWithDifferentOrigin) { + GURL opener_url = + https_server()->GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy: same-origin&" + "Cross-Origin-Embedder-Policy: require-corp"); + GURL openee_url = + https_server()->GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy: same-origin&" + "Cross-Origin-Embedder-Policy: require-corp&" + "Content-Security-Policy: sandbox"); + + // Load the first window. + EXPECT_TRUE(NavigateToURL(shell(), opener_url)); + RenderFrameHostImpl* opener_current_main_document = current_frame_host(); + + // Load the second window. + ShellAddedObserver shell_observer; + EXPECT_TRUE( + ExecJs(current_frame_host(), JsReplace("window.open($1)", openee_url))); + WebContents* popup = shell_observer.GetShell()->web_contents(); + WaitForLoadStop(popup); + + RenderFrameHostImpl* openee_current_main_document = + static_cast<WebContentsImpl*>(popup) + ->GetFrameTree() + ->root() + ->current_frame_host(); + + // Those documents aren't error pages. + EXPECT_EQ(opener_current_main_document->GetLastCommittedURL(), opener_url); + EXPECT_EQ(openee_current_main_document->GetLastCommittedURL(), openee_url); + EXPECT_EQ(opener_current_main_document->last_http_status_code(), 200); + EXPECT_EQ(openee_current_main_document->last_http_status_code(), 200); + + // We have two main documents in the same cross-origin isolated process from a + // different origin. + // TODO(https://crbug.com/1115426): Investigate what needs to be done. + EXPECT_NE(opener_current_main_document->GetLastCommittedOrigin(), + openee_current_main_document->GetLastCommittedOrigin()); + EXPECT_EQ(opener_current_main_document->GetProcess(), + openee_current_main_document->GetProcess()); + EXPECT_EQ(opener_current_main_document->GetSiteInstance(), + openee_current_main_document->GetSiteInstance()); + + // TODO(arthursonzogni): Check whether the processes are marked as + // cross-origin isolated or not. +} + // Navigate in between two documents. Check the virtual browsing context group // is properly updated. IN_PROC_BROWSER_TEST_P(VirtualBrowsingContextGroupTest, Navigation) {
diff --git a/content/browser/devtools/browser_devtools_agent_host.cc b/content/browser/devtools/browser_devtools_agent_host.cc index 26c2de5..f7c02396 100644 --- a/content/browser/devtools/browser_devtools_agent_host.cc +++ b/content/browser/devtools/browser_devtools_agent_host.cc
@@ -67,7 +67,8 @@ BrowserDevToolsAgentHostInstances().erase(this); } -bool BrowserDevToolsAgentHost::AttachSession(DevToolsSession* session) { +bool BrowserDevToolsAgentHost::AttachSession(DevToolsSession* session, + bool acquire_wake_lock) { if (!session->GetClient()->MayAttachToBrowser()) return false;
diff --git a/content/browser/devtools/browser_devtools_agent_host.h b/content/browser/devtools/browser_devtools_agent_host.h index 48fc174..bb966730 100644 --- a/content/browser/devtools/browser_devtools_agent_host.h +++ b/content/browser/devtools/browser_devtools_agent_host.h
@@ -24,7 +24,7 @@ ~BrowserDevToolsAgentHost() override; // DevToolsAgentHostImpl overrides. - bool AttachSession(DevToolsSession* session) override; + bool AttachSession(DevToolsSession* session, bool acquire_wake_lock) override; void DetachSession(DevToolsSession* session) override; // DevToolsAgentHost implementation.
diff --git a/content/browser/devtools/devtools_agent_host_impl.cc b/content/browser/devtools/devtools_agent_host_impl.cc index 4d70646a0..762a4953 100644 --- a/content/browser/devtools/devtools_agent_host_impl.cc +++ b/content/browser/devtools/devtools_agent_host_impl.cc
@@ -129,10 +129,16 @@ bool DevToolsAgentHostImpl::AttachInternal( std::unique_ptr<DevToolsSession> session_owned) { + return AttachInternal(std::move(session_owned), true); +} + +bool DevToolsAgentHostImpl::AttachInternal( + std::unique_ptr<DevToolsSession> session_owned, + bool acquire_wake_lock) { scoped_refptr<DevToolsAgentHostImpl> protect(this); DevToolsSession* session = session_owned.get(); session->SetAgentHost(this); - if (!AttachSession(session)) + if (!AttachSession(session, acquire_wake_lock)) return false; renderer_channel_.AttachSession(session); sessions_.push_back(session); @@ -151,7 +157,17 @@ if (SessionByClient(client)) return false; return AttachInternal( - std::make_unique<DevToolsSession>(client, /*session_id=*/"")); + std::make_unique<DevToolsSession>(client, /*session_id=*/""), + /*acquire_wake_lock=*/true); +} + +bool DevToolsAgentHostImpl::AttachClientWithoutWakeLock( + content::DevToolsAgentHostClient* client) { + if (SessionByClient(client)) + return false; + return AttachInternal( + std::make_unique<DevToolsSession>(client, /*session_id=*/""), + /*acquire_wake_lock=*/false); } bool DevToolsAgentHostImpl::DetachClient(DevToolsAgentHostClient* client) { @@ -281,7 +297,8 @@ } } -bool DevToolsAgentHostImpl::AttachSession(DevToolsSession* session) { +bool DevToolsAgentHostImpl::AttachSession(DevToolsSession* session, + bool acquire_wake_lock) { return false; }
diff --git a/content/browser/devtools/devtools_agent_host_impl.h b/content/browser/devtools/devtools_agent_host_impl.h index ac5abf76..dfdf9bf7 100644 --- a/content/browser/devtools/devtools_agent_host_impl.h +++ b/content/browser/devtools/devtools_agent_host_impl.h
@@ -30,6 +30,7 @@ public: // DevToolsAgentHost implementation. bool AttachClient(DevToolsAgentHostClient* client) override; + bool AttachClientWithoutWakeLock(DevToolsAgentHostClient* client) override; bool DetachClient(DevToolsAgentHostClient* client) override; void DispatchProtocolMessage(DevToolsAgentHostClient* client, base::span<const uint8_t> message) override; @@ -72,7 +73,7 @@ static bool ShouldForceCreation(); // Returning |false| will block the attach. - virtual bool AttachSession(DevToolsSession* session); + virtual bool AttachSession(DevToolsSession* session, bool acquire_wake_lock); virtual void DetachSession(DevToolsSession* session); virtual void UpdateRendererChannel(bool force); @@ -93,6 +94,8 @@ friend class DevToolsRendererChannel; bool AttachInternal(std::unique_ptr<DevToolsSession> session); + bool AttachInternal(std::unique_ptr<DevToolsSession> session, + bool acquire_wake_lock); void DetachInternal(DevToolsSession* session); void NotifyAttached(); void NotifyDetached();
diff --git a/content/browser/devtools/devtools_video_consumer_unittest.cc b/content/browser/devtools/devtools_video_consumer_unittest.cc index 1613c754..7d4f41d 100644 --- a/content/browser/devtools/devtools_video_consumer_unittest.cc +++ b/content/browser/devtools/devtools_video_consumer_unittest.cc
@@ -140,7 +140,7 @@ } MOCK_METHOD0(Done, void()); - MOCK_METHOD1(ProvideFeedback, void(double utilization)); + MOCK_METHOD1(ProvideFeedback, void(const media::VideoFrameFeedback&)); private: mojo::Receiver<viz::mojom::FrameSinkVideoConsumerFrameCallbacks> receiver_{
diff --git a/content/browser/devtools/forwarding_agent_host.cc b/content/browser/devtools/forwarding_agent_host.cc index adb6d0cb..e675ca88 100644 --- a/content/browser/devtools/forwarding_agent_host.cc +++ b/content/browser/devtools/forwarding_agent_host.cc
@@ -19,7 +19,8 @@ ForwardingAgentHost::~ForwardingAgentHost() = default; -bool ForwardingAgentHost::AttachSession(DevToolsSession* session) { +bool ForwardingAgentHost::AttachSession(DevToolsSession* session, + bool acquire_wake_lock) { session->TurnIntoExternalProxy(delegate_.get()); return true; }
diff --git a/content/browser/devtools/forwarding_agent_host.h b/content/browser/devtools/forwarding_agent_host.h index 8b26529..8128e57 100644 --- a/content/browser/devtools/forwarding_agent_host.h +++ b/content/browser/devtools/forwarding_agent_host.h
@@ -23,7 +23,7 @@ ~ForwardingAgentHost() override; // DevToolsAgentHostImpl overrides. - bool AttachSession(DevToolsSession* session) override; + bool AttachSession(DevToolsSession* session, bool acquire_wake_lock) override; void DetachSession(DevToolsSession* session) override; // DevToolsAgentHost implementation.
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc index 70737ad..3afed9ba 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.cc +++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -285,7 +285,8 @@ return web_contents(); } -bool RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session) { +bool RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session, + bool acquire_wake_lock) { if (!ShouldAllowSession(session)) return false; @@ -358,7 +359,8 @@ #endif UpdateRawHeadersAccess(nullptr, frame_host_); #if defined(OS_ANDROID) - GetWakeLock()->RequestWakeLock(); + if (acquire_wake_lock) + GetWakeLock()->RequestWakeLock(); #endif } return true;
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.h b/content/browser/devtools/render_frame_devtools_agent_host.h index de7df8a..07474b6 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.h +++ b/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -117,7 +117,7 @@ ~RenderFrameDevToolsAgentHost() override; // DevToolsAgentHostImpl overrides. - bool AttachSession(DevToolsSession* session) override; + bool AttachSession(DevToolsSession* session, bool acquire_wake_lock) override; void DetachSession(DevToolsSession* session) override; void InspectElement(RenderFrameHost* frame_host, int x, int y) override; void UpdateRendererChannel(bool force) override;
diff --git a/content/browser/devtools/service_worker_devtools_agent_host.cc b/content/browser/devtools/service_worker_devtools_agent_host.cc index 1ccdae9..f6cb19c 100644 --- a/content/browser/devtools/service_worker_devtools_agent_host.cc +++ b/content/browser/devtools/service_worker_devtools_agent_host.cc
@@ -127,7 +127,8 @@ ServiceWorkerDevToolsManager::GetInstance()->AgentHostDestroyed(this); } -bool ServiceWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session) { +bool ServiceWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session, + bool acquire_wake_lock) { session->AddHandler(base::WrapUnique(new protocol::InspectorHandler())); session->AddHandler(base::WrapUnique(new protocol::NetworkHandler( GetId(), devtools_worker_token_, GetIOContext(), base::DoNothing())));
diff --git a/content/browser/devtools/service_worker_devtools_agent_host.h b/content/browser/devtools/service_worker_devtools_agent_host.h index 48a03cf0..8f88bb3 100644 --- a/content/browser/devtools/service_worker_devtools_agent_host.h +++ b/content/browser/devtools/service_worker_devtools_agent_host.h
@@ -86,7 +86,7 @@ void UpdateIsAttached(bool attached); // DevToolsAgentHostImpl overrides. - bool AttachSession(DevToolsSession* session) override; + bool AttachSession(DevToolsSession* session, bool acquire_wake_lock) override; void DetachSession(DevToolsSession* session) override; void UpdateLoaderFactories(base::OnceClosure callback);
diff --git a/content/browser/devtools/shared_worker_devtools_agent_host.cc b/content/browser/devtools/shared_worker_devtools_agent_host.cc index d05a1a0e..e0ef52b9 100644 --- a/content/browser/devtools/shared_worker_devtools_agent_host.cc +++ b/content/browser/devtools/shared_worker_devtools_agent_host.cc
@@ -69,7 +69,8 @@ return true; } -bool SharedWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session) { +bool SharedWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session, + bool acquire_wake_lock) { session->AddHandler(std::make_unique<protocol::InspectorHandler>()); session->AddHandler(std::make_unique<protocol::NetworkHandler>( GetId(), devtools_worker_token_, GetIOContext(),
diff --git a/content/browser/devtools/shared_worker_devtools_agent_host.h b/content/browser/devtools/shared_worker_devtools_agent_host.h index 6399c26..4b6db3e9b 100644 --- a/content/browser/devtools/shared_worker_devtools_agent_host.h +++ b/content/browser/devtools/shared_worker_devtools_agent_host.h
@@ -50,7 +50,7 @@ ~SharedWorkerDevToolsAgentHost() override; // DevToolsAgentHostImpl overrides. - bool AttachSession(DevToolsSession* session) override; + bool AttachSession(DevToolsSession* session, bool acquire_wake_lock) override; void DetachSession(DevToolsSession* session) override; enum WorkerState {
diff --git a/content/browser/devtools/worker_devtools_agent_host.cc b/content/browser/devtools/worker_devtools_agent_host.cc index 1eefe013..8981b8e 100644 --- a/content/browser/devtools/worker_devtools_agent_host.cc +++ b/content/browser/devtools/worker_devtools_agent_host.cc
@@ -79,7 +79,8 @@ return false; } -bool WorkerDevToolsAgentHost::AttachSession(DevToolsSession* session) { +bool WorkerDevToolsAgentHost::AttachSession(DevToolsSession* session, + bool acquire_wake_lock) { session->AddHandler(std::make_unique<protocol::TargetHandler>( protocol::TargetHandler::AccessMode::kAutoAttachOnly, GetId(), GetRendererChannel(), session->GetRootSession()));
diff --git a/content/browser/devtools/worker_devtools_agent_host.h b/content/browser/devtools/worker_devtools_agent_host.h index b490fff..a2b0a20b 100644 --- a/content/browser/devtools/worker_devtools_agent_host.h +++ b/content/browser/devtools/worker_devtools_agent_host.h
@@ -40,7 +40,7 @@ void Disconnected(); // DevToolsAgentHostImpl overrides. - bool AttachSession(DevToolsSession* session) override; + bool AttachSession(DevToolsSession* session, bool acquire_wake_lock) override; void DetachSession(DevToolsSession* session) override; const int process_id_;
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc index 5d8ba51..aa33633 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -9,8 +9,6 @@ #include "base/bind.h" #include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/important_file_writer.h" #include "base/format_macros.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" @@ -25,6 +23,7 @@ #include "base/task/post_task.h" #include "base/trace_event/memory_dump_manager.h" #include "build/build_config.h" +#include "components/services/storage/filesystem_proxy_factory.h" #include "components/services/storage/indexed_db/scopes/leveldb_scope.h" #include "components/services/storage/indexed_db/scopes/leveldb_scopes.h" #include "components/services/storage/indexed_db/scopes/varint_coding.h" @@ -63,7 +62,6 @@ #include "third_party/leveldatabase/env_chromium.h" using base::FilePath; -using base::ImportantFileWriter; using base::StringPiece; using blink::IndexedDBDatabaseMetadata; using blink::IndexedDBKey; @@ -113,14 +111,6 @@ return path; } -bool MakeIDBBlobDirectory(const FilePath& path_base, - int64_t database_id, - int64_t blob_number) { - FilePath path = - GetBlobDirectoryNameForKey(path_base, database_id, blob_number); - return base::CreateDirectory(path); -} - std::string ComputeOriginIdentifier(const Origin& origin) { return storage::GetIdentifierFromOrigin(origin) + "@1"; } @@ -394,9 +384,11 @@ return true; } -bool IsPathTooLong(const FilePath& leveldb_dir) { - int limit = base::GetMaximumPathComponentLength(leveldb_dir.DirName()); - if (limit == -1) { +bool IsPathTooLong(storage::FilesystemProxy* filesystem, + const base::FilePath& leveldb_dir) { + base::Optional<int> limit = + filesystem->GetMaximumPathComponentLength(leveldb_dir.DirName()); + if (!limit.has_value()) { DLOG(WARNING) << "GetMaximumPathComponentLength returned -1"; // In limited testing, ChromeOS returns 143, other OSes 255. #if defined(OS_CHROMEOS) @@ -406,9 +398,9 @@ #endif } size_t component_length = leveldb_dir.BaseName().value().length(); - if (component_length > static_cast<uint32_t>(limit)) { + if (component_length > static_cast<uint32_t>(*limit)) { DLOG(WARNING) << "Path component length (" << component_length - << ") exceeds maximum (" << limit + << ") exceeds maximum (" << *limit << ") allowed by this filesystem."; const int min = 140; const int max = 300; @@ -615,6 +607,7 @@ std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, storage::mojom::NativeFileSystemContext* native_file_system_context, + std::unique_ptr<storage::FilesystemProxy> filesystem_proxy, BlobFilesCleanedCallback blob_files_cleaned, ReportOutstandingBlobsCallback report_outstanding_blobs, scoped_refptr<base::SequencedTaskRunner> idb_task_runner, @@ -625,6 +618,7 @@ blob_path_(blob_path), blob_storage_context_(blob_storage_context), native_file_system_context_(native_file_system_context), + filesystem_proxy_(std::move(filesystem_proxy)), origin_identifier_(ComputeOriginIdentifier(origin)), idb_task_runner_(idb_task_runner), io_task_runner_(io_task_runner), @@ -693,9 +687,11 @@ PutInt(write_batch.get(), data_version_key, db_data_version.Encode())); // If a blob directory already exists for this database, blow it away. It's // leftover from a partially-purged previous generation of data. - if (!base::DeletePathRecursively(blob_path_)) { - INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA); - return IOErrorStatus(); + if (filesystem_proxy_) { + if (!filesystem_proxy_->RemoveDirectoryRecursively(blob_path_)) { + INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA); + return IOErrorStatus(); + } } } else { if (db_schema_version > indexed_db::kLatestKnownSchemaVersion) @@ -833,7 +829,7 @@ // Delete all empty files that resulted from the migration to v4. If this // fails it's not a big deal. for (const auto& path : empty_blobs_to_delete) { - base::DeleteFile(path); + filesystem_proxy_->RemoveFile(path); } if (clean_active_journal) { @@ -958,16 +954,18 @@ continue; } needs_rewrite = true; - base::File::Info info; base::FilePath path = GetBlobFileName(metadata.id, object.blob_number()); - if (!base::GetFileInfo(path, &info)) { + + base::Optional<base::File::Info> info = + filesystem_proxy_->GetFileInfo(path); + if (!info.has_value()) { return leveldb::Status::Corruption( "Unable to upgrade to database version 4.", ""); } - object.set_size(info.size); - object.set_last_modified(info.last_modified); - if (info.size == 0) + object.set_size(info->size); + object.set_last_modified(info->last_modified); + if (info->size == 0) empty_blobs_to_delete->push_back(path); } if (!needs_rewrite) @@ -1081,20 +1079,22 @@ } // static -bool IndexedDBBackingStore::RecordCorruptionInfo(const FilePath& path_base, - const Origin& origin, - const std::string& message) { - const FilePath info_path = +bool IndexedDBBackingStore::RecordCorruptionInfo( + const base::FilePath& path_base, + const Origin& origin, + const std::string& message) { + auto filesystem = storage::CreateFilesystemProxy(); + const base::FilePath info_path = path_base.Append(indexed_db::ComputeCorruptionFileName(origin)); - if (IsPathTooLong(info_path)) + if (IsPathTooLong(filesystem.get(), info_path)) return false; base::DictionaryValue root_dict; root_dict.SetString("message", message); std::string output_js; + base::JSONWriter::Write(root_dict, &output_js); - return base::ImportantFileWriter::WriteFileAtomically(info_path, - output_js.c_str()); + return filesystem->WriteFileAtomically(info_path, std::move(output_js)); } Status IndexedDBBackingStore::DeleteDatabase( @@ -1705,13 +1705,13 @@ DVLOG(1) << "Deleting blob " << blob_number << " from IndexedDB database " << database_id << " at path " << path.value(); #endif - return base::DeleteFile(path); + return filesystem_proxy_->RemoveFile(path); } bool IndexedDBBackingStore::RemoveBlobDirectory(int64_t database_id) const { DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_); FilePath path = GetBlobDirectoryName(blob_path_, database_id); - return base::DeletePathRecursively(path); + return filesystem_proxy_->RemoveDirectoryRecursively(path); } Status IndexedDBBackingStore::CleanUpBlobJournal( @@ -3000,7 +3000,7 @@ // m78 and m79, they need to be checked. See https://crbug.com/1039446 base::FilePath blob_path = backing_store_->GetBlobFileName(database_id_, next_blob_number); - while (base::PathExists(blob_path)) { + while (backing_store_->filesystem_proxy_->PathExists(blob_path)) { ++next_blob_number; blob_path = backing_store_->GetBlobFileName(database_id_, next_blob_number); } @@ -3336,8 +3336,9 @@ continue; // If this directory creation fails then the WriteBlobToFile call // will fail. So there is no need to special-case handle it here. - MakeIDBBlobDirectory(backing_store_->blob_path_, database_id_, - entry.blob_number()); + FilePath path = GetBlobDirectoryNameForKey( + backing_store_->blob_path_, database_id_, entry.blob_number()); + backing_store_->filesystem_proxy_->CreateDirectory(path); // TODO(dmurph): Refactor IndexedDBExternalObject to not use a // SharedRemote, so this code can just move the remote, instead of // cloning.
diff --git a/content/browser/indexed_db/indexed_db_backing_store.h b/content/browser/indexed_db/indexed_db_backing_store.h index 21bff56..db673b0 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.h +++ b/content/browser/indexed_db/indexed_db_backing_store.h
@@ -25,6 +25,7 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "components/services/storage/indexed_db/scopes/scope_lock.h" +#include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h" #include "components/services/storage/public/mojom/blob_storage_context.mojom-forward.h" #include "components/services/storage/public/mojom/native_file_system_context.mojom-forward.h" #include "content/browser/indexed_db/indexed_db.h" @@ -346,6 +347,7 @@ std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, storage::mojom::NativeFileSystemContext* native_file_system_context, + std::unique_ptr<storage::FilesystemProxy> filesystem_proxy, BlobFilesCleanedCallback blob_files_cleaned, ReportOutstandingBlobsCallback report_outstanding_blobs, scoped_refptr<base::SequencedTaskRunner> idb_task_runner, @@ -599,6 +601,9 @@ storage::mojom::BlobStorageContext* blob_storage_context_; storage::mojom::NativeFileSystemContext* native_file_system_context_; + // Filesystem proxy to use for file operations. nullptr if in memory. + std::unique_ptr<storage::FilesystemProxy> filesystem_proxy_; + // The origin identifier is a key prefix unique to the origin used in the // leveldb backing store to partition data by origin. It is a normalized // version of the origin URL with a versioning suffix appended, e.g.
diff --git a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc index 3a782cbe..c55dbcf 100644 --- a/content/browser/indexed_db/indexed_db_backing_store_unittest.cc +++ b/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
@@ -75,6 +75,7 @@ std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, storage::mojom::NativeFileSystemContext* native_file_system_context, + std::unique_ptr<storage::FilesystemProxy> filesystem_proxy, BlobFilesCleanedCallback blob_files_cleaned, ReportOutstandingBlobsCallback report_outstanding_blobs, scoped_refptr<base::SequencedTaskRunner> idb_task_runner, @@ -86,6 +87,7 @@ std::move(db), blob_storage_context, native_file_system_context, + std::move(filesystem_proxy), std::move(blob_files_cleaned), std::move(report_outstanding_blobs), std::move(idb_task_runner), @@ -137,6 +139,7 @@ std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext*, storage::mojom::NativeFileSystemContext*, + std::unique_ptr<storage::FilesystemProxy> filesystem_proxy, IndexedDBBackingStore::BlobFilesCleanedCallback blob_files_cleaned, IndexedDBBackingStore::ReportOutstandingBlobsCallback report_outstanding_blobs, @@ -148,8 +151,9 @@ return std::make_unique<TestableIndexedDBBackingStore>( backing_store_mode, leveldb_factory, origin, blob_path, std::move(db), blob_storage_context_, native_file_system_context_, - std::move(blob_files_cleaned), std::move(report_outstanding_blobs), - std::move(idb_task_runner), std::move(io_task_runner)); + std::move(filesystem_proxy), std::move(blob_files_cleaned), + std::move(report_outstanding_blobs), std::move(idb_task_runner), + std::move(io_task_runner)); } private: @@ -1523,9 +1527,13 @@ } TEST_F(IndexedDBBackingStoreTest, ReadCorruptionInfo) { + auto filesystem_proxy = std::make_unique<storage::FilesystemProxy>( + storage::FilesystemProxy::UNRESTRICTED, base::FilePath()); + // No |path_base|. - EXPECT_TRUE( - indexed_db::ReadCorruptionInfo(base::FilePath(), Origin()).empty()); + EXPECT_TRUE(indexed_db::ReadCorruptionInfo(filesystem_proxy.get(), + base::FilePath(), Origin()) + .empty()); const base::FilePath path_base = temp_dir_.GetPath(); const Origin origin = Origin::Create(GURL("http://www.google.com/")); @@ -1533,7 +1541,9 @@ ASSERT_TRUE(PathIsWritable(path_base)); // File not found. - EXPECT_TRUE(indexed_db::ReadCorruptionInfo(path_base, origin).empty()); + EXPECT_TRUE( + indexed_db::ReadCorruptionInfo(filesystem_proxy.get(), path_base, origin) + .empty()); const base::FilePath info_path = path_base.AppendASCII("http_www.google.com_0.indexeddb.leveldb") @@ -1543,45 +1553,59 @@ // Empty file. std::string dummy_data; ASSERT_TRUE(base::WriteFile(info_path, dummy_data)); - EXPECT_TRUE(indexed_db::ReadCorruptionInfo(path_base, origin).empty()); + EXPECT_TRUE( + indexed_db::ReadCorruptionInfo(filesystem_proxy.get(), path_base, origin) + .empty()); EXPECT_FALSE(PathExists(info_path)); // File size > 4 KB. dummy_data.resize(5000, 'c'); ASSERT_TRUE(base::WriteFile(info_path, dummy_data)); - EXPECT_TRUE(indexed_db::ReadCorruptionInfo(path_base, origin).empty()); + EXPECT_TRUE( + indexed_db::ReadCorruptionInfo(filesystem_proxy.get(), path_base, origin) + .empty()); EXPECT_FALSE(PathExists(info_path)); // Random string. ASSERT_TRUE(base::WriteFile(info_path, "foo bar")); - EXPECT_TRUE(indexed_db::ReadCorruptionInfo(path_base, origin).empty()); + EXPECT_TRUE( + indexed_db::ReadCorruptionInfo(filesystem_proxy.get(), path_base, origin) + .empty()); EXPECT_FALSE(PathExists(info_path)); // Not a dictionary. ASSERT_TRUE(base::WriteFile(info_path, "[]")); - EXPECT_TRUE(indexed_db::ReadCorruptionInfo(path_base, origin).empty()); + EXPECT_TRUE( + indexed_db::ReadCorruptionInfo(filesystem_proxy.get(), path_base, origin) + .empty()); EXPECT_FALSE(PathExists(info_path)); // Empty dictionary. ASSERT_TRUE(base::WriteFile(info_path, "{}")); - EXPECT_TRUE(indexed_db::ReadCorruptionInfo(path_base, origin).empty()); + EXPECT_TRUE( + indexed_db::ReadCorruptionInfo(filesystem_proxy.get(), path_base, origin) + .empty()); EXPECT_FALSE(PathExists(info_path)); // Dictionary, no message key. ASSERT_TRUE(base::WriteFile(info_path, "{\"foo\":\"bar\"}")); - EXPECT_TRUE(indexed_db::ReadCorruptionInfo(path_base, origin).empty()); + EXPECT_TRUE( + indexed_db::ReadCorruptionInfo(filesystem_proxy.get(), path_base, origin) + .empty()); EXPECT_FALSE(PathExists(info_path)); // Dictionary, message key. ASSERT_TRUE(base::WriteFile(info_path, "{\"message\":\"bar\"}")); - std::string message = indexed_db::ReadCorruptionInfo(path_base, origin); + std::string message = + indexed_db::ReadCorruptionInfo(filesystem_proxy.get(), path_base, origin); EXPECT_FALSE(message.empty()); EXPECT_FALSE(PathExists(info_path)); EXPECT_EQ("bar", message); // Dictionary, message key and more. ASSERT_TRUE(base::WriteFile(info_path, "{\"message\":\"foo\",\"bar\":5}")); - message = indexed_db::ReadCorruptionInfo(path_base, origin); + message = + indexed_db::ReadCorruptionInfo(filesystem_proxy.get(), path_base, origin); EXPECT_FALSE(message.empty()); EXPECT_FALSE(PathExists(info_path)); EXPECT_EQ("foo", message);
diff --git a/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc b/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc index 823187a75..31be9ad 100644 --- a/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc +++ b/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc
@@ -53,6 +53,7 @@ TransactionalLevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase), /*blob_storage_context=*/nullptr, /*native_file_system_context=*/nullptr, + /*filesystem_proxy=*/nullptr, IndexedDBBackingStore::BlobFilesCleanedCallback(), IndexedDBBackingStore::ReportOutstandingBlobsCallback(), task_runner, task_runner); @@ -91,6 +92,7 @@ TransactionalLevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase), /*blob_storage_context=*/nullptr, /*native_file_system_context=*/nullptr, + /*filesystem_proxy=*/nullptr, IndexedDBBackingStore::BlobFilesCleanedCallback(), IndexedDBBackingStore::ReportOutstandingBlobsCallback(), task_runner, task_runner);
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc index 96a7b11b..de390c5 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.cc +++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -13,7 +13,6 @@ #include "base/check_op.h" #include "base/command_line.h" #include "base/files/file_enumerator.h" -#include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/metrics/histogram_functions.h" #include "base/sequenced_task_runner.h" @@ -25,6 +24,7 @@ #include "base/time/default_clock.h" #include "base/time/time.h" #include "base/values.h" +#include "components/services/storage/filesystem_proxy_factory.h" #include "components/services/storage/indexed_db/leveldb/leveldb_factory.h" #include "components/services/storage/indexed_db/scopes/varint_coding.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" @@ -129,7 +129,8 @@ force_keep_session_state_(false), quota_manager_proxy_(quota_manager_proxy), io_task_runner_(io_task_runner), - clock_(clock) { + clock_(clock), + filesystem_proxy_(storage::CreateFilesystemProxy()) { IDB_TRACE("init"); if (!data_path.empty()) data_path_ = data_path.Append(kIndexedDBDirectory); @@ -220,7 +221,8 @@ idb_directory); bool success = s.ok(); if (success) - success = base::DeletePathRecursively(GetBlobStorePath(origin)); + success = + filesystem_proxy_->RemoveDirectoryRecursively(GetBlobStorePath(origin)); QueryDiskAndUpdateQuotaUsage(origin); if (success) { GetOriginSet()->erase(origin); @@ -703,10 +705,11 @@ } base::FilePath idb_directory = GetLevelDBPath(origin); - base::File::Info file_info; - if (!base::GetFileInfo(idb_directory, &file_info)) + base::Optional<base::File::Info> info = + filesystem_proxy_->GetFileInfo(idb_directory); + if (!info.has_value()) return base::Time(); - return file_info.last_modified; + return info->last_modified; } size_t IndexedDBContextImpl::GetConnectionCountSync(const Origin& origin) { @@ -829,7 +832,8 @@ context->origins_to_purge_on_shutdown_.end()) continue; factory->ForceClose(*origin, false); - base::DeletePathRecursively(*file_path); + context->filesystem_proxy_->RemoveDirectoryRecursively( + *file_path); } }, base::WrapRefCounted(this))); @@ -856,7 +860,7 @@ int64_t total_size = 0; for (const base::FilePath& path : GetStoragePaths(origin)) - total_size += base::ComputeDirectorySize(path); + total_size += filesystem_proxy_->ComputeDirectorySize(path); return total_size; }
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h index 7a862de..a064584 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.h +++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -262,6 +262,7 @@ base::Optional<mojo::Receiver<storage::mojom::MockFailureInjector>> mock_failure_injector_; mojo::RemoteSet<storage::mojom::IndexedDBObserver> observers_; + std::unique_ptr<storage::FilesystemProxy> filesystem_proxy_; DISALLOW_COPY_AND_ASSIGN(IndexedDBContextImpl); };
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.cc b/content/browser/indexed_db/indexed_db_factory_impl.cc index 688d957..87e7491 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.cc +++ b/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -18,7 +18,6 @@ #include "base/compiler_specific.h" #include "base/feature_list.h" #include "base/files/file_path.h" -#include "base/files/file_util.h" #include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" @@ -33,11 +32,13 @@ #include "base/timer/timer.h" #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/process_memory_dump.h" +#include "components/services/storage/filesystem_proxy_factory.h" #include "components/services/storage/indexed_db/leveldb/leveldb_factory.h" #include "components/services/storage/indexed_db/scopes/leveldb_scopes.h" #include "components/services/storage/indexed_db/scopes/leveldb_scopes_factory.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_factory.h" +#include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h" #include "components/services/storage/public/mojom/blob_storage_context.mojom.h" #include "components/services/storage/public/mojom/indexed_db_control.mojom.h" #include "content/browser/indexed_db/indexed_db_class_factory.h" @@ -101,10 +102,11 @@ std::tuple<base::FilePath /*leveldb_path*/, base::FilePath /*blob_path*/, leveldb::Status> -CreateDatabaseDirectories(const base::FilePath& path_base, +CreateDatabaseDirectories(storage::FilesystemProxy* filesystem, + const base::FilePath& path_base, const url::Origin& origin) { leveldb::Status status; - if (!base::CreateDirectoryAndGetError(path_base, nullptr)) { + if (filesystem->CreateDirectory(path_base) != base::File::Error::FILE_OK) { status = leveldb::Status::IOError("Unable to create IndexedDB database path"); LOG(ERROR) << status.ToString() << ": \"" << path_base.AsUTF8Unsafe() @@ -118,7 +120,7 @@ path_base.Append(indexed_db::GetLevelDBFileName(origin)); base::FilePath blob_path = path_base.Append(indexed_db::GetBlobStoreFileName(origin)); - if (indexed_db::IsPathTooLong(leveldb_path)) { + if (indexed_db::IsPathTooLong(filesystem, leveldb_path)) { ReportOpenStatus(indexed_db::INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, origin); status = leveldb::Status::IOError("File path too long"); @@ -161,6 +163,7 @@ IndexedDBDataFormatVersion::Decode(raw_db_data_version)), s}; } + } // namespace IndexedDBFactoryImpl::IndexedDBFactoryImpl( @@ -679,8 +682,9 @@ leveldb::Status s = leveldb::Status::OK(); if (!is_incognito_and_in_memory) { // The database will be on-disk and not in-memory. - std::tie(database_path, blob_path, s) = - CreateDatabaseDirectories(data_directory, origin); + auto filesystem_proxy = storage::CreateFilesystemProxy(); + std::tie(database_path, blob_path, s) = CreateDatabaseDirectories( + filesystem_proxy.get(), data_directory, origin); if (!s.ok()) return {IndexedDBOriginStateHandle(), s, CreateDefaultError(), IndexedDBDataLossInfo(), /*was_cold_open=*/true}; @@ -709,11 +713,14 @@ }, origin, weak_factory_.GetWeakPtr()); const bool is_first_attempt = i == 0; + auto filesystem_proxy = !is_incognito_and_in_memory + ? storage::CreateFilesystemProxy() + : nullptr; std::tie(backing_store, s, data_loss_info, disk_full) = OpenAndVerifyIndexedDBBackingStore( origin, data_directory, database_path, blob_path, - std::move(scopes_options), &scopes_factory, is_first_attempt, - create_if_missing); + std::move(scopes_options), &scopes_factory, + std::move(filesystem_proxy), is_first_attempt, create_if_missing); if (LIKELY(is_first_attempt)) first_try_status = s; if (LIKELY(s.ok())) @@ -817,6 +824,7 @@ std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, storage::mojom::NativeFileSystemContext* native_file_system_context, + std::unique_ptr<storage::FilesystemProxy> filesystem_proxy, IndexedDBBackingStore::BlobFilesCleanedCallback blob_files_cleaned, IndexedDBBackingStore::ReportOutstandingBlobsCallback report_outstanding_blobs, @@ -825,8 +833,9 @@ return std::make_unique<IndexedDBBackingStore>( backing_store_mode, transactional_leveldb_factory, origin, blob_path, std::move(db), blob_storage_context, native_file_system_context, - std::move(blob_files_cleaned), std::move(report_outstanding_blobs), - std::move(idb_task_runner), std::move(io_task_runner)); + std::move(filesystem_proxy), std::move(blob_files_cleaned), + std::move(report_outstanding_blobs), std::move(idb_task_runner), + std::move(io_task_runner)); } std::tuple<std::unique_ptr<IndexedDBBackingStore>, leveldb::Status, @@ -839,6 +848,7 @@ base::FilePath blob_path, LevelDBScopesOptions scopes_options, LevelDBScopesFactory* scopes_factory, + std::unique_ptr<storage::FilesystemProxy> filesystem_proxy, bool is_first_attempt, bool create_if_missing) { // Please see docs/open_and_verify_leveldb_database.code2flow, and the @@ -857,8 +867,8 @@ if (!is_incognito_and_in_memory) { // Check for previous corruption, and if found then try to delete the // database. - std::string corruption_message = - indexed_db::ReadCorruptionInfo(data_directory, origin); + std::string corruption_message = indexed_db::ReadCorruptionInfo( + filesystem_proxy.get(), data_directory, origin); if (UNLIKELY(!corruption_message.empty())) { LOG(ERROR) << "IndexedDB recovering from a corrupted (and deleted) " "database."; @@ -954,7 +964,7 @@ std::unique_ptr<IndexedDBBackingStore> backing_store = CreateBackingStore( backing_store_mode, &class_factory_->transactional_leveldb_factory(), origin, blob_path, std::move(database), context_->blob_storage_context(), - context_->native_file_system_context(), + context_->native_file_system_context(), std::move(filesystem_proxy), base::BindRepeating(&IndexedDBFactoryImpl::BlobFilesCleaned, weak_factory_.GetWeakPtr(), origin), base::BindRepeating(&IndexedDBFactoryImpl::ReportOutstandingBlobs,
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.h b/content/browser/indexed_db/indexed_db_factory_impl.h index b1590b6e..cb81798 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.h +++ b/content/browser/indexed_db/indexed_db_factory_impl.h
@@ -153,6 +153,7 @@ std::unique_ptr<TransactionalLevelDBDatabase> db, storage::mojom::BlobStorageContext* blob_storage_context, storage::mojom::NativeFileSystemContext* native_file_system_context, + std::unique_ptr<storage::FilesystemProxy> filesystem_proxy, IndexedDBBackingStore::BlobFilesCleanedCallback blob_files_cleaned, IndexedDBBackingStore::ReportOutstandingBlobsCallback report_outstanding_blobs, @@ -191,14 +192,16 @@ leveldb::Status, IndexedDBDataLossInfo, bool /* is_disk_full */> - OpenAndVerifyIndexedDBBackingStore(const url::Origin& origin, - base::FilePath data_directory, - base::FilePath database_path, - base::FilePath blob_path, - LevelDBScopesOptions scopes_options, - LevelDBScopesFactory* scopes_factory, - bool is_first_attempt, - bool create_if_missing); + OpenAndVerifyIndexedDBBackingStore( + const url::Origin& origin, + base::FilePath data_directory, + base::FilePath database_path, + base::FilePath blob_path, + LevelDBScopesOptions scopes_options, + LevelDBScopesFactory* scopes_factory, + std::unique_ptr<storage::FilesystemProxy> filesystem_proxy, + bool is_first_attempt, + bool create_if_missing); void RemoveOriginState(const url::Origin& origin);
diff --git a/content/browser/indexed_db/indexed_db_fake_backing_store.cc b/content/browser/indexed_db/indexed_db_fake_backing_store.cc index d2beaf65..832d868 100644 --- a/content/browser/indexed_db/indexed_db_fake_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_fake_backing_store.cc
@@ -34,6 +34,9 @@ std::unique_ptr<TransactionalLevelDBDatabase>(), /*blob_storage_context=*/nullptr, /*native_file_system_context=*/nullptr, + std::make_unique<storage::FilesystemProxy>( + storage::FilesystemProxy::UNRESTRICTED, + base::FilePath()), BlobFilesCleanedCallback(), ReportOutstandingBlobsCallback(), base::SequencedTaskRunnerHandle::Get(), @@ -49,6 +52,9 @@ std::unique_ptr<TransactionalLevelDBDatabase>(), /*blob_storage_context=*/nullptr, /*native_file_system_context=*/nullptr, + std::make_unique<storage::FilesystemProxy>( + storage::FilesystemProxy::UNRESTRICTED, + base::FilePath()), std::move(blob_files_cleaned), std::move(report_outstanding_blobs), task_runner,
diff --git a/content/browser/indexed_db/indexed_db_leveldb_operations.cc b/content/browser/indexed_db/indexed_db_leveldb_operations.cc index 3918690..b0e137a 100644 --- a/content/browser/indexed_db/indexed_db_leveldb_operations.cc +++ b/content/browser/indexed_db/indexed_db_leveldb_operations.cc
@@ -4,7 +4,6 @@ #include "content/browser/indexed_db/indexed_db_leveldb_operations.h" -#include "base/files/file_util.h" #include "base/json/json_reader.h" #include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" @@ -74,9 +73,11 @@ FILE_PATH_LITERAL("corruption_info.json")); } -bool IsPathTooLong(const base::FilePath& leveldb_dir) { - int limit = base::GetMaximumPathComponentLength(leveldb_dir.DirName()); - if (limit == -1) { +bool IsPathTooLong(storage::FilesystemProxy* filesystem, + const base::FilePath& leveldb_dir) { + base::Optional<int> limit = + filesystem->GetMaximumPathComponentLength(leveldb_dir.DirName()); + if (!limit.has_value()) { DLOG(WARNING) << "GetMaximumPathComponentLength returned -1"; // In limited testing, ChromeOS returns 143, other OSes 255. #if defined(OS_CHROMEOS) @@ -86,9 +87,9 @@ #endif } size_t component_length = leveldb_dir.BaseName().value().length(); - if (component_length > static_cast<uint32_t>(limit)) { + if (component_length > static_cast<uint32_t>(*limit)) { DLOG(WARNING) << "Path component length (" << component_length - << ") exceeds maximum (" << limit + << ") exceeds maximum (" << *limit << ") allowed by this filesystem."; const int min = 140; const int max = 300; @@ -101,38 +102,46 @@ return false; } -std::string ReadCorruptionInfo(const base::FilePath& path_base, +std::string ReadCorruptionInfo(storage::FilesystemProxy* filesystem_proxy, + const base::FilePath& path_base, const url::Origin& origin) { const base::FilePath info_path = path_base.Append(indexed_db::ComputeCorruptionFileName(origin)); std::string message; - if (IsPathTooLong(info_path)) + if (IsPathTooLong(filesystem_proxy, info_path)) return message; const int64_t kMaxJsonLength = 4096; - int64_t file_size = 0; - if (!base::GetFileSize(info_path, &file_size)) + + base::Optional<base::File::Info> file_info = + filesystem_proxy->GetFileInfo(info_path); + if (!file_info.has_value()) return message; - if (!file_size || file_size > kMaxJsonLength) { - base::DeleteFile(info_path); + if (!file_info->size || file_info->size > kMaxJsonLength) { + filesystem_proxy->RemoveFile(info_path); return message; } - base::File file(info_path, base::File::FLAG_OPEN | base::File::FLAG_READ); - if (file.IsValid()) { - std::string input_js(file_size, '\0'); - if (file_size == file.Read(0, base::data(input_js), file_size)) { - base::Optional<base::Value> val = base::JSONReader::Read(input_js); - if (val && val->is_dict()) { - std::string* s = val->FindStringKey("message"); - if (s) - message = *s; + storage::FileErrorOr<base::File> file_or_error = filesystem_proxy->OpenFile( + info_path, base::File::FLAG_OPEN | base::File::FLAG_READ); + if (!file_or_error.is_error()) { + auto& file = file_or_error.value(); + if (file.IsValid()) { + std::string input_js(file_info->size, '\0'); + if (file_info->size == + file.Read(0, base::data(input_js), file_info->size)) { + base::Optional<base::Value> val = base::JSONReader::Read(input_js); + if (val && val->is_dict()) { + std::string* s = val->FindStringKey("message"); + if (s) + message = *s; + } } + file.Close(); } - file.Close(); } - base::DeleteFile(info_path); + filesystem_proxy->RemoveFile(info_path); return message; }
diff --git a/content/browser/indexed_db/indexed_db_leveldb_operations.h b/content/browser/indexed_db/indexed_db_leveldb_operations.h index 6dbebf8..f8a1334 100644 --- a/content/browser/indexed_db/indexed_db_leveldb_operations.h +++ b/content/browser/indexed_db/indexed_db_leveldb_operations.h
@@ -17,6 +17,7 @@ #include "base/time/time.h" #include "components/services/storage/indexed_db/scopes/leveldb_scopes_factory.h" #include "components/services/storage/indexed_db/transactional_leveldb/leveldb_write_batch.h" +#include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h" #include "content/browser/indexed_db/indexed_db_data_loss_info.h" #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" #include "content/common/content_export.h" @@ -45,14 +46,17 @@ // Returns if the given file path is too long for the current operating system's // file system. -bool IsPathTooLong(const base::FilePath& leveldb_dir); +bool IsPathTooLong(storage::FilesystemProxy* filesystem, + const base::FilePath& leveldb_dir); // If a corruption file for the given |origin| at the given |path_base| exists // it is deleted, and the message is returned. If the file does not exist, or if // there is an error parsing the message, then this method returns an empty // string (and deletes the file). -std::string CONTENT_EXPORT ReadCorruptionInfo(const base::FilePath& path_base, - const url::Origin& origin); +std::string CONTENT_EXPORT +ReadCorruptionInfo(storage::FilesystemProxy* filesystem_proxy, + const base::FilePath& path_base, + const url::Origin& origin); // Was able to use LevelDB to read the data w/o error, but the data read was not // in the expected format.
diff --git a/content/browser/launch_as_mojo_client_browsertest.cc b/content/browser/launch_as_mojo_client_browsertest.cc index a9c134c..ccf7fea1 100644 --- a/content/browser/launch_as_mojo_client_browsertest.cc +++ b/content/browser/launch_as_mojo_client_browsertest.cc
@@ -20,7 +20,6 @@ #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/platform/platform_channel.h" #include "mojo/public/cpp/system/invitation.h" -#include "mojo/public/mojom/base/binder.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #if defined(USE_OZONE) @@ -93,15 +92,12 @@ channel.RemoteProcessLaunchAttempted(); mojo::OutgoingInvitation invitation; - mojo::Remote<mojo_base::mojom::Binder> binder( - mojo::PendingRemote<mojo_base::mojom::Binder>( + mojo::Remote<mojom::ShellController> controller( + mojo::PendingRemote<mojom::ShellController>( invitation.AttachMessagePipe(0), /*version=*/0)); mojo::OutgoingInvitation::Send(std::move(invitation), content_shell_process_.Handle(), channel.TakeLocalEndpoint()); - - mojo::Remote<mojom::ShellController> controller; - binder->Bind(controller.BindNewPipeAndPassReceiver()); return controller; }
diff --git a/content/browser/manifest/manifest_browsertest.cc b/content/browser/manifest/manifest_browsertest.cc index cecb5b1..341d53eb 100644 --- a/content/browser/manifest/manifest_browsertest.cc +++ b/content/browser/manifest/manifest_browsertest.cc
@@ -9,6 +9,7 @@ #include "base/command_line.h" #include "base/macros.h" #include "base/path_service.h" +#include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "content/public/browser/render_frame_host.h" @@ -24,6 +25,9 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/manifest/manifest.h" #include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h" @@ -31,6 +35,13 @@ namespace content { +namespace { + +using ::testing::Contains; +using ::testing::HasSubstr; + +} // namespace + class ManifestBrowserTest; // Mock of a WebContentsDelegate that catches messages sent to the console. @@ -57,8 +68,9 @@ protected: friend MockWebContentsDelegate; - ManifestBrowserTest() : console_error_count_(0) { - cors_embedded_test_server_.reset(new net::EmbeddedTestServer); + ManifestBrowserTest() + : cors_embedded_test_server_( + std::make_unique<net::EmbeddedTestServer>()) { cors_embedded_test_server_->ServeFilesFromSourceDirectory( GetTestDataFilePath()); } @@ -108,11 +120,15 @@ ->GetRemoteAssociatedInterfaces() ->GetInterface(&remote); remote.FlushForTesting(); - return console_error_count_; + return console_errors_.size(); } - void OnReceivedConsoleError() { - console_error_count_++; + const std::vector<std::string>& console_errors() const { + return console_errors_; + } + + void OnReceivedConsoleError(base::StringPiece16 message) { + console_errors_.push_back(base::UTF16ToUTF8(message)); } net::EmbeddedTestServer* cors_embedded_test_server() const { @@ -155,7 +171,7 @@ std::unique_ptr<net::EmbeddedTestServer> cors_embedded_test_server_; GURL manifest_url_; blink::Manifest manifest_; - int console_error_count_; + std::vector<std::string> console_errors_; std::vector<GURL> reported_manifest_urls_; std::vector<size_t> manifests_reported_when_favicon_url_updated_; @@ -174,7 +190,7 @@ if (log_level == blink::mojom::ConsoleMessageLevel::kError || log_level == blink::mojom::ConsoleMessageLevel::kWarning) - test_->OnReceivedConsoleError(); + test_->OnReceivedConsoleError(message); return false; } @@ -361,7 +377,7 @@ GetManifestAndWait(); EXPECT_TRUE(manifest().IsEmpty()); EXPECT_FALSE(manifest_url().is_empty()); - // 1 error for CORS violation + EXPECT_THAT(console_errors(), Contains(HasSubstr("CORS"))); EXPECT_EQ(1, GetConsoleErrorCount()); expected_manifest_urls.push_back(manifest_url()); EXPECT_EQ(expected_manifest_urls, reported_manifest_urls()); @@ -411,26 +427,28 @@ // If a page's manifest is in an insecure origin while the page is in a secure // origin, requesting the manifest should return the empty manifest. IN_PROC_BROWSER_TEST_F(ManifestBrowserTest, MixedContentManifest) { + ASSERT_TRUE(cors_embedded_test_server()->Start()); std::unique_ptr<net::EmbeddedTestServer> https_server( new net::EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS)); https_server->ServeFilesFromSourceDirectory(GetTestDataFilePath()); ASSERT_TRUE(https_server->Start()); - GURL test_url = - embedded_test_server()->GetURL("/manifest/dynamic-manifest.html"); + GURL test_url = https_server->GetURL("/manifest/dynamic-manifest.html"); ASSERT_TRUE(NavigateToURL(shell(), test_url)); - std::string manifest_link = - https_server->GetURL("/manifest/dummy-manifest.json").spec(); - ASSERT_TRUE(ExecuteScript(shell(), "setManifestTo('" + manifest_link + "')")); + GURL manifest_link = cors_embedded_test_server()->GetURL( + "insecure.example", "/manifest/manifest-cors.json"); + // Ensure the manifest really is mixed content: + ASSERT_FALSE(network::IsUrlPotentiallyTrustworthy(manifest_link)); + ASSERT_TRUE( + ExecuteScript(shell(), JsReplace("setManifestTo($1)", manifest_link))); GetManifestAndWait(); EXPECT_TRUE(manifest().IsEmpty()); EXPECT_FALSE(manifest_url().is_empty()); - // 1 error for mixed-content check violation - EXPECT_EQ(1, GetConsoleErrorCount()); + EXPECT_THAT(console_errors(), Contains(HasSubstr("Mixed Content"))); ASSERT_EQ(1u, reported_manifest_urls().size()); EXPECT_EQ(manifest_url(), reported_manifest_urls()[0]); ASSERT_EQ(1u, manifests_reported_when_favicon_url_updated().size());
diff --git a/content/browser/media/capture/frame_sink_video_capture_device.cc b/content/browser/media/capture/frame_sink_video_capture_device.cc index 11c02ab..64c426e 100644 --- a/content/browser/media/capture/frame_sink_video_capture_device.cc +++ b/content/browser/media/capture/frame_sink_video_capture_device.cc
@@ -182,8 +182,9 @@ } } -void FrameSinkVideoCaptureDevice::OnUtilizationReport(int frame_feedback_id, - double utilization) { +void FrameSinkVideoCaptureDevice::OnUtilizationReport( + int frame_feedback_id, + media::VideoFrameFeedback feedback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Assumption: The mojo InterfacePtr in |frame_callbacks_| should be valid at @@ -191,7 +192,7 @@ // VideoFrameReceiver signals it is done consuming the frame. const auto index = static_cast<size_t>(frame_feedback_id); DCHECK_LT(index, frame_callbacks_.size()); - frame_callbacks_[index]->ProvideFeedback(utilization); + frame_callbacks_[index]->ProvideFeedback(feedback); } void FrameSinkVideoCaptureDevice::OnFrameCaptured(
diff --git a/content/browser/media/capture/frame_sink_video_capture_device.h b/content/browser/media/capture/frame_sink_video_capture_device.h index 4508c09..766a949 100644 --- a/content/browser/media/capture/frame_sink_video_capture_device.h +++ b/content/browser/media/capture/frame_sink_video_capture_device.h
@@ -72,7 +72,8 @@ void MaybeSuspend() final; void Resume() final; void StopAndDeAllocate() final; - void OnUtilizationReport(int frame_feedback_id, double utilization) final; + void OnUtilizationReport(int frame_feedback_id, + media::VideoFrameFeedback feedback) final; // FrameSinkVideoConsumer implementation. void OnFrameCaptured(
diff --git a/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc b/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc index 3fb27b6..e003af1 100644 --- a/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc +++ b/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc
@@ -147,7 +147,7 @@ } MOCK_METHOD0(Done, void()); - MOCK_METHOD1(ProvideFeedback, void(double utilization)); + MOCK_METHOD1(ProvideFeedback, void(const media::VideoFrameFeedback&)); private: mojo::Receiver<viz::mojom::FrameSinkVideoConsumerFrameCallbacks> receiver_{ @@ -493,15 +493,17 @@ MockFrameSinkVideoConsumerFrameCallbacks& callbacks = callbackses[frame_number - first_frame_number]; - const double fake_utilization = - static_cast<double>(frame_number) / kNumFramesToDeliver; - EXPECT_CALL(callbacks, ProvideFeedback(fake_utilization)); + const media::VideoFrameFeedback fake_feedback = + media::VideoFrameFeedback( + static_cast<double>(frame_number) / kNumFramesToDeliver, + std::numeric_limits<float>::infinity(), base::nullopt); + EXPECT_CALL(callbacks, ProvideFeedback(fake_feedback)); EXPECT_CALL(callbacks, Done()); EXPECT_CALL(*receiver, OnBufferRetired(buffer_id)); const int feedback_id = receiver->TakeFeedbackId(buffer_id); POST_DEVICE_METHOD_CALL(OnUtilizationReport, feedback_id, - fake_utilization); + fake_feedback); receiver->ReleaseAccessPermission(buffer_id); WAIT_FOR_DEVICE_TASKS(); }
diff --git a/content/browser/media/capture/screen_capture_device_android.cc b/content/browser/media/capture/screen_capture_device_android.cc index 098a40b..382da05 100644 --- a/content/browser/media/capture/screen_capture_device_android.cc +++ b/content/browser/media/capture/screen_capture_device_android.cc
@@ -68,11 +68,12 @@ capture_machine_.MaybeCaptureForRefresh(); } -void ScreenCaptureDeviceAndroid::OnUtilizationReport(int frame_feedback_id, - double utilization) { +void ScreenCaptureDeviceAndroid::OnUtilizationReport( + int frame_feedback_id, + media::VideoFrameFeedback feedback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(oracle_proxy_); - oracle_proxy_->OnConsumerReportingUtilization(frame_feedback_id, utilization); + oracle_proxy_->OnConsumerReportingUtilization(frame_feedback_id, feedback); } } // namespace content
diff --git a/content/browser/media/capture/screen_capture_device_android.h b/content/browser/media/capture/screen_capture_device_android.h index 14112269..8c4fa3e 100644 --- a/content/browser/media/capture/screen_capture_device_android.h +++ b/content/browser/media/capture/screen_capture_device_android.h
@@ -29,7 +29,8 @@ std::unique_ptr<Client> client) override; void StopAndDeAllocate() override; void RequestRefreshFrame() override; - void OnUtilizationReport(int frame_feedback_id, double utilization) override; + void OnUtilizationReport(int frame_feedback_id, + media::VideoFrameFeedback feedback) override; private: SEQUENCE_CHECKER(sequence_checker_);
diff --git a/content/browser/media/capture/slow_window_capturer_chromeos.cc b/content/browser/media/capture/slow_window_capturer_chromeos.cc index 2598222..4b8d45f 100644 --- a/content/browser/media/capture/slow_window_capturer_chromeos.cc +++ b/content/browser/media/capture/slow_window_capturer_chromeos.cc
@@ -197,7 +197,7 @@ buffer_ = base::MappedReadOnlyRegion(); } - void ProvideFeedback(double utilization) final {} + void ProvideFeedback(const media::VideoFrameFeedback& feedback) final {} private: base::WeakPtr<SlowWindowCapturerChromeOS> capturer_;
diff --git a/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc b/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc index c52e805..37b9704 100644 --- a/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc +++ b/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc
@@ -46,8 +46,9 @@ base::OnceClosure done_cb) override { // Do nothing. } - void OnUtilizationReport(int frame_feedback_id, double utilization) override { - device_->OnUtilizationReport(frame_feedback_id, utilization); + void OnUtilizationReport(int frame_feedback_id, + media::VideoFrameFeedback feedback) override { + device_->OnUtilizationReport(frame_feedback_id, feedback); } private:
diff --git a/content/browser/renderer_host/media/in_process_launched_video_capture_device.cc b/content/browser/renderer_host/media/in_process_launched_video_capture_device.cc index a9c0ad6..5631156 100644 --- a/content/browser/renderer_host/media/in_process_launched_video_capture_device.cc +++ b/content/browser/renderer_host/media/in_process_launched_video_capture_device.cc
@@ -139,7 +139,7 @@ void InProcessLaunchedVideoCaptureDevice::OnUtilizationReport( int frame_feedback_id, - double utilization) { + media::VideoFrameFeedback feedback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); // Unretained() is safe to use here because |device| would be null if it // was scheduled for shutdown and destruction, and because this task is @@ -147,7 +147,7 @@ device_task_runner_->PostTask( FROM_HERE, base::BindOnce(&media::VideoCaptureDevice::OnUtilizationReport, base::Unretained(device_.get()), - frame_feedback_id, utilization)); + frame_feedback_id, feedback)); } void InProcessLaunchedVideoCaptureDevice::
diff --git a/content/browser/renderer_host/media/in_process_launched_video_capture_device.h b/content/browser/renderer_host/media/in_process_launched_video_capture_device.h index f25a1ba..8f82de47 100644 --- a/content/browser/renderer_host/media/in_process_launched_video_capture_device.h +++ b/content/browser/renderer_host/media/in_process_launched_video_capture_device.h
@@ -33,7 +33,8 @@ void SetDesktopCaptureWindowIdAsync(gfx::NativeViewId window_id, base::OnceClosure done_cb) override; - void OnUtilizationReport(int frame_feedback_id, double utilization) override; + void OnUtilizationReport(int frame_feedback_id, + media::VideoFrameFeedback feedback) override; private: void SetDesktopCaptureWindowIdOnDeviceThread(
diff --git a/content/browser/renderer_host/media/mock_video_capture_provider.h b/content/browser/renderer_host/media/mock_video_capture_provider.h index c53a1fb..08987fd 100644 --- a/content/browser/renderer_host/media/mock_video_capture_provider.h +++ b/content/browser/renderer_host/media/mock_video_capture_provider.h
@@ -76,7 +76,7 @@ MOCK_METHOD2(DoSetDesktopCaptureWindowId, void(gfx::NativeViewId window_id, base::OnceClosure* done_cb)); MOCK_METHOD2(OnUtilizationReport, - void(int frame_feedback_id, double utilization)); + void(int frame_feedback_id, media::VideoFrameFeedback)); void GetPhotoState( media::VideoCaptureDevice::GetPhotoStateCallback callback) override {
diff --git a/content/browser/renderer_host/media/service_launched_video_capture_device.cc b/content/browser/renderer_host/media/service_launched_video_capture_device.cc index 4f785f10..294cb918 100644 --- a/content/browser/renderer_host/media/service_launched_video_capture_device.cc +++ b/content/browser/renderer_host/media/service_launched_video_capture_device.cc
@@ -92,7 +92,7 @@ void ServiceLaunchedVideoCaptureDevice::OnUtilizationReport( int frame_feedback_id, - double utilization) { + media::VideoFrameFeedback feedback) { DCHECK(sequence_checker_.CalledOnValidSequence()); // Nothing to do here. The video capture service does not support utilization // reporting.
diff --git a/content/browser/renderer_host/media/service_launched_video_capture_device.h b/content/browser/renderer_host/media/service_launched_video_capture_device.h index b0fdca69..4e8a06f 100644 --- a/content/browser/renderer_host/media/service_launched_video_capture_device.h +++ b/content/browser/renderer_host/media/service_launched_video_capture_device.h
@@ -38,7 +38,8 @@ void SetDesktopCaptureWindowIdAsync(gfx::NativeViewId window_id, base::OnceClosure done_cb) override; - void OnUtilizationReport(int frame_feedback_id, double utilization) override; + void OnUtilizationReport(int frame_feedback_id, + media::VideoFrameFeedback feedback) override; private: void OnLostConnectionToSourceOrSubscription();
diff --git a/content/browser/renderer_host/media/video_capture_browsertest.cc b/content/browser/renderer_host/media/video_capture_browsertest.cc index 08aa596..e960f692 100644 --- a/content/browser/renderer_host/media/video_capture_browsertest.cc +++ b/content/browser/renderer_host/media/video_capture_browsertest.cc
@@ -326,9 +326,10 @@ received_frame_info.timestamp = frame_info->timestamp; received_frame_infos.emplace_back(received_frame_info); - const double kArbitraryUtilization = 0.5; + const media::VideoFrameFeedback kArbitraryFeedback = + media::VideoFrameFeedback(0.5, 60.0, base::nullopt); controller_->ReturnBuffer(id, &mock_controller_event_handler_, - buffer_id, kArbitraryUtilization); + buffer_id, kArbitraryFeedback); if ((received_frame_infos.size() >= kMinFramesToReceive && !must_wait_for_gpu_decode_to_start) ||
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc index a4fe0a29..eaad71e 100644 --- a/content/browser/renderer_host/media/video_capture_controller.cc +++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -180,8 +180,6 @@ frame_feedback_id_(0), consumer_feedback_observer_(consumer_feedback_observer), buffer_handle_(std::move(buffer_handle)), - max_consumer_utilization_( - media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded), consumer_hold_count_(0) {} VideoCaptureController::BufferContext::~BufferContext() = default; @@ -193,11 +191,8 @@ operator=(BufferContext&& other) = default; void VideoCaptureController::BufferContext::RecordConsumerUtilization( - double utilization) { - if (std::isfinite(utilization) && utilization >= 0.0) { - max_consumer_utilization_ = - std::max(max_consumer_utilization_, utilization); - } + const media::VideoFrameFeedback& feedback) { + combined_consumer_feedback_.Combine(feedback); } void VideoCaptureController::BufferContext::IncreaseConsumerCount() { @@ -208,14 +203,12 @@ consumer_hold_count_--; if (consumer_hold_count_ == 0) { if (consumer_feedback_observer_ != nullptr && - max_consumer_utilization_ != - media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded) { + !combined_consumer_feedback_.Empty()) { consumer_feedback_observer_->OnUtilizationReport( - frame_feedback_id_, max_consumer_utilization_); + frame_feedback_id_, combined_consumer_feedback_); } buffer_read_permission_.reset(); - max_consumer_utilization_ = - media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded; + combined_consumer_feedback_ = media::VideoFrameFeedback(); } } @@ -355,9 +348,8 @@ return base::UnguessableToken(); for (const auto& buffer_id : client->buffers_in_use) { - OnClientFinishedConsumingBuffer( - client, buffer_id, - media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded); + OnClientFinishedConsumingBuffer(client, buffer_id, + media::VideoFrameFeedback()); } client->buffers_in_use.clear(); @@ -447,7 +439,7 @@ const VideoCaptureControllerID& id, VideoCaptureControllerEventHandler* event_handler, int buffer_id, - double consumer_resource_utilization) { + const media::VideoFrameFeedback& feedback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); ControllerClient* client = FindClient(id, event_handler, controller_clients_); @@ -467,8 +459,7 @@ } client->buffers_in_use.erase(buffers_in_use_entry_iter); - OnClientFinishedConsumingBuffer(client, buffer_id, - consumer_resource_utilization); + OnClientFinishedConsumingBuffer(client, buffer_id, feedback); } const base::Optional<media::VideoCaptureFormat> @@ -810,12 +801,12 @@ void VideoCaptureController::OnClientFinishedConsumingBuffer( ControllerClient* client, int buffer_context_id, - double consumer_resource_utilization) { + const media::VideoFrameFeedback& feedback) { auto buffer_context_iter = FindBufferContextFromBufferContextId(buffer_context_id); DCHECK(buffer_context_iter != buffer_contexts_.end()); - buffer_context_iter->RecordConsumerUtilization(consumer_resource_utilization); + buffer_context_iter->RecordConsumerUtilization(feedback); buffer_context_iter->DecreaseConsumerCount(); if (!buffer_context_iter->HasConsumers() && buffer_context_iter->is_retired()) {
diff --git a/content/browser/renderer_host/media/video_capture_controller.h b/content/browser/renderer_host/media/video_capture_controller.h index 0b248bc4..8bb87b8 100644 --- a/content/browser/renderer_host/media/video_capture_controller.h +++ b/content/browser/renderer_host/media/video_capture_controller.h
@@ -105,7 +105,7 @@ void ReturnBuffer(const VideoCaptureControllerID& id, VideoCaptureControllerEventHandler* event_handler, int buffer_id, - double consumer_resource_utilization); + const media::VideoFrameFeedback& feedback); const base::Optional<media::VideoCaptureFormat> GetVideoCaptureFormat() const; @@ -191,7 +191,7 @@ buffer_read_permission) { buffer_read_permission_ = std::move(buffer_read_permission); } - void RecordConsumerUtilization(double utilization); + void RecordConsumerUtilization(const media::VideoFrameFeedback& feedback); void IncreaseConsumerCount(); void DecreaseConsumerCount(); bool HasConsumers() const { return consumer_hold_count_ > 0; } @@ -204,7 +204,8 @@ int frame_feedback_id_; media::VideoFrameConsumerFeedbackObserver* consumer_feedback_observer_; media::mojom::VideoBufferHandlePtr buffer_handle_; - double max_consumer_utilization_; + media::VideoFrameFeedback combined_consumer_feedback_; + int consumer_hold_count_; std::unique_ptr< media::VideoCaptureDevice::Client::Buffer::ScopedAccessPermission> @@ -237,9 +238,10 @@ std::vector<BufferContext>::iterator FindUnretiredBufferContextFromBufferId( int buffer_id); - void OnClientFinishedConsumingBuffer(ControllerClient* client, - int buffer_id, - double consumer_resource_utilization); + void OnClientFinishedConsumingBuffer( + ControllerClient* client, + int buffer_id, + const media::VideoFrameFeedback& feedback); void ReleaseBufferContext( const std::vector<BufferContext>::iterator& buffer_state_iter);
diff --git a/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/content/browser/renderer_host/media/video_capture_controller_unittest.cc index 2a487b3..8c71a36 100644 --- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc +++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
@@ -69,7 +69,7 @@ public: explicit MockVideoCaptureControllerEventHandler( VideoCaptureController* controller) - : controller_(controller), resource_utilization_(-1.0) {} + : controller_(controller) {} ~MockVideoCaptureControllerEventHandler() override {} void set_enable_auto_return_buffer_on_buffer_ready(bool enable) { enable_auto_return_buffer_on_buffer_ready_ = enable; @@ -114,7 +114,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&VideoCaptureController::ReturnBuffer, base::Unretained(controller_), id, this, - buffer_id, resource_utilization_)); + buffer_id, feedback_)); } } void OnEnded(const VideoCaptureControllerID& id) override { @@ -129,7 +129,7 @@ VideoCaptureController* controller_; media::VideoPixelFormat expected_pixel_format_ = media::PIXEL_FORMAT_I420; gfx::ColorSpace expected_color_space_ = gfx::ColorSpace::CreateREC709(); - double resource_utilization_; + media::VideoFrameFeedback feedback_; bool enable_auto_return_buffer_on_buffer_ready_ = true; }; @@ -409,12 +409,15 @@ EXPECT_CALL(*client_a_, DoBufferReady(client_a_route_2, device_format.frame_size)); } - client_a_->resource_utilization_ = 0.5; - client_b_->resource_utilization_ = -1.0; + client_a_->feedback_.resource_utilization = 0.5; + client_b_->feedback_.resource_utilization = base::nullopt; // Expect VideoCaptureController to call the load observer with a // resource utilization of 0.5 (the largest of all reported values). - EXPECT_CALL(*mock_launched_device_, - OnUtilizationReport(arbitrary_frame_feedback_id, 0.5)); + const media::VideoFrameFeedback kExpectedFeedback = media::VideoFrameFeedback( + 0.5, std::numeric_limits<float>::infinity(), base::nullopt); + EXPECT_CALL( + *mock_launched_device_, + OnUtilizationReport(arbitrary_frame_feedback_id, kExpectedFeedback)); device_client_->OnIncomingCapturedBuffer(std::move(buffer), device_format, arbitrary_reference_time_, @@ -437,12 +440,15 @@ result_code_2); auto buffer2_access = buffer2.handle_provider->GetHandleForInProcessAccess(); memset(buffer2_access->data(), buffer_no++, buffer2_access->mapped_size()); - client_a_->resource_utilization_ = 0.5; - client_b_->resource_utilization_ = 3.14; + + client_a_->feedback_ = media::VideoFrameFeedback(0.5, 60, 1000); + client_b_->feedback_ = media::VideoFrameFeedback(3.14, 30, base::nullopt); // Expect VideoCaptureController to call the load observer with a - // resource utilization of 3.14 (the largest of all reported values). + // resource utilization of 3.14 (the largest of all reported values) and + // sink constraints being the minimum of all reported values. EXPECT_CALL(*mock_launched_device_, - OnUtilizationReport(arbitrary_frame_feedback_id_2, 3.14)); + OnUtilizationReport(arbitrary_frame_feedback_id_2, + media::VideoFrameFeedback(3.14, 30, 1000))); device_client_->OnIncomingCapturedBuffer(std::move(buffer2), device_format, arbitrary_reference_time_, @@ -703,17 +709,19 @@ for (int frame_index = 0; frame_index < kTestFrameSequenceLength; frame_index++) { const int stub_frame_feedback_id = frame_index; - const float stub_consumer_utilization = - static_cast<float>(frame_index) / kTestFrameSequenceLength; + const media::VideoFrameFeedback stub_consumer_feedback = + media::VideoFrameFeedback( + static_cast<float>(frame_index) / kTestFrameSequenceLength, + std::numeric_limits<float>::infinity(), base::nullopt); - client_a_->resource_utilization_ = stub_consumer_utilization; + client_a_->feedback_ = stub_consumer_feedback; EXPECT_CALL(*client_a_, DoBufferReady(route_id, arbitrary_format.frame_size)) .Times(1); EXPECT_CALL( *mock_launched_device_, - OnUtilizationReport(stub_frame_feedback_id, stub_consumer_utilization)) + OnUtilizationReport(stub_frame_feedback_id, stub_consumer_feedback)) .Times(1); // Device prepares and pushes a frame. @@ -814,10 +822,10 @@ // |client_a_| signals to |controller_| that it has finished consuming the // frame. EXPECT_CALL(*client_a_, DoBufferDestroyed(_, _)).Times(1); - const double arbitrary_utilization = 0.0; + const media::VideoFrameFeedback arbitrary_feedback = + media::VideoFrameFeedback(); controller_->ReturnBuffer(arbitrary_route_id_, client_a_.get(), - buffer_id_reported_to_client, - arbitrary_utilization); + buffer_id_reported_to_client, arbitrary_feedback); base::RunLoop().RunUntilIdle(); Mock::VerifyAndClearExpectations(client_a_.get()); } @@ -873,9 +881,10 @@ // first frame. EXPECT_CALL(*client_a_, DoBufferDestroyed(_, first_buffer_id)).Times(1); EXPECT_CALL(*client_a_, DoBufferDestroyed(_, second_buffer_id)).Times(0); - const double arbitrary_utilization = 0.0; + const media::VideoFrameFeedback arbitrary_feedback = + media::VideoFrameFeedback(); controller_->ReturnBuffer(arbitrary_route_id_, client_a_.get(), - first_buffer_id, arbitrary_utilization); + first_buffer_id, arbitrary_feedback); base::RunLoop().RunUntilIdle(); Mock::VerifyAndClearExpectations(client_a_.get()); @@ -885,7 +894,7 @@ EXPECT_CALL(*client_a_, DoBufferDestroyed(_, first_buffer_id)).Times(0); EXPECT_CALL(*client_a_, DoBufferDestroyed(_, second_buffer_id)).Times(0); controller_->ReturnBuffer(arbitrary_route_id_, client_a_.get(), - second_buffer_id, arbitrary_utilization); + second_buffer_id, arbitrary_feedback); base::RunLoop().RunUntilIdle(); Mock::VerifyAndClearExpectations(client_a_.get()); }
diff --git a/content/browser/renderer_host/media/video_capture_host.cc b/content/browser/renderer_host/media/video_capture_host.cc index a5b883c..067c963 100644 --- a/content/browser/renderer_host/media/video_capture_host.cc +++ b/content/browser/renderer_host/media/video_capture_host.cc
@@ -277,9 +277,10 @@ } } -void VideoCaptureHost::ReleaseBuffer(const base::UnguessableToken& device_id, - int32_t buffer_id, - double consumer_resource_utilization) { +void VideoCaptureHost::ReleaseBuffer( + const base::UnguessableToken& device_id, + int32_t buffer_id, + const media::VideoFrameFeedback& feedback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); VideoCaptureControllerID controller_id(device_id); @@ -289,8 +290,7 @@ const base::WeakPtr<VideoCaptureController>& controller = it->second; if (controller) { - controller->ReturnBuffer(controller_id, this, buffer_id, - consumer_resource_utilization); + controller->ReturnBuffer(controller_id, this, buffer_id, feedback); } }
diff --git a/content/browser/renderer_host/media/video_capture_host.h b/content/browser/renderer_host/media/video_capture_host.h index 0e5ff7d7b..183d973 100644 --- a/content/browser/renderer_host/media/video_capture_host.h +++ b/content/browser/renderer_host/media/video_capture_host.h
@@ -85,7 +85,7 @@ void RequestRefreshFrame(const base::UnguessableToken& device_id) override; void ReleaseBuffer(const base::UnguessableToken& device_id, int32_t buffer_id, - double consumer_resource_utilization) override; + const media::VideoFrameFeedback& feedback) override; void GetDeviceSupportedFormats( const base::UnguessableToken& device_id, const base::UnguessableToken& session_id,
diff --git a/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/content/browser/renderer_host/render_widget_host_view_event_handler.cc index 44586cc..51342ad 100644 --- a/content/browser/renderer_host/render_widget_host_view_event_handler.cc +++ b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
@@ -994,8 +994,10 @@ gfx::PointF mouse_screen_position) { // Do not need to move to center in unadjusted movement mode as // the movement value are directly from OS. +#if defined(OS_WIN) if (mouse_locked_unadjusted_movement_) return false; +#endif gfx::Rect rect = window_->bounds(); rect = delegate_->ConvertRectToScreen(rect);
diff --git a/content/common/render_accessibility.mojom b/content/common/render_accessibility.mojom index c03f2a0..5f8b2f5 100644 --- a/content/common/render_accessibility.mojom +++ b/content/common/render_accessibility.mojom
@@ -48,10 +48,21 @@ // reset request from the browser. When the browser requests a reset, it // ignores incoming remote calls until it sees one with the correct reset // token. Any other time, it ignores further calls with a reset token. + // + // The accessibility information sent to the browser is dependent on both + // the number of nodes in the DOM (and their accessibility metadata) as well + // as the number of changes that generate events. Therefore, this payload can + // become arbitrarily large. + // TODO(crbug.com/1088484) tracks work to improve the payload size. + [UnlimitedSize] HandleAXEvents(array<ax.mojom.AXTreeUpdate> updates, array<ax.mojom.AXEvent> events, int32 reset_token) => (); // Sent to update the browser of the location of accessibility objects. + // Similar to HandleAXEvents, the message size is also unbounded (though in + // practice these message sizes are quite a bit smaller than HandleAXEvents). + // TODO(crbug.com/1088484) tracks work to improve the payload size. + [UnlimitedSize] HandleAXLocationChanges(array<LocationChanges> changes); };
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index c3dd4fc..7b19c20 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -1120,7 +1120,7 @@ } void ContentBrowserClient::BindBrowserControlInterface( - mojo::GenericPendingReceiver receiver) {} + mojo::ScopedMessagePipeHandle pipe) {} bool ContentBrowserClient::ShouldInheritCrossOriginEmbedderPolicyImplicitly( const GURL& url) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 4c27c7fb..0229ba39 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -41,6 +41,7 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/system/message_pipe.h" #include "ppapi/buildflags/buildflags.h" #include "services/network/public/mojom/network_context.mojom-forward.h" #include "services/network/public/mojom/restricted_cookie_manager.mojom-forward.h" @@ -1881,8 +1882,7 @@ // External applications and services may launch the browser in a mode which // exposes browser control interfaces via Mojo. Any such interface binding // request received from an external client is passed to this method. - virtual void BindBrowserControlInterface( - mojo::GenericPendingReceiver receiver); + virtual void BindBrowserControlInterface(mojo::ScopedMessagePipeHandle pipe); // Returns true when a context (e.g., iframe) whose URL is |url| should // inherit the parent COEP value implicitly, similar to "blob:"
diff --git a/content/public/browser/devtools_agent_host.h b/content/public/browser/devtools_agent_host.h index d633f53..a978c21 100644 --- a/content/public/browser/devtools_agent_host.h +++ b/content/public/browser/devtools_agent_host.h
@@ -126,6 +126,9 @@ // embedder or |client| itself may prevent attaching. virtual bool AttachClient(DevToolsAgentHostClient* client) = 0; + // Same as the above, but does not acquire the WakeLock. + virtual bool AttachClientWithoutWakeLock(DevToolsAgentHostClient* client) = 0; + // Already attached client detaches from this agent host to stop debugging it. // Returns true iff detach succeeded. virtual bool DetachClient(DevToolsAgentHostClient* client) = 0;
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h index e1bd458..8ab07f1 100644 --- a/content/public/renderer/render_frame_observer.h +++ b/content/public/renderer/render_frame_observer.h
@@ -56,7 +56,7 @@ public IPC::Sender { public: // A subclass can use this to delete itself. If it does not, the subclass must - // always null-check each call to render_frame() becase the RenderFrame can + // always null-check each call to render_frame() because the RenderFrame can // go away at any time. virtual void OnDestruct() = 0;
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 5f5645c..491e16e 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -440,12 +440,10 @@ } void ShellContentBrowserClient::BindBrowserControlInterface( - mojo::GenericPendingReceiver receiver) { - if (auto r = receiver.As<mojom::ShellController>()) { - mojo::MakeSelfOwnedReceiver(std::make_unique<ShellControllerImpl>(), - std::move(r)); - return; - } + mojo::ScopedMessagePipeHandle pipe) { + mojo::MakeSelfOwnedReceiver( + std::make_unique<ShellControllerImpl>(), + mojo::PendingReceiver<mojom::ShellController>(std::move(pipe))); } ShellBrowserContext* ShellContentBrowserClient::browser_context() {
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h index c85d7c0..9e0009f 100644 --- a/content/shell/browser/shell_content_browser_client.h +++ b/content/shell/browser/shell_content_browser_client.h
@@ -112,8 +112,7 @@ network::mojom::CertVerifierCreationParams* cert_verifier_creation_params) override; std::vector<base::FilePath> GetNetworkContextsParentDirectory() override; - void BindBrowserControlInterface( - mojo::GenericPendingReceiver receiver) override; + void BindBrowserControlInterface(mojo::ScopedMessagePipeHandle pipe) override; ShellBrowserContext* browser_context(); ShellBrowserContext* off_the_record_browser_context();
diff --git a/content/test/gpu/trim_culprit_cls.py b/content/test/gpu/trim_culprit_cls.py index 32e2585..3ae6df6 100755 --- a/content/test/gpu/trim_culprit_cls.py +++ b/content/test/gpu/trim_culprit_cls.py
@@ -8,6 +8,29 @@ There are cases where CLs can be absolved of a CI failure if they ran on a similar trybot before being submitted. This CL will go through each CL in a given blamelist and determine whether they ran on a specified trybot or not. + +This script depends on the `bq` tool, which is available as part of the Google +Cloud SDK https://cloud.google.com/sdk/docs/quickstarts. + +Example usage: + +trim_culprit_cls.py \ + --start-revision <first/oldest revision in the blamelist> \ + --end-revision <last/newest revision in the blamelist> \ + --trybot <optional trybot name> \ + --project <billing project> + +Concrete example: + +trim_culprit_cls.py \ + --start-revision 1cdf916d194215f1e4139f295e494fc1c1863c3c \ + --end-revision 9aa31419100be8d0f02708a500aaed7c33a53a10 \ + --trybot win_optional_gpu_tests_rel \ + --project chromium-swarm + +The --project argument can be any project you are associated with in the +Google Cloud console https://console.cloud.google.com/ (see drop-down menu in +the top left corner). """ import argparse
diff --git a/device/bluetooth/bluetooth_classic_device_mac.h b/device/bluetooth/bluetooth_classic_device_mac.h index b7ed051..68fab55 100644 --- a/device/bluetooth/bluetooth_classic_device_mac.h +++ b/device/bluetooth/bluetooth_classic_device_mac.h
@@ -33,6 +33,7 @@ // BluetoothDevice override uint32_t GetBluetoothClass() const override; std::string GetAddress() const override; + AddressType GetAddressType() const override; VendorIDSource GetVendorIDSource() const override; uint16_t GetVendorID() const override; uint16_t GetProductID() const override;
diff --git a/device/bluetooth/bluetooth_classic_device_mac.mm b/device/bluetooth/bluetooth_classic_device_mac.mm index 839aca9..43bac24 100644 --- a/device/bluetooth/bluetooth_classic_device_mac.mm +++ b/device/bluetooth/bluetooth_classic_device_mac.mm
@@ -85,6 +85,11 @@ return GetDeviceAddress(device_); } +BluetoothDevice::AddressType BluetoothClassicDeviceMac::GetAddressType() const { + NOTIMPLEMENTED(); + return ADDR_TYPE_UNKNOWN; +} + BluetoothDevice::VendorIDSource BluetoothClassicDeviceMac::GetVendorIDSource() const { return VENDOR_ID_UNKNOWN;
diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h index 643cad1f..31aa41b 100644 --- a/device/bluetooth/bluetooth_device.h +++ b/device/bluetooth/bluetooth_device.h
@@ -60,6 +60,13 @@ VENDOR_ID_MAX_VALUE = VENDOR_ID_USB }; + // Possible values that may be returned by GetAddressType(). + enum AddressType { + ADDR_TYPE_UNKNOWN, + ADDR_TYPE_PUBLIC, + ADDR_TYPE_RANDOM, + }; + // The value returned if the RSSI or transmit power cannot be read. static const int kUnknownPower = 127; // The value returned if the appearance is not present. @@ -219,6 +226,10 @@ // a unique key to identify the device and copied where needed. virtual std::string GetAddress() const = 0; + // Returns the Bluetooth address type of the device. Currently available on + // Linux and Chrome OS. + virtual AddressType GetAddressType() const = 0; + // Returns the allocation source of the identifier returned by GetVendorID(), // where available, or VENDOR_ID_UNKNOWN where not. virtual VendorIDSource GetVendorIDSource() const = 0;
diff --git a/device/bluetooth/bluetooth_device_android.cc b/device/bluetooth/bluetooth_device_android.cc index 9e25f6a..27347ad 100644 --- a/device/bluetooth/bluetooth_device_android.cc +++ b/device/bluetooth/bluetooth_device_android.cc
@@ -67,6 +67,11 @@ Java_ChromeBluetoothDevice_getAddress(AttachCurrentThread(), j_device_)); } +BluetoothDevice::AddressType BluetoothDeviceAndroid::GetAddressType() const { + NOTIMPLEMENTED(); + return ADDR_TYPE_UNKNOWN; +} + BluetoothDevice::VendorIDSource BluetoothDeviceAndroid::GetVendorIDSource() const { // Android API does not provide Vendor ID.
diff --git a/device/bluetooth/bluetooth_device_android.h b/device/bluetooth/bluetooth_device_android.h index bfeff535..d6dc20f 100644 --- a/device/bluetooth/bluetooth_device_android.h +++ b/device/bluetooth/bluetooth_device_android.h
@@ -50,6 +50,7 @@ // BluetoothDevice: uint32_t GetBluetoothClass() const override; std::string GetAddress() const override; + AddressType GetAddressType() const override; VendorIDSource GetVendorIDSource() const override; uint16_t GetVendorID() const override; uint16_t GetProductID() const override;
diff --git a/device/bluetooth/bluetooth_device_win.cc b/device/bluetooth/bluetooth_device_win.cc index 82b7e0f..17bcbabe 100644 --- a/device/bluetooth/bluetooth_device_win.cc +++ b/device/bluetooth/bluetooth_device_win.cc
@@ -63,6 +63,11 @@ return address_; } +BluetoothDevice::AddressType BluetoothDeviceWin::GetAddressType() const { + NOTIMPLEMENTED(); + return ADDR_TYPE_UNKNOWN; +} + BluetoothDevice::VendorIDSource BluetoothDeviceWin::GetVendorIDSource() const { return VENDOR_ID_UNKNOWN;
diff --git a/device/bluetooth/bluetooth_device_win.h b/device/bluetooth/bluetooth_device_win.h index e55dbde..96692510 100644 --- a/device/bluetooth/bluetooth_device_win.h +++ b/device/bluetooth/bluetooth_device_win.h
@@ -42,6 +42,7 @@ // BluetoothDevice override uint32_t GetBluetoothClass() const override; std::string GetAddress() const override; + AddressType GetAddressType() const override; VendorIDSource GetVendorIDSource() const override; uint16_t GetVendorID() const override; uint16_t GetProductID() const override;
diff --git a/device/bluetooth/bluetooth_device_winrt.cc b/device/bluetooth/bluetooth_device_winrt.cc index 482c9f1..6ba09a2 100644 --- a/device/bluetooth/bluetooth_device_winrt.cc +++ b/device/bluetooth/bluetooth_device_winrt.cc
@@ -208,6 +208,11 @@ return address_; } +BluetoothDevice::AddressType BluetoothDeviceWinrt::GetAddressType() const { + NOTIMPLEMENTED(); + return ADDR_TYPE_UNKNOWN; +} + BluetoothDevice::VendorIDSource BluetoothDeviceWinrt::GetVendorIDSource() const { NOTIMPLEMENTED();
diff --git a/device/bluetooth/bluetooth_device_winrt.h b/device/bluetooth/bluetooth_device_winrt.h index 0062316..84cdbf9a 100644 --- a/device/bluetooth/bluetooth_device_winrt.h +++ b/device/bluetooth/bluetooth_device_winrt.h
@@ -48,6 +48,7 @@ // BluetoothDevice: uint32_t GetBluetoothClass() const override; std::string GetAddress() const override; + AddressType GetAddressType() const override; VendorIDSource GetVendorIDSource() const override; uint16_t GetVendorID() const override; uint16_t GetProductID() const override;
diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.h b/device/bluetooth/bluetooth_low_energy_device_mac.h index 83df27b..7adb071 100644 --- a/device/bluetooth/bluetooth_low_energy_device_mac.h +++ b/device/bluetooth/bluetooth_low_energy_device_mac.h
@@ -42,6 +42,7 @@ std::string GetIdentifier() const override; uint32_t GetBluetoothClass() const override; std::string GetAddress() const override; + AddressType GetAddressType() const override; BluetoothDevice::VendorIDSource GetVendorIDSource() const override; uint16_t GetVendorID() const override; uint16_t GetProductID() const override;
diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.mm b/device/bluetooth/bluetooth_low_energy_device_mac.mm index df268cf..95c6888 100644 --- a/device/bluetooth/bluetooth_low_energy_device_mac.mm +++ b/device/bluetooth/bluetooth_low_energy_device_mac.mm
@@ -72,6 +72,12 @@ return hash_address_; } +BluetoothDevice::AddressType BluetoothLowEnergyDeviceMac::GetAddressType() + const { + NOTIMPLEMENTED(); + return ADDR_TYPE_UNKNOWN; +} + BluetoothDevice::VendorIDSource BluetoothLowEnergyDeviceMac::GetVendorIDSource() const { return VENDOR_ID_UNKNOWN;
diff --git a/device/bluetooth/bluez/bluetooth_bluez_unittest.cc b/device/bluetooth/bluez/bluetooth_bluez_unittest.cc index 8d95453..2896da6c 100644 --- a/device/bluetooth/bluez/bluetooth_bluez_unittest.cc +++ b/device/bluetooth/bluez/bluetooth_bluez_unittest.cc
@@ -1804,6 +1804,33 @@ EXPECT_EQ(0x0306, devices[idx]->GetDeviceID()); } +TEST_F(BluetoothBlueZTest, DeviceAddressType) { + GetAdapter(); + BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); + ASSERT_EQ(2U, devices.size()); + + int idx = GetDeviceIndexByAddress( + devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); + ASSERT_NE(-1, idx); + ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress, + devices[idx]->GetAddress()); + + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kPairedDevicePath)); + + properties->address_type.set_valid(false); + EXPECT_EQ(BluetoothDevice::ADDR_TYPE_UNKNOWN, devices[idx]->GetAddressType()); + + properties->address_type.set_valid(true); + + properties->address_type.ReplaceValue(bluetooth_device::kAddressTypePublic); + EXPECT_EQ(BluetoothDevice::ADDR_TYPE_PUBLIC, devices[idx]->GetAddressType()); + + properties->address_type.ReplaceValue(bluetooth_device::kAddressTypeRandom); + EXPECT_EQ(BluetoothDevice::ADDR_TYPE_RANDOM, devices[idx]->GetAddressType()); +} + TEST_F(BluetoothBlueZTest, DeviceClassChanged) { // Simulate a change of class of a device, as sometimes occurs // during discovery.
diff --git a/device/bluetooth/bluez/bluetooth_device_bluez.cc b/device/bluetooth/bluez/bluetooth_device_bluez.cc index 0bf76e6..1cf95ef 100644 --- a/device/bluetooth/bluez/bluetooth_device_bluez.cc +++ b/device/bluetooth/bluez/bluetooth_device_bluez.cc
@@ -302,6 +302,24 @@ return device::CanonicalizeBluetoothAddress(properties->address.value()); } +BluetoothDeviceBlueZ::AddressType BluetoothDeviceBlueZ::GetAddressType() const { + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( + object_path_); + DCHECK(properties); + + if (!properties->address_type.is_valid()) + return ADDR_TYPE_UNKNOWN; + + if (properties->address_type.value() == bluetooth_device::kAddressTypePublic) + return ADDR_TYPE_PUBLIC; + if (properties->address_type.value() == bluetooth_device::kAddressTypeRandom) + return ADDR_TYPE_RANDOM; + + LOG(WARNING) << "Unknown address type: " << properties->address_type.value(); + return ADDR_TYPE_UNKNOWN; +} + BluetoothDevice::VendorIDSource BluetoothDeviceBlueZ::GetVendorIDSource() const { VendorIDSource vendor_id_source = VENDOR_ID_UNKNOWN;
diff --git a/device/bluetooth/bluez/bluetooth_device_bluez.h b/device/bluetooth/bluez/bluetooth_device_bluez.h index a0fe2f2..500cb5d 100644 --- a/device/bluetooth/bluez/bluetooth_device_bluez.h +++ b/device/bluetooth/bluez/bluetooth_device_bluez.h
@@ -56,6 +56,7 @@ uint32_t GetBluetoothClass() const override; device::BluetoothTransport GetType() const override; std::string GetAddress() const override; + AddressType GetAddressType() const override; VendorIDSource GetVendorIDSource() const override; uint16_t GetVendorID() const override; uint16_t GetProductID() const override;
diff --git a/device/bluetooth/cast/bluetooth_device_cast.cc b/device/bluetooth/cast/bluetooth_device_cast.cc index fc92253..7ca4f06 100644 --- a/device/bluetooth/cast/bluetooth_device_cast.cc +++ b/device/bluetooth/cast/bluetooth_device_cast.cc
@@ -84,6 +84,11 @@ return address_; } +BluetoothDevice::AddressType BluetoothDeviceCast::GetAddressType() const { + NOTIMPLEMENTED(); + return ADDR_TYPE_UNKNOWN; +} + BluetoothDevice::VendorIDSource BluetoothDeviceCast::GetVendorIDSource() const { return VENDOR_ID_UNKNOWN; }
diff --git a/device/bluetooth/cast/bluetooth_device_cast.h b/device/bluetooth/cast/bluetooth_device_cast.h index df4bfdd..569321b9 100644 --- a/device/bluetooth/cast/bluetooth_device_cast.h +++ b/device/bluetooth/cast/bluetooth_device_cast.h
@@ -40,6 +40,7 @@ uint32_t GetBluetoothClass() const override; BluetoothTransport GetType() const override; std::string GetAddress() const override; + AddressType GetAddressType() const override; VendorIDSource GetVendorIDSource() const override; uint16_t GetVendorID() const override; uint16_t GetProductID() const override;
diff --git a/device/bluetooth/dbus/bluetooth_device_client.cc b/device/bluetooth/dbus/bluetooth_device_client.cc index 2f71e142..4b18eb4 100644 --- a/device/bluetooth/dbus/bluetooth_device_client.cc +++ b/device/bluetooth/dbus/bluetooth_device_client.cc
@@ -185,6 +185,7 @@ const PropertyChangedCallback& callback) : dbus::PropertySet(object_proxy, interface_name, callback) { RegisterProperty(bluetooth_device::kAddressProperty, &address); + RegisterProperty(bluetooth_device::kAddressTypeProperty, &address_type); RegisterProperty(bluetooth_device::kNameProperty, &name); RegisterProperty(bluetooth_device::kIconProperty, &icon); RegisterProperty(bluetooth_device::kClassProperty, &bluetooth_class);
diff --git a/device/bluetooth/dbus/bluetooth_device_client.h b/device/bluetooth/dbus/bluetooth_device_client.h index a6339b1..866fdf1 100644 --- a/device/bluetooth/dbus/bluetooth_device_client.h +++ b/device/bluetooth/dbus/bluetooth_device_client.h
@@ -51,6 +51,9 @@ // The Bluetooth device address of the device. Read-only. dbus::Property<std::string> address; + // The Bluetooth address type of the device. Read-only. + dbus::Property<std::string> address_type; + // The Bluetooth friendly name of the device. Read-only, to give a // different local name, use the |alias| property. dbus::Property<std::string> name;
diff --git a/device/bluetooth/test/fake_peripheral.cc b/device/bluetooth/test/fake_peripheral.cc index b320025d..6d43c89c 100644 --- a/device/bluetooth/test/fake_peripheral.cc +++ b/device/bluetooth/test/fake_peripheral.cc
@@ -135,6 +135,11 @@ return address_; } +device::BluetoothDevice::AddressType FakePeripheral::GetAddressType() const { + NOTREACHED(); + return ADDR_TYPE_UNKNOWN; +} + device::BluetoothDevice::VendorIDSource FakePeripheral::GetVendorIDSource() const { NOTREACHED();
diff --git a/device/bluetooth/test/fake_peripheral.h b/device/bluetooth/test/fake_peripheral.h index 2452f773..3e73945 100644 --- a/device/bluetooth/test/fake_peripheral.h +++ b/device/bluetooth/test/fake_peripheral.h
@@ -73,6 +73,7 @@ #endif std::string GetIdentifier() const override; std::string GetAddress() const override; + AddressType GetAddressType() const override; VendorIDSource GetVendorIDSource() const override; uint16_t GetVendorID() const override; uint16_t GetProductID() const override;
diff --git a/device/bluetooth/test/mock_bluetooth_device.h b/device/bluetooth/test/mock_bluetooth_device.h index b6fbcba..2a11426 100644 --- a/device/bluetooth/test/mock_bluetooth_device.h +++ b/device/bluetooth/test/mock_bluetooth_device.h
@@ -39,6 +39,7 @@ MOCK_CONST_METHOD0(GetType, BluetoothTransport()); MOCK_CONST_METHOD0(GetIdentifier, std::string()); MOCK_CONST_METHOD0(GetAddress, std::string()); + MOCK_CONST_METHOD0(GetAddressType, BluetoothDevice::AddressType()); MOCK_CONST_METHOD0(GetVendorIDSource, BluetoothDevice::VendorIDSource()); MOCK_CONST_METHOD0(GetVendorID, uint16_t()); MOCK_CONST_METHOD0(GetProductID, uint16_t());
diff --git a/docs/gpu/pixel_wrangling.md b/docs/gpu/pixel_wrangling.md index 06ff5af..400475f 100644 --- a/docs/gpu/pixel_wrangling.md +++ b/docs/gpu/pixel_wrangling.md
@@ -167,6 +167,12 @@ revert message, provide a clear description of what broke, links to failing builds, and excerpts of the failure logs, because the build logs expire after a few days. + 1. If the failure is one that you believe should have been caught by an + optional GPU trybot, you can use the script at + [`//content/test/gpu/trim_culprit_cls.py`][trim culprit cls] to help + trim down the blamelist by finding out which CLs passed said trybot + before submission. See the documentation at the top of the script for + example usage, etc. 1. Make sure the bots are running jobs. 1. Keep an eye on the console views of the various bots. 1. Make sure the bots are all actively processing jobs. If they go offline @@ -269,6 +275,7 @@ modifier][gtest-DISABLED] to suppress any failures if necessary. [Sheriff-O-Matic]: https://sheriff-o-matic.appspot.com/chromium.gpu +[trim culprit cls]: https://source.chromium.org/chromium/chromium/src/+/master:content/test/gpu/trim_culprit_cls.py [tree sheriffing page]: https://sites.google.com/a/chromium.org/dev/developers/tree-sheriffs [linux-rel]: https://ci.chromium.org/p/chromium/builders/luci.chromium.try/linux-rel [luci.chromium.try]: https://ci.chromium.org/p/chromium/g/luci.chromium.try/builders
diff --git a/extensions/browser/api/app_window/app_window_apitest.cc b/extensions/browser/api/app_window/app_window_apitest.cc index 523e7b1..f801208 100644 --- a/extensions/browser/api/app_window/app_window_apitest.cc +++ b/extensions/browser/api/app_window/app_window_apitest.cc
@@ -64,7 +64,7 @@ #define MAYBE_OnMinimizedEvent OnMinimizedEvent #define MAYBE_OnMaximizedEvent OnMaximizedEvent #define MAYBE_OnRestoredEvent OnRestoredEvent -#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) IN_PROC_BROWSER_TEST_F(AppWindowApiTest, MAYBE_OnMinimizedEvent) { #if defined(OS_MAC)
diff --git a/extensions/browser/api/declarative_net_request/BUILD.gn b/extensions/browser/api/declarative_net_request/BUILD.gn index 5f73a052..60a2195 100644 --- a/extensions/browser/api/declarative_net_request/BUILD.gn +++ b/extensions/browser/api/declarative_net_request/BUILD.gn
@@ -73,8 +73,8 @@ "indexed_rule.h", "parse_info.cc", "parse_info.h", - "ruleset_checksum.cc", - "ruleset_checksum.h", + "ruleset_install_pref.cc", + "ruleset_install_pref.h", "ruleset_source.cc", "ruleset_source.h", "utils.cc",
diff --git a/extensions/browser/api/declarative_net_request/constants.cc b/extensions/browser/api/declarative_net_request/constants.cc index 692e1c2..d416625 100644 --- a/extensions/browser/api/declarative_net_request/constants.cc +++ b/extensions/browser/api/declarative_net_request/constants.cc
@@ -90,6 +90,8 @@ "Rule with * couldn't be parsed. Parse error: *."; const char kTooManyParseFailuresWarning[] = "Too many rule parse failures; Reporting the first *."; +const char kIndexingRuleLimitExceeded[] = + "Ruleset with id * exceeds the indexing rule limit and will be ignored."; const char kInternalErrorUpdatingDynamicRules[] = "Internal error while updating dynamic rules."; const char kInternalErrorGettingDynamicRules[] = @@ -129,5 +131,8 @@ "have activeTab granted for the specified tab ID in order to call this " "function."; +const base::Feature kDeclarativeNetRequestGlobalRules{ + "DeclarativeNetRequestGlobalRules", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace declarative_net_request } // namespace extensions
diff --git a/extensions/browser/api/declarative_net_request/constants.h b/extensions/browser/api/declarative_net_request/constants.h index 8b54d660..f3390ad 100644 --- a/extensions/browser/api/declarative_net_request/constants.h +++ b/extensions/browser/api/declarative_net_request/constants.h
@@ -8,6 +8,7 @@ #include <cstddef> #include <cstdint> +#include "base/feature_list.h" #include "extensions/common/api/declarative_net_request/constants.h" namespace extensions { @@ -161,6 +162,7 @@ extern const char kEnabledRegexRuleCountExceeded[]; extern const char kRuleNotParsedWarning[]; extern const char kTooManyParseFailuresWarning[]; +extern const char kIndexingRuleLimitExceeded[]; // Dynamic rules API errors. extern const char kInternalErrorUpdatingDynamicRules[]; @@ -191,6 +193,14 @@ // extension does not have sufficient permissions to make the call. extern const char kErrorGetMatchedRulesMissingPermissions[]; +// The maximum amount of static rules in the global rule pool for a single +// profile. +constexpr int kMaxStaticRulesPerProfile = 300000; + +// Enables extensions to enable more rules than the per-extension static rule +// count, up to a global limit shared between all extensions. +extern const base::Feature kDeclarativeNetRequestGlobalRules; + } // namespace declarative_net_request } // namespace extensions
diff --git a/extensions/browser/api/declarative_net_request/file_sequence_helper.cc b/extensions/browser/api/declarative_net_request/file_sequence_helper.cc index 9afe17d..ebd246d 100644 --- a/extensions/browser/api/declarative_net_request/file_sequence_helper.cc +++ b/extensions/browser/api/declarative_net_request/file_sequence_helper.cc
@@ -87,6 +87,7 @@ void OnReindexCompleted(RulesetInfo* ruleset, base::OnceClosure done_closure, IndexAndPersistJSONRulesetResult result) { + using IndexStatus = IndexAndPersistJSONRulesetResult::Status; DCHECK(ruleset); // The checksum of the reindexed ruleset should have been the same as the @@ -95,13 +96,15 @@ // other issue (like the JSON rules file has been modified from the one used // during installation or preferences are corrupted). But taking care of // these is beyond our scope here, so simply signal a failure. - bool reindexing_success = result.success && ruleset->expected_checksum() == - result.ruleset_checksum; + bool reindexing_success = + result.status == IndexStatus::kSuccess && + ruleset->expected_checksum() == result.ruleset_checksum; // In case of updates to the ruleset version, the change of ruleset checksum // is expected. - if (result.success && ruleset->load_ruleset_result() == - LoadRulesetResult::kErrorVersionMismatch) { + if (result.status == IndexStatus::kSuccess && + ruleset->load_ruleset_result() == + LoadRulesetResult::kErrorVersionMismatch) { ruleset->set_new_checksum(result.ruleset_checksum); // Also change the |expected_checksum| so that any subsequent load
diff --git a/extensions/browser/api/declarative_net_request/index_helper.cc b/extensions/browser/api/declarative_net_request/index_helper.cc index 579e95d..2d046bd 100644 --- a/extensions/browser/api/declarative_net_request/index_helper.cc +++ b/extensions/browser/api/declarative_net_request/index_helper.cc
@@ -28,8 +28,11 @@ std::vector<std::pair<const RulesetSource*, IndexAndPersistJSONRulesetResult>> results, bool log_histograms) { + using IndexStatus = IndexAndPersistJSONRulesetResult::Status; + IndexHelper::Result total_result; - total_result.ruleset_checksums.reserve(results.size()); + total_result.ruleset_install_prefs.reserve(results.size()); + bool any_ruleset_indexed_successfully = false; size_t total_rules_count = 0; size_t enabled_rules_count = 0; size_t enabled_regex_rules_count = 0; @@ -48,25 +51,42 @@ static_cast<size_t>(GetRegexRuleLimit())); DCHECK_LE(index_result.rules_count, source->rule_count_limit()); - if (!index_result.success) { + if (index_result.status == IndexStatus::kError) { total_result.error = std::move(index_result.error); return total_result; } - total_result.ruleset_checksums.emplace_back( - source->id(), std::move(index_result.ruleset_checksum)); - total_result.warnings.insert( total_result.warnings.end(), std::make_move_iterator(index_result.warnings.begin()), std::make_move_iterator(index_result.warnings.end())); - total_index_and_persist_time += index_result.index_and_persist_time; - total_rules_count += index_result.rules_count; + if (index_result.status == IndexStatus::kIgnore) { + // If the ruleset was ignored and not indexed, there should be install + // warnings associated. + DCHECK(!index_result.warnings.empty()); + total_result.ruleset_install_prefs.emplace_back( + source->id(), base::nullopt /* ruleset_checksum */, + true /* ignored */); + continue; + } - if (source->enabled_by_default()) { - enabled_rules_count += index_result.rules_count; - enabled_regex_rules_count += index_result.regex_rules_count; + DCHECK_EQ(IndexStatus::kSuccess, index_result.status); + + if (index_result.status == IndexStatus::kSuccess) { + any_ruleset_indexed_successfully = true; + + total_result.ruleset_install_prefs.emplace_back( + source->id(), std::move(index_result.ruleset_checksum), + false /* ignored */); + + total_index_and_persist_time += index_result.index_and_persist_time; + total_rules_count += index_result.rules_count; + + if (source->enabled_by_default()) { + enabled_rules_count += index_result.rules_count; + enabled_regex_rules_count += index_result.regex_rules_count; + } } } @@ -85,7 +105,7 @@ dnr_api::DNRInfo::kRuleResources); } - if (log_histograms) { + if (log_histograms && any_ruleset_indexed_successfully) { UMA_HISTOGRAM_TIMES( declarative_net_request::kIndexAndPersistRulesTimeHistogram, total_index_and_persist_time);
diff --git a/extensions/browser/api/declarative_net_request/index_helper.h b/extensions/browser/api/declarative_net_request/index_helper.h index ee1ad961..8c23fee 100644 --- a/extensions/browser/api/declarative_net_request/index_helper.h +++ b/extensions/browser/api/declarative_net_request/index_helper.h
@@ -12,7 +12,7 @@ #include "base/callback_forward.h" #include "base/memory/ref_counted.h" #include "base/optional.h" -#include "extensions/browser/api/declarative_net_request/ruleset_checksum.h" +#include "extensions/browser/api/declarative_net_request/ruleset_install_pref.h" #include "extensions/browser/api/declarative_net_request/ruleset_source.h" #include "extensions/common/install_warning.h" #include "services/data_decoder/public/cpp/data_decoder.h" @@ -36,7 +36,7 @@ // Valid if |error| is base::nullopt. Clients should not use these fields in // case of a failure since these may be partially populated. std::vector<InstallWarning> warnings; - std::vector<RulesetChecksum> ruleset_checksums; + std::vector<RulesetInstallPref> ruleset_install_prefs; }; // Starts indexing rulesets. Must be called on a sequence which supports file @@ -85,4 +85,4 @@ } // namespace declarative_net_request } // namespace extensions -#endif // EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_INDEX_HELPER_H_ +#endif // EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_INDEX_HELPER_H_ \ No newline at end of file
diff --git a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc index 6e1123b8..991dd913 100644 --- a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc +++ b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
@@ -222,7 +222,11 @@ bool enabled = prefs_enabled_rulesets ? base::Contains(*prefs_enabled_rulesets, source.id()) : source.enabled_by_default(); - if (!enabled) + + bool ignored = + prefs_->ShouldIgnoreDNRRuleset(extension->id(), source.id()); + + if (!enabled || ignored) continue; if (!prefs_->GetDNRStaticRulesetChecksum(extension->id(), source.id(),
diff --git a/extensions/browser/api/declarative_net_request/ruleset_install_pref.cc b/extensions/browser/api/declarative_net_request/ruleset_install_pref.cc new file mode 100644 index 0000000..84e1487f --- /dev/null +++ b/extensions/browser/api/declarative_net_request/ruleset_install_pref.cc
@@ -0,0 +1,20 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/api/declarative_net_request/ruleset_install_pref.h" + +#include "base/check_op.h" + +namespace extensions { +namespace declarative_net_request { + +RulesetInstallPref::RulesetInstallPref(RulesetID ruleset_id, + base::Optional<int> checksum, + bool ignored) + : ruleset_id(ruleset_id), checksum(checksum), ignored(ignored) { + DCHECK_NE(ignored, checksum.has_value()); +} + +} // namespace declarative_net_request +} // namespace extensions
diff --git a/extensions/browser/api/declarative_net_request/ruleset_install_pref.h b/extensions/browser/api/declarative_net_request/ruleset_install_pref.h new file mode 100644 index 0000000..8ff7710 --- /dev/null +++ b/extensions/browser/api/declarative_net_request/ruleset_install_pref.h
@@ -0,0 +1,35 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULESET_INSTALL_PREF_H_ +#define EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULESET_INSTALL_PREF_H_ + +#include <vector> + +#include "base/optional.h" +#include "extensions/common/api/declarative_net_request/constants.h" + +namespace extensions { +namespace declarative_net_request { + +struct RulesetInstallPref { + // ID of the ruleset. + RulesetID ruleset_id; + // Checksum of the indexed ruleset if specified. + base::Optional<int> checksum; + + // If set to true, then the ruleset was ignored and not indexed. + bool ignored; + + RulesetInstallPref(RulesetID ruleset_id, + base::Optional<int> checksum, + bool ignored); +}; + +using RulesetInstallPrefs = std::vector<RulesetInstallPref>; + +} // namespace declarative_net_request +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_RULESET_INSTALL_PREF_H_
diff --git a/extensions/browser/api/declarative_net_request/ruleset_source.cc b/extensions/browser/api/declarative_net_request/ruleset_source.cc index 157d65a..a39604d 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_source.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_source.cc
@@ -12,6 +12,7 @@ #include "base/callback.h" #include "base/callback_helpers.h" #include "base/check_op.h" +#include "base/feature_list.h" #include "base/files/file_util.h" #include "base/json/json_reader.h" #include "base/json/json_string_value_serializer.h" @@ -104,9 +105,11 @@ base::JoinString(rule_ids, ", " /* separator */), kRegexFilterKey))); } -ReadJSONRulesResult ParseRulesFromJSON(const base::FilePath& json_path, +ReadJSONRulesResult ParseRulesFromJSON(const RulesetID& ruleset_id, + const base::FilePath& json_path, const base::Value& rules, - size_t rule_limit) { + size_t rule_limit, + bool is_dynamic_ruleset) { ReadJSONRulesResult result; if (!rules.is_list()) { @@ -126,6 +129,20 @@ // fails if a single Value can't be deserialized. However we want to ignore // values which can't be parsed to maintain backwards compatibility. const auto& rules_list = rules.GetList(); + + // When the global rule limit is enabled, ignore any rulesets which exceed the + // static rule count limit (This is defined as + // dnr_api::GUARANTEED_MINIMUM_STATIC_RULES + the global rule count limit). We + // do this because such a ruleset can never be enabled in its entirety. + if (base::FeatureList::IsEnabled(kDeclarativeNetRequestGlobalRules) && + rules_list.size() > rule_limit && !is_dynamic_ruleset) { + result.status = ReadJSONRulesResult::Status::kRuleCountLimitExceeded; + result.error = ErrorUtils::FormatErrorMessage( + kIndexingRuleLimitExceeded, std::to_string(ruleset_id.value())); + + return result; + } + for (size_t i = 0; i < rules_list.size(); i++) { dnr_api::Rule parsed_rule; base::string16 parse_error; @@ -194,11 +211,22 @@ const RulesetSource& source, ReadJSONRulesResult read_result, const base::ElapsedTimer& timer) { - if (read_result.status != Status::kSuccess) { + // Rulesets which exceed the rule limit are ignored because they can never be + // enabled without breaking the limit. + if (read_result.status == Status::kRuleCountLimitExceeded) { + std::vector<InstallWarning> warnings; + warnings.push_back( + CreateInstallWarning(source.json_path(), read_result.error)); + + return IndexAndPersistJSONRulesetResult::CreateIgnoreResult( + std::move(warnings)); + } else if (read_result.status != Status::kSuccess) { return IndexAndPersistJSONRulesetResult::CreateErrorResult( GetErrorWithFilename(source.json_path(), read_result.error)); } + DCHECK_EQ(Status::kSuccess, read_result.status); + const ParseInfo info = source.IndexAndPersistRules(std::move(read_result.rules)); @@ -235,8 +263,9 @@ } base::ElapsedTimer timer; - ReadJSONRulesResult read_result = - ParseRulesFromJSON(json_path, *result.value, source.rule_count_limit()); + ReadJSONRulesResult read_result = ParseRulesFromJSON( + source.id(), json_path, *result.value, source.rule_count_limit(), + source.is_dynamic_ruleset()); std::move(callback).Run(IndexAndPersistRuleset( source, std::move(read_result), timer)); @@ -253,7 +282,7 @@ size_t regex_rules_count, base::TimeDelta index_and_persist_time) { IndexAndPersistJSONRulesetResult result; - result.success = true; + result.status = IndexAndPersistJSONRulesetResult::Status::kSuccess; result.ruleset_checksum = ruleset_checksum; result.warnings = std::move(warnings); result.rules_count = rules_count; @@ -264,9 +293,19 @@ // static IndexAndPersistJSONRulesetResult +IndexAndPersistJSONRulesetResult::CreateIgnoreResult( + std::vector<InstallWarning> warnings) { + IndexAndPersistJSONRulesetResult result; + result.status = IndexAndPersistJSONRulesetResult::Status::kIgnore; + result.warnings = std::move(warnings); + return result; +} + +// static +IndexAndPersistJSONRulesetResult IndexAndPersistJSONRulesetResult::CreateErrorResult(std::string error) { IndexAndPersistJSONRulesetResult result; - result.success = false; + result.status = IndexAndPersistJSONRulesetResult::Status::kError; result.error = std::move(error); return result; } @@ -465,8 +504,8 @@ Status::kJSONParseError, std::move(value_with_error.error_message)); } - return ParseRulesFromJSON(json_path(), *value_with_error.value, - rule_count_limit_); + return ParseRulesFromJSON(id_, json_path(), *value_with_error.value, + rule_count_limit_, is_dynamic_ruleset()); } bool RulesetSource::WriteRulesToJSON(
diff --git a/extensions/browser/api/declarative_net_request/ruleset_source.h b/extensions/browser/api/declarative_net_request/ruleset_source.h index 4666d77..cf6c7d2 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_source.h +++ b/extensions/browser/api/declarative_net_request/ruleset_source.h
@@ -40,40 +40,52 @@ struct IndexAndPersistJSONRulesetResult { public: + enum class Status { + // The ruleset was successfully indexed. + kSuccess, + // The ruleset was ignored during indexing since it exceeded the maximum + // rules limit. + kIgnore, + // The ruleset was unsuccessfully indexed and an error was raised. + kError, + }; + static IndexAndPersistJSONRulesetResult CreateSuccessResult( int ruleset_checksum, std::vector<InstallWarning> warnings, size_t rules_count, size_t regex_rules_count, base::TimeDelta index_and_persist_time); + static IndexAndPersistJSONRulesetResult CreateIgnoreResult( + std::vector<InstallWarning> warnings); static IndexAndPersistJSONRulesetResult CreateErrorResult(std::string error); ~IndexAndPersistJSONRulesetResult(); IndexAndPersistJSONRulesetResult(IndexAndPersistJSONRulesetResult&&); IndexAndPersistJSONRulesetResult& operator=( IndexAndPersistJSONRulesetResult&&); - // Whether IndexAndPersistRules succeeded. - bool success = false; + // The result of IndexAndPersistRules. + Status status = Status::kError; - // Checksum of the persisted indexed ruleset file. Valid if |success| if true. - // Note: there's no sane default value for this, any integer value is a valid - // checksum value. + // Checksum of the persisted indexed ruleset file. Valid if |status| if + // kSuccess. Note: there's no sane default value for this, any integer value + // is a valid checksum value. int ruleset_checksum = 0; - // Valid if |success| is true. + // Valid if |status| is kSuccess or kIgnore. std::vector<InstallWarning> warnings; - // The number of indexed rules. Valid if |success| is true. + // The number of indexed rules. Valid if |status| is kSuccess. size_t rules_count = 0; - // The number of indexed regex rules. Valid if |success| is true. + // The number of indexed regex rules. Valid if |status| is kSuccess. size_t regex_rules_count = 0; // Time taken to deserialize the JSON rules and persist them in flatbuffer - // format. Valid if success is true. + // format. Valid if status is kSuccess. base::TimeDelta index_and_persist_time; - // Valid if |success| is false. + // Valid if |status| is kError. std::string error; private: @@ -91,9 +103,13 @@ kJSONParseError = 3, kJSONIsNotList = 4, + // Status returned when the list of rules to be read exceeds the static rule + // count limit. + kRuleCountLimitExceeded = 5, + // Magic constant used by histograms code. Should be equal to the maximum // enum value. - kMaxValue = kJSONIsNotList + kMaxValue = kRuleCountLimitExceeded }; static ReadJSONRulesResult CreateErrorResult(Status status,
diff --git a/extensions/browser/api/declarative_net_request/test_utils.cc b/extensions/browser/api/declarative_net_request/test_utils.cc index a6c468b..69e6b8c 100644 --- a/extensions/browser/api/declarative_net_request/test_utils.cc +++ b/extensions/browser/api/declarative_net_request/test_utils.cc
@@ -315,11 +315,14 @@ content::BrowserContext* browser_context) { std::vector<RulesetSource> sources = RulesetSource::CreateStatic(extension); + const ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context); for (RulesetSource& source : sources) { + if (prefs->ShouldIgnoreDNRRuleset(extension.id(), source.id())) + continue; + int expected_checksum = -1; - if (!ExtensionPrefs::Get(browser_context) - ->GetDNRStaticRulesetChecksum(extension.id(), source.id(), - &expected_checksum)) { + if (!prefs->GetDNRStaticRulesetChecksum(extension.id(), source.id(), + &expected_checksum)) { return false; } @@ -338,6 +341,8 @@ const RulesetSource& source, std::unique_ptr<RulesetMatcher>* matcher, int* expected_checksum) { + using IndexStatus = IndexAndPersistJSONRulesetResult::Status; + // Serialize |rules|. ListBuilder builder; for (const auto& rule : rules) @@ -347,7 +352,7 @@ // Index ruleset. IndexAndPersistJSONRulesetResult result = source.IndexAndPersistJSONRulesetUnsafe(); - if (!result.success) { + if (result.status == IndexStatus::kError) { DCHECK(result.error.empty()) << result.error; return false; } @@ -355,6 +360,7 @@ if (!result.warnings.empty()) return false; + DCHECK_EQ(IndexStatus::kSuccess, result.status); if (expected_checksum) *expected_checksum = result.ruleset_checksum;
diff --git a/extensions/browser/api/declarative_net_request/utils.cc b/extensions/browser/api/declarative_net_request/utils.cc index a0428894..c55f428 100644 --- a/extensions/browser/api/declarative_net_request/utils.cc +++ b/extensions/browser/api/declarative_net_request/utils.cc
@@ -57,6 +57,7 @@ constexpr int kInvalidRuleLimit = -1; int g_static_rule_limit_for_testing = kInvalidRuleLimit; +int g_global_static_rule_limit_for_testing = kInvalidRuleLimit; int g_regex_rule_limit_for_testing = kInvalidRuleLimit; int GetIndexedRulesetFormatVersion() { @@ -291,9 +292,26 @@ } int GetStaticRuleLimit() { - return g_static_rule_limit_for_testing == kInvalidRuleLimit - ? dnr_api::MAX_NUMBER_OF_RULES - : g_static_rule_limit_for_testing; + bool global_rules_enabled = + base::FeatureList::IsEnabled(kDeclarativeNetRequestGlobalRules); + + int default_static_rule_constant = + global_rules_enabled ? dnr_api::GUARANTEED_MINIMUM_STATIC_RULES + : dnr_api::MAX_NUMBER_OF_RULES; + + int static_rule_limit = g_static_rule_limit_for_testing == kInvalidRuleLimit + ? default_static_rule_constant + : g_static_rule_limit_for_testing; + + if (!global_rules_enabled) + return static_rule_limit; + + int global_rule_limit = + g_global_static_rule_limit_for_testing == kInvalidRuleLimit + ? kMaxStaticRulesPerProfile + : g_global_static_rule_limit_for_testing; + + return static_rule_limit + global_rule_limit; } int GetDynamicRuleLimit() { @@ -311,6 +329,11 @@ return base::AutoReset<int>(&g_static_rule_limit_for_testing, limit); } +ScopedRuleLimitOverride CreateScopedGlobalStaticRuleLimitOverrideForTesting( + int limit) { + return base::AutoReset<int>(&g_global_static_rule_limit_for_testing, limit); +} + ScopedRuleLimitOverride CreateScopedRegexRuleLimitOverrideForTesting( int limit) { return base::AutoReset<int>(&g_regex_rule_limit_for_testing, limit);
diff --git a/extensions/browser/api/declarative_net_request/utils.h b/extensions/browser/api/declarative_net_request/utils.h index 6e840a8d..af76089 100644 --- a/extensions/browser/api/declarative_net_request/utils.h +++ b/extensions/browser/api/declarative_net_request/utils.h
@@ -99,7 +99,7 @@ std::vector<std::string> GetPublicRulesetIDs(const Extension& extension, const CompositeMatcher& matcher); -// Returns the per-extension static rule limit. +// Returns the maximum number of rules a valid static ruleset can have. int GetStaticRuleLimit(); // Returns the per-extension dynamic rule limit. @@ -114,6 +114,8 @@ using ScopedRuleLimitOverride = base::AutoReset<int>; ScopedRuleLimitOverride CreateScopedStaticRuleLimitOverrideForTesting( int limit); +ScopedRuleLimitOverride CreateScopedGlobalStaticRuleLimitOverrideForTesting( + int limit); ScopedRuleLimitOverride CreateScopedRegexRuleLimitOverrideForTesting(int limit); // Helper to convert a flatbufffers::String to a string-like object with type T.
diff --git a/extensions/browser/extension_prefs.cc b/extensions/browser/extension_prefs.cc index 97a3a7f..2ec51f6 100644 --- a/extensions/browser/extension_prefs.cc +++ b/extensions/browser/extension_prefs.cc
@@ -234,6 +234,9 @@ constexpr const char kPrefDNRUseActionCountAsBadgeText[] = "dnr_use_action_count_as_badge_text"; +// A boolean that indicates if a ruleset should be ignored. +constexpr const char kDNRIgnoreRulesetKey[] = "ignore_ruleset"; + // The default value to use for permission withholding when setting the pref on // installation or for extensions where the pref has not been set. constexpr bool kDefaultWithholdingBehavior = false; @@ -1350,7 +1353,7 @@ const syncer::StringOrdinal& page_ordinal, int install_flags, const std::string& install_parameter, - const declarative_net_request::RulesetChecksums& ruleset_checksums) { + const declarative_net_request::RulesetInstallPrefs& ruleset_install_prefs) { // If the extension was previously an external extension that was uninstalled, // clear the external uninstall bit. // TODO(devlin): We previously did this because we indicated external @@ -1369,7 +1372,7 @@ const base::Time install_time = clock_->Now(); PopulateExtensionInfoPrefs(extension, install_time, initial_state, install_flags, install_parameter, - ruleset_checksums, extension_dict.get()); + ruleset_install_prefs, extension_dict.get()); FinishExtensionInfoPrefs(extension->id(), install_time, extension->RequiresSortOrdinal(), page_ordinal, @@ -1578,12 +1581,12 @@ DelayReason delay_reason, const syncer::StringOrdinal& page_ordinal, const std::string& install_parameter, - const declarative_net_request::RulesetChecksums& ruleset_checksums) { + const declarative_net_request::RulesetInstallPrefs& ruleset_install_prefs) { ScopedDictionaryUpdate update(this, extension->id(), kDelayedInstallInfo); auto extension_dict = update.Create(); PopulateExtensionInfoPrefs(extension, clock_->Now(), initial_state, install_flags, install_parameter, - ruleset_checksums, extension_dict.get()); + ruleset_install_prefs, extension_dict.get()); // Add transient data that is needed by FinishDelayedInstallInfo(), but // should not be in the final extension prefs. All entries here should have @@ -2156,6 +2159,15 @@ std::make_unique<base::Value>(use_action_count_as_badge_text)); } +bool ExtensionPrefs::ShouldIgnoreDNRRuleset( + const ExtensionId& extension_id, + declarative_net_request::RulesetID ruleset_id) const { + std::string pref = JoinPrefs({kDNRStaticRulesetPref, + base::NumberToString(ruleset_id.value()), + kDNRIgnoreRulesetKey}); + return ReadPrefAsBooleanAndReturn(extension_id, pref); +} + // static void ExtensionPrefs::SetRunAlertsInFirstRunForTest() { g_run_alerts_in_first_run_for_testing = true; @@ -2307,7 +2319,7 @@ Extension::State initial_state, int install_flags, const std::string& install_parameter, - const declarative_net_request::RulesetChecksums& ruleset_checksums, + const declarative_net_request::RulesetInstallPrefs& ruleset_install_prefs, prefs::DictionaryValueUpdate* extension_dict) const { extension_dict->SetInteger(kPrefState, initial_state); extension_dict->SetInteger(kPrefLocation, extension->location()); @@ -2323,20 +2335,23 @@ if (install_flags & kInstallFlagIsBlocklistedForMalware) extension_dict->SetBoolean(kPrefBlocklist, true); - // If |ruleset_checksums| is empty, explicitly remove the - // |kDNRStaticRulesetPref| entry to ensure any remaining old entries from the - // previous install are cleared up in case of an update. Else just set the + // If |ruleset_install_prefs| is empty, explicitly remove + // the |kDNRStaticRulesetPref| entry to ensure any remaining old entries from + // the previous install are cleared up in case of an update. Else just set the // entry (which will overwrite any existing value). - if (ruleset_checksums.empty()) { + if (ruleset_install_prefs.empty()) { extension_dict->Remove(kDNRStaticRulesetPref, nullptr /* out_value */); } else { auto ruleset_prefs = std::make_unique<base::DictionaryValue>(); - for (const declarative_net_request::RulesetChecksum& checksum : - ruleset_checksums) { + for (const declarative_net_request::RulesetInstallPref& install_pref : + ruleset_install_prefs) { auto ruleset_dict = std::make_unique<base::DictionaryValue>(); - ruleset_dict->SetIntKey(kDNRChecksumKey, checksum.checksum); + if (install_pref.checksum) + ruleset_dict->SetIntKey(kDNRChecksumKey, *install_pref.checksum); - std::string id_key = base::NumberToString(checksum.ruleset_id.value()); + ruleset_dict->SetBoolean(kDNRIgnoreRulesetKey, install_pref.ignored); + std::string id_key = + base::NumberToString(install_pref.ruleset_id.value()); DCHECK(!ruleset_prefs->FindKey(id_key)); ruleset_prefs->SetDictionary(id_key, std::move(ruleset_dict)); }
diff --git a/extensions/browser/extension_prefs.h b/extensions/browser/extension_prefs.h index f8dd2011..a708acc5 100644 --- a/extensions/browser/extension_prefs.h +++ b/extensions/browser/extension_prefs.h
@@ -19,7 +19,7 @@ #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/scoped_user_pref_update.h" #include "components/sync/model/string_ordinal.h" -#include "extensions/browser/api/declarative_net_request/ruleset_checksum.h" +#include "extensions/browser/api/declarative_net_request/ruleset_install_pref.h" #include "extensions/browser/blocklist_state.h" #include "extensions/browser/disable_reason.h" #include "extensions/browser/extension_prefs_scope.h" @@ -199,16 +199,16 @@ // Called when an extension is installed, so that prefs get created. // If |page_ordinal| is invalid then a page will be found for the App. // |install_flags| are a bitmask of extension::InstallFlags. - // |ruleset_checksums| are the checksum for the indexed static rulesets - // corresponding to the Declarative Net Request API. - void OnExtensionInstalled( - const Extension* extension, - Extension::State initial_state, - const syncer::StringOrdinal& page_ordinal, - int install_flags, - const std::string& install_parameter, - const declarative_net_request::RulesetChecksums& ruleset_checksums); - // OnExtensionInstalled with no install flags and |ruleset_checksums|. + // |ruleset_install_prefs| contains install prefs needed for the Declarative + // Net Request API. + void OnExtensionInstalled(const Extension* extension, + Extension::State initial_state, + const syncer::StringOrdinal& page_ordinal, + int install_flags, + const std::string& install_parameter, + const declarative_net_request::RulesetInstallPrefs& + ruleset_install_prefs); + // OnExtensionInstalled with no install flags and |ruleset_install_prefs|. void OnExtensionInstalled(const Extension* extension, Extension::State initial_state, const syncer::StringOrdinal& page_ordinal, @@ -534,14 +534,14 @@ // to install it. // // |install_flags| are a bitmask of extension::InstallFlags. - void SetDelayedInstallInfo( - const Extension* extension, - Extension::State initial_state, - int install_flags, - DelayReason delay_reason, - const syncer::StringOrdinal& page_ordinal, - const std::string& install_parameter, - const declarative_net_request::RulesetChecksums& ruleset_checksums = {}); + void SetDelayedInstallInfo(const Extension* extension, + Extension::State initial_state, + int install_flags, + DelayReason delay_reason, + const syncer::StringOrdinal& page_ordinal, + const std::string& install_parameter, + const declarative_net_request::RulesetInstallPrefs& + ruleset_install_prefs = {}); // Removes any delayed install information we have for the given // |extension_id|. Returns true if there was info to remove; false otherwise. @@ -676,6 +676,12 @@ void SetDNRUseActionCountAsBadgeText(const ExtensionId& extension_id, bool use_action_count_as_badge_text); + // Whether the ruleset for the given |extension_id| and |ruleset_id| should be + // ignored while loading the extension. + bool ShouldIgnoreDNRRuleset( + const ExtensionId& extension_id, + declarative_net_request::RulesetID ruleset_id) const; + // Migrates the disable reasons extension pref for extensions that were // disabled due to a deprecated reason. // TODO(archanasimha): Remove this around M89. @@ -869,7 +875,7 @@ Extension::State initial_state, int install_flags, const std::string& install_parameter, - const declarative_net_request::RulesetChecksums& ruleset_checksums, + const declarative_net_request::RulesetInstallPrefs& ruleset_install_prefs, prefs::DictionaryValueUpdate* extension_dict) const; void InitExtensionControlledPrefs(const ExtensionsInfo& extensions_info);
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc index b216c08..b2082d5 100644 --- a/extensions/browser/sandboxed_unpacker.cc +++ b/extensions/browser/sandboxed_unpacker.cc
@@ -634,7 +634,7 @@ if (!result.warnings.empty()) extension_->AddInstallWarnings(std::move(result.warnings)); - ruleset_checksums_ = std::move(result.ruleset_checksums); + ruleset_install_prefs_ = std::move(result.ruleset_install_prefs); CheckComputeHashes(); } @@ -894,11 +894,11 @@ temp_dir_.Take(), extension_root_, base::DictionaryValue::From( base::Value::ToUniquePtrValue(std::move(manifest_.value()))), - extension_.get(), install_icon_, std::move(ruleset_checksums_)); + extension_.get(), install_icon_, std::move(ruleset_install_prefs_)); // Interestingly, the C++ standard doesn't guarantee that a moved-from vector // is empty. - ruleset_checksums_.clear(); + ruleset_install_prefs_.clear(); extension_.reset();
diff --git a/extensions/browser/sandboxed_unpacker.h b/extensions/browser/sandboxed_unpacker.h index 6e5edfe..342c631 100644 --- a/extensions/browser/sandboxed_unpacker.h +++ b/extensions/browser/sandboxed_unpacker.h
@@ -18,7 +18,7 @@ #include "base/strings/string_piece.h" #include "base/values.h" #include "extensions/browser/api/declarative_net_request/index_helper.h" -#include "extensions/browser/api/declarative_net_request/ruleset_checksum.h" +#include "extensions/browser/api/declarative_net_request/ruleset_install_pref.h" #include "extensions/browser/crx_file_info.h" #include "extensions/browser/image_sanitizer.h" #include "extensions/browser/install/crx_install_error.h" @@ -75,8 +75,8 @@ // // install_icon - The icon we will display in the installation UI, if any. // - // ruleset_checksums - Checksums for the indexed rulesets corresponding to - // the Declarative Net Request API. + // ruleset_install_prefs - Install prefs needed for the Declarative Net + // Request API. // // Note: OnUnpackSuccess/Failure may be called either synchronously or // asynchronously from SandboxedUnpacker::StartWithCrx/Directory. @@ -86,7 +86,7 @@ std::unique_ptr<base::DictionaryValue> original_manifest, const Extension* extension, const SkBitmap& install_icon, - declarative_net_request::RulesetChecksums ruleset_checksums) = 0; + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs) = 0; virtual void OnUnpackFailure(const CrxInstallError& error) = 0; // Called after stage of installation is changed. @@ -265,9 +265,8 @@ // is called. base::Optional<base::Value> manifest_; - // Checksums for the indexed rulesets, see more in - // SandboxedUnpackerClient::OnUnpackSuccess description. - declarative_net_request::RulesetChecksums ruleset_checksums_; + // Install prefs needed for the Declarative Net Request API. + declarative_net_request::RulesetInstallPrefs ruleset_install_prefs_; // Represents the extension we're unpacking. scoped_refptr<Extension> extension_;
diff --git a/extensions/browser/sandboxed_unpacker_unittest.cc b/extensions/browser/sandboxed_unpacker_unittest.cc index c40af802..9615040 100644 --- a/extensions/browser/sandboxed_unpacker_unittest.cc +++ b/extensions/browser/sandboxed_unpacker_unittest.cc
@@ -124,13 +124,13 @@ std::move(callback).Run(should_compute_hashes_); } - void OnUnpackSuccess( - const base::FilePath& temp_dir, - const base::FilePath& extension_root, - std::unique_ptr<base::DictionaryValue> original_manifest, - const Extension* extension, - const SkBitmap& install_icon, - declarative_net_request::RulesetChecksums ruleset_checksums) override { + void OnUnpackSuccess(const base::FilePath& temp_dir, + const base::FilePath& extension_root, + std::unique_ptr<base::DictionaryValue> original_manifest, + const Extension* extension, + const SkBitmap& install_icon, + declarative_net_request::RulesetInstallPrefs + ruleset_install_prefs) override { temp_dir_ = temp_dir; std::move(quit_closure_).Run(); }
diff --git a/extensions/common/api/declarative_net_request.idl b/extensions/common/api/declarative_net_request.idl index 8bfa2aa..2bb7a8b 100644 --- a/extensions/common/api/declarative_net_request.idl +++ b/extensions/common/api/declarative_net_request.idl
@@ -456,6 +456,13 @@ // warning will be raised. [value=30000] static long MAX_NUMBER_OF_RULES(); + // The number of rules that an extension can specify across its enabled + // static rulesets that will not count towards the global total. Up to this + // number of rules can be enabled regardless of the number of rules that + // count towards the global total. + // TODO(crbug.com/983299): Add documentation once implementation is complete. + [nodoc, value=30000] static long GUARANTEED_MINIMUM_STATIC_RULES(); + // The maximum number of dynamic rules that an extension can add. [value=5000] static long MAX_NUMBER_OF_DYNAMIC_RULES();
diff --git a/extensions/common/extension_l10n_util.cc b/extensions/common/extension_l10n_util.cc index c102fc13..6e9267dc 100644 --- a/extensions/common/extension_l10n_util.cc +++ b/extensions/common/extension_l10n_util.cc
@@ -532,7 +532,16 @@ if (base::Contains(subdir, '.')) return true; - if (all_locales.find(subdir) == all_locales.end()) + // On case-insensitive file systems we will load messages by matching them + // with locale names (see LoadMessageCatalogs). Reversed comparison must still + // work here, when we match locale name with file name. + auto find_iter = std::find_if(all_locales.begin(), all_locales.end(), + [subdir](const std::string& locale) { + return base::CompareCaseInsensitiveASCII( + subdir, locale) == 0; + }); + + if (find_iter == all_locales.end()) return true; return false;
diff --git a/extensions/common/extension_l10n_util_unittest.cc b/extensions/common/extension_l10n_util_unittest.cc index debef722..c386fbb5 100644 --- a/extensions/common/extension_l10n_util_unittest.cc +++ b/extensions/common/extension_l10n_util_unittest.cc
@@ -143,6 +143,36 @@ EXPECT_EQ("Not in the US or GB.", bundle->GetL10nMessage("not_in_US_or_GB")); } +TEST(ExtensionL10nUtil, LoadMessageCatalogsLowercaseLocales) { + extension_l10n_util::ScopedLocaleForTest scoped_locale("en-US"); + base::FilePath install_dir; + ASSERT_TRUE(base::PathService::Get(DIR_TEST_DATA, &install_dir)); + install_dir = install_dir.AppendASCII("extension_with_lowercase_locales") + .Append(kLocaleFolder); + + std::string error; + std::unique_ptr<MessageBundle> bundle( + extension_l10n_util::LoadMessageCatalogs( + install_dir, "en-US", GzippedMessagesPermission::kDisallow, &error)); + ASSERT_TRUE(bundle); + EXPECT_TRUE(error.empty()); + const base::FilePath locale_uppercase_path = install_dir.AppendASCII("en_US"); + const base::FilePath locale_lowercase_path = install_dir.AppendASCII("en_us"); + if (base::PathExists(locale_uppercase_path) && + base::PathExists(locale_lowercase_path)) { + // Path system is case-insensitive. + EXPECT_EQ("color lowercase", bundle->GetL10nMessage("color")); + } else { + EXPECT_EQ("", bundle->GetL10nMessage("color")); + } + std::set<std::string> all_locales; + extension_l10n_util::GetAllLocales(&all_locales); + EXPECT_FALSE(extension_l10n_util::ShouldSkipValidation( + install_dir, locale_uppercase_path, all_locales)); + EXPECT_FALSE(extension_l10n_util::ShouldSkipValidation( + install_dir, locale_lowercase_path, all_locales)); +} + TEST(ExtensionL10nUtil, LoadMessageCatalogsMissingFiles) { extension_l10n_util::ScopedLocaleForTest scoped_locale("sr"); base::ScopedTempDir temp;
diff --git a/extensions/test/data/extension_with_lowercase_locales/_locales/en_us/messages.json b/extensions/test/data/extension_with_lowercase_locales/_locales/en_us/messages.json new file mode 100644 index 0000000..92e5c62 --- /dev/null +++ b/extensions/test/data/extension_with_lowercase_locales/_locales/en_us/messages.json
@@ -0,0 +1,11 @@ +{ + "chrome_extension_name": { + "message": "My extension 1" + }, + "chrome_extension_description": { + "message": "The first extension that I made." + }, + "color": { + "message": "color lowercase" + } +}
diff --git a/extensions/test/data/extension_with_lowercase_locales/manifest.json b/extensions/test/data/extension_with_lowercase_locales/manifest.json new file mode 100644 index 0000000..04da45a --- /dev/null +++ b/extensions/test/data/extension_with_lowercase_locales/manifest.json
@@ -0,0 +1,7 @@ +{ + "version": "1.0.0.0", + "manifest_version": 2, + "name": "__MSG_chrome_extension_name__", + "description": "__MSG_chrome_extension_description__", + "default_locale": "en_US" +}
diff --git a/gpu/vulkan/generate_bindings.py b/gpu/vulkan/generate_bindings.py index d812423b..326f5ee 100755 --- a/gpu/vulkan/generate_bindings.py +++ b/gpu/vulkan/generate_bindings.py
@@ -382,7 +382,9 @@ #endif #if defined(USE_VULKAN_XLIB) -#include <X11/Xlib.h> +typedef struct _XDisplay Display; +typedef unsigned long Window; +typedef unsigned long VisualID; #include <vulkan/vulkan_xlib.h> #endif
diff --git a/gpu/vulkan/vulkan_function_pointers.h b/gpu/vulkan/vulkan_function_pointers.h index 50d8063..79d9b96a 100644 --- a/gpu/vulkan/vulkan_function_pointers.h +++ b/gpu/vulkan/vulkan_function_pointers.h
@@ -32,7 +32,9 @@ #endif #if defined(USE_VULKAN_XLIB) -#include <X11/Xlib.h> +typedef struct _XDisplay Display; +typedef unsigned long Window; +typedef unsigned long VisualID; #include <vulkan/vulkan_xlib.h> #endif
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm index 029664b..a6b1065 100644 --- a/ios/chrome/browser/passwords/password_controller.mm +++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -379,7 +379,7 @@ for (size_t i = 0; i < count; i++) { InfoBarIOS* infobar = static_cast<InfoBarIOS*>(infoBarManager->infobar_at(i)); - if (infobar->InfobarUIDelegate().infobarType == infobarType && + if (infobar->infobar_type() == infobarType && infobar->skip_banner() == manual) return infobar; }
diff --git a/ios/chrome/browser/ui/location_bar/BUILD.gn b/ios/chrome/browser/ui/location_bar/BUILD.gn index de4490c9..7bd46cd 100644 --- a/ios/chrome/browser/ui/location_bar/BUILD.gn +++ b/ios/chrome/browser/ui/location_bar/BUILD.gn
@@ -116,6 +116,7 @@ "//ios/chrome/browser/reading_list", "//ios/chrome/browser/ssl", "//ios/chrome/browser/web_state_list", + "//ios/components/security_interstitials", "//ios/components/webui:url_constants", "//ios/web/public", "//ios/web/public/security",
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_model_delegate_ios.mm b/ios/chrome/browser/ui/location_bar/location_bar_model_delegate_ios.mm index 3b973332..7947e35 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_model_delegate_ios.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_model_delegate_ios.mm
@@ -16,6 +16,7 @@ #include "ios/chrome/browser/pref_names.h" #import "ios/chrome/browser/reading_list/offline_page_tab_helper.h" #include "ios/chrome/browser/web_state_list/web_state_list.h" +#import "ios/components/security_interstitials/ios_blocking_page_tab_helper.h" #include "ios/components/webui/web_ui_url_constants.h" #import "ios/web/public/navigation/navigation_item.h" #import "ios/web/public/navigation/navigation_manager.h" @@ -66,6 +67,15 @@ } bool LocationBarModelDelegateIOS::ShouldDisplayURL() const { + if (web::WebState* web_state = GetActiveWebState()) { + security_interstitials::IOSBlockingPageTabHelper* tab_helper = + security_interstitials::IOSBlockingPageTabHelper::FromWebState( + web_state); + if (tab_helper && tab_helper->GetCurrentBlockingPage()) { + return tab_helper->ShouldDisplayURL(); + } + } + web::NavigationItem* item = GetNavigationItem(); if (item) { GURL url = item->GetURL();
diff --git a/ios/chrome/browser/ui/tab_grid/grid/grid_view_controller.mm b/ios/chrome/browser/ui/tab_grid/grid/grid_view_controller.mm index ff5e7e5b..87c027e 100644 --- a/ios/chrome/browser/ui/tab_grid/grid/grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_grid/grid/grid_view_controller.mm
@@ -455,7 +455,8 @@ NSIndexPath* dropIndexPath = coordinator.destinationIndexPath; if (!dropIndexPath) { - dropIndexPath = [NSIndexPath indexPathForItem:self.items.count inSection:0]; + dropIndexPath = [NSIndexPath indexPathForItem:(self.items.count - 1) + inSection:0]; } NSUInteger destinationIndex =
diff --git a/ios/chrome/browser/web/lookalike_url_egtest.mm b/ios/chrome/browser/web/lookalike_url_egtest.mm index c69227e..62d569f 100644 --- a/ios/chrome/browser/web/lookalike_url_egtest.mm +++ b/ios/chrome/browser/web/lookalike_url_egtest.mm
@@ -35,6 +35,8 @@ using chrome_test_util::BackButton; using chrome_test_util::ForwardButton; +using chrome_test_util::Omnibox; +using chrome_test_util::OmniboxText; namespace { // Relative paths used for a page that opens a lookalike in a new tab. @@ -119,6 +121,11 @@ // Load the lookalike page and verify a warning is shown. [ChromeEarlGrey loadURL:_lookalikeURL]; [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + // Lookalike URL blocking pages should not display URL. + [[EarlGrey selectElementWithMatcher:OmniboxText(_lookalikeURL.GetContent())] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:Omnibox()] + assertWithMatcher:OmniboxText("")]; // Tap on the "Go to" button and verify that the suggested page // contents are loaded. @@ -132,6 +139,8 @@ [[EarlGrey selectElementWithMatcher:ForwardButton()] performAction:grey_tap()]; [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; + [[EarlGrey selectElementWithMatcher:OmniboxText(_safeURL.GetContent())] + assertWithMatcher:grey_notNil()]; } // Tests that a lookalike URL navigation is blocked, and the text link for @@ -141,11 +150,18 @@ // Load the lookalike page and verify a warning is shown. [ChromeEarlGrey loadURL:_lookalikeURL]; [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + // Lookalike URL blocking pages should not display URL. + [[EarlGrey selectElementWithMatcher:OmniboxText(_lookalikeURL.GetContent())] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:Omnibox()] + assertWithMatcher:OmniboxText("")]; // Tap on the site suggestion link and verify that the suggested page // contents are loaded. [ChromeEarlGrey tapWebStateElementWithID:@"dont-proceed-link"]; [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; + [[EarlGrey selectElementWithMatcher:OmniboxText(_safeURL.GetContent())] + assertWithMatcher:grey_notNil()]; // Verify that the warning is shown when navigating back and that safe // content is shown when navigating forward again. @@ -174,11 +190,18 @@ [ChromeEarlGrey waitForWebStateContainingText:l10n_util::GetStringUTF8( IDS_LOOKALIKE_URL_BACK_TO_SAFETY)]; + // Lookalike URL blocking pages should not display URL. + [[EarlGrey selectElementWithMatcher:OmniboxText(_lookalikeURL.GetContent())] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:Omnibox()] + assertWithMatcher:OmniboxText("")]; // Tap on the "Back to safety" button and verify that the safe content // is loaded. [ChromeEarlGrey tapWebStateElementWithID:@"primary-button"]; [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; + [[EarlGrey selectElementWithMatcher:OmniboxText(_safeURL.GetContent())] + assertWithMatcher:grey_notNil()]; // Verify that the warning is shown when navigating forward and that safe // content is shown when navigating back again. @@ -211,6 +234,11 @@ [ChromeEarlGrey waitForWebStateContainingText:l10n_util::GetStringUTF8( IDS_LOOKALIKE_URL_CLOSE_PAGE)]; + // Lookalike URL blocking pages should not display URL. + [[EarlGrey selectElementWithMatcher:OmniboxText(_lookalikeURL.GetContent())] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:Omnibox()] + assertWithMatcher:OmniboxText("")]; // Tap on the "Close" button and verify that the page closes. [ChromeEarlGrey tapWebStateElementWithID:@"primary-button"]; @@ -223,10 +251,17 @@ // Load the lookalike page and verify a warning is shown. [ChromeEarlGrey loadURL:_lookalikeURL]; [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + // Lookalike URL blocking pages should not display URL. + [[EarlGrey selectElementWithMatcher:OmniboxText(_lookalikeURL.GetContent())] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:Omnibox()] + assertWithMatcher:OmniboxText("")]; // Tap on the link to ignore the warning, and verify that the page is loaded. [ChromeEarlGrey tapWebStateElementWithID:@"proceed-button"]; [ChromeEarlGrey waitForWebStateContainingText:kLookalikeContent]; + [[EarlGrey selectElementWithMatcher:OmniboxText(_lookalikeURL.GetContent())] + assertWithMatcher:grey_notNil()]; // In a new tab, the warning should not be shown. [ChromeEarlGrey openNewTab]; @@ -248,10 +283,17 @@ // Load the lookalike page and verify a warning is shown. [ChromeEarlGrey loadURL:_lookalikeURL]; [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + // Lookalike URL blocking pages should not display URL. + [[EarlGrey selectElementWithMatcher:OmniboxText(_lookalikeURL.GetContent())] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:Omnibox()] + assertWithMatcher:OmniboxText("")]; // Tap on the link to ignore the warning, and verify that the page is loaded. [ChromeEarlGrey tapWebStateElementWithID:@"proceed-button"]; [ChromeEarlGrey waitForWebStateContainingText:kLookalikeContent]; + [[EarlGrey selectElementWithMatcher:OmniboxText(_lookalikeURL.GetContent())] + assertWithMatcher:grey_notNil()]; // Verify that no warning is shown when navigating back and then forward to // the unsafe page. @@ -274,6 +316,11 @@ // Load the lookalike URL page and verify a warning is shown. [ChromeEarlGrey loadURL:_lookalikeURL]; [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + // Lookalike URL blocking pages should not display URL. + [[EarlGrey selectElementWithMatcher:OmniboxText(_lookalikeURL.GetContent())] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:Omnibox()] + assertWithMatcher:OmniboxText("")]; // Tap on the "Go to" button and verify that the suggested page contents // are loaded.
diff --git a/ios/chrome/test/earl_grey/chrome_test_case.mm b/ios/chrome/test/earl_grey/chrome_test_case.mm index 67a0cd6..f824e0d5 100644 --- a/ios/chrome/test/earl_grey/chrome_test_case.mm +++ b/ios/chrome/test/earl_grey/chrome_test_case.mm
@@ -428,14 +428,6 @@ GREYAssertTrue([ChromeEarlGrey isCustomWebKitLoadedIfRequested], @"Unable to load custom WebKit"); - // TODO(crbug.com/1103822): Investigate why this is causing EG2 tests to spin - // on iOS14. - if (base::ios::IsRunningOnIOS14OrLater()) { - [[GREYConfiguration sharedConfiguration] - setValue:@0 - forConfigKey:kGREYConfigKeyDispatchAfterMaxTrackableDelay]; - } - [[self class] startHTTPServer]; [[self class] enableMockAuthentication];
diff --git a/ios/components/security_interstitials/ios_blocking_page_tab_helper.h b/ios/components/security_interstitials/ios_blocking_page_tab_helper.h index cf611e72..4f70a2054 100644 --- a/ios/components/security_interstitials/ios_blocking_page_tab_helper.h +++ b/ios/components/security_interstitials/ios_blocking_page_tab_helper.h
@@ -32,6 +32,9 @@ int64_t navigation_id, std::unique_ptr<IOSSecurityInterstitialPage> blocking_page); + // Determines whether a URL should be shown on the current navigation page. + bool ShouldDisplayURL() const; + // Returns the blocking page for the currently-visible interstitial, if any. IOSSecurityInterstitialPage* GetCurrentBlockingPage() const;
diff --git a/ios/components/security_interstitials/ios_blocking_page_tab_helper.mm b/ios/components/security_interstitials/ios_blocking_page_tab_helper.mm index ab1d5e33..dc9dbf3 100644 --- a/ios/components/security_interstitials/ios_blocking_page_tab_helper.mm +++ b/ios/components/security_interstitials/ios_blocking_page_tab_helper.mm
@@ -48,6 +48,10 @@ } } +bool IOSBlockingPageTabHelper::ShouldDisplayURL() const { + return blocking_page_for_currently_committed_navigation_->ShouldDisplayURL(); +} + IOSSecurityInterstitialPage* IOSBlockingPageTabHelper::GetCurrentBlockingPage() const { return blocking_page_for_currently_committed_navigation_.get();
diff --git a/ios/components/security_interstitials/ios_security_interstitial_page.h b/ios/components/security_interstitials/ios_security_interstitial_page.h index a28f692..60fd9d3 100644 --- a/ios/components/security_interstitials/ios_security_interstitial_page.h +++ b/ios/components/security_interstitials/ios_security_interstitial_page.h
@@ -38,6 +38,10 @@ // web::WebInterstitialDelegate implementation. std::string GetHtmlContents() const override; + // Whether a URL should be displayed on this interstitial page. This is + // respected by committed interstitials only. + virtual bool ShouldDisplayURL() const; + // Handles JS commands from the interstitial page. Overridden in subclasses // to handle actions specific to the type of interstitial. virtual void HandleScriptCommand(const base::DictionaryValue& message,
diff --git a/ios/components/security_interstitials/ios_security_interstitial_page.mm b/ios/components/security_interstitials/ios_security_interstitial_page.mm index 75ffc83..c35d6d1 100644 --- a/ios/components/security_interstitials/ios_security_interstitial_page.mm +++ b/ios/components/security_interstitials/ios_security_interstitial_page.mm
@@ -87,6 +87,10 @@ return webui::GetI18nTemplateHtml(html, &load_time_data); } +bool IOSSecurityInterstitialPage::ShouldDisplayURL() const { + return true; +} + base::string16 IOSSecurityInterstitialPage::GetFormattedHostName() const { return security_interstitials::common_string_util::GetFormattedHostName( request_url_);
diff --git a/ios/components/security_interstitials/lookalikes/lookalike_url_blocking_page.h b/ios/components/security_interstitials/lookalikes/lookalike_url_blocking_page.h index b6005a0..4e93b07 100644 --- a/ios/components/security_interstitials/lookalikes/lookalike_url_blocking_page.h +++ b/ios/components/security_interstitials/lookalikes/lookalike_url_blocking_page.h
@@ -33,6 +33,7 @@ bool ShouldCreateNewNavigation() const override; void PopulateInterstitialStrings( base::DictionaryValue* load_time_data) const override; + bool ShouldDisplayURL() const override; private: void HandleScriptCommand(const base::DictionaryValue& message,
diff --git a/ios/components/security_interstitials/lookalikes/lookalike_url_blocking_page.mm b/ios/components/security_interstitials/lookalikes/lookalike_url_blocking_page.mm index 4466e63..b6f38de 100644 --- a/ios/components/security_interstitials/lookalikes/lookalike_url_blocking_page.mm +++ b/ios/components/security_interstitials/lookalikes/lookalike_url_blocking_page.mm
@@ -70,6 +70,10 @@ request_url()); } +bool LookalikeUrlBlockingPage::ShouldDisplayURL() const { + return false; +} + void LookalikeUrlBlockingPage::HandleScriptCommand( const base::DictionaryValue& message, const GURL& origin_url,
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn index 8d281dd..1fdbe90 100644 --- a/media/base/BUILD.gn +++ b/media/base/BUILD.gn
@@ -315,6 +315,8 @@ "video_encoder.h", "video_frame.cc", "video_frame.h", + "video_frame_feedback.cc", + "video_frame_feedback.h", "video_frame_layout.cc", "video_frame_layout.h", "video_frame_metadata.cc",
diff --git a/media/base/video_frame.h b/media/base/video_frame.h index 0cb07b4..001fe617 100644 --- a/media/base/video_frame.h +++ b/media/base/video_frame.h
@@ -28,6 +28,7 @@ #include "gpu/command_buffer/common/mailbox_holder.h" #include "gpu/ipc/common/vulkan_ycbcr_info.h" #include "media/base/hdr_metadata.h" +#include "media/base/video_frame_feedback.h" #include "media/base/video_frame_layout.h" #include "media/base/video_frame_metadata.h" #include "media/base/video_types.h" @@ -546,6 +547,9 @@ // Resets |metadata_|. void clear_metadata() { set_metadata(VideoFrameMetadata()); } + const VideoFrameFeedback* feedback() const { return &feedback_; } + VideoFrameFeedback* feedback() { return &feedback_; } + // The time span between the current frame and the first frame of the stream. // This is the media timestamp, and not the reference time. // See VideoFrameMetadata::REFERENCE_TIME for details. @@ -699,6 +703,8 @@ VideoFrameMetadata metadata_; + VideoFrameFeedback feedback_; + // Generated at construction time. const int unique_id_;
diff --git a/media/base/video_frame_feedback.cc b/media/base/video_frame_feedback.cc new file mode 100644 index 0000000..d2473ec --- /dev/null +++ b/media/base/video_frame_feedback.cc
@@ -0,0 +1,53 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/video_frame_feedback.h" + +#include <cmath> + +namespace media { + +VideoFrameFeedback::VideoFrameFeedback() = default; +VideoFrameFeedback::VideoFrameFeedback(const VideoFrameFeedback& other) = + default; + +VideoFrameFeedback::VideoFrameFeedback( + base::Optional<double> resource_utilization, + float max_framerate_fps, + base::Optional<int> max_pixels) + : resource_utilization(resource_utilization), + max_framerate_fps(max_framerate_fps), + max_pixels(max_pixels) {} + +void VideoFrameFeedback::Combine(const VideoFrameFeedback& other) { + // Take maximum of non-negative and finite |resource_utilization| values. + if (other.resource_utilization.has_value() && + *other.resource_utilization >= 0 && + std::isfinite(*other.resource_utilization)) { + if (!resource_utilization.has_value() || + !std::isfinite(*resource_utilization) || + resource_utilization < other.resource_utilization) { + resource_utilization = other.resource_utilization; + } + } + + // Take minimum max_pixels value to satisfy both constraints. + // Explicit checks for nullopt, since it's lower than any other value by + // design of base::Optional. + if (other.max_pixels.has_value() && + (!max_pixels.has_value() || *max_pixels > *other.max_pixels)) + max_pixels = other.max_pixels; + + // Take minimum of non-negative max_framerate_fps. + if (other.max_framerate_fps >= 0.0 && + (max_framerate_fps < 0.0 || max_framerate_fps > other.max_framerate_fps)) + max_framerate_fps = other.max_framerate_fps; +} + +bool VideoFrameFeedback::Empty() const { + return !std::isfinite(max_framerate_fps) && !max_pixels.has_value() && + (!resource_utilization.has_value() || *resource_utilization < 0.0); +} + +} // namespace media
diff --git a/media/base/video_frame_feedback.h b/media/base/video_frame_feedback.h new file mode 100644 index 0000000..e95c610 --- /dev/null +++ b/media/base/video_frame_feedback.h
@@ -0,0 +1,67 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_VIDEO_FRAME_FEEDBACK_H_ +#define MEDIA_BASE_VIDEO_FRAME_FEEDBACK_H_ + +#include "base/optional.h" +#include "media/base/media_export.h" + +namespace media { + +// Feedback from the frames consumer. +// This class is passed from the frames sink to the capturer to limit +// incoming video feed frame-rate and/or resolution. +struct MEDIA_EXPORT VideoFrameFeedback { + VideoFrameFeedback(); + VideoFrameFeedback(const VideoFrameFeedback& other); + + VideoFrameFeedback(base::Optional<double> resource_utilization, + float max_framerate_fps, + base::Optional<int> max_pixels); + + bool operator==(const VideoFrameFeedback& other) const { + return resource_utilization == other.resource_utilization && + max_pixels == other.max_pixels && + max_framerate_fps == other.max_framerate_fps; + } + // Combine constraints of two different sinks resulting in constraints fitting + // both of them. + void Combine(const VideoFrameFeedback& other); + + // True if no actionable feedback is present (no resource utilization recorded + // and all constraints are infinite or absent). + bool Empty() const; + + // A feedback signal that indicates the fraction of the tolerable maximum + // amount of resources that were utilized to process this frame. A producer + // can check this value after-the-fact, usually via a VideoFrame destruction + // observer, to determine whether the consumer can handle more or less data + // volume, and achieve the right quality versus performance trade-off. + // + // Values are interpreted as follows: + // Less than 0.0 is meaningless and should be ignored. 1.0 indicates a + // maximum sustainable utilization. Greater than 1.0 indicates the consumer + // is likely to stall or drop frames if the data volume is not reduced. + // + // Example: In a system that encodes and transmits video frames over the + // network, this value can be used to indicate whether sufficient CPU + // is available for encoding and/or sufficient bandwidth is available for + // transmission over the network. The maximum of the two utilization + // measurements would be used as feedback. + base::Optional<double> resource_utilization; + + // A feedback signal that indicates how big of a frame-rate and image size the + // consumer can consume without overloading. A producer can check this value + // after-the-fact, usually via a VideoFrame destruction observer, to + // limit produced frame size and frame-rate accordingly. + float max_framerate_fps = std::numeric_limits<float>::infinity(); + + // Maximum requested resolution by a sink (given as a number of pixels). + // -1 means no restriction. + base::Optional<int> max_pixels; +}; + +} // namespace media +#endif // MEDIA_BASE_VIDEO_FRAME_FEEDBACK_H_
diff --git a/media/base/video_frame_metadata.cc b/media/base/video_frame_metadata.cc index cb1784e..584bdf6b 100644 --- a/media/base/video_frame_metadata.cc +++ b/media/base/video_frame_metadata.cc
@@ -37,7 +37,6 @@ MERGE_FIELD(frame_rate, metadata_source); MERGE_FIELD(interactive_content, metadata_source); MERGE_FIELD(reference_time, metadata_source); - MERGE_FIELD(resource_utilization, metadata_source); MERGE_FIELD(read_lock_fences_enabled, metadata_source); MERGE_FIELD(rotation, metadata_source); MERGE_FIELD(texture_owner, metadata_source);
diff --git a/media/base/video_frame_metadata.h b/media/base/video_frame_metadata.h index 9b84525..eed8b13 100644 --- a/media/base/video_frame_metadata.h +++ b/media/base/video_frame_metadata.h
@@ -109,24 +109,6 @@ // and for A/V synchronization purposes. base::Optional<base::TimeTicks> reference_time; - // A feedback signal that indicates the fraction of the tolerable maximum - // amount of resources that were utilized to process this frame. A producer - // can check this value after-the-fact, usually via a VideoFrame destruction - // observer, to determine whether the consumer can handle more or less data - // volume, and achieve the right quality versus performance trade-off. - // - // Values are interpreted as follows: - // Less than 0.0 is meaningless and should be ignored. 1.0 indicates a - // maximum sustainable utilization. Greater than 1.0 indicates the consumer - // is likely to stall or drop frames if the data volume is not reduced. - // - // Example: In a system that encodes and transmits video frames over the - // network, this value can be used to indicate whether sufficient CPU - // is available for encoding and/or sufficient bandwidth is available for - // transmission over the network. The maximum of the two utilization - // measurements would be used as feedback. - base::Optional<double> resource_utilization; - // Sources of VideoFrames use this marker to indicate that an instance of // VideoFrameExternalResources produced from the associated video frame // should use read lock fences.
diff --git a/media/base/video_frame_unittest.cc b/media/base/video_frame_unittest.cc index 5e3ec211a..a36cf85 100644 --- a/media/base/video_frame_unittest.cc +++ b/media/base/video_frame_unittest.cc
@@ -86,7 +86,6 @@ metadata.root_scroll_offset_x = 100.2; metadata.root_scroll_offset_y = 200.1; metadata.top_controls_visible_height = 25.5; - metadata.resource_utilization = 95.8; metadata.frame_rate = 29.94; metadata.rtp_timestamp = 1.0; @@ -120,7 +119,6 @@ EXPECT_EQ(a.frame_rate, b.frame_rate); EXPECT_EQ(a.interactive_content, b.interactive_content); EXPECT_EQ(a.reference_time, b.reference_time); - EXPECT_EQ(a.resource_utilization, b.resource_utilization); EXPECT_EQ(a.read_lock_fences_enabled, b.read_lock_fences_enabled); EXPECT_EQ(a.rotation, b.rotation); EXPECT_EQ(a.texture_owner, b.texture_owner); @@ -750,13 +748,11 @@ const base::TimeTicks kTempTicks = base::TimeTicks::Now() + base::TimeDelta::FromSeconds(2); const base::TimeDelta kTempDelta = base::TimeDelta::FromMilliseconds(31415); - const double kTempDouble = 123.45; VideoFrameMetadata partial_metadata; partial_metadata.capture_update_rect = kTempRect; partial_metadata.reference_time = kTempTicks; partial_metadata.processing_time = kTempDelta; - partial_metadata.resource_utilization = kTempDouble; partial_metadata.allow_overlay = false; // Merging partial metadata into full metadata partially override it. @@ -765,7 +761,6 @@ EXPECT_EQ(partial_metadata.capture_update_rect, kTempRect); EXPECT_EQ(partial_metadata.reference_time, kTempTicks); EXPECT_EQ(partial_metadata.processing_time, kTempDelta); - EXPECT_EQ(partial_metadata.resource_utilization, kTempDouble); EXPECT_EQ(partial_metadata.allow_overlay, false); }
diff --git a/media/capture/content/android/thread_safe_capture_oracle.cc b/media/capture/content/android/thread_safe_capture_oracle.cc index 498f65f..5714497 100644 --- a/media/capture/content/android/thread_safe_capture_oracle.cc +++ b/media/capture/content/android/thread_safe_capture_oracle.cc
@@ -237,9 +237,9 @@ void ThreadSafeCaptureOracle::OnConsumerReportingUtilization( int frame_number, - double utilization) { + const media::VideoFrameFeedback& feedback) { base::AutoLock guard(lock_); - oracle_.RecordConsumerFeedback(frame_number, utilization); + oracle_.RecordConsumerFeedback(frame_number, feedback); } } // namespace media
diff --git a/media/capture/content/android/thread_safe_capture_oracle.h b/media/capture/content/android/thread_safe_capture_oracle.h index 451378bb..6dc4b19d 100644 --- a/media/capture/content/android/thread_safe_capture_oracle.h +++ b/media/capture/content/android/thread_safe_capture_oracle.h
@@ -78,7 +78,9 @@ // Signal device started to the client. void ReportStarted(); - void OnConsumerReportingUtilization(int frame_number, double utilization); + void OnConsumerReportingUtilization( + int frame_number, + const media::VideoFrameFeedback& feedback); private: // Helper struct to hold the many arguments needed by DidCaptureFrame(), and
diff --git a/media/capture/content/video_capture_oracle.cc b/media/capture/content/video_capture_oracle.cc index 4176b03..d20eee5 100644 --- a/media/capture/content/video_capture_oracle.cc +++ b/media/capture/content/video_capture_oracle.cc
@@ -331,19 +331,25 @@ num_frames_pending_ = 0; } -void VideoCaptureOracle::RecordConsumerFeedback(int frame_number, - double resource_utilization) { +void VideoCaptureOracle::RecordConsumerFeedback( + int frame_number, + const media::VideoFrameFeedback& feedback) { if (capture_size_throttling_mode_ == kThrottlingDisabled) return; - if (!std::isfinite(resource_utilization)) { + if (feedback.resource_utilization && + !std::isfinite(feedback.resource_utilization.value())) { LOG(DFATAL) << "Non-finite utilization provided by consumer for frame #" - << frame_number << ": " << resource_utilization; + << frame_number << ": " + << feedback.resource_utilization.value(); return; } - if (resource_utilization <= 0.0) + if (!feedback.resource_utilization || + feedback.resource_utilization.value() <= 0.0) return; // Non-positive values are normal, meaning N/A. + double resource_utilization = *feedback.resource_utilization; + if (capture_size_throttling_mode_ != kThrottlingActive) { VLOG(1) << "Received consumer feedback at frame #" << frame_number << "; activating capture size auto-throttling.";
diff --git a/media/capture/content/video_capture_oracle.h b/media/capture/content/video_capture_oracle.h index ee4e267..b19c75e 100644 --- a/media/capture/content/video_capture_oracle.h +++ b/media/capture/content/video_capture_oracle.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/time/time.h" #include "media/base/feedback_signal_accumulator.h" +#include "media/base/video_frame_feedback.h" #include "media/capture/capture_export.h" #include "media/capture/content/animated_content_sampler.h" #include "media/capture/content/capture_resolution_chooser.h" @@ -104,7 +105,8 @@ // utilization relative to a sustainable maximum (not the absolute maximum). // This method should only be called for frames where CompleteCapture() // returned true. - void RecordConsumerFeedback(int frame_number, double resource_utilization); + void RecordConsumerFeedback(int frame_number, + const media::VideoFrameFeedback& feedback); // Sets the minimum amount of time that must pass between changes to the // capture size. This throttles the rate of size changes, to avoid stressing
diff --git a/media/capture/content/video_capture_oracle_unittest.cc b/media/capture/content/video_capture_oracle_unittest.cc index 8535f40..e6be214c 100644 --- a/media/capture/content/video_capture_oracle_unittest.cc +++ b/media/capture/content/video_capture_oracle_unittest.cc
@@ -312,7 +312,10 @@ const int frame_number = oracle.next_frame_number(); oracle.RecordCapture(0.0); ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored)); - oracle.RecordConsumerFeedback(frame_number, 0.0); + oracle.RecordConsumerFeedback( + frame_number, + media::VideoFrameFeedback(0.0, std::numeric_limits<float>::infinity(), + base::nullopt)); } // Now run 30 seconds of frame captures with lots of random source size @@ -342,7 +345,10 @@ const int frame_number = oracle.next_frame_number(); oracle.RecordCapture(0.0); ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored)); - oracle.RecordConsumerFeedback(frame_number, 0.0); + oracle.RecordConsumerFeedback( + frame_number, + media::VideoFrameFeedback(0.0, std::numeric_limits<float>::infinity(), + base::nullopt)); } } @@ -380,7 +386,10 @@ const int frame_number = oracle.next_frame_number(); oracle.RecordCapture(0.0); ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored)); - oracle.RecordConsumerFeedback(frame_number, 0.0); + oracle.RecordConsumerFeedback( + frame_number, + media::VideoFrameFeedback(0.0, std::numeric_limits<float>::infinity(), + base::nullopt)); } } @@ -422,12 +431,18 @@ base::TimeTicks ignored; ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored)); if (with_consumer_feedback) { - oracle.RecordConsumerFeedback(frame_number, utilization); + oracle.RecordConsumerFeedback( + frame_number, media::VideoFrameFeedback( + utilization, std::numeric_limits<float>::infinity(), + base::nullopt)); } else if (t == kInitialTestTimeTicks) { // Provide feedback with the very first capture to activate the capture // size auto-throttling logic. After this, no consumer feedback applies // and the buffer utilization will be the only consideration. - oracle.RecordConsumerFeedback(frame_number, 0.0); + oracle.RecordConsumerFeedback( + frame_number, + media::VideoFrameFeedback(0.0, std::numeric_limits<float>::infinity(), + base::nullopt)); } } @@ -464,7 +479,11 @@ base::TimeTicks ignored; ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored)); if (with_consumer_feedback) - oracle.RecordConsumerFeedback(frame_number, utilization); + oracle.RecordConsumerFeedback( + frame_number, + media::VideoFrameFeedback(utilization, + std::numeric_limits<float>::infinity(), + base::nullopt)); } } @@ -505,7 +524,11 @@ base::TimeTicks ignored; ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored)); if (with_consumer_feedback) - oracle.RecordConsumerFeedback(frame_number, utilization); + oracle.RecordConsumerFeedback( + frame_number, + media::VideoFrameFeedback(utilization, + std::numeric_limits<float>::infinity(), + base::nullopt)); } } } @@ -593,7 +616,10 @@ oracle.RecordCapture(0.25); base::TimeTicks ignored; ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored)); - oracle.RecordConsumerFeedback(frame_number, 0.25); + oracle.RecordConsumerFeedback( + frame_number, + media::VideoFrameFeedback(0.25, std::numeric_limits<float>::infinity(), + base::nullopt)); } // Now, set the source size to 720p, continuing to report under-utilization, @@ -614,7 +640,10 @@ oracle.RecordCapture(0.25); base::TimeTicks ignored; ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored)); - oracle.RecordConsumerFeedback(frame_number, 0.25); + oracle.RecordConsumerFeedback( + frame_number, + media::VideoFrameFeedback(0.25, std::numeric_limits<float>::infinity(), + base::nullopt)); } ASSERT_EQ(k720pSize, oracle.capture_size()); @@ -645,7 +674,10 @@ oracle.RecordCapture(utilization); base::TimeTicks ignored; ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored)); - oracle.RecordConsumerFeedback(frame_number, utilization); + oracle.RecordConsumerFeedback( + frame_number, media::VideoFrameFeedback( + utilization, std::numeric_limits<float>::infinity(), + base::nullopt)); } ASSERT_FALSE(stepped_down_size.IsEmpty()); @@ -678,7 +710,10 @@ oracle.RecordCapture(utilization); base::TimeTicks ignored; ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored)); - oracle.RecordConsumerFeedback(frame_number, utilization); + oracle.RecordConsumerFeedback( + frame_number, media::VideoFrameFeedback( + utilization, std::numeric_limits<float>::infinity(), + base::nullopt)); } ASSERT_FALSE(stepped_up_size.IsEmpty()); } @@ -704,7 +739,10 @@ const int frame_number = oracle.next_frame_number(); oracle.RecordCapture(0.9); ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored)); - oracle.RecordConsumerFeedback(frame_number, 0.9); + oracle.RecordConsumerFeedback( + frame_number, + media::VideoFrameFeedback(0.9, std::numeric_limits<float>::infinity(), + base::nullopt)); } // Now run 10 seconds with overload indicated. Still, expect no capture size @@ -718,7 +756,10 @@ const int frame_number = oracle.next_frame_number(); oracle.RecordCapture(2.0); ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored)); - oracle.RecordConsumerFeedback(frame_number, 2.0); + oracle.RecordConsumerFeedback( + frame_number, + media::VideoFrameFeedback(2.0, std::numeric_limits<float>::infinity(), + base::nullopt)); } }
diff --git a/media/capture/mojom/BUILD.gn b/media/capture/mojom/BUILD.gn index 03969c5..434f14d 100644 --- a/media/capture/mojom/BUILD.gn +++ b/media/capture/mojom/BUILD.gn
@@ -69,6 +69,10 @@ mojom = "media.mojom.VideoFacingMode" cpp = "::media::VideoFacingMode" }, + { + mojom = "media.mojom.VideoFrameFeedback" + cpp = "::media::VideoFrameFeedback" + }, ] traits_headers = [ "video_capture_types_mojom_traits.h" ] traits_public_deps = [ ":video_capture_mojom_support" ]
diff --git a/media/capture/mojom/video_capture.mojom b/media/capture/mojom/video_capture.mojom index 9650e198..2260227 100644 --- a/media/capture/mojom/video_capture.mojom +++ b/media/capture/mojom/video_capture.mojom
@@ -104,7 +104,7 @@ // Indicates that a renderer has finished using a previously shared buffer. ReleaseBuffer(mojo_base.mojom.UnguessableToken device_id, int32 buffer_id, - double consumer_resource_utilization); + VideoFrameFeedback feedback); // Get the formats supported by a device referenced by |session_id|. GetDeviceSupportedFormats(mojo_base.mojom.UnguessableToken device_id,
diff --git a/media/capture/mojom/video_capture_types.mojom b/media/capture/mojom/video_capture_types.mojom index 28b663e..22f3cb7 100644 --- a/media/capture/mojom/video_capture_types.mojom +++ b/media/capture/mojom/video_capture_types.mojom
@@ -267,6 +267,27 @@ bool enable_face_detection; }; +// |resource_utilization| reports that the frame incurred some fractional +// utilization of the downstream pipeline's per-frame processing capacity. +// See code comments in media::base::VideoFrameMetadata for a discussion of +// how utilization is interpreted. The capturer uses this information to +// auto-adjust the capture resolution based on performance variances in the +// live system environment. +// +// |max_framerate_fps| reports requested maximum frame-rate +// flat::inifinty used to signal no limit. +// +// |max_pixels| reports requested maximum resolution (in sense of image area). +struct VideoFrameFeedback { + bool has_resource_utilization; + double resource_utilization; + + float max_framerate_fps; + + bool has_max_pixels; + int32 max_pixels; +}; + // Contains one stride value per image plane. Stride means the number of bytes // per row. If the image format uses fewer than kMaxPlanes planes, the values // for higher plane indices are ignored. For example, for a YUV format, plane
diff --git a/media/capture/mojom/video_capture_types_mojom_traits.cc b/media/capture/mojom/video_capture_types_mojom_traits.cc index 97cc207..54a02fe 100644 --- a/media/capture/mojom/video_capture_types_mojom_traits.cc +++ b/media/capture/mojom/video_capture_types_mojom_traits.cc
@@ -1703,4 +1703,22 @@ return true; } +// static +bool StructTraits<media::mojom::VideoFrameFeedbackDataView, + media::VideoFrameFeedback>:: + Read(media::mojom::VideoFrameFeedbackDataView data, + media::VideoFrameFeedback* output) { + output->max_framerate_fps = data.max_framerate_fps(); + + if (data.has_max_pixels()) { + output->max_pixels = data.max_pixels(); + } + + if (data.has_resource_utilization()) { + output->resource_utilization = data.resource_utilization(); + } + + return true; +} + } // namespace mojo
diff --git a/media/capture/mojom/video_capture_types_mojom_traits.h b/media/capture/mojom/video_capture_types_mojom_traits.h index db7de92a..6992a4e 100644 --- a/media/capture/mojom/video_capture_types_mojom_traits.h +++ b/media/capture/mojom/video_capture_types_mojom_traits.h
@@ -5,7 +5,9 @@ #ifndef MEDIA_CAPTURE_MOJOM_VIDEO_CAPTURE_TYPES_MOJOM_TRAITS_H_ #define MEDIA_CAPTURE_MOJOM_VIDEO_CAPTURE_TYPES_MOJOM_TRAITS_H_ +#include "base/optional.h" #include "media/base/video_facing.h" +#include "media/base/video_frame_feedback.h" #include "media/capture/mojom/video_capture_types.mojom-shared.h" #include "media/capture/video/video_capture_device_descriptor.h" #include "media/capture/video/video_capture_device_info.h" @@ -215,6 +217,36 @@ static bool Read(media::mojom::VideoCaptureDeviceInfoDataView data, media::VideoCaptureDeviceInfo* output); }; + +template <> +struct COMPONENT_EXPORT(MEDIA_CAPTURE_MOJOM_TRAITS) + StructTraits<media::mojom::VideoFrameFeedbackDataView, + media::VideoFrameFeedback> { + static bool has_resource_utilization( + const media::VideoFrameFeedback& feedback) { + return feedback.resource_utilization.has_value(); + } + + static double resource_utilization( + const media::VideoFrameFeedback& feedback) { + return feedback.resource_utilization.value_or(-1.0); + } + + static float max_framerate_fps(const media::VideoFrameFeedback& feedback) { + return feedback.max_framerate_fps; + } + + static int max_pixels(const media::VideoFrameFeedback& feedback) { + return feedback.max_pixels.value_or(0); + } + + static bool has_max_pixels(const media::VideoFrameFeedback& feedback) { + return feedback.max_pixels.has_value(); + } + + static bool Read(media::mojom::VideoFrameFeedbackDataView data, + media::VideoFrameFeedback* output); +}; } // namespace mojo #endif // MEDIA_CAPTURE_MOJOM_VIDEO_CAPTURE_TYPES_MOJOM_TRAITS_H_
diff --git a/media/capture/video/mock_device.h b/media/capture/video/mock_device.h index 4de03688..1676709 100644 --- a/media/capture/video/mock_device.h +++ b/media/capture/video/mock_device.h
@@ -35,7 +35,7 @@ SetPhotoOptionsCallback* callback)); MOCK_METHOD1(DoTakePhoto, void(TakePhotoCallback* callback)); MOCK_METHOD2(OnUtilizationReport, - void(int frame_feedback_id, double utilization)); + void(int frame_feedback_id, media::VideoFrameFeedback)); void AllocateAndStart(const media::VideoCaptureParams& params, std::unique_ptr<Client> client) override;
diff --git a/media/capture/video/mock_device_factory.cc b/media/capture/video/mock_device_factory.cc index e617b9b476..8643a51f 100644 --- a/media/capture/video/mock_device_factory.cc +++ b/media/capture/video/mock_device_factory.cc
@@ -37,8 +37,9 @@ void TakePhoto(TakePhotoCallback callback) override { device_->TakePhoto(std::move(callback)); } - void OnUtilizationReport(int frame_feedback_id, double utilization) override { - device_->OnUtilizationReport(frame_feedback_id, utilization); + void OnUtilizationReport(int frame_feedback_id, + media::VideoFrameFeedback feedback) override { + device_->OnUtilizationReport(frame_feedback_id, feedback); } private:
diff --git a/media/capture/video/video_capture_device.h b/media/capture/video/video_capture_device.h index b7143da..3a1a7424 100644 --- a/media/capture/video/video_capture_device.h +++ b/media/capture/video/video_capture_device.h
@@ -62,9 +62,8 @@ // previously sent out by the VideoCaptureDevice we are giving feedback about. // It is used to indicate which particular frame the reported utilization // corresponds to. - virtual void OnUtilizationReport(int frame_feedback_id, double utilization) {} - - static constexpr double kNoUtilizationRecorded = -1.0; + virtual void OnUtilizationReport(int frame_feedback_id, + media::VideoFrameFeedback feedback) {} }; class CAPTURE_EXPORT VideoCaptureDevice
diff --git a/media/capture/video_capture_types.h b/media/capture/video_capture_types.h index 4fab0d0a..375b6d05 100644 --- a/media/capture/video_capture_types.h +++ b/media/capture/video_capture_types.h
@@ -9,6 +9,7 @@ #include <vector> +#include "base/optional.h" #include "base/unguessable_token.h" #include "build/build_config.h" #include "media/base/video_types.h"
diff --git a/media/cast/sender/video_sender.cc b/media/cast/sender/video_sender.cc index 18d2810..7b1677a 100644 --- a/media/cast/sender/video_sender.cc +++ b/media/cast/sender/video_sender.cc
@@ -326,7 +326,7 @@ // Key frames are artificially capped to 1.0 because their actual // utilization is atypical compared to the other frames in the stream, and // this can misguide the producer of the input video frames. - video_frame->metadata()->resource_utilization = + video_frame->feedback()->resource_utilization = encoded_frame->dependency == EncodedFrame::KEY ? std::min(1.0, attenuated_utilization) : attenuated_utilization;
diff --git a/media/cast/sender/video_sender_unittest.cc b/media/cast/sender/video_sender_unittest.cc index b783fb03..c3335021d 100644 --- a/media/cast/sender/video_sender_unittest.cc +++ b/media/cast/sender/video_sender_unittest.cc
@@ -573,7 +573,7 @@ for (int i = 0; i < 3; ++i) { scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); - ASSERT_FALSE(video_frame->metadata()->resource_utilization.has_value()); + ASSERT_FALSE(video_frame->feedback()->resource_utilization.has_value()); const base::TimeTicks reference_time = testing_clock_.NowTicks(); video_sender_->InsertRawVideoFrame(video_frame, reference_time); @@ -586,7 +586,7 @@ // Check that the resource_utilization value is set and non-negative. Don't // check for specific values because they are dependent on real-world CPU // encode time, which can vary across test runs. - double utilization = *video_frame->metadata()->resource_utilization; + double utilization = *video_frame->feedback()->resource_utilization; EXPECT_LE(0.0, utilization); if (i == 0) EXPECT_GE(1.0, utilization); // Key frames never exceed 1.0.
diff --git a/media/mojo/mojom/media_types.mojom b/media/mojo/mojom/media_types.mojom index a1060fe..6eaf65e8 100644 --- a/media/mojo/mojom/media_types.mojom +++ b/media/mojo/mojom/media_types.mojom
@@ -293,9 +293,6 @@ mojo_base.mojom.TimeTicks? reference_time; - bool has_resource_utilization; - double resource_utilization; - bool read_lock_fences_enabled; bool has_rotation;
diff --git a/media/mojo/mojom/video_frame_metadata_mojom_traits.cc b/media/mojo/mojom/video_frame_metadata_mojom_traits.cc index 235234c1..33c7655 100644 --- a/media/mojo/mojom/video_frame_metadata_mojom_traits.cc +++ b/media/mojo/mojom/video_frame_metadata_mojom_traits.cc
@@ -51,7 +51,6 @@ DESERIALIZE_INTO_OPT(root_scroll_offset_x); DESERIALIZE_INTO_OPT(root_scroll_offset_y); DESERIALIZE_INTO_OPT(top_controls_visible_height); - DESERIALIZE_INTO_OPT(resource_utilization); DESERIALIZE_INTO_OPT(frame_rate); DESERIALIZE_INTO_OPT(rtp_timestamp);
diff --git a/media/mojo/mojom/video_frame_metadata_mojom_traits.h b/media/mojo/mojom/video_frame_metadata_mojom_traits.h index 9c6fee3..aca9211 100644 --- a/media/mojo/mojom/video_frame_metadata_mojom_traits.h +++ b/media/mojo/mojom/video_frame_metadata_mojom_traits.h
@@ -81,7 +81,6 @@ GENERATE_OPT_SERIALIZATION(double, root_scroll_offset_x, 0.0) GENERATE_OPT_SERIALIZATION(double, root_scroll_offset_y, 0.0) GENERATE_OPT_SERIALIZATION(double, top_controls_visible_height, 0.0) - GENERATE_OPT_SERIALIZATION(double, resource_utilization, 0.0) GENERATE_OPT_SERIALIZATION(double, frame_rate, 0.0) GENERATE_OPT_SERIALIZATION(double, rtp_timestamp, 0.0)
diff --git a/media/mojo/mojom/video_frame_metadata_mojom_traits_unittest.cc b/media/mojo/mojom/video_frame_metadata_mojom_traits_unittest.cc index b05f0f50..66ebc41 100644 --- a/media/mojo/mojom/video_frame_metadata_mojom_traits_unittest.cc +++ b/media/mojo/mojom/video_frame_metadata_mojom_traits_unittest.cc
@@ -79,7 +79,6 @@ EXPECT_FALSE(metadata_out.root_scroll_offset_x.has_value()); EXPECT_FALSE(metadata_out.root_scroll_offset_y.has_value()); EXPECT_FALSE(metadata_out.top_controls_visible_height.has_value()); - EXPECT_FALSE(metadata_out.resource_utilization.has_value()); EXPECT_FALSE(metadata_out.frame_rate.has_value()); EXPECT_FALSE(metadata_out.rtp_timestamp.has_value()); EXPECT_FALSE(metadata_out.receive_time.has_value()); @@ -131,7 +130,6 @@ metadata_in.root_scroll_offset_x = 100.2; metadata_in.root_scroll_offset_y = 200.1; metadata_in.top_controls_visible_height = 25.5; - metadata_in.resource_utilization = 95.8; metadata_in.frame_rate = 29.94; metadata_in.rtp_timestamp = 1.0; @@ -177,8 +175,6 @@ metadata_out.root_scroll_offset_y); EXPECT_EQ(metadata_in.top_controls_visible_height, metadata_out.top_controls_visible_height); - EXPECT_EQ(metadata_in.resource_utilization, - metadata_out.resource_utilization); EXPECT_EQ(metadata_in.frame_rate, metadata_out.frame_rate); EXPECT_EQ(metadata_in.rtp_timestamp, metadata_out.rtp_timestamp); EXPECT_EQ(metadata_in.receive_time, metadata_out.receive_time);
diff --git a/mojo/public/tools/bindings/generators/cpp_tracing_support.py b/mojo/public/tools/bindings/generators/cpp_tracing_support.py index 9ce7b5de..bbda833 100644 --- a/mojo/public/tools/bindings/generators/cpp_tracing_support.py +++ b/mojo/public/tools/bindings/generators/cpp_tracing_support.py
@@ -362,6 +362,26 @@ for line in _WrapIfNullable(loop_generator): yield line return + if (mojom.IsInterfaceRequestKind(kind) + or mojom.IsAssociatedInterfaceRequestKind(kind)): + yield output_context.AddSingleValue('Boolean', + cpp_parameter_name + '.is_pending()') + return + if (mojom.IsAnyHandleOrInterfaceKind(kind) + and not mojom.IsInterfaceKind(kind)): + yield output_context.AddSingleValue('Boolean', + cpp_parameter_name + '.is_valid()') + return + """ The case |mojom.IsInterfaceKind(kind)| is not covered. + |mojom.IsInterfaceKind(kind) == True| for the following types: + |mojo::InterfacePtrInfo|, |mojo::InterfacePtr|. + There is |mojo::InterfacePtrInfo::is_valid|, + but not |mojo::InterfacePtrInfo::is_bound|. + There is |mojo::InterfacePtr::is_bound|, + but not |mojo::InterfacePtr::is_valid|. + + Both |mojo::InterfacePtrInfo| and |mojo::InterfacePtr| are deprecated. + """ yield output_context.AddSingleValue('String', _TraceEventToString())
diff --git a/net/base/load_flags_list.h b/net/base/load_flags_list.h index 6ba0990..96d1a51 100644 --- a/net/base/load_flags_list.h +++ b/net/base/load_flags_list.h
@@ -51,17 +51,6 @@ // to avoid having a circular dependency. LOAD_FLAG(BYPASS_PROXY, 1 << 7) -// This load will not send any cookies. -// Deprecated. Use URLRequest::set_allow_credentials instead. See -// https://crbug.com/799935. -LOAD_FLAG(DO_NOT_SEND_COOKIES, 1 << 8) - -// This load will not send authentication data (user name/password) -// to the server (as opposed to the proxy). -// Deprecated. Use URLRequest::set_allow_credentials instead. See -// https://crbug.com/799935. -LOAD_FLAG(DO_NOT_SEND_AUTH_DATA, 1 << 9) - // DO NOT USE THIS FLAG // The network stack should not have frame level knowledge. Any pre-connect // or pre-resolution requiring that knowledge should be done from the @@ -69,27 +58,27 @@ // Indicate that this is a top level frame, so that we don't assume it is a // subresource and speculatively pre-connect or pre-resolve when a referring // page is loaded. -LOAD_FLAG(MAIN_FRAME_DEPRECATED, 1 << 10) +LOAD_FLAG(MAIN_FRAME_DEPRECATED, 1 << 8) // Indicates that this load was motivated by the rel=prefetch feature, // and is (in theory) not intended for the current frame. -LOAD_FLAG(PREFETCH, 1 << 11) +LOAD_FLAG(PREFETCH, 1 << 9) // Indicates that this load could cause deadlock if it has to wait for another // request. Overrides socket limits. Must always be used with MAXIMUM_PRIORITY. -LOAD_FLAG(IGNORE_LIMITS, 1 << 12) +LOAD_FLAG(IGNORE_LIMITS, 1 << 10) // Indicates that the username:password portion of the URL should not // be honored, but that other forms of authority may be used. -LOAD_FLAG(DO_NOT_USE_EMBEDDED_IDENTITY, 1 << 13) +LOAD_FLAG(DO_NOT_USE_EMBEDDED_IDENTITY, 1 << 11) // Indicates that this request is not to be migrated to a cellular network when // QUIC connection migration is enabled. -LOAD_FLAG(DISABLE_CONNECTION_MIGRATION_TO_CELLULAR, 1 << 14) +LOAD_FLAG(DISABLE_CONNECTION_MIGRATION_TO_CELLULAR, 1 << 12) // Indicates that the cache should not check that the request matches the // response's vary header. -LOAD_FLAG(SKIP_VARY_CHECK, 1 << 15) +LOAD_FLAG(SKIP_VARY_CHECK, 1 << 13) // The creator of this URLRequest wishes to receive stale responses when allowed // by the "Cache-Control: stale-while-revalidate" directive and is able to issue @@ -99,16 +88,16 @@ // resource by issuing a new request without this flag set. If the revalidation // does not complete in 60 seconds, the cache treat the stale resource as // invalid, as it did not specify stale-while-revalidate. -LOAD_FLAG(SUPPORT_ASYNC_REVALIDATION, 1 << 16) +LOAD_FLAG(SUPPORT_ASYNC_REVALIDATION, 1 << 14) // Indicates that a prefetch request's cached response should be restricted in // in terms of reuse. The cached response can only be reused by requests with // the LOAD_CAN_USE_RESTRICTED_PREFETCH load flag. -LOAD_FLAG(RESTRICTED_PREFETCH, 1 << 17) +LOAD_FLAG(RESTRICTED_PREFETCH, 1 << 15) // This flag must be set on requests that are allowed to reuse cache entries // that are marked as RESTRICTED_PREFETCH. Requests without this flag cannot // reuse restricted prefetch responses in the cache. Restricted response reuse // is considered privileged, and therefore this flag must only be set from a // trusted process. -LOAD_FLAG(CAN_USE_RESTRICTED_PREFETCH, 1 << 18) +LOAD_FLAG(CAN_USE_RESTRICTED_PREFETCH, 1 << 16)
diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc index 80592ea9..02e2fba 100644 --- a/net/base/network_delegate.cc +++ b/net/base/network_delegate.cc
@@ -103,7 +103,7 @@ bool NetworkDelegate::CanGetCookies(const URLRequest& request, bool allowed_from_caller) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(!(request.load_flags() & LOAD_DO_NOT_SEND_COOKIES)); + DCHECK_EQ(PrivacyMode::PRIVACY_MODE_DISABLED, request.privacy_mode()); return OnCanGetCookies(request, allowed_from_caller); }
diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc index 274fea28..c634da52 100644 --- a/net/dns/dns_transaction_unittest.cc +++ b/net/dns/dns_transaction_unittest.cc
@@ -827,7 +827,7 @@ } } - EXPECT_EQ(PRIVACY_MODE_ENABLED, request->privacy_mode()); + EXPECT_FALSE(request->allow_credentials()); EXPECT_TRUE(request->disable_secure_dns()); std::string accept;
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 69b55e23..c468fba 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc
@@ -1686,7 +1686,7 @@ } bool HttpNetworkTransaction::ShouldApplyServerAuth() const { - return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); + return request_->privacy_mode == PRIVACY_MODE_DISABLED; } int HttpNetworkTransaction::HandleAuthChallenge() { @@ -1709,9 +1709,7 @@ return ERR_UNEXPECTED_PROXY_AUTH; int rv = auth_controllers_[target]->HandleAuthChallenge( - headers, response_.ssl_info, - (request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA) != 0, false, - net_log_); + headers, response_.ssl_info, !ShouldApplyServerAuth(), false, net_log_); if (auth_controllers_[target]->HaveAuthHandler()) pending_auth_target_ = target;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index b883035..f8fcca1 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -3087,7 +3087,7 @@ HttpRequestInfo request; request.method = "GET"; request.url = GURL("http://www.example.org/"); - request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA; + request.privacy_mode = PRIVACY_MODE_ENABLED; request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); @@ -3471,7 +3471,7 @@ request.method = "GET"; request.url = GURL("https://www.example.org/"); // when the no authentication data flag is set. - request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA; + request.privacy_mode = PRIVACY_MODE_ENABLED; request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); @@ -3618,7 +3618,7 @@ request.method = "GET"; request.url = GURL("https://www.example.org/"); // when the no authentication data flag is set. - request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA; + request.privacy_mode = PRIVACY_MODE_ENABLED; request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); @@ -3761,7 +3761,7 @@ request.url = GURL("https://www.example.org/"); // Ensure that proxy authentication is attempted even // when the no authentication data flag is set. - request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA; + request.privacy_mode = PRIVACY_MODE_ENABLED; request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); @@ -3873,7 +3873,7 @@ request.url = GURL("https://www.example.org/"); // Ensure that proxy authentication is attempted even // when the no authentication data flag is set. - request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA; + request.privacy_mode = PRIVACY_MODE_ENABLED; request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); @@ -3982,7 +3982,7 @@ request.method = "GET"; request.url = GURL("https://www.example.org/"); // when the no authentication data flag is set. - request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA; + request.privacy_mode = PRIVACY_MODE_ENABLED; request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); @@ -4108,7 +4108,7 @@ request.url = GURL("https://www.example.org/"); // Ensure that proxy authentication is attempted even // when the no authentication data flag is set. - request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA; + request.privacy_mode = PRIVACY_MODE_ENABLED; request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); @@ -7717,7 +7717,7 @@ request.method = "GET"; request.url = GURL("http://www.example.org/"); // when the no authentication data flag is set. - request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA; + request.privacy_mode = PRIVACY_MODE_ENABLED; request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); @@ -11126,7 +11126,7 @@ request.method = "GET"; request.url = GURL("https://www.example.org/"); // when the no authentication data flag is set. - request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA; + request.privacy_mode = PRIVACY_MODE_ENABLED; request.traffic_annotation = net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc index c37c471d..dae313b 100644 --- a/net/quic/quic_network_transaction_unittest.cc +++ b/net/quic/quic_network_transaction_unittest.cc
@@ -8991,8 +8991,8 @@ request_.url = GURL("https://mail.example.org/"); // Ensure that proxy authentication is attempted even - // when the no authentication data flag is set. - request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA; + // when privacy mode is enabled. + request_.privacy_mode = PRIVACY_MODE_ENABLED; { HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); RunTransaction(&trans);
diff --git a/net/url_request/report_sender_unittest.cc b/net/url_request/report_sender_unittest.cc index 5b654d9..e897d36d 100644 --- a/net/url_request/report_sender_unittest.cc +++ b/net/url_request/report_sender_unittest.cc
@@ -152,7 +152,7 @@ num_requests_++; EXPECT_EQ(expect_url_, request->url()); EXPECT_STRCASEEQ("POST", request->method().data()); - EXPECT_TRUE(request->load_flags() & LOAD_DO_NOT_SEND_COOKIES); + EXPECT_FALSE(request->allow_credentials()); EXPECT_TRUE(request->load_flags() & LOAD_DO_NOT_SAVE_COOKIES); const HttpRequestHeaders& extra_headers = request->extra_request_headers();
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index d96b342..f80f04e 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc
@@ -479,12 +479,11 @@ } void URLRequest::set_allow_credentials(bool allow_credentials) { + allow_credentials_ = allow_credentials; if (allow_credentials) { - load_flags_ &= ~(LOAD_DO_NOT_SAVE_COOKIES | LOAD_DO_NOT_SEND_COOKIES | - LOAD_DO_NOT_SEND_AUTH_DATA); + load_flags_ &= ~LOAD_DO_NOT_SAVE_COOKIES; } else { - load_flags_ |= (LOAD_DO_NOT_SAVE_COOKIES | LOAD_DO_NOT_SEND_COOKIES | - LOAD_DO_NOT_SEND_AUTH_DATA); + load_flags_ |= LOAD_DO_NOT_SAVE_COOKIES; } } @@ -547,7 +546,8 @@ first_party_url_policy_( RedirectInfo::FirstPartyURLPolicy::NEVER_CHANGE_URL), load_flags_(LOAD_NORMAL), - privacy_mode_(PRIVACY_MODE_ENABLED), + allow_credentials_(true), + privacy_mode_(PRIVACY_MODE_DISABLED), disable_secure_dns_(false), #if BUILDFLAG(ENABLE_REPORTING) reporting_upload_depth_(0), @@ -996,7 +996,7 @@ } bool URLRequest::CanGetCookies() const { - DCHECK(!(load_flags_ & LOAD_DO_NOT_SEND_COOKIES)); + DCHECK_EQ(PrivacyMode::PRIVACY_MODE_DISABLED, privacy_mode_); bool can_get_cookies = g_default_can_use_cookies; if (network_delegate_) { can_get_cookies = @@ -1022,10 +1022,11 @@ return can_set_cookies; } -net::PrivacyMode URLRequest::DeterminePrivacyMode() const { - // Enable privacy mode if flags tell us not send or save cookies. - if ((load_flags_ & LOAD_DO_NOT_SEND_COOKIES) || - (load_flags_ & LOAD_DO_NOT_SAVE_COOKIES)) { +PrivacyMode URLRequest::DeterminePrivacyMode() const { + if (!allow_credentials_) { + // |allow_credentials_| implies LOAD_DO_NOT_SAVE_COOKIES. + DCHECK(load_flags_ & LOAD_DO_NOT_SAVE_COOKIES); + // TODO(https://crbug.com/775438): Client certs should always be // affirmatively omitted for these requests. return send_client_certs_ ? PRIVACY_MODE_ENABLED
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h index b139941..262f6300 100644 --- a/net/url_request/url_request.h +++ b/net/url_request/url_request.h
@@ -341,11 +341,10 @@ // If credentials are allowed, the request will send and save HTTP // cookies, as well as authentication to the origin server. If not, // they will not be sent, however proxy-level authentication will - // still occur. - // Setting this to false is equivalent to setting the - // LOAD_DO_NOT_SAVE_COOKIES, LOAD_DO_NOT_SEND_COOKIES, and - // LOAD_DO_NOT_SEND_AUTH_DATA flags. See https://crbug.com/799935. + // still occur. Setting this will force the LOAD_DO_NOT_SAVE_COOKIES field to + // be set in |load_flags_|. See https://crbug.com/799935. void set_allow_credentials(bool allow_credentials); + bool allow_credentials() const { return allow_credentials_; } // Sets the upload data. void set_upload(std::unique_ptr<UploadDataStream> upload); @@ -509,10 +508,10 @@ // Returns PrivacyMode that should be used for the request. Updated every time // the request is redirected. - PrivacyMode privacy_mode() { return privacy_mode_; } + PrivacyMode privacy_mode() const { return privacy_mode_; } // Returns whether secure DNS should be disabled for the request. - bool disable_secure_dns() { return disable_secure_dns_; } + bool disable_secure_dns() const { return disable_secure_dns_; } void set_maybe_sent_cookies(CookieAccessResultList cookies); void set_maybe_stored_cookies(CookieAndLineAccessResultList cookies); @@ -847,8 +846,16 @@ ReferrerPolicy referrer_policy_; RedirectInfo::FirstPartyURLPolicy first_party_url_policy_; HttpRequestHeaders extra_request_headers_; - int load_flags_; // Flags indicating the request type for the load; - // expected values are LOAD_* enums above. + // Flags indicating the request type for the load. Expected values are LOAD_* + // enums above. + int load_flags_; + // Whether the request is allowed to send credentials in general. Set by + // caller. + bool allow_credentials_; + // Privacy mode for current hop. Based on |allow_credentials_|, |load_flags_|, + // and information provided by |network_delegate_|. Saving cookies can + // currently be blocked independently of this field by setting the deprecated + // LOAD_DO_NOT_SAVE_COOKIES field in |load_flags_|. PrivacyMode privacy_mode_; bool disable_secure_dns_;
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 0f66b6e..3210babd 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -575,7 +575,10 @@ void URLRequestHttpJob::AddCookieHeaderAndStart() { CookieStore* cookie_store = request_->context()->cookie_store(); - if (cookie_store && !(request_info_.load_flags & LOAD_DO_NOT_SEND_COOKIES)) { + // Read cookies whenever allow_credentials() is true, even if the PrivacyMode + // is being overridden by NetworkDelegate and will eventually block them, as + // blocked cookies still need to be logged in that case. + if (cookie_store && request_->allow_credentials()) { CookieOptions options; options.set_return_excluded_cookies(); options.set_include_httponly(); @@ -606,7 +609,8 @@ const CookieAccessResultList& excluded_list) { DCHECK(request_->maybe_sent_cookies().empty()); - bool can_get_cookies = CanGetCookies(); + bool can_get_cookies = + (request_info_.privacy_mode == PRIVACY_MODE_DISABLED && CanGetCookies()); if (!cookies_with_access_result_list.empty() && can_get_cookies) { std::string cookie_line = CanonicalCookie::BuildCookieLine(cookies_with_access_result_list); @@ -614,9 +618,6 @@ request_info_.extra_headers.SetHeader(HttpRequestHeaders::kCookie, cookie_line); - // Disable privacy mode as we are sending cookies anyway. - request_info_.privacy_mode = PRIVACY_MODE_DISABLED; - // TODO(crbug.com/1031664): Reduce the number of times the cookie list is // iterated over. Get metrics for every cookie which is included. for (const auto& c : cookies_with_access_result_list) {
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 0e83d22d..4588b3f 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -1831,7 +1831,7 @@ EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); } - // Verify that the cookie isn't sent when LOAD_DO_NOT_SEND_COOKIES is set. + // Verify that the cookie isn't sent when credentials are not allowed. { TestNetworkDelegate network_delegate; default_context().set_network_delegate(&network_delegate); @@ -1839,14 +1839,14 @@ std::unique_ptr<URLRequest> req(default_context().CreateFirstPartyRequest( test_server.GetURL("/echoheader?Cookie"), DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS)); - req->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES); + req->set_allow_credentials(false); req->Start(); d.RunUntilComplete(); EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1") == std::string::npos); - // LOAD_DO_NOT_SEND_COOKIES does not trigger OnGetCookies. + // When credentials are blocked, OnGetCookies() is not invoked. EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); } @@ -8316,7 +8316,7 @@ TRAFFIC_ANNOTATION_FOR_TESTS)); // Don't send cookies (Collecting cookies is asynchronous, and need request to // try to create an HttpNetworkTransaction synchronously on start). - req->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES); + req->set_allow_credentials(false); req->Start(); req->Cancel(); d.RunUntilComplete();
diff --git a/services/device/public/mojom/serial.mojom b/services/device/public/mojom/serial.mojom index 905ea45..30a79631 100644 --- a/services/device/public/mojom/serial.mojom +++ b/services/device/public/mojom/serial.mojom
@@ -18,7 +18,7 @@ // This member is used to identify whether the SerialPortInfo object is // converted from a Bluetooth serial device. - DeviceType type; + DeviceType type = PLATFORM_SERIAL; // On macOS a serial device may have two paths, one for the call-out device // and one for the dial-in device. The call-out device is preferred. If
diff --git a/services/device/serial/bluetooth_serial_device_enumerator.cc b/services/device/serial/bluetooth_serial_device_enumerator.cc index 0735967..6418b61 100644 --- a/services/device/serial/bluetooth_serial_device_enumerator.cc +++ b/services/device/serial/bluetooth_serial_device_enumerator.cc
@@ -34,7 +34,7 @@ if (base::Contains(device_uuids, GetSerialPortProfileUUID())) { auto port = mojom::SerialPortInfo::New(); port->token = base::UnguessableToken::Create(); - port->path = base::FilePath::FromUTF8Unsafe(device->GetIdentifier()); + port->path = base::FilePath::FromUTF8Unsafe(device->GetAddress()); port->type = mojom::DeviceType::SPP_DEVICE; bluetooth_ports_.insert( std::make_pair(device->GetAddress(), port->token)); @@ -49,7 +49,7 @@ if (base::Contains(device_uuids, GetSerialPortProfileUUID())) { auto port = mojom::SerialPortInfo::New(); port->token = base::UnguessableToken::Create(); - port->path = base::FilePath::FromUTF8Unsafe(device->GetIdentifier()); + port->path = base::FilePath::FromUTF8Unsafe(device->GetAddress()); port->type = mojom::DeviceType::SPP_DEVICE; bluetooth_ports_.insert(std::make_pair(device->GetAddress(), port->token)); AddPort(std::move(port)); @@ -65,4 +65,18 @@ RemovePort(token); } +scoped_refptr<BluetoothAdapter> BluetoothSerialDeviceEnumerator::GetAdapter() { + return adapter_; +} + +base::Optional<std::string> +BluetoothSerialDeviceEnumerator::GetAddressFromToken( + const base::UnguessableToken& token) { + for (const auto& entry : bluetooth_ports_) { + if (entry.second == token) + return entry.first; + } + return base::nullopt; +} + } // namespace device
diff --git a/services/device/serial/bluetooth_serial_device_enumerator.h b/services/device/serial/bluetooth_serial_device_enumerator.h index fa3928b8..7b3e5d56 100644 --- a/services/device/serial/bluetooth_serial_device_enumerator.h +++ b/services/device/serial/bluetooth_serial_device_enumerator.h
@@ -29,6 +29,13 @@ void DeviceRemoved(BluetoothAdapter* adapter, BluetoothDevice* device) override; + scoped_refptr<BluetoothAdapter> GetAdapter(); + + // This method will search the map of Bluetooth ports and find the + // address with the matching token. + base::Optional<std::string> GetAddressFromToken( + const base::UnguessableToken& token); + protected: scoped_refptr<BluetoothAdapter> adapter_;
diff --git a/services/device/serial/bluetooth_serial_port_impl.cc b/services/device/serial/bluetooth_serial_port_impl.cc index 346a44ae..3d8d293 100644 --- a/services/device/serial/bluetooth_serial_port_impl.cc +++ b/services/device/serial/bluetooth_serial_port_impl.cc
@@ -14,26 +14,29 @@ // static void BluetoothSerialPortImpl::Create( - std::unique_ptr<BluetoothDevice> device, + scoped_refptr<BluetoothAdapter> adapter, + const std::string& address, mojo::PendingReceiver<mojom::SerialPort> receiver, mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher) { DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBluetoothSerialPortProfileInSerialApi)); // This BluetoothSerialPortImpl is owned by |receiver| and |watcher|. - new BluetoothSerialPortImpl(std::move(device), std::move(receiver), + new BluetoothSerialPortImpl(std::move(adapter), address, std::move(receiver), std::move(watcher)); } BluetoothSerialPortImpl::BluetoothSerialPortImpl( - std::unique_ptr<BluetoothDevice> device, + scoped_refptr<BluetoothAdapter> adapter, + const std::string& address, mojo::PendingReceiver<mojom::SerialPort> receiver, mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher) : receiver_(this, std::move(receiver)), watcher_(std::move(watcher)), in_stream_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL), out_stream_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL), - bluetooth_device_(std::move(device)) { + bluetooth_adapter_(std::move(adapter)), + address_(address) { receiver_.set_disconnect_handler( base::BindOnce([](BluetoothSerialPortImpl* self) { delete self; }, base::Unretained(this))); @@ -55,12 +58,16 @@ OpenCallback callback) { if (client) client_.Bind(std::move(client)); - - BluetoothDevice::UUIDSet device_uuids = bluetooth_device_->GetUUIDs(); + BluetoothDevice* device = bluetooth_adapter_->GetDevice(address_); + if (!device) { + std::move(callback).Run(false); + return; + } + BluetoothDevice::UUIDSet device_uuids = device->GetUUIDs(); if (base::Contains(device_uuids, GetSerialPortProfileUUID())) { auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback)); - bluetooth_device_->ConnectToService( + device->ConnectToService( GetSerialPortProfileUUID(), base::BindOnce(&BluetoothSerialPortImpl::OnSocketConnected, weak_ptr_factory_.GetWeakPtr(), copyable_callback),
diff --git a/services/device/serial/bluetooth_serial_port_impl.h b/services/device/serial/bluetooth_serial_port_impl.h index 107d3de..46e0840d7 100644 --- a/services/device/serial/bluetooth_serial_port_impl.h +++ b/services/device/serial/bluetooth_serial_port_impl.h
@@ -7,6 +7,7 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" +#include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_socket.h" #include "mojo/public/cpp/system/data_pipe.h" @@ -22,15 +23,17 @@ class BluetoothSerialPortImpl : public mojom::SerialPort { public: // Creates of instance of BluetoothSerialPortImpl using a Bluetooth - // device and a receiver/watcher to create a pipe. The receiver and - // watcher will own this object. + // adapter, a Bluetooth device address and a receiver/watcher to + // create a pipe. The receiver and watcher will own this object. static void Create( - std::unique_ptr<BluetoothDevice> device, + scoped_refptr<BluetoothAdapter> adapter, + const std::string& address, mojo::PendingReceiver<mojom::SerialPort> receiver, mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher); BluetoothSerialPortImpl( - std::unique_ptr<BluetoothDevice> device, + scoped_refptr<BluetoothAdapter> adapter, + const std::string& address, mojo::PendingReceiver<mojom::SerialPort> receiver, mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher); BluetoothSerialPortImpl(const BluetoothSerialPortImpl&) = delete; @@ -91,8 +94,9 @@ FlushCallback write_flush_callback_; DrainCallback drain_callback_; - scoped_refptr<device::BluetoothSocket> bluetooth_socket_; - std::unique_ptr<BluetoothDevice> bluetooth_device_; + scoped_refptr<BluetoothSocket> bluetooth_socket_; + const scoped_refptr<BluetoothAdapter> bluetooth_adapter_; + const std::string address_; bool read_pending_ = false; bool write_pending_ = false;
diff --git a/services/device/serial/bluetooth_serial_port_impl_unittest.cc b/services/device/serial/bluetooth_serial_port_impl_unittest.cc index 0067f97..b74b85e 100644 --- a/services/device/serial/bluetooth_serial_port_impl_unittest.cc +++ b/services/device/serial/bluetooth_serial_port_impl_unittest.cc
@@ -33,6 +33,7 @@ using ::base::test::RunOnceCallback; using ::testing::_; using ::testing::Invoke; +using ::testing::Return; using ::testing::WithArgs; constexpr char kBuffer[] = "test"; @@ -62,15 +63,17 @@ scoped_refptr<MockBluetoothAdapter> adapter = base::MakeRefCounted<MockBluetoothAdapter>(); device::BluetoothAdapterFactory::SetAdapterForTesting(adapter); - auto mock_device = std::make_unique<MockBluetoothDevice>( + mock_device_ = std::make_unique<MockBluetoothDevice>( adapter.get(), 0, "Test Device", kDeviceAddress, false, false); - mock_device->AddUUID(GetSerialPortProfileUUID()); + mock_device_->AddUUID(GetSerialPortProfileUUID()); - EXPECT_CALL(*mock_device, + EXPECT_CALL(*adapter, GetDevice(kDeviceAddress)) + .WillOnce(Return(mock_device_.get())); + EXPECT_CALL(*mock_device_, ConnectToService(GetSerialPortProfileUUID(), _, _)) .WillOnce(RunOnceCallback<1>(mock_socket_)); - BluetoothSerialPortImpl::Create(std::move(mock_device), + BluetoothSerialPortImpl::Create(std::move(adapter), kDeviceAddress, port->BindNewPipeAndPassReceiver(), std::move(watcher_remote)); } @@ -86,15 +89,17 @@ scoped_refptr<MockBluetoothAdapter> adapter = base::MakeRefCounted<MockBluetoothAdapter>(); device::BluetoothAdapterFactory::SetAdapterForTesting(adapter); - auto mock_device = std::make_unique<MockBluetoothDevice>( + mock_device_ = std::make_unique<MockBluetoothDevice>( adapter.get(), 0, "Test Device", kDeviceAddress, false, false); - mock_device->AddUUID(GetSerialPortProfileUUID()); + mock_device_->AddUUID(GetSerialPortProfileUUID()); - EXPECT_CALL(*mock_device, + EXPECT_CALL(*adapter, GetDevice(kDeviceAddress)) + .WillOnce(Return(mock_device_.get())); + EXPECT_CALL(*mock_device_, ConnectToService(GetSerialPortProfileUUID(), _, _)) .WillOnce(RunOnceCallback<2>("Error")); - BluetoothSerialPortImpl::Create(std::move(mock_device), + BluetoothSerialPortImpl::Create(std::move(adapter), kDeviceAddress, port->BindNewPipeAndPassReceiver(), std::move(watcher_remote)); } @@ -116,6 +121,7 @@ private: scoped_refptr<MockBluetoothSocket> mock_socket_ = base::MakeRefCounted<MockBluetoothSocket>(); + std::unique_ptr<MockBluetoothDevice> mock_device_; base::test::SingleThreadTaskEnvironment task_environment_; };
diff --git a/services/device/serial/serial_port_manager_impl.cc b/services/device/serial/serial_port_manager_impl.cc index bdfecb3..180d676 100644 --- a/services/device/serial/serial_port_manager_impl.cc +++ b/services/device/serial/serial_port_manager_impl.cc
@@ -14,6 +14,7 @@ #include "device/bluetooth/bluetooth_adapter_factory.h" #include "services/device/public/cpp/serial/serial_switches.h" #include "services/device/serial/bluetooth_serial_device_enumerator.h" +#include "services/device/serial/bluetooth_serial_port_impl.h" #include "services/device/serial/serial_device_enumerator.h" #include "services/device/serial/serial_port_impl.h" @@ -90,6 +91,17 @@ FROM_HERE, base::BindOnce(&SerialPortImpl::Create, *path, std::move(receiver), std::move(watcher), ui_task_runner_)); + return; + } + + DCHECK(bluetooth_enumerator_); + base::Optional<std::string> address = + bluetooth_enumerator_->GetAddressFromToken(token); + if (address) { + ui_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&BluetoothSerialPortImpl::Create, + bluetooth_enumerator_->GetAdapter(), *address, + std::move(receiver), std::move(watcher))); } }
diff --git a/services/device/serial/serial_port_manager_impl_unittest.cc b/services/device/serial/serial_port_manager_impl_unittest.cc index 05a5991..dd0989a 100644 --- a/services/device/serial/serial_port_manager_impl_unittest.cc +++ b/services/device/serial/serial_port_manager_impl_unittest.cc
@@ -14,16 +14,19 @@ #include "base/macros.h" #include "base/task/post_task.h" #include "base/test/bind_test_util.h" +#include "base/test/gmock_callback_support.h" #include "base/threading/thread.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/public/cpp/bluetooth_uuid.h" #include "device/bluetooth/test/mock_bluetooth_adapter.h" #include "device/bluetooth/test/mock_bluetooth_device.h" +#include "device/bluetooth/test/mock_bluetooth_socket.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "services/device/device_service_test_base.h" +#include "services/device/public/cpp/bluetooth/bluetooth_utils.h" #include "services/device/public/cpp/serial/serial_switches.h" #include "services/device/public/mojom/serial.mojom.h" #include "services/device/serial/bluetooth_serial_device_enumerator.h" @@ -31,8 +34,10 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -using testing::_; -using testing::Invoke; +using ::base::test::RunOnceCallback; +using ::testing::_; +using ::testing::Invoke; +using ::testing::Return; namespace device { @@ -63,6 +68,25 @@ mojo::Receiver<mojom::SerialPortManagerClient> receiver_{this}; }; +class FakeSerialPortClient : public mojom::SerialPortClient { + public: + FakeSerialPortClient() = default; + FakeSerialPortClient(FakeSerialPortClient&) = delete; + FakeSerialPortClient& operator=(FakeSerialPortClient&) = delete; + ~FakeSerialPortClient() override = default; + + void Bind(mojo::PendingReceiver<device::mojom::SerialPortClient> receiver) { + receiver_.Bind(std::move(receiver)); + } + + // mojom::SerialPortClient + void OnReadError(mojom::SerialReceiveError error) override {} + void OnSendError(mojom::SerialSendError error) override {} + + private: + mojo::Receiver<mojom::SerialPortClient> receiver_{this}; +}; + } // namespace class SerialPortManagerImplTest : public DeviceServiceTestBase { @@ -94,8 +118,7 @@ auto mock_device = std::make_unique<MockBluetoothDevice>( adapter_.get(), 0, "Test Device", kDeviceAddress, false, false); - static const BluetoothUUID kSerialPortProfileUUID("1101"); - mock_device->AddUUID(kSerialPortProfileUUID); + mock_device->AddUUID(GetSerialPortProfileUUID()); adapter_->AddMockDevice(std::move(mock_device)); auto bluetooth_enumerator = @@ -106,11 +129,42 @@ std::move(bluetooth_enumerator)); } + void SetupBluetoothEnumeratorWithExpectations() { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableBluetoothSerialPortProfileInSerialApi); + + ON_CALL(*adapter_, GetDevices()) + .WillByDefault( + Invoke(adapter_.get(), &MockBluetoothAdapter::GetConstMockDevices)); + device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_); + + auto mock_device = std::make_unique<MockBluetoothDevice>( + adapter_.get(), 0, "Test Device", kDeviceAddress, false, false); + mock_device->AddUUID(GetSerialPortProfileUUID()); + MockBluetoothDevice* mock_device_ptr = mock_device.get(); + adapter_->AddMockDevice(std::move(mock_device)); + + EXPECT_CALL(*adapter_, GetDevice(kDeviceAddress)) + .WillOnce(Return(mock_device_ptr)); + EXPECT_CALL(*mock_device_ptr, + ConnectToService(GetSerialPortProfileUUID(), _, _)) + .WillOnce(RunOnceCallback<1>(mock_socket_)); + + auto bluetooth_enumerator = + std::make_unique<BluetoothSerialDeviceEnumerator>(); + bluetooth_enumerator_ = bluetooth_enumerator.get(); + + manager_->SetBluetoothSerialEnumeratorForTesting( + std::move(bluetooth_enumerator)); + } + protected: FakeSerialEnumerator* enumerator_; BluetoothSerialDeviceEnumerator* bluetooth_enumerator_; scoped_refptr<MockBluetoothAdapter> adapter_ = base::MakeRefCounted<MockBluetoothAdapter>(); + scoped_refptr<MockBluetoothSocket> mock_socket_ = + base::MakeRefCounted<MockBluetoothSocket>(); void Bind(mojo::PendingReceiver<mojom::SerialPortManager> receiver) { manager_->Bind(std::move(receiver)); @@ -154,11 +208,9 @@ SetupBluetoothEnumerator(); mojo::Remote<mojom::SerialPortManager> port_manager; Bind(port_manager.BindNewPipeAndPassReceiver()); - const std::string address_identifier = - std::string(kDeviceAddress) + "-Identifier"; const std::set<base::FilePath> expected_paths = { kFakeDevicePath1, kFakeDevicePath2, - base::FilePath::FromUTF8Unsafe(address_identifier)}; + base::FilePath::FromUTF8Unsafe(kDeviceAddress)}; base::RunLoop loop; port_manager->GetDevices(base::BindLambdaForTesting( @@ -247,6 +299,58 @@ loop.Run(); } +TEST_F(SerialPortManagerImplTest, GetBluetoothDevicePort) { + SetupBluetoothEnumeratorWithExpectations(); + mojo::Remote<mojom::SerialPortManager> port_manager; + Bind(port_manager.BindNewPipeAndPassReceiver()); + mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher_remote; + mojo::SelfOwnedReceiverRef<mojom::SerialPortConnectionWatcher> watcher = + mojo::MakeSelfOwnedReceiver( + std::make_unique<mojom::SerialPortConnectionWatcher>(), + watcher_remote.InitWithNewPipeAndPassReceiver()); + auto options = mojom::SerialConnectionOptions::New(); + mojo::PendingRemote<mojom::SerialPortClient> client; + FakeSerialPortClient serial_client; + serial_client.Bind(client.InitWithNewPipeAndPassReceiver()); + mojo::Remote<mojom::SerialPort> serial_port; + + // Since we only want to use devices enumerated by the Bluetooth + // enumerator, we can remove the devices that are not. + enumerator_->RemoveDevicePath(kFakeDevicePath1); + enumerator_->RemoveDevicePath(kFakeDevicePath2); + + const std::set<base::FilePath> expected_paths = { + base::FilePath::FromUTF8Unsafe(kDeviceAddress)}; + + base::RunLoop loop; + port_manager->GetDevices(base::BindLambdaForTesting( + [&](std::vector<mojom::SerialPortInfoPtr> results) { + EXPECT_EQ(expected_paths.size(), results.size()); + std::set<base::FilePath> actual_paths; + for (size_t i = 0; i < results.size(); ++i) + actual_paths.insert(results[i]->path); + EXPECT_EQ(expected_paths, actual_paths); + + port_manager->GetPort(results[0]->token, + /*use_alternate_path=*/false, + serial_port.BindNewPipeAndPassReceiver(), + /*watcher=*/std::move(watcher_remote)); + serial_port->Open(std::move(options), std::move(client), + base::BindLambdaForTesting([&loop](bool success) { + EXPECT_TRUE(success); + loop.Quit(); + })); + })); + + loop.Run(); + + base::RunLoop disconnect_loop; + watcher->set_connection_error_handler(disconnect_loop.QuitClosure()); + + serial_port.reset(); + disconnect_loop.Run(); +} + TEST_F(SerialPortManagerImplTest, BluetoothPortRemovedAndAdded) { SetupBluetoothEnumerator(); mojo::Remote<mojom::SerialPortManager> port_manager; @@ -255,16 +359,13 @@ MockSerialPortManagerClient client; port_manager->SetClient(client.BindNewPipeAndPassRemote()); - const std::string address_identifier = - std::string(kDeviceAddress) + "-Identifier"; base::UnguessableToken port1_token; { base::RunLoop run_loop; port_manager->GetDevices(base::BindLambdaForTesting( [&](std::vector<mojom::SerialPortInfoPtr> results) { for (const auto& port : results) { - if (port->path == - base::FilePath::FromUTF8Unsafe(address_identifier)) { + if (port->path == base::FilePath::FromUTF8Unsafe(kDeviceAddress)) { port1_token = port->token; break; } @@ -282,8 +383,7 @@ EXPECT_CALL(client, OnPortRemoved(_)) .WillOnce(Invoke([&](mojom::SerialPortInfoPtr port) { EXPECT_EQ(port1_token, port->token); - EXPECT_EQ(port->path, - base::FilePath::FromUTF8Unsafe(address_identifier)); + EXPECT_EQ(port->path, base::FilePath::FromUTF8Unsafe(kDeviceAddress)); EXPECT_EQ(mojom::DeviceType::SPP_DEVICE, port->type); run_loop.Quit(); })); @@ -303,8 +403,7 @@ EXPECT_CALL(client, OnPortAdded(_)) .WillOnce(Invoke([&](mojom::SerialPortInfoPtr port) { EXPECT_NE(port1_token, port->token); - EXPECT_EQ(port->path, - base::FilePath::FromUTF8Unsafe(address_identifier)); + EXPECT_EQ(port->path, base::FilePath::FromUTF8Unsafe(kDeviceAddress)); EXPECT_EQ(mojom::DeviceType::SPP_DEVICE, port->type); run_loop.Quit(); }));
diff --git a/services/network/chunked_data_pipe_upload_data_stream.cc b/services/network/chunked_data_pipe_upload_data_stream.cc index 6520227..3bf5c6b4 100644 --- a/services/network/chunked_data_pipe_upload_data_stream.cc +++ b/services/network/chunked_data_pipe_upload_data_stream.cc
@@ -48,6 +48,18 @@ if (!chunked_data_pipe_getter_.is_connected()) return net::ERR_FAILED; + switch (cache_state_) { + case CacheState::kActive: + if (data_pipe_.is_valid()) + return net::OK; + else + break; + case CacheState::kExhausted: + return net::ERR_FAILED; + case CacheState::kDisabled: + break; + } + // Get a new data pipe and start. mojo::ScopedDataPipeProducerHandle data_pipe_producer; mojo::ScopedDataPipeConsumerHandle data_pipe_consumer; @@ -81,6 +93,10 @@ return net::OK; } + int cache_read_len = ReadFromCacheIfNeeded(buf, buf_len); + if (cache_read_len > 0) + return cache_read_len; + // Only start watching once a read starts. This is because OnHandleReadable() // uses |buf_| implicitly assuming that this method has already been called. if (!handle_watcher_.IsWatching()) { @@ -103,6 +119,7 @@ // allow it. if (size_ && *size_ == bytes_read_) SetIsFinalChunk(); + WriteToCacheIfNeeded(buf, num_bytes); return num_bytes; } @@ -134,12 +151,14 @@ } void ChunkedDataPipeUploadDataStream::ResetInternal() { - // Init rewinds the stream. Throw away current state, other than |size_| and - // |status_|. buf_ = nullptr; buf_len_ = 0; handle_watcher_.Cancel(); bytes_read_ = 0; + if (cache_state_ != CacheState::kDisabled) + return; + // Init rewinds the stream. Throw away current state, other than |size_| and + // |status_|. data_pipe_.reset(); } @@ -211,4 +230,49 @@ OnSizeReceived(net::ERR_FAILED, 0); } +void ChunkedDataPipeUploadDataStream::EnableCache(size_t dst_window_size) { + DCHECK_EQ(bytes_read_, 0u); + DCHECK_EQ(cache_state_, CacheState::kDisabled); + DCHECK(cache_.empty()); + cache_state_ = CacheState::kActive; + dst_window_size_ = dst_window_size; +} + +void ChunkedDataPipeUploadDataStream::WriteToCacheIfNeeded(net::IOBuffer* buf, + uint32_t num_bytes) { + if (cache_state_ != CacheState::kActive) + return; + + // |cache_state_ == CacheState::kActive| and |cache_.size() >= bytes_read_| + // means we're reading from the cache. + if (cache_.size() >= bytes_read_) + return; + + if (cache_.size() >= dst_window_size_) { + // Attempted to write over the max size. Replay must be failed. + // Notes: CDPUDS caches chunks from the date pipe until whole size gets over + // the max size. For example, if the date pipe sends [60k, 60k, 60k] chunks, + // CDPUDS caches the first 2 60ks. If it is [120k, 1k,], CDPUDS caches the + // 120k chunk or any size if it is the first chunk. + cache_state_ = CacheState::kExhausted; + return; + } + cache_.insert(cache_.end(), buf->data(), buf->data() + num_bytes); +} + +int ChunkedDataPipeUploadDataStream::ReadFromCacheIfNeeded(net::IOBuffer* buf, + int buf_len) { + if (cache_state_ != CacheState::kActive) + return 0; + if (cache_.size() <= bytes_read_) + return 0; + + int read_size = + std::min(static_cast<int>(cache_.size() - bytes_read_), buf_len); + DCHECK_GT(read_size, 0); + memcpy(buf->data(), &cache_[bytes_read_], read_size); + bytes_read_ += read_size; + return read_size; +} + } // namespace network
diff --git a/services/network/chunked_data_pipe_upload_data_stream.h b/services/network/chunked_data_pipe_upload_data_stream.h index 1059003..3fb88dd 100644 --- a/services/network/chunked_data_pipe_upload_data_stream.h +++ b/services/network/chunked_data_pipe_upload_data_stream.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include <memory> +#include <vector> #include "base/component_export.h" #include "base/macros.h" @@ -45,7 +46,21 @@ bool AllowHTTP1() const override; + static const size_t kDefaultDestinationWindowSize = 65535; + // This has ChunkedDataPipeUploadDataStream cache each chunk from the datapipe + // up to the size that just exceeds |dst_window_size| so that the destination + // resends the data. + // InitInternal() doesn't reset the data pipe and this instance replays the + // all cached chunks and continues datapipe withdrawing after that. + void EnableCache(size_t dst_window_size = kDefaultDestinationWindowSize); + private: + enum class CacheState { + kDisabled, + kActive, + kExhausted, + }; + // net::UploadDataStream implementation. int InitInternal(const net::NetLogWithSource& net_log) override; int ReadInternal(net::IOBuffer* buf, int buf_len) override; @@ -63,6 +78,9 @@ void OnDataPipeGetterClosed(); + void WriteToCacheIfNeeded(net::IOBuffer* buf, uint32_t num_bytes); + int ReadFromCacheIfNeeded(net::IOBuffer* buf, int buf_len); + scoped_refptr<ResourceRequestBody> resource_request_body_; mojo::Remote<mojom::ChunkedDataPipeGetter> chunked_data_pipe_getter_; mojo::ScopedDataPipeConsumerHandle data_pipe_; @@ -85,6 +103,11 @@ // error. int status_ = net::OK; + // Variables used for EnableCache(). + CacheState cache_state_ = CacheState::kDisabled; + size_t dst_window_size_ = kDefaultDestinationWindowSize; + std::vector<char> cache_; + DISALLOW_COPY_AND_ASSIGN(ChunkedDataPipeUploadDataStream); };
diff --git a/services/network/chunked_data_pipe_upload_data_stream_unittest.cc b/services/network/chunked_data_pipe_upload_data_stream_unittest.cc index 13f3bd7c..412673f 100644 --- a/services/network/chunked_data_pipe_upload_data_stream_unittest.cc +++ b/services/network/chunked_data_pipe_upload_data_stream_unittest.cc
@@ -32,19 +32,32 @@ namespace { +net::CompletionOnceCallback NoCallback() { + return base::BindOnce([](int result) { + NOTREACHED() << "This callback should not be called. result=" << result; + }); +} + class ChunkedDataPipeUploadDataStreamTest : public testing::Test { public: ChunkedDataPipeUploadDataStreamTest() { CreateAndInitChunkedUploadStream(); } void CreateAndInitChunkedUploadStream() { + CreateChunkedUploadStream(); + InitChunkedUploadStream(); + } + + void CreateChunkedUploadStream() { chunked_data_pipe_getter_ = std::make_unique<TestChunkedDataPipeGetter>(); chunked_upload_stream_ = std::make_unique<ChunkedDataPipeUploadDataStream>( base::MakeRefCounted<network::ResourceRequestBody>(), chunked_data_pipe_getter_->GetDataPipeGetterRemote()); + } + + void InitChunkedUploadStream() { // Nothing interesting happens before Init, so always wait for it in the // test fixture. - net::TestCompletionCallback callback; - EXPECT_EQ(net::OK, chunked_upload_stream_->Init(callback.callback(), + EXPECT_EQ(net::OK, chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource())); get_size_callback_ = chunked_data_pipe_getter_->WaitForGetSize(); write_pipe_ = chunked_data_pipe_getter_->WaitForStartReading(); @@ -788,6 +801,287 @@ net::NetLogWithSource())); } +#define EXPECT_READ(chunked_upload_stream, io_buffer, expected) \ + { \ + int result = chunked_upload_stream->Read(io_buffer.get(), \ + io_buffer->size(), NoCallback()); \ + EXPECT_GT(result, 0); \ + EXPECT_EQ(std::string(io_buffer->data(), result), expected); \ + } + +#define EXPECT_EOF(chunked_upload_stream, size) \ + { \ + net::TestCompletionCallback callback; \ + auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(1); \ + int result = \ + chunked_upload_stream->Read(io_buffer.get(), 1u, callback.callback()); \ + EXPECT_EQ(net::ERR_IO_PENDING, result); \ + std::move(get_size_callback_).Run(net::OK, size); \ + EXPECT_EQ(net::OK, callback.GetResult(result)); \ + EXPECT_TRUE(chunked_upload_stream->IsEOF()); \ + } + +#define WRITE_DATA_SYNC(write_pipe, str) \ + { \ + std::string data(str); \ + uint32_t num_size = data.size(); \ + EXPECT_EQ(write_pipe->WriteData((void*)data.c_str(), &num_size, \ + MOJO_WRITE_DATA_FLAG_NONE), \ + MOJO_RESULT_OK); \ + EXPECT_EQ(num_size, data.size()); \ + } + +TEST_F(ChunkedDataPipeUploadDataStreamTest, CacheNotUsed) { + chunked_upload_stream_->EnableCache(); + + const std::string kData = "1234567890"; + WRITE_DATA_SYNC(write_pipe_, kData); + + auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(7); + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + EXPECT_EOF(chunked_upload_stream_, kData.size()); +} + +TEST_F(ChunkedDataPipeUploadDataStreamTest, CacheEnableBeforeInit1) { + CreateChunkedUploadStream(); + chunked_upload_stream_->EnableCache(); + InitChunkedUploadStream(); + + auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(7); + int result = chunked_upload_stream_->Read(io_buffer.get(), io_buffer->size(), + NoCallback()); + EXPECT_EQ(result, net::ERR_IO_PENDING); + + // Destroy the DataPipeGetter pipe, which is the pipe used for + // GetSizeCallback. + chunked_data_pipe_getter_->ClosePipe(); +} + +TEST_F(ChunkedDataPipeUploadDataStreamTest, CacheEnableBeforeInit2) { + CreateChunkedUploadStream(); + chunked_upload_stream_->EnableCache(); + InitChunkedUploadStream(); + + WRITE_DATA_SYNC(write_pipe_, "1234567890"); + + auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(7); + + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + EXPECT_EQ(chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource()), + net::OK); + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + EXPECT_EOF(chunked_upload_stream_, 10); +} + +TEST_F(ChunkedDataPipeUploadDataStreamTest, CacheRead) { + chunked_upload_stream_->EnableCache(); + + WRITE_DATA_SYNC(write_pipe_, "1234567890"); + + auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(7); + + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + EXPECT_EQ(chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource()), + net::OK); + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + EXPECT_EOF(chunked_upload_stream_, 10); +} + +TEST_F(ChunkedDataPipeUploadDataStreamTest, CacheOverWindowOnce) { + const size_t kMaxSize = 4u; + chunked_upload_stream_->EnableCache(kMaxSize); + + WRITE_DATA_SYNC(write_pipe_, "1234567890"); + + auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(7); + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + EXPECT_EQ(chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource()), + net::OK); + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + EXPECT_EOF(chunked_upload_stream_, 10); +} + +TEST_F(ChunkedDataPipeUploadDataStreamTest, CacheOverWindowTwice) { + const size_t kMaxSize = 4u; + chunked_upload_stream_->EnableCache(kMaxSize); + + WRITE_DATA_SYNC(write_pipe_, "1234567890"); + + auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(7); + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + + int result = + chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource()); + EXPECT_EQ(net::ERR_FAILED, result); + + // Destroy the DataPipeGetter pipe, which is the pipe used for + // GetSizeCallback. + chunked_data_pipe_getter_->ClosePipe(); +} + +TEST_F(ChunkedDataPipeUploadDataStreamTest, CacheInitBeforeRead) { + chunked_upload_stream_->EnableCache(); + WRITE_DATA_SYNC(write_pipe_, "1234567890"); + auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(7); + + EXPECT_EQ(chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource()), + net::OK); + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + EXPECT_EOF(chunked_upload_stream_, 10); +} + +TEST_F(ChunkedDataPipeUploadDataStreamTest, CacheInitWhileRead) { + chunked_upload_stream_->EnableCache(); + WRITE_DATA_SYNC(write_pipe_, "1234567890"); + auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(7); + + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + + io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(3); + EXPECT_EQ(chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource()), + net::OK); + EXPECT_READ(chunked_upload_stream_, io_buffer, "123"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "456"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + // Re-init in the middle of reading from the cache + EXPECT_EQ(chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource()), + net::OK); + EXPECT_READ(chunked_upload_stream_, io_buffer, "123"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "456"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "7"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + // Re-init exactly after reading the last cached bit. + EXPECT_EQ(chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource()), + net::OK); + EXPECT_READ(chunked_upload_stream_, io_buffer, "123"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "456"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "7"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + // Reading "890" over the first cache should append "890" to the cache. + io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(7); + EXPECT_EQ(chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource()), + net::OK); + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + EXPECT_EOF(chunked_upload_stream_, 10); +} + +TEST_F(ChunkedDataPipeUploadDataStreamTest, CacheReadAppendDataBeforeInit) { + chunked_upload_stream_->EnableCache(); + WRITE_DATA_SYNC(write_pipe_, "1234567890"); + auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(7); + + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + net::TestCompletionCallback callback; + int result = chunked_upload_stream_->Read(io_buffer.get(), io_buffer->size(), + callback.callback()); + EXPECT_EQ(net::ERR_IO_PENDING, result); + + WRITE_DATA_SYNC(write_pipe_, "abc"); + EXPECT_EQ(chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource()), + net::OK); + // Wait mojo. + base::RunLoop().RunUntilIdle(); + // We should not receive the second mojo data. + EXPECT_FALSE(callback.have_result()); + + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "abc"); + + EXPECT_EOF(chunked_upload_stream_, 13); +} + +TEST_F(ChunkedDataPipeUploadDataStreamTest, CacheReadAppendDataAfterInit) { + chunked_upload_stream_->EnableCache(); + WRITE_DATA_SYNC(write_pipe_, "1234567890"); + auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(7); + + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + net::TestCompletionCallback callback; + int result = chunked_upload_stream_->Read(io_buffer.get(), io_buffer->size(), + callback.callback()); + EXPECT_EQ(net::ERR_IO_PENDING, result); + EXPECT_EQ(chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource()), + net::OK); + WRITE_DATA_SYNC(write_pipe_, "abc"); + // Wait mojo. + base::RunLoop().RunUntilIdle(); + // We should not receive the second mojo data. + EXPECT_FALSE(callback.have_result()); + + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "abc"); + + EXPECT_EOF(chunked_upload_stream_, 13); +} + +TEST_F(ChunkedDataPipeUploadDataStreamTest, CacheReadAppendDataDuringRead) { + chunked_upload_stream_->EnableCache(); + WRITE_DATA_SYNC(write_pipe_, "1234567890"); + auto io_buffer = base::MakeRefCounted<net::IOBufferWithSize>(7); + + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_FALSE(chunked_upload_stream_->IsEOF()); + + net::TestCompletionCallback callback; + int result = chunked_upload_stream_->Read(io_buffer.get(), io_buffer->size(), + callback.callback()); + EXPECT_EQ(net::ERR_IO_PENDING, result); + EXPECT_EQ(chunked_upload_stream_->Init(NoCallback(), net::NetLogWithSource()), + net::OK); + // We should not receive the second mojo data. + EXPECT_FALSE(callback.have_result()); + EXPECT_READ(chunked_upload_stream_, io_buffer, "1234567"); + + WRITE_DATA_SYNC(write_pipe_, "abc"); + // Wait mojo. + base::RunLoop().RunUntilIdle(); + + EXPECT_READ(chunked_upload_stream_, io_buffer, "890"); + EXPECT_READ(chunked_upload_stream_, io_buffer, "abc"); + + EXPECT_EOF(chunked_upload_stream_, 13); +} + } // namespace } // namespace network
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 5b4588f..ae873fb 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -1585,9 +1585,7 @@ request_info.load_flags = net::LOAD_NORMAL; request_info.privacy_mode = net::PRIVACY_MODE_DISABLED; } else { - request_info.load_flags = net::LOAD_DO_NOT_SEND_COOKIES | - net::LOAD_DO_NOT_SAVE_COOKIES | - net::LOAD_DO_NOT_SEND_AUTH_DATA; + request_info.load_flags = net::LOAD_DO_NOT_SAVE_COOKIES; request_info.privacy_mode = net::PRIVACY_MODE_ENABLED; } request_info.network_isolation_key = network_isolation_key;
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc index d2581663..f105994 100644 --- a/services/network/public/cpp/resource_request.cc +++ b/services/network/public/cpp/resource_request.cc
@@ -119,8 +119,7 @@ } bool ResourceRequest::SendsCookies() const { - return credentials_mode == network::mojom::CredentialsMode::kInclude && - !(load_flags & net::LOAD_DO_NOT_SEND_COOKIES); + return credentials_mode == network::mojom::CredentialsMode::kInclude; } bool ResourceRequest::SavesCookies() const {
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index 18a71fc4..d1de1a9 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -216,9 +216,14 @@ network::mojom::DataElementType type = body->elements()->begin()->type(); if (type == network::mojom::DataElementType::kChunkedDataPipe || type == network::mojom::DataElementType::kReadOnceStream) { - return std::make_unique<ChunkedDataPipeUploadDataStream>( - body, - body->elements_mutable()->begin()->ReleaseChunkedDataPipeGetter()); + auto upload_data_stream = + std::make_unique<ChunkedDataPipeUploadDataStream>( + body, body->elements_mutable() + ->begin() + ->ReleaseChunkedDataPipeGetter()); + if (type == network::mojom::DataElementType::kReadOnceStream) + upload_data_stream->EnableCache(); + return upload_data_stream; } } @@ -631,11 +636,6 @@ if (request.credentials_mode == mojom::CredentialsMode::kOmit || request.credentials_mode == mojom::CredentialsMode::kOmitBug_775438_Workaround) { - const auto creds_mask = net::LOAD_DO_NOT_SAVE_COOKIES | - net::LOAD_DO_NOT_SEND_COOKIES | - net::LOAD_DO_NOT_SEND_AUTH_DATA; - DCHECK((request.load_flags & creds_mask) == 0 || - (request.load_flags & creds_mask) == creds_mask); url_request_->set_allow_credentials(false); url_request_->set_send_client_certs(request.credentials_mode == mojom::CredentialsMode::kOmit);
diff --git a/services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom b/services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom index 331efbe..1db7716 100644 --- a/services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom +++ b/services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom
@@ -21,12 +21,9 @@ // video frame. Done(); - // Reports that the frame incurred some fractional |utilization| of the - // downstream pipeline's per-frame processing capacity. See code comments in - // media::base::VideoFrameMetadata for a discussion of how |utilization| is - // interpreted. The capturer uses this information to auto-adjust the capture - // resolution based on performance variances in the live system environment. - ProvideFeedback(double utilization); + // |feedback| contains consumer feedback like resource utilization, + // maximum requested frame-rate and resolution. + ProvideFeedback(media.mojom.VideoFrameFeedback feedback); }; // Interface for a consumer that receives frames and notifications related to
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 5186b9f..7c22d35 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -555,6 +555,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -602,6 +603,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -654,6 +656,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -709,6 +712,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -757,6 +761,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -807,6 +812,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -855,6 +861,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -904,6 +911,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -955,6 +963,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -1002,6 +1011,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -1054,6 +1064,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -1109,6 +1120,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -1157,6 +1169,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -1207,6 +1220,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -1255,6 +1269,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -1304,6 +1319,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [
diff --git a/testing/buildbot/chromium.ci.json b/testing/buildbot/chromium.ci.json index 4b4f25e..af20f51 100644 --- a/testing/buildbot/chromium.ci.json +++ b/testing/buildbot/chromium.ci.json
@@ -11688,6 +11688,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -11735,6 +11736,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -11787,6 +11789,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -11842,6 +11845,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -11890,6 +11894,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -11940,6 +11945,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -11988,6 +11994,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -12037,6 +12044,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -12088,6 +12096,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -12135,6 +12144,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -12187,6 +12197,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -12242,6 +12253,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -12290,6 +12302,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -12340,6 +12353,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -12388,6 +12402,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -12437,6 +12452,7 @@ "os": "Android" } ], + "expiration": 10800, "output_links": [ { "link": [ @@ -94963,6 +94979,10 @@ ] }, "Site Isolation Android": { + "additional_compile_targets": [ + "content_browsertests", + "content_unittests" + ], "gtest_tests": [ { "args": [ @@ -133599,6 +133619,9 @@ ] }, "WebKit Linux composite_after_paint Dummy Builder": { + "additional_compile_targets": [ + "blink_tests" + ], "isolated_scripts": [ { "args": [ @@ -133630,6 +133653,9 @@ ] }, "WebKit Linux layout_ng_disabled Builder": { + "additional_compile_targets": [ + "blink_tests" + ], "gtest_tests": [ { "args": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 3731d86..964c3dae 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -2019,6 +2019,10 @@ ] }, "Site Isolation Android": { + "additional_compile_targets": [ + "content_browsertests", + "content_unittests" + ], "gtest_tests": [ { "args": [ @@ -2243,6 +2247,9 @@ ] }, "WebKit Linux composite_after_paint Dummy Builder": { + "additional_compile_targets": [ + "blink_tests" + ], "isolated_scripts": [ { "args": [ @@ -2274,6 +2281,9 @@ ] }, "WebKit Linux layout_ng_disabled Builder": { + "additional_compile_targets": [ + "blink_tests" + ], "gtest_tests": [ { "args": [
diff --git a/testing/buildbot/chromium.goma.fyi.json b/testing/buildbot/chromium.goma.fyi.json index cb9f2be2a..81e3447 100644 --- a/testing/buildbot/chromium.goma.fyi.json +++ b/testing/buildbot/chromium.goma.fyi.json
@@ -294,7 +294,33 @@ }, "android-archive-dbg-goma-canary": { "additional_compile_targets": [ - "all" + "all", + "chromedriver_webview_shell_apk" + ] + }, + "android-archive-dbg-goma-latest": { + "additional_compile_targets": [ + "chromedriver_webview_shell_apk" + ] + }, + "android-archive-dbg-goma-rbe-ats-canary": { + "additional_compile_targets": [ + "chromedriver_webview_shell_apk" + ] + }, + "android-archive-dbg-goma-rbe-ats-latest": { + "additional_compile_targets": [ + "chromedriver_webview_shell_apk" + ] + }, + "android-archive-dbg-goma-rbe-canary": { + "additional_compile_targets": [ + "chromedriver_webview_shell_apk" + ] + }, + "android-archive-dbg-goma-rbe-latest": { + "additional_compile_targets": [ + "chromedriver_webview_shell_apk" ] }, "chromeos-amd64-generic-rel-goma-canary": { @@ -501,6 +527,11 @@ } ] }, + "mac-archive-rel-goma-latest-localoutputcache": { + "additional_compile_targets": [ + "chrome" + ] + }, "win32-archive-rel-goma-canary-localoutputcache": { "additional_compile_targets": [ "all"
diff --git a/testing/buildbot/chromium.goma.json b/testing/buildbot/chromium.goma.json index 1e55c69c..19641820 100644 --- a/testing/buildbot/chromium.goma.json +++ b/testing/buildbot/chromium.goma.json
@@ -700,7 +700,33 @@ }, "android-archive-dbg-goma-canary": { "additional_compile_targets": [ - "all" + "all", + "chromedriver_webview_shell_apk" + ] + }, + "android-archive-dbg-goma-latest": { + "additional_compile_targets": [ + "chromedriver_webview_shell_apk" + ] + }, + "android-archive-dbg-goma-rbe-ats-canary": { + "additional_compile_targets": [ + "chromedriver_webview_shell_apk" + ] + }, + "android-archive-dbg-goma-rbe-ats-latest": { + "additional_compile_targets": [ + "chromedriver_webview_shell_apk" + ] + }, + "android-archive-dbg-goma-rbe-canary": { + "additional_compile_targets": [ + "chromedriver_webview_shell_apk" + ] + }, + "android-archive-dbg-goma-rbe-latest": { + "additional_compile_targets": [ + "chromedriver_webview_shell_apk" ] }, "chromeos-amd64-generic-rel-goma-canary": { @@ -907,6 +933,11 @@ } ] }, + "mac-archive-rel-goma-latest-localoutputcache": { + "additional_compile_targets": [ + "chrome" + ] + }, "win32-archive-rel-goma-canary-localoutputcache": { "additional_compile_targets": [ "all"
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 73873eb..80179d18 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -504,6 +504,10 @@ "script": "//testing/xvfb.py", "type": "script", }, + "chromedriver_webview_shell_apk": { + "label": "//chrome/test/chromedriver/test/webview_shell:chromedriver_webview_shell_apk", + "type": "additional_compile_target", + }, "webdriver_wpt_tests": { "label": "//:webdriver_wpt_tests", "type": "script",
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index a27efe3..bc83643 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -347,6 +347,7 @@ 'os': 'Android', }, ], + 'expiration': 10800, }, 'use_swarming': True, 'os_type': 'android', @@ -359,6 +360,9 @@ 'test_suites': { 'gtest_tests': 'webview_bot_all_gtests', }, + 'swarming': { + 'expiration': 10800, + }, 'use_swarming': True, 'os_type': 'android', }, @@ -1872,6 +1876,10 @@ }, }, 'Site Isolation Android': { + 'additional_compile_targets': [ + 'content_browsertests', + 'content_unittests', + ], 'swarming': { 'dimension_sets': [ { @@ -1900,6 +1908,9 @@ 'mixins': [ 'linux-xenial', ], + 'additional_compile_targets': [ + 'blink_tests', + ], 'swarming': { 'hard_timeout': 900, }, @@ -1911,6 +1922,9 @@ 'mixins': [ 'linux-xenial', ], + 'additional_compile_targets': [ + 'blink_tests', + ], 'swarming': { 'hard_timeout': 900, }, @@ -2774,6 +2788,33 @@ 'android-archive-dbg-goma-canary': { 'additional_compile_targets': [ 'all', + # This was copied over from recipe config, 'all' was already present + 'chromedriver_webview_shell_apk', + ], + }, + 'android-archive-dbg-goma-latest': { + 'additional_compile_targets': [ + 'chromedriver_webview_shell_apk', + ], + }, + 'android-archive-dbg-goma-rbe-ats-canary': { + 'additional_compile_targets': [ + 'chromedriver_webview_shell_apk', + ], + }, + 'android-archive-dbg-goma-rbe-ats-latest': { + 'additional_compile_targets': [ + 'chromedriver_webview_shell_apk', + ], + }, + 'android-archive-dbg-goma-rbe-canary': { + 'additional_compile_targets': [ + 'chromedriver_webview_shell_apk', + ], + }, + 'android-archive-dbg-goma-rbe-latest': { + 'additional_compile_targets': [ + 'chromedriver_webview_shell_apk', ], }, # Note: @@ -2861,6 +2902,11 @@ 'gtest_tests': 'goma_mac_gtests', }, }, + 'mac-archive-rel-goma-latest-localoutputcache': { + 'additional_compile_targets': [ + 'chrome', + ], + }, 'win32-archive-rel-goma-canary-localoutputcache': { 'additional_compile_targets': [ 'all',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 8fc9a48f..7838d8cf 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1510,21 +1510,6 @@ ] } ], - "CrOSUserSpaceLowMemoryNotification": [ - { - "platforms": [ - "chromeos" - ], - "experiments": [ - { - "name": "Enabled_20200520", - "enable_features": [ - "CrOSUserSpaceLowMemoryNotification" - ] - } - ] - } - ], "CrostiniWebUIUpgrader": [ { "platforms": [ @@ -4454,6 +4439,21 @@ ] } ], + "OfflineIndicatorV2": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OfflineIndicatorV2" + ] + } + ] + } + ], "OfflinePagesCctV2": [ { "platforms": [
diff --git a/third_party/blink/perf_tests/parser/resources/html5.html b/third_party/blink/perf_tests/parser/resources/html5.html index 96b5267..ff6cb28c 100644 --- a/third_party/blink/perf_tests/parser/resources/html5.html +++ b/third_party/blink/perf_tests/parser/resources/html5.html
@@ -9528,7 +9528,7 @@ simply being the primary interface of the document object, it is no longer defined as inheriting from <code><a href=#document>Document</a></code>.</p> - <pre class=idl>[OverrideBuiltins] + <pre class=idl>[LegacyOverrideBuiltins] interface <dfn id=htmldocument>HTMLDocument</dfn> { // <a href=#resource-metadata-management>resource metadata management</a> [PutForwards=<a href=#dom-location-href title=dom-location-href>href</a>] readonly attribute <a href=#location>Location</a>? <a href=#dom-document-location title=dom-document-location>location</a>; @@ -10222,7 +10222,7 @@ <!-- Note that this named getter overrides built-in properties, as in: http://software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0D%0A...%3Ciframe%20name%3Dbody%3E%3C%2Fiframe%3E%3Cscript%3Ew(document.body)%3C%2Fscript%3E - This is what the "OverrideBuiltins" bit means in the IDL. + This is what the "LegacyOverrideBuiltins" bit means in the IDL. --> </ol><p><dfn id=dom-document-nameditem-filter title=dom-document-nameditem-filter>Named elements</dfn> @@ -42582,7 +42582,7 @@ <dd><code title=attr-fs-target><a href=#attr-fs-target>target</a></code></dd> <dt>DOM interface:</dt> <dd> -<pre class=idl>[OverrideBuiltins] +<pre class=idl>[LegacyOverrideBuiltins] interface <dfn id=htmlformelement>HTMLFormElement</dfn> : <a href=#htmlelement>HTMLElement</a> { attribute DOMString <a href=#dom-form-acceptcharset title=dom-form-acceptCharset>acceptCharset</a>; attribute DOMString <a href=#dom-fs-action title=dom-fs-action>action</a>;
diff --git a/third_party/blink/public/blink_image_resources.grd b/third_party/blink/public/blink_image_resources.grd index 889f915..3cf7adec 100644 --- a/third_party/blink/public/blink_image_resources.grd +++ b/third_party/blink/public/blink_image_resources.grd
@@ -13,6 +13,8 @@ <structure type="chrome_scaled_image" name="IDR_BROKENIMAGE" file="blink/broken_image.png" /> <structure type="chrome_scaled_image" name="IDR_SEARCH_CANCEL" file="blink/search_cancel.png" /> <structure type="chrome_scaled_image" name="IDR_SEARCH_CANCEL_PRESSED" file="blink/search_cancel_pressed.png" /> + <structure type="chrome_scaled_image" name="IDR_SEARCH_CANCEL_DARK_MODE" file="blink/search_cancel_dark_mode.png" /> + <structure type="chrome_scaled_image" name="IDR_SEARCH_CANCEL_PRESSED_DARK_MODE" file="blink/search_cancel_pressed_dark_mode.png" /> <structure type="chrome_scaled_image" name="IDR_PLACEHOLDER_ICON" file="blink/placeholder_icon.png" /> </structures> </release>
diff --git a/third_party/blink/public/default_100_percent/blink/search_cancel_dark_mode.png b/third_party/blink/public/default_100_percent/blink/search_cancel_dark_mode.png new file mode 100644 index 0000000..a2df359f --- /dev/null +++ b/third_party/blink/public/default_100_percent/blink/search_cancel_dark_mode.png Binary files differ
diff --git a/third_party/blink/public/default_100_percent/blink/search_cancel_pressed_dark_mode.png b/third_party/blink/public/default_100_percent/blink/search_cancel_pressed_dark_mode.png new file mode 100644 index 0000000..fe14a45 --- /dev/null +++ b/third_party/blink/public/default_100_percent/blink/search_cancel_pressed_dark_mode.png Binary files differ
diff --git a/third_party/blink/renderer/bindings/IDLExtendedAttributes.md b/third_party/blink/renderer/bindings/IDLExtendedAttributes.md index 97b2ed56..7009475 100644 --- a/third_party/blink/renderer/bindings/IDLExtendedAttributes.md +++ b/third_party/blink/renderer/bindings/IDLExtendedAttributes.md
@@ -92,7 +92,7 @@ [ImplementedAs=setItem] setter DOMString (unsigned long index); ``` -There is one interface extended attribute that only affects special operations: `[OverrideBuiltins]`. +There is one interface extended attribute that only affects special operations: `[LegacyOverrideBuiltins]`. The following extended attributes are used on special operations, as on methods generally: `[RaisesException]`. @@ -408,9 +408,9 @@ }; ``` -### [OverrideBuiltins] _(i)_ +### [LegacyOverrideBuiltins] _(i)_ -Standard: [OverrideBuiltins](http://heycam.github.io/webidl/#OverrideBuiltins) +Standard: [LegacyOverrideBuiltins](https://heycam.github.io/webidl/#OverrideBuiltins) Summary: Affects named property operations, making named properties shadow built-in properties of the object.
diff --git a/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt b/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt index 2498fc0..fff0e107 100644 --- a/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt +++ b/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt
@@ -64,6 +64,7 @@ HTMLConstructor ImmutablePrototype ImplementedAs=* +LegacyOverrideBuiltins LegacyTreatAsPartialInterface LegacyTreatNonObjectAsNull LegacyUnenumerableNamedProperties @@ -83,7 +84,6 @@ NamedConstructor_RaisesException NoInterfaceObject NotEnumerable -OverrideBuiltins PartialInterfaceImplementedAs=* PermissiveDictionaryConversion PerWorldBindings
diff --git a/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc b/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc index 6fdce97..37f6ed6 100644 --- a/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc +++ b/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc
@@ -395,7 +395,7 @@ const QualifiedName& content_attribute, const char* interface_name, const char* attribute_name) { - PerformAttributeSetCEReactionsReflect<IDLStringV2, const AtomicString&, + PerformAttributeSetCEReactionsReflect<IDLStringV2, AtomicString, &Element::setAttribute>( info, content_attribute, interface_name, attribute_name); } @@ -406,8 +406,7 @@ const char* interface_name, const char* attribute_name) { PerformAttributeSetCEReactionsReflect<IDLStringTreatNullAsEmptyStringV2, - const AtomicString&, - &Element::setAttribute>( + AtomicString, &Element::setAttribute>( info, content_attribute, interface_name, attribute_name); } @@ -416,8 +415,8 @@ const QualifiedName& content_attribute, const char* interface_name, const char* attribute_name) { - PerformAttributeSetCEReactionsReflect< - IDLNullable<IDLStringV2>, const AtomicString&, &Element::setAttribute>( + PerformAttributeSetCEReactionsReflect<IDLNullable<IDLStringV2>, AtomicString, + &Element::setAttribute>( info, content_attribute, interface_name, attribute_name); }
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc index cdf3c2f..81287dbc 100644 --- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc +++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
@@ -473,7 +473,7 @@ // GetNamedProperty(), Getter(), NamedItemAdded(), and NamedItemRemoved() // optimize property access performance for Document. // -// Document interface has [OverrideBuiltins] and a named getter. If we +// Document interface has [LegacyOverrideBuiltins] and a named getter. If we // implemented the named getter as a standard IDL-mapped code, we would call a // Blink function before any of Document property access, and it would be // performance overhead even for builtin properties. Our implementation updates
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py index ef49c662..4ccb29a 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
@@ -2961,7 +2961,8 @@ // https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty\ """)) - if "OverrideBuiltins" not in cg_context.interface.extended_attributes: + if ("LegacyOverrideBuiltins" not in + cg_context.interface.extended_attributes): body.append( TextNode("""\ // step 2.1. If the result of running the named property visibility algorithm @@ -5606,7 +5607,7 @@ and props.named_setter.owner, props.named_deleter and props.named_deleter.owner)) flags = ["v8::PropertyHandlerFlags::kOnlyInterceptStrings"] - if "OverrideBuiltins" not in interface.extended_attributes: + if "LegacyOverrideBuiltins" not in interface.extended_attributes: flags.append("v8::PropertyHandlerFlags::kNonMasking") if (props.named_getter.extended_attributes.value_of("Affects") == "Nothing"):
diff --git a/third_party/blink/renderer/bindings/scripts/v8_interface.py b/third_party/blink/renderer/bindings/scripts/v8_interface.py index 7d95aee..f32ddae0 100644 --- a/third_party/blink/renderer/bindings/scripts/v8_interface.py +++ b/third_party/blink/renderer/bindings/scripts/v8_interface.py
@@ -592,7 +592,7 @@ 'indexed_property_deleter': property_deleter(interface.indexed_property_deleter), 'is_override_builtins': - 'OverrideBuiltins' in extended_attributes, + 'LegacyOverrideBuiltins' in extended_attributes, 'named_property_getter': property_getter(interface.named_property_getter, ['name']), 'named_property_setter':
diff --git a/third_party/blink/renderer/bindings/tests/idls/core/test_special_operations.idl b/third_party/blink/renderer/bindings/tests/idls/core/test_special_operations.idl index 3bdc8a40..aecea67 100644 --- a/third_party/blink/renderer/bindings/tests/idls/core/test_special_operations.idl +++ b/third_party/blink/renderer/bindings/tests/idls/core/test_special_operations.idl
@@ -3,10 +3,10 @@ // found in the LICENSE file. [ - OverrideBuiltins + LegacyOverrideBuiltins ] interface TestSpecialOperations { // [ImplementedAs], union return, nullability - // [OverrideBuiltins] affects named property operations + // [LegacyOverrideBuiltins] affects named property operations [ImplementedAs=getItem] getter (Node or NodeList) namedItem(DOMString name); setter Node (DOMString name, Node? value); };
diff --git a/third_party/blink/renderer/core/accessibility/ax_context.h b/third_party/blink/renderer/core/accessibility/ax_context.h index 28e62f6..5d4a614 100644 --- a/third_party/blink/renderer/core/accessibility/ax_context.h +++ b/third_party/blink/renderer/core/accessibility/ax_context.h
@@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ACCESSIBILITY_AX_CONTEXT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ACCESSIBILITY_AX_CONTEXT_H_ -#include "base/macros.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/platform/heap/persistent.h" @@ -23,6 +22,8 @@ public: explicit AXContext(Document& document); + AXContext(const AXContext&) = delete; + AXContext& operator=(const AXContext&) = delete; virtual ~AXContext(); // Note: it's an error to call this after |document| is no longer active. @@ -31,8 +32,6 @@ protected: WeakPersistent<Document> document_; - - DISALLOW_COPY_AND_ASSIGN(AXContext); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.h b/third_party/blink/renderer/core/accessibility/ax_object_cache.h index dd947f3..7acf8cd 100644 --- a/third_party/blink/renderer/core/accessibility/ax_object_cache.h +++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
@@ -29,7 +29,6 @@ #include <memory> -#include "base/macros.h" #include "third_party/blink/renderer/core/accessibility/axid.h" #include "third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h" #include "third_party/blink/renderer/core/core_export.h" @@ -57,6 +56,8 @@ static AXObjectCache* Create(Document&); + AXObjectCache(const AXObjectCache&) = delete; + AXObjectCache& operator=(const AXObjectCache&) = delete; virtual ~AXObjectCache() = default; virtual void Trace(Visitor*) const {} @@ -180,7 +181,6 @@ AXObjectCache() = default; static AXObjectCacheCreateFunction create_function_; - DISALLOW_COPY_AND_ASSIGN(AXObjectCache); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h b/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h index 8e52e3e..d3290f1 100644 --- a/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h +++ b/third_party/blink/renderer/core/accessibility/ax_object_cache_base.h
@@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ACCESSIBILITY_AX_OBJECT_CACHE_BASE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_ACCESSIBILITY_AX_OBJECT_CACHE_BASE_H_ -#include "base/macros.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/wtf/casting.h" @@ -24,6 +23,8 @@ // new public API methods or similar) and remove this class. class CORE_EXPORT AXObjectCacheBase : public AXObjectCache { public: + AXObjectCacheBase(const AXObjectCacheBase&) = delete; + AXObjectCacheBase& operator=(const AXObjectCacheBase&) = delete; ~AXObjectCacheBase() override = default; virtual AXObject* Get(const Node*) = 0; @@ -31,7 +32,6 @@ protected: AXObjectCacheBase() = default; - DISALLOW_COPY_AND_ASSIGN(AXObjectCacheBase); }; template <>
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc index 91d5e8ee..848dcfd 100644 --- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc +++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -103,6 +103,16 @@ style.SetBackgroundColor(bg_color); } +bool HostIsInputFile(const Element* element) { + if (!element || !element->IsInUserAgentShadowRoot()) + return false; + if (const Element* shadow_host = element->OwnerShadowHost()) { + if (const auto* input = DynamicTo<HTMLInputElement>(shadow_host)) + return input->type() == input_type_names::kFile; + } + return false; +} + } // namespace static EDisplay EquivalentBlockDisplay(EDisplay display) { @@ -350,17 +360,6 @@ return; } - if (const auto* input = DynamicTo<HTMLInputElement>(element)) { - if (input->type() == input_type_names::kFile) { - if (style.Display() == EDisplay::kFlex || - style.Display() == EDisplay::kGrid) - style.SetDisplay(EDisplay::kBlock); - else if (style.Display() == EDisplay::kInlineFlex || - style.Display() == EDisplay::kInlineGrid) - style.SetDisplay(EDisplay::kInlineBlock); - } - } - if (IsA<HTMLTextAreaElement>(element)) { // Textarea considers overflow visible as auto. style.SetOverflowX(style.OverflowX() == EOverflow::kVisible @@ -445,9 +444,10 @@ static void AdjustStyleForDisplay(ComputedStyle& style, const ComputedStyle& layout_parent_style, + const Element* element, Document* document) { // Blockify the children of flex, grid or LayoutCustom containers. - if (layout_parent_style.BlockifiesChildren()) { + if (layout_parent_style.BlockifiesChildren() && !HostIsInputFile(element)) { style.SetIsInBlockifyingDisplay(); if (style.Display() != EDisplay::kContents) { style.SetDisplay(EquivalentBlockDisplay(style.Display())); @@ -649,7 +649,7 @@ AdjustStyleForFirstLine(style); AdjustStyleForMarker(style, parent_style, state.GetElement()); - AdjustStyleForDisplay(style, layout_parent_style, + AdjustStyleForDisplay(style, layout_parent_style, element, element ? &element->GetDocument() : nullptr); // If this is a child of a LayoutNGCustom, we need the name of the parent
diff --git a/third_party/blink/renderer/core/dom/attribute.h b/third_party/blink/renderer/core/dom/attribute.h index 1869c50..3db098e 100644 --- a/third_party/blink/renderer/core/dom/attribute.h +++ b/third_party/blink/renderer/core/dom/attribute.h
@@ -39,8 +39,8 @@ DISALLOW_NEW(); public: - Attribute(const QualifiedName& name, const AtomicString& value) - : name_(name), value_(value) {} + Attribute(const QualifiedName& name, AtomicString value) + : name_(name), value_(std::move(value)) {} // NOTE: The references returned by these functions are only valid for as long // as the Attribute stays in place. For example, calling a function that @@ -56,7 +56,10 @@ bool Matches(const QualifiedName&) const; bool MatchesCaseInsensitive(const QualifiedName&) const; - void SetValue(const AtomicString& value) { value_ = value; } + void SetValue(AtomicString value) { value_ = std::move(value); } + AtomicString ExchangeValue(AtomicString value) { + return std::exchange(value_, std::move(value)); + } // Note: This API is only for HTMLTreeBuilder. It is not safe to change the // name of an attribute once parseAttribute has been called as DOM
diff --git a/third_party/blink/renderer/core/dom/attribute_collection.h b/third_party/blink/renderer/core/dom/attribute_collection.h index c403f85..30df3cc 100644 --- a/third_party/blink/renderer/core/dom/attribute_collection.h +++ b/third_party/blink/renderer/core/dom/attribute_collection.h
@@ -160,13 +160,15 @@ attributes) {} // These functions do no error/duplicate checking. - void Append(const QualifiedName&, const AtomicString& value); + const AtomicString& Append(const QualifiedName&, AtomicString value); void Remove(unsigned index); }; -inline void MutableAttributeCollection::Append(const QualifiedName& name, - const AtomicString& value) { - attributes_.push_back(Attribute(name, value)); +inline const AtomicString& MutableAttributeCollection::Append( + const QualifiedName& name, + AtomicString value) { + attributes_.emplace_back(name, std::move(value)); + return attributes_.back().Value(); } inline void MutableAttributeCollection::Remove(unsigned index) {
diff --git a/third_party/blink/renderer/core/dom/dom_string_map.idl b/third_party/blink/renderer/core/dom/dom_string_map.idl index 8f47e3b..755e355 100644 --- a/third_party/blink/renderer/core/dom/dom_string_map.idl +++ b/third_party/blink/renderer/core/dom/dom_string_map.idl
@@ -26,7 +26,7 @@ // https://html.spec.whatwg.org/C/#the-domstringmap-interface [ - OverrideBuiltins, + LegacyOverrideBuiltins, Exposed=Window ] interface DOMStringMap { [ImplementedAs=item] getter DOMString (DOMString name);
diff --git a/third_party/blink/renderer/core/dom/element-hot.cc b/third_party/blink/renderer/core/dom/element-hot.cc index bee9f40f..87b14332 100644 --- a/third_party/blink/renderer/core/dom/element-hot.cc +++ b/third_party/blink/renderer/core/dom/element-hot.cc
@@ -120,45 +120,45 @@ g_null_atom)); } -void Element::setAttribute(const QualifiedName& name, - const AtomicString& value) { +void Element::setAttribute(const QualifiedName& name, AtomicString value) { SynchronizeAttribute(name); wtf_size_t index = GetElementData() ? GetElementData()->Attributes().FindIndex(name) : kNotFound; - SetAttributeInternal(index, name, value, + SetAttributeInternal(index, name, std::move(value), kNotInSynchronizationOfLazyAttribute); } void Element::setAttribute(const QualifiedName& name, - const AtomicString& value, + AtomicString value, ExceptionState& exception_state) { SynchronizeAttribute(name); wtf_size_t index = GetElementData() ? GetElementData()->Attributes().FindIndex(name) : kNotFound; - AtomicString trusted_value( - TrustedTypesCheckFor(ExpectedTrustedTypeForAttribute(name), value, - GetExecutionContext(), exception_state)); + AtomicString trusted_value(TrustedTypesCheckFor( + ExpectedTrustedTypeForAttribute(name), std::move(value), + GetExecutionContext(), exception_state)); if (exception_state.HadException()) return; - SetAttributeInternal(index, name, trusted_value, + SetAttributeInternal(index, name, std::move(trusted_value), kNotInSynchronizationOfLazyAttribute); } void Element::SetSynchronizedLazyAttribute(const QualifiedName& name, - const AtomicString& value) { + AtomicString value) { wtf_size_t index = GetElementData() ? GetElementData()->Attributes().FindIndex(name) : kNotFound; - SetAttributeInternal(index, name, value, kInSynchronizationOfLazyAttribute); + SetAttributeInternal(index, name, std::move(value), + kInSynchronizationOfLazyAttribute); } void Element::SetAttributeHinted(const AtomicString& local_name, WTF::AtomicStringTable::WeakResult hint, - const AtomicString& value, + AtomicString value, ExceptionState& exception_state) { if (!Document::IsValidName(local_name)) { exception_state.ThrowDOMException( @@ -178,7 +178,7 @@ if (exception_state.HadException()) return; - SetAttributeInternal(index, q_name, trusted_value, + SetAttributeInternal(index, q_name, std::move(trusted_value), kNotInSynchronizationOfLazyAttribute); } @@ -204,14 +204,14 @@ GetExecutionContext(), exception_state)); if (exception_state.HadException()) return; - SetAttributeInternal(index, q_name, value, + SetAttributeInternal(index, q_name, std::move(value), kNotInSynchronizationOfLazyAttribute); } ALWAYS_INLINE void Element::SetAttributeInternal( wtf_size_t index, const QualifiedName& name, - const AtomicString& new_value, + AtomicString new_value, SynchronizationOfLazyAttribute in_synchronization_of_lazy_attribute) { if (new_value.IsNull()) { if (index != kNotFound) @@ -220,25 +220,32 @@ } if (index == kNotFound) { - AppendAttributeInternal(name, new_value, + AppendAttributeInternal(name, std::move(new_value), in_synchronization_of_lazy_attribute); return; } const Attribute& existing_attribute = GetElementData()->Attributes().at(index); - AtomicString existing_attribute_value = existing_attribute.Value(); - QualifiedName existing_attribute_name = existing_attribute.GetName(); if (!in_synchronization_of_lazy_attribute) { - WillModifyAttribute(existing_attribute_name, existing_attribute_value, - new_value); + WillModifyAttribute(existing_attribute.GetName(), + existing_attribute.Value(), new_value); } - if (new_value != existing_attribute_value) - EnsureUniqueElementData().Attributes().at(index).SetValue(new_value); + + AtomicString old_value_storage; // Keep the old value alive in an update. + const AtomicString* old_val_ptr = &existing_attribute.Value(); + const AtomicString* new_val_ptr = &new_value; + if (new_value != *old_val_ptr) { + Attribute& attribute = EnsureUniqueElementData().Attributes().at(index); + old_value_storage = attribute.ExchangeValue(std::move(new_value)); + old_val_ptr = &old_value_storage; + new_val_ptr = &attribute.Value(); + } + if (!in_synchronization_of_lazy_attribute) { - DidModifyAttribute(existing_attribute_name, existing_attribute_value, - new_value); + DidModifyAttribute(existing_attribute.GetName(), *old_val_ptr, + *new_val_ptr); } } @@ -301,7 +308,7 @@ } } - SetAttributeInternal(index, attr_node->GetQualifiedName(), value, + SetAttributeInternal(index, attr_node->GetQualifiedName(), std::move(value), kNotInSynchronizationOfLazyAttribute); attr_node->AttachToElement(this, local_name);
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index dcbca6fb..1bc3b60 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3794,7 +3794,7 @@ if (exception_state.HadException()) return; - setAttribute(parsed_name, value); + setAttribute(parsed_name, std::move(value)); } void Element::RemoveAttributeInternal( @@ -3828,13 +3828,14 @@ void Element::AppendAttributeInternal( const QualifiedName& name, - const AtomicString& value, + AtomicString value, SynchronizationOfLazyAttribute in_synchronization_of_lazy_attribute) { if (!in_synchronization_of_lazy_attribute) WillModifyAttribute(name, g_null_atom, value); - EnsureUniqueElementData().Attributes().Append(name, value); + const AtomicString& stored_value = + EnsureUniqueElementData().Attributes().Append(name, std::move(value)); if (!in_synchronization_of_lazy_attribute) - DidAddAttribute(name, value); + DidAddAttribute(name, stored_value); } void Element::removeAttributeNS(const AtomicString& namespace_uri, @@ -5544,9 +5545,9 @@ DispatchSubtreeModifiedEvent(); } -void Element::DidModifyAttribute(const QualifiedName& name, - const AtomicString& old_value, - const AtomicString& new_value) { +void Element::DidModifyAttribute(QualifiedName name, + AtomicString old_value, + AtomicString new_value) { if (name == html_names::kIdAttr) UpdateId(old_value, new_value); AttributeChanged(AttributeModificationParams(
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index 7d6143be..b50c9ada 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -162,12 +162,9 @@ // Passing g_null_atom as the second parameter removes the attribute when // calling either of these set methods. - void setAttribute(const QualifiedName&, const AtomicString& value); - void setAttribute(const QualifiedName&, - const AtomicString& value, - ExceptionState&); - void SetSynchronizedLazyAttribute(const QualifiedName&, - const AtomicString& value); + void setAttribute(const QualifiedName&, AtomicString value); + void setAttribute(const QualifiedName&, AtomicString value, ExceptionState&); + void SetSynchronizedLazyAttribute(const QualifiedName&, AtomicString value); void removeAttribute(const QualifiedName&); @@ -233,7 +230,7 @@ void setAttribute(const AtomicString& name, AtomicString value, ExceptionState& exception_state = ASSERT_NO_EXCEPTION) { - SetAttributeHinted(name, WeakLowercaseIfNecessary(name), value, + SetAttributeHinted(name, WeakLowercaseIfNecessary(name), std::move(value), exception_state); } @@ -265,7 +262,7 @@ bool toggleAttribute(const AtomicString&, bool force, ExceptionState&); const AtomicString& GetIdAttribute() const; - void SetIdAttribute(const AtomicString&); + void SetIdAttribute(AtomicString); const AtomicString& GetNameAttribute() const; const AtomicString& GetClassAttribute() const; @@ -1081,9 +1078,12 @@ void WillModifyAttribute(const QualifiedName&, const AtomicString& old_value, const AtomicString& new_value); - void DidModifyAttribute(const QualifiedName&, - const AtomicString& old_value, - const AtomicString& new_value); + // Take arguments by copy as DidModifyAttribute() may modify the + // ElementData().Attributes(). If the arguments are references to entries of + // that array, this would cause a UaF. + void DidModifyAttribute(QualifiedName, + AtomicString old_value, + AtomicString new_value); void DidRemoveAttribute(const QualifiedName&, const AtomicString& old_value); void SynchronizeAllAttributes() const; @@ -1102,10 +1102,10 @@ void SetAttributeInternal(wtf_size_t index, const QualifiedName&, - const AtomicString& value, + AtomicString value, SynchronizationOfLazyAttribute); void AppendAttributeInternal(const QualifiedName&, - const AtomicString& value, + AtomicString value, SynchronizationOfLazyAttribute); void RemoveAttributeInternal(wtf_size_t index, SynchronizationOfLazyAttribute); @@ -1129,7 +1129,7 @@ WTF::AtomicStringTable::WeakResult hint) const; void SetAttributeHinted(const AtomicString& name, WTF::AtomicStringTable::WeakResult hint, - const AtomicString& value, + AtomicString value, ExceptionState& = ASSERT_NO_EXCEPTION); void SetAttributeHinted( const AtomicString& name, @@ -1329,8 +1329,8 @@ return FastGetAttribute(html_names::kClassAttr); } -inline void Element::SetIdAttribute(const AtomicString& value) { - setAttribute(html_names::kIdAttr, value); +inline void Element::SetIdAttribute(AtomicString value) { + setAttribute(html_names::kIdAttr, std::move(value)); } inline const SpaceSplitString& Element::ClassNames() const {
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 e8a0cdb8..8bf14b4 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
@@ -676,9 +676,7 @@ if (print_context_) PrintEnd(); print_client_.reset(); -#if DCHECK_IS_ON() is_in_printing_ = false; -#endif } WebString WebLocalFrameImpl::AssignedName() const { @@ -1539,12 +1537,10 @@ void WebLocalFrameImpl::DispatchBeforePrintEvent( base::WeakPtr<WebPrintClient> print_client) { -#if DCHECK_IS_ON() - DCHECK(!is_in_printing_) << "DispatchAfterPrintEvent() should have been " - "called after the previous " - "DispatchBeforePrintEvent() call."; + CHECK(!is_in_printing_) << "DispatchAfterPrintEvent() should have been " + "called after the previous " + "DispatchBeforePrintEvent() call."; is_in_printing_ = true; -#endif print_client_ = print_client; @@ -1560,11 +1556,9 @@ } void WebLocalFrameImpl::DispatchAfterPrintEvent() { -#if DCHECK_IS_ON() - DCHECK(is_in_printing_) << "DispatchBeforePrintEvent() should be called " - "before DispatchAfterPrintEvent()."; + CHECK(is_in_printing_) << "DispatchBeforePrintEvent() should be called " + "before DispatchAfterPrintEvent()."; is_in_printing_ = false; -#endif print_client_.reset();
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 a9b91f3..f0a9408 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
@@ -541,11 +541,11 @@ // cleared upon close(). SelfKeepAlive<WebLocalFrameImpl> self_keep_alive_; -#if DCHECK_IS_ON() // True if DispatchBeforePrintEvent() was called, and // DispatchAfterPrintEvent() is not called yet. + // TODO(crbug.com/1121077) After fixing the bug, make this member variable + // only available when DCHECK_IS_ON(). bool is_in_printing_ = false; -#endif }; template <>
diff --git a/third_party/blink/renderer/core/html/forms/html_form_element.idl b/third_party/blink/renderer/core/html/forms/html_form_element.idl index 4a5986bc..8e6f5bb 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_element.idl +++ b/third_party/blink/renderer/core/html/forms/html_form_element.idl
@@ -23,7 +23,7 @@ [ Exposed=Window, HTMLConstructor, - OverrideBuiltins + LegacyOverrideBuiltins ] interface HTMLFormElement : HTMLElement { [CEReactions, Reflect=accept_charset] attribute DOMString acceptCharset; [CEReactions, URL] attribute USVString action;
diff --git a/third_party/blink/renderer/core/html/html_embed_element.idl b/third_party/blink/renderer/core/html/html_embed_element.idl index 800a6bc..5a94909 100644 --- a/third_party/blink/renderer/core/html/html_embed_element.idl +++ b/third_party/blink/renderer/core/html/html_embed_element.idl
@@ -20,10 +20,10 @@ // https://html.spec.whatwg.org/C/#the-embed-element -// TODO(yukishiino): HTMLEmbedElement should not have [OverrideBuiltins]. +// TODO(yukishiino): HTMLEmbedElement should not have [LegacyOverrideBuiltins]. [ Exposed=Window, - OverrideBuiltins, + LegacyOverrideBuiltins, ActiveScriptWrappable, HTMLConstructor ] interface HTMLEmbedElement : HTMLElement {
diff --git a/third_party/blink/renderer/core/html/html_frame_set_element.idl b/third_party/blink/renderer/core/html/html_frame_set_element.idl index edbcced..a9a87cd 100644 --- a/third_party/blink/renderer/core/html/html_frame_set_element.idl +++ b/third_party/blink/renderer/core/html/html_frame_set_element.idl
@@ -20,11 +20,11 @@ // https://html.spec.whatwg.org/C/#htmlframesetelement -// FIXME: HTMLFrameSetElement should not have [OverrideBuiltins]. +// FIXME: HTMLFrameSetElement should not have [LegacyOverrideBuiltins]. [ Exposed=Window, HTMLConstructor, - OverrideBuiltins + LegacyOverrideBuiltins ] interface HTMLFrameSetElement : HTMLElement { [CEReactions, Reflect] attribute DOMString cols; [CEReactions, Reflect] attribute DOMString rows;
diff --git a/third_party/blink/renderer/core/html/html_object_element.idl b/third_party/blink/renderer/core/html/html_object_element.idl index 1279fd48..a5b9d30 100644 --- a/third_party/blink/renderer/core/html/html_object_element.idl +++ b/third_party/blink/renderer/core/html/html_object_element.idl
@@ -20,10 +20,10 @@ // https://html.spec.whatwg.org/C/#the-object-element -// TODO(yukishiino): HTMLObjectElement should not have [OverrideBuiltins]. +// TODO(yukishiino): HTMLObjectElement should not have [LegacyOverrideBuiltins]. [ Exposed=Window, - OverrideBuiltins, + LegacyOverrideBuiltins, ActiveScriptWrappable, HTMLConstructor ] interface HTMLObjectElement : HTMLElement {
diff --git a/third_party/blink/renderer/core/html/link_web_bundle.cc b/third_party/blink/renderer/core/html/link_web_bundle.cc index 4e91698f..b6a4b882 100644 --- a/third_party/blink/renderer/core/html/link_web_bundle.cc +++ b/third_party/blink/renderer/core/html/link_web_bundle.cc
@@ -204,6 +204,11 @@ return bundle_loader_->GetURLLoaderFactory(); } +String LinkWebBundle::GetCacheIdentifier() const { + DCHECK(bundle_loader_); + return bundle_loader_->url().GetString(); +} + // static KURL LinkWebBundle::ParseResourceUrl(const AtomicString& str) { // The implementation is almost copy and paste from ParseExchangeURL() defined
diff --git a/third_party/blink/renderer/core/html/link_web_bundle.h b/third_party/blink/renderer/core/html/link_web_bundle.h index 14605fe6..dcfa286 100644 --- a/third_party/blink/renderer/core/html/link_web_bundle.h +++ b/third_party/blink/renderer/core/html/link_web_bundle.h
@@ -43,6 +43,7 @@ bool CanHandleRequest(const KURL& url) const override; mojo::PendingRemote<network::mojom::blink::URLLoaderFactory> GetURLLoaderFactory() override; + String GetCacheIdentifier() const override; // Parse the given |str| as a url. If |str| doesn't meet the criteria which // WebBundles specification requires, this returns invalid empty KURL as an
diff --git a/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc b/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc index bdbda40d..c794037 100644 --- a/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc +++ b/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc
@@ -412,7 +412,7 @@ KURL url = document->CompleteURL( StripLeadingAndTrailingHTMLSpaces(image_candidates[i]->Url())); if (GetMemoryCache()->ResourceForURL( - url, document->Fetcher()->GetCacheIdentifier()) || + url, document->Fetcher()->GetCacheIdentifier(url)) || url.ProtocolIsData()) return i; }
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc index 6f9fe7e..739ea97 100644 --- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -1801,7 +1801,7 @@ Resource* cached_resource = document->Fetcher()->CachedResource(url); if (!cached_resource) { cached_resource = GetMemoryCache()->ResourceForURL( - url, document->Fetcher()->GetCacheIdentifier()); + url, document->Fetcher()->GetCacheIdentifier(url)); } if (cached_resource && InspectorPageAgent::CachedResourceContent( cached_resource, content, base64_encoded))
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc index 60f407a7..43cd2bb 100644 --- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -155,7 +155,7 @@ } if (!cached_resource) { cached_resource = GetMemoryCache()->ResourceForURL( - url, document->Fetcher()->GetCacheIdentifier()); + url, document->Fetcher()->GetCacheIdentifier(url)); } if (!cached_resource) cached_resource = loader->ResourceForURL(url);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc index 9bde4d2..89897ba 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_container_fragment.cc
@@ -110,6 +110,14 @@ outline_rects, additional_offset, outline_type, containing_block); continue; } + if (item.IsText()) { + if (outline_type == NGOutlineType::kDontIncludeBlockVisualOverflow) + continue; + outline_rects->push_back( + PhysicalRect(additional_offset + item.OffsetInContainerBlock(), + item.Size().ToLayoutSize())); + continue; + } if (item.Type() == NGFragmentItem::kBox) { if (const NGPhysicalBoxFragment* child_box = item.PostLayoutBoxFragment()) { @@ -120,7 +128,6 @@ } continue; } - DCHECK(item.IsText()); } // Don't add |Children()|. If |this| has |NGFragmentItems|, children are // either line box, which we already handled in items, or OOF, which we
diff --git a/third_party/blink/renderer/core/layout/ng/table/interface_casting.h b/third_party/blink/renderer/core/layout/ng/table/interface_casting.h index c74cecc..0c0429be 100644 --- a/third_party/blink/renderer/core/layout/ng/table/interface_casting.h +++ b/third_party/blink/renderer/core/layout/ng/table/interface_casting.h
@@ -5,6 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_INTERFACE_CASTING_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_INTERFACE_CASTING_H_ +#include "base/notreached.h" + namespace blink { // These are the helpers for downcasting to mixin classes. @@ -54,6 +56,8 @@ template <typename U> static bool AllowFrom(const U&) { static_assert(sizeof(U) == 0, "no downcast traits specialization for T"); + NOTREACHED(); + return false; } template <typename U> static const T& ConvertFrom(const U&) {
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc index 697485c..fb271af6 100644 --- a/third_party/blink/renderer/core/loader/image_loader.cc +++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -754,7 +754,7 @@ // content when style recalc is over and DOM mutation is allowed again. if (!url.IsNull()) { Resource* resource = GetMemoryCache()->ResourceForURL( - url, element_->GetDocument().Fetcher()->GetCacheIdentifier()); + url, element_->GetDocument().Fetcher()->GetCacheIdentifier(url)); if (resource && !resource->ErrorOccurred() && CanReuseFromListOfAvailableImages(
diff --git a/third_party/blink/renderer/core/paint/theme_painter_default.cc b/third_party/blink/renderer/core/paint/theme_painter_default.cc index 015f211..06b5ac9 100644 --- a/third_party/blink/renderer/core/paint/theme_painter_default.cc +++ b/third_party/blink/renderer/core/paint/theme_painter_default.cc
@@ -507,15 +507,26 @@ cancel_button_size, cancel_button_size); IntRect painting_rect = ConvertToPaintingRect( input_layout_box, cancel_button_object, cancel_button_rect, r); - + WebColorScheme color_scheme = + cancel_button_object.StyleRef().UsedColorScheme(); DEFINE_STATIC_REF(Image, cancel_image, (Image::LoadPlatformResource(IDR_SEARCH_CANCEL))); DEFINE_STATIC_REF(Image, cancel_pressed_image, (Image::LoadPlatformResource(IDR_SEARCH_CANCEL_PRESSED))); + DEFINE_STATIC_REF(Image, cancel_image_dark_mode, + (Image::LoadPlatformResource(IDR_SEARCH_CANCEL_DARK_MODE))); + DEFINE_STATIC_REF( + Image, cancel_pressed_image_dark_mode, + (Image::LoadPlatformResource(IDR_SEARCH_CANCEL_PRESSED_DARK_MODE))); + Image* color_scheme_adjusted_cancel_image = + color_scheme == kLight ? cancel_image : cancel_image_dark_mode; + Image* color_scheme_adjusted_cancel_pressed_image = + color_scheme == kLight ? cancel_pressed_image + : cancel_pressed_image_dark_mode; paint_info.context.DrawImage( LayoutTheme::IsPressed(cancel_button_object.GetNode()) - ? cancel_pressed_image - : cancel_image, + ? color_scheme_adjusted_cancel_pressed_image + : color_scheme_adjusted_cancel_image, Image::kSyncDecode, FloatRect(painting_rect)); return false; }
diff --git a/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h b/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h index 4b90b1fb..fb7837f 100644 --- a/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h +++ b/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.h
@@ -25,10 +25,11 @@ // ScrollAnimatorMac. class ProgrammaticScrollAnimator : public ScrollAnimatorCompositorCoordinator { - DISALLOW_COPY_AND_ASSIGN(ProgrammaticScrollAnimator); - public: explicit ProgrammaticScrollAnimator(ScrollableArea*); + ProgrammaticScrollAnimator(const ProgrammaticScrollAnimator&) = delete; + ProgrammaticScrollAnimator& operator=(const ProgrammaticScrollAnimator&) = + delete; ~ProgrammaticScrollAnimator() override; void ScrollToOffsetWithoutAnimation(const ScrollOffset&,
diff --git a/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h b/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h index 48c6b27..0b62020 100644 --- a/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h +++ b/third_party/blink/renderer/core/scroll/scroll_animator_compositor_coordinator.h
@@ -34,7 +34,6 @@ : public GarbageCollected<ScrollAnimatorCompositorCoordinator>, private CompositorAnimationClient, CompositorAnimationDelegate { - DISALLOW_COPY_AND_ASSIGN(ScrollAnimatorCompositorCoordinator); USING_PRE_FINALIZER(ScrollAnimatorCompositorCoordinator, Dispose); public: @@ -82,6 +81,10 @@ kRunningOnCompositorButNeedsAdjustment, }; + ScrollAnimatorCompositorCoordinator( + const ScrollAnimatorCompositorCoordinator&) = delete; + ScrollAnimatorCompositorCoordinator& operator=( + const ScrollAnimatorCompositorCoordinator&) = delete; ~ScrollAnimatorCompositorCoordinator() override; bool HasAnimationThatRequiresService() const;
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.h b/third_party/blink/renderer/core/scroll/scrollable_area.h index 1b1dbbe..578ad26 100644 --- a/third_party/blink/renderer/core/scroll/scrollable_area.h +++ b/third_party/blink/renderer/core/scroll/scrollable_area.h
@@ -74,12 +74,14 @@ }; class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin { - DISALLOW_COPY_AND_ASSIGN(ScrollableArea); USING_PRE_FINALIZER(ScrollableArea, Dispose); public: using ScrollCallback = base::OnceClosure; + ScrollableArea(const ScrollableArea&) = delete; + ScrollableArea& operator=(const ScrollableArea&) = delete; + static int PixelsPerLineStep(LocalFrame*); static float MinFractionToStepWhenPaging(); int MaxOverlapBetweenPages() const;
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h b/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h index dcdb884..2dcafc4 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h +++ b/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h
@@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_LAYER_DELEGATE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_LAYER_DELEGATE_H_ -#include "base/macros.h" #include "cc/input/scrollbar.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/heap/persistent.h" @@ -20,6 +19,8 @@ public: ScrollbarLayerDelegate(blink::Scrollbar& scrollbar, float device_scale_factor); + ScrollbarLayerDelegate(const ScrollbarLayerDelegate&) = delete; + ScrollbarLayerDelegate& operator=(const ScrollbarLayerDelegate&) = delete; // cc::Scrollbar implementation. bool IsSame(const cc::Scrollbar& other) const override; @@ -55,8 +56,6 @@ Persistent<blink::Scrollbar> scrollbar_; float device_scale_factor_; - - DISALLOW_COPY_AND_ASSIGN(ScrollbarLayerDelegate); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme.h b/third_party/blink/renderer/core/scroll/scrollbar_theme.h index 6bd154b..a2b5c91 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar_theme.h +++ b/third_party/blink/renderer/core/scroll/scrollbar_theme.h
@@ -39,11 +39,12 @@ class WebMouseEvent; class CORE_EXPORT ScrollbarTheme { - DISALLOW_COPY_AND_ASSIGN(ScrollbarTheme); USING_FAST_MALLOC(ScrollbarTheme); public: ScrollbarTheme() = default; + ScrollbarTheme(const ScrollbarTheme&) = delete; + ScrollbarTheme& operator=(const ScrollbarTheme&) = delete; virtual ~ScrollbarTheme() = default; // If true, then scrollbars with this theme will be painted every time
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image.cc b/third_party/blink/renderer/core/svg/graphics/svg_image.cc index 026eadc..432a109 100644 --- a/third_party/blink/renderer/core/svg/graphics/svg_image.cc +++ b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
@@ -410,7 +410,7 @@ PaintImage SVGImage::PaintImageForCurrentFrame() { auto builder = CreatePaintImageBuilder().set_completion_state(completion_state()); - PopulatePaintRecordForCurrentFrameForContainer(builder, NullURL(), Size()); + PopulatePaintRecordForCurrentFrameForContainer(builder, Size(), 1, NullURL()); return builder.TakePaintImage(); } @@ -489,16 +489,21 @@ void SVGImage::PopulatePaintRecordForCurrentFrameForContainer( PaintImageBuilder& builder, - const KURL& url, - const IntSize& container_size) { + const IntSize& zoomed_container_size, + float zoom, + const KURL& url) { if (!page_) return; - const IntRect container_rect(IntPoint(), container_size); + const IntRect container_rect(IntPoint(), zoomed_container_size); + // Compute a new container size based on the zoomed (and potentially + // rounded) size. + FloatSize container_size(zoomed_container_size); + container_size.Scale(1 / zoom); PaintRecorder recorder; cc::PaintCanvas* canvas = recorder.beginRecording(container_rect); - DrawForContainer(canvas, PaintFlags(), FloatSize(container_rect.Size()), 1, + DrawForContainer(canvas, PaintFlags(), container_size, zoom, FloatRect(container_rect), FloatRect(container_rect), url); builder.set_paint_record(recorder.finishRecordingAsPicture(), container_rect, PaintImage::GetNextContentId()); @@ -937,8 +942,9 @@ auto builder = CreatePaintImageBuilder().set_completion_state(completion_state()); - PopulatePaintRecordForCurrentFrameForContainer(builder, NullURL(), - scaled_size); + // TODO(fs): Pass |device_scale_factor| as zoom. + PopulatePaintRecordForCurrentFrameForContainer(builder, scaled_size, 1, + NullURL()); PaintImage paint_image = builder.TakePaintImage(); if (!paint_image)
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image.h b/third_party/blink/renderer/core/svg/graphics/svg_image.h index a888240..60b40ce 100644 --- a/third_party/blink/renderer/core/svg/graphics/svg_image.h +++ b/third_party/blink/renderer/core/svg/graphics/svg_image.h
@@ -181,8 +181,9 @@ const KURL&); void PopulatePaintRecordForCurrentFrameForContainer( PaintImageBuilder&, - const KURL&, - const IntSize& container_size); + const IntSize& container_size, + float zoom, + const KURL&); // Paints the current frame. Returns new PaintRecord. sk_sp<PaintRecord> PaintRecordForCurrentFrame(const KURL&);
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.cc b/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.cc index 6e70117..d50cda4 100644 --- a/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.cc +++ b/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.cc
@@ -72,7 +72,8 @@ PaintImage SVGImageForContainer::PaintImageForCurrentFrame() { auto builder = CreatePaintImageBuilder().set_completion_state( image_->completion_state()); - image_->PopulatePaintRecordForCurrentFrameForContainer(builder, url_, Size()); + image_->PopulatePaintRecordForCurrentFrameForContainer(builder, Size(), zoom_, + url_); return builder.TakePaintImage(); }
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h b/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h index 50b4eb6..c170dc07 100644 --- a/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h +++ b/third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h
@@ -26,6 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_GRAPHICS_SVG_IMAGE_FOR_CONTAINER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_GRAPHICS_SVG_IMAGE_FOR_CONTAINER_H_ +#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/svg/graphics/svg_image.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/float_size.h" @@ -54,7 +55,7 @@ // // SVGImageForContainer stores this per-use information and delegates to the // SVGImage for how to draw the image. -class SVGImageForContainer final : public Image { +class CORE_EXPORT SVGImageForContainer final : public Image { USING_FAST_MALLOC(SVGImageForContainer); public:
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc b/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc index 3b56dc1..8b710d9 100644 --- a/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc +++ b/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc
@@ -17,6 +17,7 @@ #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/svg/animation/smil_time_container.h" #include "third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h" +#include "third_party/blink/renderer/core/svg/graphics/svg_image_for_container.h" #include "third_party/blink/renderer/core/svg/svg_svg_element.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" #include "third_party/blink/renderer/core/testing/sim/sim_test.h" @@ -234,6 +235,27 @@ EXPECT_TRUE(time_container->EventsDisabled()); } +TEST_F(SVGImageTest, PaintFrameForCurrentFrameWithMQAndZoom) { + const bool kShouldPause = false; + Load(R"SVG( + <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'> + <style>@media(max-width:50px){rect{fill:blue}}</style> + <rect width='10' height='10' fill='red'/> + </svg>)SVG", + kShouldPause); + + scoped_refptr<SVGImageForContainer> container = SVGImageForContainer::Create( + &GetImage(), FloatSize(100, 100), 2, NullURL()); + SkBitmap bitmap = + container->AsSkBitmapForCurrentFrame(kDoNotRespectImageOrientation); + ASSERT_EQ(bitmap.width(), 100); + ASSERT_EQ(bitmap.height(), 100); + EXPECT_EQ(bitmap.getColor(10, 10), SK_ColorBLUE); + EXPECT_EQ(bitmap.getColor(90, 10), SK_ColorBLUE); + EXPECT_EQ(bitmap.getColor(10, 90), SK_ColorBLUE); + EXPECT_EQ(bitmap.getColor(90, 90), SK_ColorBLUE); +} + class SVGImageSimTest : public SimTest, private ScopedMockOverlayScrollbars {}; TEST_F(SVGImageSimTest, PageVisibilityHiddenToVisible) {
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index c452233..d9a2d51b 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -478,9 +478,11 @@ bool Internals::isLoading(const String& url) { if (!document_) return false; - const String cache_identifier = document_->Fetcher()->GetCacheIdentifier(); - Resource* resource = GetMemoryCache()->ResourceForURL( - document_->CompleteURL(url), cache_identifier); + const KURL full_url = document_->CompleteURL(url); + const String cache_identifier = + document_->Fetcher()->GetCacheIdentifier(full_url); + Resource* resource = + GetMemoryCache()->ResourceForURL(full_url, cache_identifier); // We check loader() here instead of isLoading(), because a multipart // ImageResource lies isLoading() == false after the first part is loaded. return resource && resource->Loader(); @@ -489,9 +491,11 @@ bool Internals::isLoadingFromMemoryCache(const String& url) { if (!document_) return false; - const String cache_identifier = document_->Fetcher()->GetCacheIdentifier(); - Resource* resource = GetMemoryCache()->ResourceForURL( - document_->CompleteURL(url), cache_identifier); + const KURL full_url = document_->CompleteURL(url); + const String cache_identifier = + document_->Fetcher()->GetCacheIdentifier(full_url); + Resource* resource = + GetMemoryCache()->ResourceForURL(full_url, cache_identifier); return resource && resource->GetStatus() == ResourceStatus::kCached; }
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc index 6a674327..bd1c1f6d 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
@@ -134,7 +134,7 @@ RegisterExtension(ext_texture_compression_bptc_); RegisterExtension(ext_texture_compression_rgtc_); RegisterExtension(ext_texture_filter_anisotropic_); - RegisterExtension(ext_texture_norm16_, kDraftExtension); + RegisterExtension(ext_texture_norm16_); RegisterExtension(khr_parallel_shader_compile_); RegisterExtension(oes_draw_buffers_indexed_, kDraftExtension); RegisterExtension(oes_texture_float_linear_);
diff --git a/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc b/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc index ecaddbf..93722cd 100644 --- a/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc +++ b/third_party/blink/renderer/platform/exported/video_capture/web_video_capture_impl_manager_test.cc
@@ -83,7 +83,9 @@ MOCK_METHOD1(RequestRefreshFrame, void(const base::UnguessableToken&)); MOCK_METHOD3(ReleaseBuffer, - void(const base::UnguessableToken&, int32_t, double)); + void(const base::UnguessableToken&, + int32_t, + const media::VideoFrameFeedback&)); void GetDeviceSupportedFormats(const base::UnguessableToken&, const base::UnguessableToken&,
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc index e5d25316..09a6580ee 100644 --- a/third_party/blink/renderer/platform/exported/web_url_request.cc +++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -499,12 +499,6 @@ break; } - if (!resource_request_->AllowStoredCredentials()) { - load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; - load_flags |= net::LOAD_DO_NOT_SEND_COOKIES; - load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA; - } - if (resource_request_->GetRequestContext() == blink::mojom::RequestContextType::PREFETCH) load_flags |= net::LOAD_PREFETCH;
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc index 0c816d50..507fcec 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc +++ b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.cc
@@ -110,6 +110,10 @@ const PaintImage& paint_image, const SkRect& src, const SkRect& dst) { + // Empty paint image cannot be classified. + if (!paint_image) + return DarkModeClassification::kDoNotApplyFilter; + DarkModeImageClassificationCache* cache = DarkModeImageClassificationCache::GetInstance(); PaintImage::Id image_id = paint_image.stable_id(); @@ -131,6 +135,8 @@ bool DarkModeImageClassifier::GetBitmap(const PaintImage& paint_image, const SkRect& src, SkBitmap* bitmap) { + DCHECK(paint_image); + if (!src.width() || !src.height()) return false;
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc index 709fb62..a83566d5 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc +++ b/third_party/blink/renderer/platform/graphics/dark_mode_image_classifier_test.cc
@@ -150,6 +150,14 @@ EXPECT_NEAR(0.0f, features.background_ratio, kEpsilon); } +TEST_F(DarkModeImageClassifierTest, InvalidImage) { + PaintImage paint_image; + SkRect src = SkRect::MakeWH(50, 50); + SkRect dst = SkRect::MakeWH(50, 50); + EXPECT_EQ(image_classifier()->Classify(paint_image, src, dst), + DarkModeClassification::kDoNotApplyFilter); +} + TEST_F(DarkModeImageClassifierTest, Caching) { PaintImage::Id image_id = PaintImage::GetNextId(); SkRect src1 = SkRect::MakeXYWH(0, 0, 50, 50);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index c404041..3d45eb90 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -706,7 +706,7 @@ if (!archive_ && factory.GetType() == ResourceType::kRaw) return nullptr; - const String cache_identifier = GetCacheIdentifier(); + const String cache_identifier = GetCacheIdentifier(url); // Most off-main-thread resource fetches use Resource::kRaw and don't reach // this point, but off-main-thread module fetches might. if (IsMainThread()) { @@ -1093,8 +1093,8 @@ // found, we may need to make it block the onload event. MakePreloadedResourceBlockOnloadIfNeeded(resource, params); } else if (IsMainThread()) { - resource = - GetMemoryCache()->ResourceForURL(params.Url(), GetCacheIdentifier()); + resource = GetMemoryCache()->ResourceForURL( + params.Url(), GetCacheIdentifier(params.Url())); if (resource) { policy = DetermineRevalidationPolicy(resource_type, params, *resource, is_static_data); @@ -1288,7 +1288,8 @@ Resource* ResourceFetcher::CreateResourceForLoading( const FetchParameters& params, const ResourceFactory& factory) { - const String cache_identifier = GetCacheIdentifier(); + const String cache_identifier = + GetCacheIdentifier(params.GetResourceRequest().Url()); DCHECK(!IsMainThread() || params.IsStaleRevalidation() || !GetMemoryCache()->ResourceForURL(params.GetResourceRequest().Url(), cache_identifier)); @@ -2119,13 +2120,19 @@ to_be_removed.clear(); } -String ResourceFetcher::GetCacheIdentifier() const { +String ResourceFetcher::GetCacheIdentifier(const KURL& url) const { if (properties_->GetControllerServiceWorkerMode() != mojom::ControllerServiceWorkerMode::kNoController) { return String::Number(properties_->ServiceWorkerId()); } if (properties_->WebBundlePhysicalUrl().IsValid()) return properties_->WebBundlePhysicalUrl().GetString(); + + for (auto& bundle : subresource_web_bundles_) { + if (bundle->CanHandleRequest(url)) + return bundle->GetCacheIdentifier(); + } + return MemoryCache::DefaultCacheIdentifier(); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h index daef9db..f166856 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -223,7 +223,7 @@ uint32_t inflight_keepalive_bytes); blink::mojom::ControllerServiceWorkerMode IsControlledByServiceWorker() const; - String GetCacheIdentifier() const; + String GetCacheIdentifier(const KURL& url) const; enum IsImageSet { kImageNotImageSet, kImageIsImageSet };
diff --git a/third_party/blink/renderer/platform/loader/fetch/subresource_web_bundle.h b/third_party/blink/renderer/platform/loader/fetch/subresource_web_bundle.h index 6079ec8..2971478b 100644 --- a/third_party/blink/renderer/platform/loader/fetch/subresource_web_bundle.h +++ b/third_party/blink/renderer/platform/loader/fetch/subresource_web_bundle.h
@@ -24,6 +24,7 @@ virtual bool CanHandleRequest(const KURL& url) const = 0; virtual mojo::PendingRemote<network::mojom::blink::URLLoaderFactory> GetURLLoaderFactory() = 0; + virtual String GetCacheIdentifier() const = 0; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc b/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc index 387062e..56c6086 100644 --- a/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc +++ b/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
@@ -505,7 +505,8 @@ if (!consume_buffer) { OnFrameDropped( media::VideoCaptureFrameDropReason::kVideoCaptureImplNotInStartedState); - GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer_id, -1.0); + GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer_id, + media::VideoFrameFeedback()); return; } @@ -656,12 +657,13 @@ if (!frame) { OnFrameDropped(media::VideoCaptureFrameDropReason:: kVideoCaptureImplFailedToWrapDataAsMediaVideoFrame); - GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer_id, -1.0); + GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer_id, + media::VideoFrameFeedback()); return; } frame->AddDestructionObserver(base::BindOnce( - &VideoCaptureImpl::DidFinishConsumingFrame, frame->metadata(), + &VideoCaptureImpl::DidFinishConsumingFrame, frame->feedback(), media::BindToCurrentLoop(base::BindOnce( &VideoCaptureImpl::OnAllClientsFinishedConsumingFrame, weak_factory_.GetWeakPtr(), buffer_id, std::move(buffer_context))))); @@ -692,7 +694,7 @@ void VideoCaptureImpl::OnAllClientsFinishedConsumingFrame( int buffer_id, scoped_refptr<BufferContext> buffer_context, - double consumer_resource_utilization) { + const media::VideoFrameFeedback feedback) { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); // Subtle race note: It's important that the |buffer_context| argument be @@ -714,8 +716,7 @@ buffer_context = nullptr; #endif - GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer_id, - consumer_resource_utilization); + GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer_id, feedback); } void VideoCaptureImpl::StopDevice() { @@ -796,12 +797,11 @@ // static void VideoCaptureImpl::DidFinishConsumingFrame( - const media::VideoFrameMetadata* metadata, + const media::VideoFrameFeedback* feedback, BufferFinishedCallback callback_to_io_thread) { // Note: This function may be called on any thread by the VideoFrame // destructor. |metadata| is still valid for read-access at this point. - std::move(callback_to_io_thread) - .Run(metadata->resource_utilization.value_or(-1.0)); + std::move(callback_to_io_thread).Run(*feedback); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/video_capture/video_capture_impl.h b/third_party/blink/renderer/platform/video_capture/video_capture_impl.h index 7bca6db..3562874 100644 --- a/third_party/blink/renderer/platform/video_capture/video_capture_impl.h +++ b/third_party/blink/renderer/platform/video_capture/video_capture_impl.h
@@ -105,7 +105,7 @@ using ClientInfoMap = std::map<int, ClientInfo>; using BufferFinishedCallback = - base::OnceCallback<void(double consumer_resource_utilization)>; + base::OnceCallback<void(media::VideoFrameFeedback feedback)>; void OnVideoFrameReady(int32_t buffer_id, base::TimeTicks reference_time, @@ -116,7 +116,7 @@ void OnAllClientsFinishedConsumingFrame( int buffer_id, scoped_refptr<BufferContext> buffer_context, - double consumer_resource_utilization); + media::VideoFrameFeedback feedback); void StopDevice(); void RestartCapture(); @@ -140,7 +140,7 @@ // RESOURCE_UTILIZATION value from the |metadata| and then runs the given // callback, to trampoline back to the IO thread with the values. static void DidFinishConsumingFrame( - const media::VideoFrameMetadata* metadata, + const media::VideoFrameFeedback* feedback, BufferFinishedCallback callback_to_io_thread); // |device_id_| and |session_id_| are different concepts, but we reuse the
diff --git a/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc b/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc index d261dcb..c425dfa 100644 --- a/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc +++ b/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc
@@ -74,7 +74,9 @@ const media::VideoCaptureParams&)); MOCK_METHOD1(RequestRefreshFrame, void(const base::UnguessableToken&)); MOCK_METHOD3(ReleaseBuffer, - void(const base::UnguessableToken&, int32_t, double)); + void(const base::UnguessableToken&, + int32_t, + const media::VideoFrameFeedback&)); MOCK_METHOD3(GetDeviceSupportedFormatsMock, void(const base::UnguessableToken&, const base::UnguessableToken&,
diff --git a/third_party/blink/renderer/platform/wtf/casting.h b/third_party/blink/renderer/platform/wtf/casting.h index ee2873f..c465ed5 100644 --- a/third_party/blink/renderer/platform/wtf/casting.h +++ b/third_party/blink/renderer/platform/wtf/casting.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_CASTING_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_CASTING_H_ +#include "base/notreached.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" namespace blink { @@ -57,6 +58,8 @@ template <typename U> static bool AllowFrom(const U&) { static_assert(sizeof(U) == 0, "no downcast traits specialization for T"); + NOTREACHED(); + return false; } };
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index aadc708..fac130f8c 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3069,9 +3069,6 @@ virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-operations.https.html [ Pass ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-restartIce-onnegotiationneeded.https.html [ Pass ] -# Tests that start hanging after implementing RTCRtpTransceiver.stop -crbug.com/1115087 external/wpt/webrtc/RTCRtpTransceiver.https.html [ Timeout ] - # See also crbug.com/920100 (sheriff 2019-01-09). crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/external-stylesheet.html [ Timeout Failure ] crbug.com/626703 external/wpt/referrer-policy/css-integration/svg/inline-style.html [ Timeout Failure ] @@ -5209,6 +5206,7 @@ crbug.com/829952 fast/webgl/texImage-imageBitmap-from-image-resize.html [ Pass Timeout ] # Sheriff 2018-04-13 +crbug.com/833655 [ Linux ] media/controls/closed-captions-dynamic-update.html [ Skip ] crbug.com/833658 [ Linux ] media/video-controls-focus-movement-on-hide.html [ Pass Failure ] crbug.com/833658 [ Win ] media/video-controls-focus-movement-on-hide.html [ Pass Failure ] crbug.com/833658 [ Mac ] media/video-controls-focus-movement-on-hide.html [ Pass Failure ] @@ -6709,3 +6707,6 @@ crbug.com/1120330 virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-disabled-scrollbar-tentative.html [ Pass Failure ] crbug.com/1119676 external/wpt/html/cross-origin-embedder-policy/reporting-to-endpoint.https.html [ Failure ] + +# Sheriff 2020-08-25 +crbug.com/1121429 fast/selectors/placeholder-shown-style-update.html [ Pass Crash ]
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 23a5f1a..0bd04ae3 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
@@ -203433,6 +203433,30 @@ ] } }, + "font-access": { + "OWNERS": [ + "2adf71cfa8c45ac70ca23dd86e57912b2942777c", + [] + ], + "README.md": [ + "f0d654ed398412143fdab5302509988f50e816e8", + [] + ], + "resources": { + "test-expectations.js": [ + "2b35507db2c4bf629686ea08cf8222040176c431", + [] + ], + "window-tests-blob.js": [ + "0d6db5399118372da9ca783eeb2551e435ea85d7", + [] + ], + "window-tests-enumeration.js": [ + "15455f0b4b62e4ae5e4cc3fcdff70b7e4b7ec253", + [] + ] + } + }, "fonts": { "AD.woff": [ "3df8ea8efdabd11bc45fdcc6d4f3fec771be6650", @@ -237205,7 +237229,7 @@ [] ], "testloader.py": [ - "af1b00725dc43ba6e864bec8f8c837923c8da38d", + "4a3fa4273654a8a86d5224ef6b0a9daed73b01d7", [] ], "testrunner.py": [ @@ -237321,7 +237345,7 @@ } }, "wptrunner.py": [ - "f033205a00b88a6ab2521c5e1e6df51095cf4801", + "897b4a9f815486d9e651de9ddd3cfae7d7872949", [] ], "wpttest.py": [ @@ -240117,7 +240141,7 @@ [] ], "RTCPeerConnection-helper.js": [ - "2d91e5f583715d5aca5efdf4e704db70b02fbfc9", + "54aaa010d809019a4a3c5d6f7435d982f6ad9cd5", [] ], "RTCPeerConnection-mandatory-getStats.https-expected.txt": [ @@ -316757,6 +316781,60 @@ ] ] }, + "font-access": { + "font_access-blob.tentative.https.window.js": [ + "ff90075c966932f8a5be8bf0cf109934f37f6837", + [ + "font-access/font_access-blob.tentative.https.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testdriver.js" + ], + [ + "script", + "/resources/testdriver-vendor.js" + ], + [ + "script", + "resources/test-expectations.js" + ], + [ + "script", + "resources/window-tests-blob.js" + ] + ] + } + ] + ], + "font_access-enumeration.tentative.https.window.js": [ + "677fe82c70233de2e1cbeab4beb41437319688b3", + [ + "font-access/font_access-enumeration.tentative.https.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testdriver.js" + ], + [ + "script", + "/resources/testdriver-vendor.js" + ], + [ + "script", + "resources/test-expectations.js" + ], + [ + "script", + "resources/window-tests-enumeration.js" + ] + ] + } + ] + ] + }, "forced-colors-mode": { "forced-colors-mode-03.html": [ "ebe42e4e7502a327849fe2c65924480e00de4399", @@ -403864,7 +403942,7 @@ ] ], "video-decoder.html": [ - "1d98f89f669ddce50841eae3c99ed8102dd9799f", + "79f6256e77dd6c5514b25876f1596ea339964cdc", [ null, {} @@ -405387,7 +405465,7 @@ ] ], "RTCPeerConnection-videoDetectorTest.html": [ - "71fffdc68603465b22b32da738ab5fedab378f41", + "6786bd49ede68eaa075fdb2d127d4074e5e90035", [ null, {
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro.https.html new file mode 100644 index 0000000..c349b9a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/access-to-coop-page-from-other_coop-ro.https.html
@@ -0,0 +1,75 @@ +<title> + One window accesses a second one. They are aren't related by an opener/openee + relationship. The second window has set + Cross-Origin-Opener-Policy-Report-Only:same-origin, so it receives a + "access-to-coop-page-from-other" report. +</title> +<meta name=timeout content=long> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src=/common/get-host-info.sub.js></script> +<script src="/common/utils.js"></script> +<script src="../resources/dispatcher.js"></script> +<script src="../resources/try-access.js"></script> +<script> + +const directory = "/html/cross-origin-opener-policy/reporting"; +const executor_path = directory + "/resources/executor.html?pipe="; +const same_origin = get_host_info().HTTPS_ORIGIN; +const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)'; + +promise_test(async t => { + // The test window. + const this_window_token = token(); + + // The "opener" window. + const opener_token = token(); + const opener_url = same_origin + executor_path + `&uuid=${opener_token}`; + + // The "openee" window. With COOP:same-origin + reporter. + const openee_report_token= token(); + const openee_token = token(); + const openee_reportTo = reportToHeaders(openee_report_token); + const openee_url = same_origin + executor_path + openee_reportTo.header + + openee_reportTo.coopReportOnlySameOriginHeader + coep_header + + `&uuid=${openee_token}`; + + // The "other" window. + const other_token = token(); + const other_url = same_origin + executor_path + `&uuid=${other_token}`; + + t.add_cleanup(() => { + send(opener_token, "window.close()") + send(openee_token, "window.close()") + send(other_token, "window.close()") + }) + + // 1. Create the opener window. + let opener_window_proxy = window.open(opener_url); + + // 2. The opener opens its openee and the other window. + send(opener_token, ` + window.openee = window.open('${openee_url.replace(/,/g, '\\,')}'); + window.other = window.open('${other_url}'); + `); + + // 3. Make sure the openee is loaded. + send(openee_token, `send("${this_window_token}", "Loaded");`); + assert_equals(await receive(this_window_token), "Loaded"); + + // 4. The "other" window attempts to access the openee though the opener. + send(other_token, `tryAccess(opener.openee);`); + + // 4. Check a report sent to the openee. + let report = + await receiveReport(openee_report_token, "access-to-coop-page-from-other") + assert_not_equals(report, "timeout", "Report not received"); + assert_equals(report.type, "coop"); + assert_equals(report.url, openee_url.replace(/"/g, '%22')); + assert_equals(report.body.disposition, "reporting"); + assert_equals(report.body.effectivePolicy, "same-origin-plus-coep"); + assert_equals(report.body.property, "blur"); + assert_source_location_missing(report); +}, "access-to-coop-page-from-other (COOP-RO)"); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/testloader.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/testloader.py index af1b007..4a3fa42 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/testloader.py +++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/testloader.py
@@ -208,6 +208,7 @@ total_chunks=1, chunk_number=1, include_https=True, + include_h2=True, include_quic=False, skip_timeout=False, skip_implementation_status=None, @@ -222,6 +223,7 @@ self.tests = None self.disabled_tests = None self.include_https = include_https + self.include_h2 = include_h2 self.include_quic = include_quic self.skip_timeout = skip_timeout self.skip_implementation_status = skip_implementation_status @@ -309,6 +311,8 @@ enabled = not test.disabled() if not self.include_https and test.environment["protocol"] == "https": enabled = False + if not self.include_h2 and test.environment["protocol"] == "h2": + enabled = False if not self.include_quic and test.environment["quic"]: enabled = False if self.skip_timeout and test.expected() == "TIMEOUT":
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptrunner.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptrunner.py index f033205..897b4a9 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptrunner.py +++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/wptrunner.py
@@ -5,6 +5,7 @@ import sys from six import iteritems, itervalues +import wptserve from wptserve import sslutils from . import environment as env @@ -75,6 +76,7 @@ explicit=kwargs["default_exclude"])) ssl_enabled = sslutils.get_cls(kwargs["ssl_type"]).ssl_enabled + h2_enabled = wptserve.utils.http2_compatible() test_loader = testloader.TestLoader(test_manifests, kwargs["test_types"], run_info, @@ -83,6 +85,7 @@ total_chunks=kwargs["total_chunks"], chunk_number=kwargs["this_chunk"], include_https=ssl_enabled, + include_h2=h2_enabled, include_quic=kwargs["enable_quic"], skip_timeout=kwargs["skip_timeout"], skip_implementation_status=kwargs["skip_implementation_status"],
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/dynamic/classic_script.js b/third_party/blink/web_tests/external/wpt/web-bundle/resources/dynamic/classic_script.js new file mode 100644 index 0000000..db69b96 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/dynamic/classic_script.js
@@ -0,0 +1 @@ +window.report_result('classic script from network');
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/dynamic1/classic_script.js b/third_party/blink/web_tests/external/wpt/web-bundle/resources/dynamic1/classic_script.js new file mode 100644 index 0000000..5fcf045 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/dynamic1/classic_script.js
@@ -0,0 +1 @@ +window.report_result('classic script from dynamic1.wbn');
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/dynamic2/classic_script.js b/third_party/blink/web_tests/external/wpt/web-bundle/resources/dynamic2/classic_script.js new file mode 100644 index 0000000..546d8a50 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/dynamic2/classic_script.js
@@ -0,0 +1 @@ +window.report_result('classic script from dynamic2.wbn');
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-crossorigin.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-crossorigin.wbn index a35e12aa..5ebb861 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-crossorigin.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1-crossorigin.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1.wbn index 22db19e7..9e69e1fd 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic1.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic2.wbn b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic2.wbn index 44c4b1e..e4d04d6 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic2.wbn +++ b/third_party/blink/web_tests/external/wpt/web-bundle/resources/wbn/dynamic2.wbn Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/web-bundle/subresource-loading/subresource-loading-from-web-bundle.tentative.html b/third_party/blink/web_tests/external/wpt/web-bundle/subresource-loading/subresource-loading-from-web-bundle.tentative.html index 3ab6d7a..1e0e78a3 100644 --- a/third_party/blink/web_tests/external/wpt/web-bundle/subresource-loading/subresource-loading-from-web-bundle.tentative.html +++ b/third_party/blink/web_tests/external/wpt/web-bundle/subresource-loading/subresource-loading-from-web-bundle.tentative.html
@@ -38,8 +38,37 @@ document.body.removeChild(link); const module4 = await import('http://web-platform.test:8001/web-bundle/resources/dynamic/resource4.js'); assert_equals(module4.result, 'resource4 from network'); + + // Module scripts are stored to the Document's module map once loaded. + // So import()ing the same module script will reuse the previously loaded + // script. + const module_second = await import('http://web-platform.test:8001/web-bundle/resources/dynamic/resource1.js'); + assert_equals(module_second.result, 'resource1 from dynamic1.wbn'); }, 'Dynamically adding / updating / removing "<link rel=webbundle>"'); + promise_test(async () => { + const classic_script_url = 'http://web-platform.test:8001/web-bundle/resources/dynamic/classic_script.js'; + const link = document.createElement("link"); + link.rel = "webbundle"; + link.href = "../resources/wbn/dynamic1.wbn"; + link.resources.add(classic_script_url); + document.body.appendChild(link); + assert_equals( + await loadScriptAndWaitReport(classic_script_url), + 'classic script from dynamic1.wbn'); + link.href = "../resources/wbn/dynamic2.wbn"; + // Loading the classic script should not reuse the previously loaded + // script. So in this case, the script must be loaded from dynamic2.wbn. + assert_equals( + await loadScriptAndWaitReport(classic_script_url), + 'classic script from dynamic2.wbn'); + document.body.removeChild(link); + // And in this case, the script must be loaded from network. + assert_equals( + await loadScriptAndWaitReport(classic_script_url), + 'classic script from network'); + }, 'Dynamically loading classic script from web bundle'); + promise_test(() => { return addLinkAndWaitForLoad("../resources/wbn/dynamic1.wbn?test-event"); }, '<link rel="webbundle"> fires a load event on load success'); @@ -89,5 +118,17 @@ document.body.appendChild(link); }); } + + async function loadScriptAndWaitReport(script_url) { + const result_promise = new Promise((resolve) => { + // This function will be called from script.js + window.report_result = resolve; + }); + + const script = document.createElement('script'); + script.src = script_url; + document.body.appendChild(script); + return result_promise; + } </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-helper.js b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-helper.js index 2d91e5f..54aaa01 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-helper.js +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-helper.js
@@ -398,7 +398,7 @@ return dst.stream.getAudioTracks()[0]; }, - video({width = 640, height = 480, signal = null} = {}) { + video({width = 640, height = 480, signal} = {}) { const canvas = Object.assign( document.createElement("canvas"), {width, height} ); @@ -406,15 +406,17 @@ const stream = canvas.captureStream(); let count = 0; - setInterval(() => { + const interval = setInterval(() => { ctx.fillStyle = `rgb(${count%255}, ${count*count%255}, ${count%255})`; count += 1; ctx.fillRect(0, 0, width, height); - // If signal is set, add a constant-color box to the video frame - // at coordinates 10 to 30 in both X and Y direction. - if (signal !== null) { + // If signal is set (0-255), add a constant-color box of that luminance to + // the video frame at coordinates 20 to 60 in both X and Y direction. + // (big enough to avoid color bleed from surrounding video in some codecs, + // for more stable tests). + if (signal != undefined) { ctx.fillStyle = `rgb(${signal}, ${signal}, ${signal})`; - ctx.fillRect(10, 10, 20, 20); + ctx.fillRect(20, 20, 40, 40); } }, 100); @@ -423,25 +425,34 @@ } else { document.addEventListener('DOMContentLoaded', () => { document.body.appendChild(canvas); - }); + }, {once: true}); } - return stream.getVideoTracks()[0]; + // Implement track.stop() for performance in some tests on some platforms + const track = stream.getVideoTracks()[0]; + const nativeStop = track.stop; + track.stop = function stop() { + clearInterval(interval); + nativeStop.apply(this); + if (document.body && canvas.parentElement == document.body) { + document.body.removeChild(canvas); + } + }; + return track; } }; // Get the signal from a video element inserted by createNoiseStream function getVideoSignal(v) { - if (v.videoWidth < 21 || v.videoHeight < 21) { - return null; + if (v.videoWidth < 60 || v.videoHeight < 60) { + throw new Error('getVideoSignal: video too small for test'); } const canvas = document.createElement("canvas"); - canvas.width = v.videoWidth; - canvas.height = v.videoHeight; + canvas.width = canvas.height = 60; const context = canvas.getContext('2d'); - context.drawImage(v, 0, 0, v.videoWidth, v.videoHeight); - // Extract pixel value at position 20, 20 - const pixel = context.getImageData(20, 20, 1, 1); + context.drawImage(v, 0, 0); + // Extract pixel value at position 40, 40 + const pixel = context.getImageData(40, 40, 1, 1); // Use luma reconstruction to get back original value according to // ITU-R rec BT.709 return (pixel.data[0] * 0.21 + pixel.data[1] * 0.72 + pixel.data[2] * 0.07); @@ -449,8 +460,9 @@ async function detectSignal(t, v, value) { while (true) { - const signal = getVideoSignal(v); - if (signal !== null && signal < value + 1 && signal > value - 1) { + const signal = getVideoSignal(v).toFixed(); + // allow off-by-two pixel error (observed in some implementations) + if (value - 2 <= signal && signal <= value + 2) { return; } // We would like to wait for each new frame instead here,
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-videoDetectorTest.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-videoDetectorTest.html index 71fffdc..6786bd49 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-videoDetectorTest.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-videoDetectorTest.html
@@ -22,38 +22,38 @@ // the test times out. async function signalSettlementTime(t, v, sender, signal, backgroundTrack) { - const detectionStream = await getNoiseStream({video: {signal: signal}}); + const detectionStream = await getNoiseStream({video: {signal}}); const [detectionTrack] = detectionStream.getTracks(); - await sender.replaceTrack(detectionTrack); - const framesBefore = v.getVideoPlaybackQuality().totalVideoFrames; - await detectSignal(t, v, signal); - const framesAfter = v.getVideoPlaybackQuality().totalVideoFrames; - await sender.replaceTrack(backgroundTrack); - await detectSignal(t, v, 100); - detectionStream.getTracks().forEach(track => track.stop()); - return (framesAfter - framesBefore); + try { + await sender.replaceTrack(detectionTrack); + const framesBefore = v.getVideoPlaybackQuality().totalVideoFrames; + await detectSignal(t, v, signal); + const framesAfter = v.getVideoPlaybackQuality().totalVideoFrames; + await sender.replaceTrack(backgroundTrack); + await detectSignal(t, v, 100); + return framesAfter - framesBefore; + } finally { + detectionTrack.stop(); + } } promise_test(async t => { const v = document.createElement('video'); v.autoplay = true; const pc1 = new RTCPeerConnection(); - t.add_cleanup(() => pc1.close()); const pc2 = new RTCPeerConnection(); + t.add_cleanup(() => pc1.close()); t.add_cleanup(() => pc2.close()); const stream1 = await getNoiseStream({video: {signal: 100}}); - t.add_cleanup(() => stream1.getTracks().forEach(track => track.stop())); const [track1] = stream1.getTracks(); + t.add_cleanup(() => track1.stop()); + const sender = pc1.addTrack(track1); - pc2.ontrack = t.step_func((e) => { - v.srcObject = new MediaStream([e.track]); - }); - const metadataToBeLoaded = new Promise((resolve) => { - v.addEventListener('loadedmetadata', resolve); - }); + const haveTrackEvent = new Promise(r => pc2.ontrack = r); exchangeIceCandidates(pc1, pc2); - exchangeOfferAnswer(pc1, pc2); - await metadataToBeLoaded; + await exchangeOfferAnswer(pc1, pc2); + v.srcObject = new MediaStream([(await haveTrackEvent).track]); + await new Promise(r => v.onloadedmetadata = r); // The basic signal is a track with signal 100. We replace this // with tracks with signal from 0 to 255 and see if they are all // reliably detected.
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt index b0e1b21..71f96185 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt
@@ -23,19 +23,19 @@ PASS checkAddTrackExistingTransceiverThenRemove FAIL checkRemoveTrackNegotiation assert_equals: pc2.setRemoteDescription(offer) should've added 2 tracks to receive stream expected 2 but got 0 FAIL checkMute assert_true: expected true got false -FAIL checkStop promise_test: Unhandled rejection with value: object "TypeError: stoppedTransceiver.stop is not a function" -FAIL checkStopAfterCreateOffer promise_test: Unhandled rejection with value: object "TypeError: pc1.getTransceivers(...)[0].stop is not a function" -FAIL checkStopAfterSetLocalOffer promise_test: Unhandled rejection with value: object "TypeError: pc1.getTransceivers(...)[0].stop is not a function" -FAIL checkStopAfterSetRemoteOffer promise_test: Unhandled rejection with value: object "TypeError: pc2.getTransceivers(...)[0].stop is not a function" -FAIL checkStopAfterCreateAnswer promise_test: Unhandled rejection with value: object "TypeError: pc2.getTransceivers(...)[0].stop is not a function" -FAIL checkStopAfterSetLocalAnswer promise_test: Unhandled rejection with value: object "TypeError: pc2.getTransceivers(...)[0].stop is not a function" -FAIL checkStopAfterClose assert_equals: Stopping a transceiver on a closed PC should throw. throws InvalidStateError expected "InvalidStateError" but got "TypeError" -FAIL checkLocalRollback promise_test: Unhandled rejection with value: object "TypeError: pc.getTransceivers(...)[0].stop is not a function" +FAIL checkStop assert_equals: getReceivers does not expose a receiver of a stopped transceiver expected 0 but got 1 +FAIL checkStopAfterCreateOffer assert_equals: expected "[{stopped:true}]" but got "[{stopped:false}]" +FAIL checkStopAfterSetLocalOffer assert_equals: expected "[{stopped:true}]" but got "[{stopped:false}]" +FAIL checkStopAfterSetRemoteOffer assert_equals: expected "[{mid:null,stopped:true}]" but got "[{mid:\"0\",stopped:false}]" +FAIL checkStopAfterCreateAnswer assert_equals: expected "[{mid:null,stopped:true}]" but got "[{mid:\"0\",stopped:false}]" +FAIL checkStopAfterSetLocalAnswer assert_equals: expected "[{mid:null,stopped:true}]" but got "[{mid:\"0\",stopped:false}]" +PASS checkStopAfterClose +FAIL checkLocalRollback assert_equals: expected "[{stopped:true}]" but got "[{stopped:false}]" PASS checkRollbackAndSetRemoteOfferWithDifferentType FAIL checkRemoteRollback assert_equals: expected "{currentDirection:null,mid:null,stopped:true}" but got "{currentDirection:null,mid:null,stopped:false}" -FAIL checkMsectionReuse promise_test: Unhandled rejection with value: object "TypeError: pc2.getTransceivers(...)[0].stop is not a function" -FAIL checkStopAfterCreateOfferWithReusedMsection promise_test: Unhandled rejection with value: object "TypeError: pc1.getTransceivers(...)[1].stop is not a function" -FAIL checkAddIceCandidateToStoppedTransceiver promise_test: Unhandled rejection with value: object "TypeError: pc1.getTransceivers(...)[1].stop is not a function" -FAIL checkBundleTagRejected promise_test: Unhandled rejection with value: object "TypeError: pc2.getTransceivers(...)[0].stop is not a function" +FAIL checkMsectionReuse assert_equals: expected "[{currentDirection:null,mid:null,stopped:true}]" but got "[{currentDirection:\"inactive\",mid:\"0\",stopped:false}]" +PASS checkStopAfterCreateOfferWithReusedMsection +PASS checkAddIceCandidateToStoppedTransceiver +FAIL checkBundleTagRejected promise_test: Unhandled rejection with value: object "InvalidAccessError: Failed to execute 'setRemoteDescription' on 'RTCPeerConnection': Failed to set remote offer sdp: The m= section with mid='1' should be rejected." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html index 4877749..45c8664 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpTransceiver.https.html
@@ -1536,9 +1536,11 @@ ]); trickle(t, pc2, pc1); + // The negotiaionneeded event is fired during processing of + // setLocalDescription() + const negotiationNeededWaiter = negotiationNeeded(pc2); await pc2.setLocalDescription(answer); - - await negotiationNeeded(pc2); + await negotiationNeededWaiter; await iceConnected(pc1); await iceConnected(pc2);
diff --git a/third_party/blink/web_tests/external/wpt/webstorage/set.window.js b/third_party/blink/web_tests/external/wpt/webstorage/set.window.js index 228ce60..1c20907 100644 --- a/third_party/blink/web_tests/external/wpt/webstorage/set.window.js +++ b/third_party/blink/web_tests/external/wpt/webstorage/set.window.js
@@ -43,7 +43,7 @@ assert_equals(storage[key], proto); assert_equals(storage.getItem(key), null); assert_equals(storage[key] = value, value); - // Hidden because no [OverrideBuiltins]. + // Hidden because no [LegacyOverrideBuiltins]. assert_equals(storage[key], proto); assert_equals(Object.getOwnPropertyDescriptor(storage, key), undefined); assert_equals(storage.getItem(key), value); @@ -62,7 +62,7 @@ storage.setItem(key, existing); - // Hidden because no [OverrideBuiltins]. + // Hidden because no [LegacyOverrideBuiltins]. assert_equals(storage[key], proto); assert_equals(Object.getOwnPropertyDescriptor(storage, key), undefined); assert_equals(storage.getItem(key), existing); @@ -93,7 +93,7 @@ assert_equals(storage[key], proto); assert_equals(storage.getItem(key), null); assert_equals(storage[key] = value, value); - // Property is hidden because no [OverrideBuiltins]. + // Property is hidden because no [LegacyOverrideBuiltins]. assert_equals(storage[key], proto); assert_equals(Object.getOwnPropertyDescriptor(storage, key), undefined); assert_equals(storage.getItem(key), value);
diff --git a/third_party/blink/web_tests/fast/css/outline-auto-location.html b/third_party/blink/web_tests/fast/css/outline-auto-location.html index 10da846..8271a89 100644 --- a/third_party/blink/web_tests/fast/css/outline-auto-location.html +++ b/third_party/blink/web_tests/fast/css/outline-auto-location.html
@@ -1,4 +1,15 @@ <html> +<style> +.test3 { + outline: auto 3px #1f5ccf; + background-color: lightblue; + margin: 20px; + font-size: 30px; + line-height: 16px; + height: 16px; + width: fit-content; +} +</style> <body> <div style="outline:solid 3px #1f5ccf; background-color: lightblue; margin: 20px"> <p>There should be one outline around the whole div</p> @@ -8,5 +19,7 @@ <p>There should be one outline around the whole div</p> <p style="margin-left: -20px">Not around each element</p> </div> + + <div class="test3">Auto outline should be taller than the div height.</div> </body> </html>
diff --git a/third_party/blink/web_tests/fast/forms/search/search-appearance-basic.html b/third_party/blink/web_tests/fast/forms/color-scheme/search/search-appearance-basic.html similarity index 97% rename from third_party/blink/web_tests/fast/forms/search/search-appearance-basic.html rename to third_party/blink/web_tests/fast/forms/color-scheme/search/search-appearance-basic.html index 4dba7f19..2c43984 100644 --- a/third_party/blink/web_tests/fast/forms/search/search-appearance-basic.html +++ b/third_party/blink/web_tests/fast/forms/color-scheme/search/search-appearance-basic.html
@@ -1,4 +1,5 @@ <!DOCTYPE html> +<meta name='color-scheme' content="light dark"> <body> <style> input {
diff --git a/third_party/blink/web_tests/fast/forms/color-scheme/search/search-cancel-button-clicked.html b/third_party/blink/web_tests/fast/forms/color-scheme/search/search-cancel-button-clicked.html new file mode 100644 index 0000000..c2a16b3 --- /dev/null +++ b/third_party/blink/web_tests/fast/forms/color-scheme/search/search-cancel-button-clicked.html
@@ -0,0 +1,18 @@ +<html> + <head> + <meta name="color-scheme" content="light dark"> + <script> + function drag() + { + var search = document.getElementById('search'); + var x = search.offsetLeft + search.offsetWidth - 6; + var y = search.offsetTop + search.offsetHeight / 2; + eventSender.mouseMoveTo(x, y); + eventSender.mouseDown(); + } + </script> + </head> + <body onload="drag()"> + <input id="search" type="search" value="foo"> + </body> +</html>
diff --git a/third_party/blink/web_tests/fast/forms/file/file-display-expected.html b/third_party/blink/web_tests/fast/forms/file/file-display-expected.html index f4d9d54..5ac2f30 100644 --- a/third_party/blink/web_tests/fast/forms/file/file-display-expected.html +++ b/third_party/blink/web_tests/fast/forms/file/file-display-expected.html
@@ -1,12 +1,12 @@ <!DOCTYPE html> <body> -<div>Flex <input type=file style="display:block"></div> -<div>Inline-flex <input type=file style="display:inline-block"></div> -<div>Grid <input type=file style="display:block"></div> -<div>Inline-grid <input type=file style="display:inline-block"></div> -<div>Table <input type=file style="display:block"></div> -<div>Inline-table <input type=file style="display:inline-block"></div> -<div>Block <input type=file style="display:block"></div> -<div>Inline <input type=file style="display:inline-block"></div> +<div>Flex <input type=file style="display:block">flex</div> +<div>Inline-flex <input type=file style="display:inline-block">inline-flex</div> +<div>Grid <input type=file style="display:block">grid</div> +<div>Inline-grid <input type=file style="display:inline-block">inline-grid</div> +<div>Table <input type=file style="display:block">table</div> +<div>Inline-table <input type=file style="display:inline-block">inline-table</div> +<div>Block <input type=file style="display:block">block</div> +<div>Inline <input type=file style="display:inline-block">inline</div> </body>
diff --git a/third_party/blink/web_tests/fast/forms/file/file-display.html b/third_party/blink/web_tests/fast/forms/file/file-display.html index 798aa4f..135cbb9 100644 --- a/third_party/blink/web_tests/fast/forms/file/file-display.html +++ b/third_party/blink/web_tests/fast/forms/file/file-display.html
@@ -9,4 +9,10 @@ <div>Inline-table <input type=file style="display:inline-table"></div> <div>Block <input type=file style="display:block"></div> <div>Inline <input type=file style="display:inline"></div> +<script> +for (let input of document.querySelectorAll('input')) { + let text = document.createTextNode(getComputedStyle(input).display); + input.parentNode.insertBefore(text, input.nextSibling); +} +</script> </body>
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png new file mode 100644 index 0000000..987052d --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/loading/wbn/wbn-subresource-origin-trial.https.html b/third_party/blink/web_tests/http/tests/loading/wbn/wbn-subresource-origin-trial.https.html index 83d5c1f5..a10a736 100644 --- a/third_party/blink/web_tests/http/tests/loading/wbn/wbn-subresource-origin-trial.https.html +++ b/third_party/blink/web_tests/http/tests/loading/wbn/wbn-subresource-origin-trial.https.html
@@ -37,19 +37,29 @@ assert_true(window.internals.isUseCounted(document, SubresourceWebBundles)); - const result_promise = new Promise((resolve) => { - // This function will be called from script.js - window.report_result = resolve; - }); + async function loadScriptAndWaitReport(script_url) { + const result_promise = new Promise((resolve) => { + // This function will be called from script.js + window.report_result = resolve; + }); - const script = document.createElement('script'); - script.src = script_url; - document.body.appendChild(script); + const script = document.createElement('script'); + script.src = script_url; + document.body.appendChild(script); + return result_promise; + } assert_equals( - await result_promise, + await loadScriptAndWaitReport(script_url), 'from web bundle', 'Script should be loaded from the web bundle.'); + document.body.removeChild(link); + + assert_equals( + await loadScriptAndWaitReport(script_url), + 'from server', + 'Script should be loaded from the server after removing the link ' + + 'rel=webbundle.'); }, 'Subresource Web Bundles Origin Trial'); </script> </body>
diff --git a/third_party/blink/web_tests/platform/linux/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png b/third_party/blink/web_tests/platform/linux/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png index 987052d..9e38f797 100644 --- a/third_party/blink/web_tests/platform/linux/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png +++ b/third_party/blink/web_tests/platform/linux/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/css/outline-auto-location-expected.png b/third_party/blink/web_tests/platform/linux/fast/css/outline-auto-location-expected.png index aeb0a15..7ccc834 100644 --- a/third_party/blink/web_tests/platform/linux/fast/css/outline-auto-location-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/css/outline-auto-location-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/search/search-appearance-basic-expected.png index 63cc8733..b32cd91 100644 --- a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/search/search-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..9c2c561 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png index 63cc8733..6e5ebf0 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..46a1a8a --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..d30a97e --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..4618fc2 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..feaa055 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..96f44f41 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..1a230da --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..4c219c94 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..feaa055 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..96f44f41 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..1a230da --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..4c219c94 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.14/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..feaa055 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.14/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/mac-mac10.14/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..96f44f41 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.14/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac-mac10.14/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..1a230da --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.14/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/mac-mac10.14/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..4c219c94 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.14/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png b/third_party/blink/web_tests/platform/mac/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png index 38731ec8..0fbc1ca 100644 --- a/third_party/blink/web_tests/platform/mac/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png +++ b/third_party/blink/web_tests/platform/mac/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/css/outline-auto-location-expected.png b/third_party/blink/web_tests/platform/mac/fast/css/outline-auto-location-expected.png index 19af56f..0a7421e2 100644 --- a/third_party/blink/web_tests/platform/mac/fast/css/outline-auto-location-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/css/outline-auto-location-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/search/search-appearance-basic-expected.png index 8a7b901..feaa055 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/search/search-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..96f44f41 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..feaa055 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..96f44f41 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..1a230da --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..4c219c94 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png b/third_party/blink/web_tests/platform/win/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png index 8f4039b..fd6bfa7a9 100644 --- a/third_party/blink/web_tests/platform/win/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png +++ b/third_party/blink/web_tests/platform/win/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/css/outline-auto-location-expected.png b/third_party/blink/web_tests/platform/win/fast/css/outline-auto-location-expected.png index 7663337..5b8e4d8 100644 --- a/third_party/blink/web_tests/platform/win/fast/css/outline-auto-location-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/css/outline-auto-location-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..1fe91ea3 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..63d8525 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png index 9e1618e..fa8eceb 100644 --- a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..2a72a63 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..9916883 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..a9bfd55e --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..432b7a9 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..81aaa6d6 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..2a72a63 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/virtual/controls-refresh-hc/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png new file mode 100644 index 0000000..3d93585 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-appearance-basic-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png new file mode 100644 index 0000000..a9bfd55e --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/virtual/dark-color-scheme/fast/forms/color-scheme/search/search-cancel-button-clicked-expected.png Binary files differ
diff --git a/third_party/closure_compiler/externs/file_manager_private.js b/third_party/closure_compiler/externs/file_manager_private.js index 7d18a799..68bff3e 100644 --- a/third_party/closure_compiler/externs/file_manager_private.js +++ b/third_party/closure_compiler/externs/file_manager_private.js
@@ -267,12 +267,6 @@ UNSHARE: 'unshare', }; -/** @enum {string} */ -chrome.fileManagerPrivate.ContentMetadataType = { - METADATATAGSIMAGES: 'metadataTagsImages', - METADATATAGS: 'metadataTags', -}; - /** * @typedef {{ * taskId: string,
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py index 78ab2b8..b95ce42 100755 --- a/tools/clang/scripts/build.py +++ b/tools/clang/scripts/build.py
@@ -253,7 +253,7 @@ return gnuwin_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'gnuwin') - GNUWIN_VERSION = '13' + GNUWIN_VERSION = '14' GNUWIN_STAMP = os.path.join(gnuwin_dir, 'stamp') if ReadStampFile(GNUWIN_STAMP) == GNUWIN_VERSION: print('GNU Win tools already up to date.')
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 8471c821..b631d62 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -960,6 +960,7 @@ 'ios-simulator-cronet': 'ios_cronet_xctest', 'ios-simulator-code-coverage': 'clang_code_coverage_ios_partial_instrumentation_xctest', 'ios-simulator-cr-recipe': 'ios_simulator_debug_static_bot_xctest', + 'ios-simulator-noncq': 'ios_simulator_debug_static_rbe_bot_xctest', 'ios-simulator-multi-window': 'ios_simulator_debug_static_bot_multi_window_xctest', 'mac-osxbeta-rel': 'gpu_tests_release_trybot_deterministic_mac', 'mac_chromium_10.10': 'gpu_tests_release_trybot_deterministic_mac',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 71ca509b..2cda02d 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -59741,6 +59741,7 @@ <int value="2" label="kFileReadError"/> <int value="3" label="kJSONParseError"/> <int value="4" label="kJSONIsNotList"/> + <int value="5" label="kRuleCountLimitExceeded"/> </enum> <enum name="ReaderModeEntryPoint"> @@ -66019,6 +66020,7 @@ <int value="1" label="Timed out"/> <int value="2" label="Connection Error"/> <int value="3" label="Cancelled"/> + <int value="4" label="Aborted"/> </enum> <enum name="SnackbarIdentifier">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index b0ccbb8..f7c64bb 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -71217,7 +71217,7 @@ </histogram> <histogram name="InputMethod.Handwriting.Actions" enum="ImeHandwritingActions" - expires_after="2020-09-01"> + expires_after="2021-03-01"> <owner>shend@chromium.org</owner> <owner>essential-inputs-team@google.com</owner> <summary> @@ -71259,7 +71259,7 @@ </histogram> <histogram name="InputMethod.Handwriting.CharsEdited10s" units="chars" - expires_after="2020-09-01"> + expires_after="2021-03-01"> <owner>shend@chromium.org</owner> <owner>essential-inputs-team@google.com</owner> <summary> @@ -71269,7 +71269,7 @@ </histogram> <histogram name="InputMethod.Handwriting.CharsEdited5s" units="chars" - expires_after="2020-09-01"> + expires_after="2021-03-01"> <owner>shend@chromium.org</owner> <owner>essential-inputs-team@google.com</owner> <summary> @@ -71279,7 +71279,7 @@ </histogram> <histogram name="InputMethod.Handwriting.CharsEdited60s" units="chars" - expires_after="2020-09-01"> + expires_after="2021-03-01"> <owner>shend@chromium.org</owner> <owner>essential-inputs-team@google.com</owner> <summary> @@ -149279,7 +149279,7 @@ with a delayed SafeBrowsing phishing warning, triggers the delayed warning (via keypress), or leaves the page without interacting. Only recorded when user has not disabled URL elision via "Always Show Full URLs" - context menu item. + context menu item, or by installing the Suspicious Site Reporter extension. </summary> </histogram> @@ -149294,6 +149294,33 @@ </summary> </histogram> +<histogram name="SafeBrowsing.DelayedWarnings.TimeOnPage" units="seconds" + expires_after="M89"> + <owner>meacer@chromium.org</owner> + <owner>estark@chromium.org</owner> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + Records how long a user in the Delayed Warnings experiment group spends on a + page with a delayed SafeBrowsing phishing warning. The time is recorded from + when the page loads to when the warning is shown or the user leaves the + page, whichever comes first. Only recorded when user has not disabled URL + elision via "Always Show Full URLs" context menu item, or by + installing the Suspicious Site Reporter extension. + </summary> +</histogram> + +<histogram name="SafeBrowsing.DelayedWarnings.TimeOnPage_UrlElisionDisabled" + units="seconds" expires_after="M89"> + <owner>meacer@chromium.org</owner> + <owner>estark@chromium.org</owner> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + Same as SafeBrowsing.DelayedWarnings.TimeOnPage but only recorded when user + has disabled URL elision via "Always Show Full URLs" context menu + item, or by installing the Suspicious Site Reporter extension. + </summary> +</histogram> + <histogram name="SafeBrowsing.EnabledSettingChanged" enum="BooleanEnabled" expires_after="2015-10-16"> <obsolete> @@ -202036,8 +202063,8 @@ <suffix name="ShoppingDomain" label="The context menu was shown for a link that its domain is on the Shopping domain allowlist in the Lens experiment."/> + <affected-histogram name="ContextMenu.SelectedOptionAndroid.Image"/> <affected-histogram name="ContextMenu.SelectedOptionAndroid.ImageLink"/> - <affected-histogram name="ContextMenu.SelectedOptionAndroid.Link"/> <affected-histogram name="ContextMenu.Shown"/> </histogram_suffixes>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 255b1a7..5999033e 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,11 +6,11 @@ }, "mac": { "hash": "856218c5e01964b2e9d6b1643de0909de34f5e01", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/746445da75a40eac88af9b710e9144e6a26eaee6/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/mac/cd8de1d295b4bedf5b0b00a6655575881df8696a/trace_processor_shell" }, "linux": { "hash": "9898e7dd58b976adcc52b6b910d711f8ab130b3f", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/746445da75a40eac88af9b710e9144e6a26eaee6/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/linux/cd8de1d295b4bedf5b0b00a6655575881df8696a/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/base/x/selection_requestor_unittest.cc b/ui/base/x/selection_requestor_unittest.cc index 951a107..c67b8e6 100644 --- a/ui/base/x/selection_requestor_unittest.cc +++ b/ui/base/x/selection_requestor_unittest.cc
@@ -5,8 +5,6 @@ #include "ui/base/x/selection_requestor.h" #include <stddef.h> -#include <xcb/xcb.h> - #include <memory> #include "base/bind.h" @@ -44,19 +42,12 @@ ui::SetStringProperty(x_window_, requestor_->x_property_, gfx::GetAtom("STRING"), value); - xcb_generic_event_t ge; - memset(&ge, 0, sizeof(ge)); - auto* event = reinterpret_cast<xcb_selection_notify_event_t*>(&ge); - event->response_type = x11::SelectionNotifyEvent::opcode; - event->sequence = 0; - event->requestor = static_cast<uint32_t>(x_window_); - event->selection = static_cast<uint32_t>(selection); - event->target = static_cast<uint32_t>(target); - event->property = static_cast<uint32_t>(requestor_->x_property_); - event->time = x11::CurrentTime; - - x11::Event xev(&ge, x11::Connection::Get()); - requestor_->OnSelectionNotify(*xev.As<x11::SelectionNotifyEvent>()); + requestor_->OnSelectionNotify({ + .requestor = x_window_, + .selection = selection, + .target = target, + .property = requestor_->x_property_, + }); } protected:
diff --git a/ui/base/x/x11_error_handler.cc b/ui/base/x/x11_error_handler.cc index e63bb8f..cab6e26 100644 --- a/ui/base/x/x11_error_handler.cc +++ b/ui/base/x/x11_error_handler.cc
@@ -31,7 +31,9 @@ int BrowserX11ErrorHandler(Display* d, XErrorEvent* error) { if (!g_in_x11_io_error_handler) { base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&x11::LogErrorEventDescription, *error)); + FROM_HERE, base::BindOnce(&x11::LogErrorEventDescription, error->serial, + error->error_code, error->request_code, + error->minor_code)); } return 0; }
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc index 67044ef..7a31e64 100644 --- a/ui/base/x/x11_util.cc +++ b/ui/base/x/x11_util.cc
@@ -101,7 +101,9 @@ if (base::CurrentThread::Get()) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&x11::LogErrorEventDescription, *e)); + FROM_HERE, + base::BindOnce(&x11::LogErrorEventDescription, e->serial, e->error_code, + e->request_code, e->minor_code)); } else { LOG(ERROR) << "X error received: " << "serial " << e->serial << ", "
diff --git a/ui/events/platform/x11/x11_event_source.cc b/ui/events/platform/x11/x11_event_source.cc index ddb9b0c..8a3285f 100644 --- a/ui/events/platform/x11/x11_event_source.cc +++ b/ui/events/platform/x11/x11_event_source.cc
@@ -4,11 +4,6 @@ #include "ui/events/platform/x11/x11_event_source.h" -#include <X11/Xlib-xcb.h> -#include <xcb/xcb.h> -#include <xcb/xcbext.h> -#include <xcb/xproto.h> - #include <algorithm> #include <memory> #include <type_traits>
diff --git a/ui/events/test/events_test_utils_x11.cc b/ui/events/test/events_test_utils_x11.cc index a8e6d790..179cd6f 100644 --- a/ui/events/test/events_test_utils_x11.cc +++ b/ui/events/test/events_test_utils_x11.cc
@@ -5,7 +5,6 @@ #include "ui/events/test/events_test_utils_x11.h" #include <stddef.h> -#include <xcb/xproto.h> #include "base/check_op.h" #include "base/notreached.h" @@ -19,6 +18,7 @@ #include "ui/gfx/x/connection.h" #include "ui/gfx/x/x11.h" #include "ui/gfx/x/xinput.h" +#include "ui/gfx/x/xproto.h" namespace { @@ -38,14 +38,15 @@ } // Converts EventType to XKeyEvent type. -int XKeyEventType(ui::EventType type) { +x11::KeyEvent::Opcode XKeyEventType(ui::EventType type) { switch (type) { case ui::ET_KEY_PRESSED: return x11::KeyEvent::Press; case ui::ET_KEY_RELEASED: return x11::KeyEvent::Release; default: - return 0; + NOTREACHED(); + return {}; } } @@ -130,76 +131,49 @@ void ScopedXI2Event::InitKeyEvent(EventType type, KeyboardCode key_code, int flags) { - auto* connection = x11::Connection::Get(); - xcb_generic_event_t ge; - memset(&ge, 0, sizeof(ge)); - auto* key = reinterpret_cast<xcb_key_press_event_t*>(&ge); - key->response_type = XKeyEventType(type); - CHECK_NE(0, key->response_type); - key->sequence = 0; - key->time = 0; - key->event = 0; - key->root = 0; - key->child = 0; - key->event_x = 0; - key->event_y = 0; - key->root_x = 0; - key->root_y = 0; - key->state = XEventState(flags); - key->detail = XKeyCodeForWindowsKeyCode(key_code, flags, connection); - key->same_screen = 1; + x11::KeyEvent key_event{ + .opcode = XKeyEventType(type), + .detail = static_cast<x11::KeyCode>( + XKeyCodeForWindowsKeyCode(key_code, flags, x11::Connection::Get())), + .state = static_cast<x11::KeyButMask>(XEventState(flags)), + .same_screen = true, + }; - x11::Event x11_event(&ge, connection); + x11::Event x11_event(key_event); event_ = std::move(x11_event); } void ScopedXI2Event::InitMotionEvent(const gfx::Point& location, const gfx::Point& root_location, int flags) { - auto* connection = x11::Connection::Get(); - xcb_generic_event_t ge; - memset(&ge, 0, sizeof(ge)); - auto* motion = reinterpret_cast<xcb_motion_notify_event_t*>(&ge); - motion->response_type = MotionNotify; - motion->sequence = 0; - motion->time = 0; - motion->event = 0; - motion->root = 0; - motion->child = 0; - motion->event_x = location.x(); - motion->event_y = location.y(); - motion->root_x = root_location.x(); - motion->root_y = root_location.y(); - motion->state = XEventState(flags); - motion->same_screen = 1; + x11::MotionNotifyEvent motion_event{ + .root_x = root_location.x(), + .root_y = root_location.y(), + .event_x = location.x(), + .event_y = location.y(), + .state = static_cast<x11::KeyButMask>(XEventState(flags)), + .same_screen = true, + }; - x11::Event x11_event(&ge, connection); + x11::Event x11_event(motion_event); event_ = std::move(x11_event); } void ScopedXI2Event::InitButtonEvent(EventType type, const gfx::Point& location, int flags) { - auto* connection = x11::Connection::Get(); - xcb_generic_event_t ge; - memset(&ge, 0, sizeof(ge)); - auto* button = reinterpret_cast<xcb_button_press_event_t*>(&ge); - button->response_type = (type == ui::ET_MOUSE_PRESSED) - ? x11::ButtonEvent::Press - : x11::ButtonEvent::Release; - button->sequence = 0; - button->time = 0; - button->event = 0; - button->root = 0; - button->event_x = location.x(); - button->event_y = location.y(); - button->root_x = location.x(); - button->root_y = location.y(); - button->state = 0; - button->detail = XButtonEventButton(type, flags); - button->same_screen = 1; + x11::ButtonEvent button_event{ + .opcode = type == ui::ET_MOUSE_PRESSED ? x11::ButtonEvent::Press + : x11::ButtonEvent::Release, + .detail = static_cast<x11::Button>(XButtonEventButton(type, flags)), + .root_x = location.x(), + .root_y = location.y(), + .event_x = location.x(), + .event_y = location.y(), + .same_screen = true, + }; - x11::Event x11_event(&ge, connection); + x11::Event x11_event(button_event); event_ = std::move(x11_event); }
diff --git a/ui/gfx/x/BUILD.gn b/ui/gfx/x/BUILD.gn index 293f111a..2232d09 100644 --- a/ui/gfx/x/BUILD.gn +++ b/ui/gfx/x/BUILD.gn
@@ -98,6 +98,7 @@ "event.cc", "x11_switches.cc", "x11_switches.h", + "x11.h", ] configs += [ ":x11_private_config", @@ -110,7 +111,6 @@ sources = [ "../gfx_export.h", - "x11.h", "x11_atom_cache.cc", "x11_atom_cache.h", "x11_error_tracker.cc",
diff --git a/ui/gfx/x/connection.cc b/ui/gfx/x/connection.cc index 003a2c0..8773412 100644 --- a/ui/gfx/x/connection.cc +++ b/ui/gfx/x/connection.cc
@@ -4,10 +4,8 @@ #include "ui/gfx/x/connection.h" -#include <X11/Xlib-xcb.h> -#include <X11/Xlib.h> -#include <X11/keysym.h> #include <xcb/xcb.h> +#include <xcb/xcbext.h> #include <algorithm> @@ -21,6 +19,7 @@ #include "ui/gfx/x/bigreq.h" #include "ui/gfx/x/event.h" #include "ui/gfx/x/randr.h" +#include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11_switches.h" #include "ui/gfx/x/xproto.h" #include "ui/gfx/x/xproto_internal.h" @@ -194,12 +193,12 @@ *upper = static_cast<KeySym>(upper32); } -bool IsKeypadKey(KeySym keysym) { +bool IsXKeypadKey(KeySym keysym) { auto key = static_cast<uint32_t>(keysym); return key >= XK_KP_Space && key <= XK_KP_Equal; } -bool IsPrivateKeypadKey(KeySym keysym) { +bool IsPrivateXKeypadKey(KeySym keysym) { auto key = static_cast<uint32_t>(keysym); return key >= 0x11000000 && key <= 0x1100FFFF; } @@ -621,7 +620,7 @@ if ((modifiers & num_lock_) && (n_keysyms > 1 && - (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) { + (IsXKeypadKey(syms[1]) || IsPrivateXKeypadKey(syms[1])))) { if ((modifiers & ShiftMask) || ((modifiers & LockMask) && (lock_meaning_ == XK_Shift_Lock))) { return syms[0];
diff --git a/ui/gfx/x/event.cc b/ui/gfx/x/event.cc index 1bedc6ee..41cd3649 100644 --- a/ui/gfx/x/event.cc +++ b/ui/gfx/x/event.cc
@@ -4,6 +4,8 @@ #include "ui/gfx/x/event.h" +#include <xcb/xcb.h> + #include <cstring> #include "base/check_op.h"
diff --git a/ui/gfx/x/event.h b/ui/gfx/x/event.h index 5ad11ca..42ef4a3d 100644 --- a/ui/gfx/x/event.h +++ b/ui/gfx/x/event.h
@@ -5,9 +5,6 @@ #ifndef UI_GFX_X_EVENT_H_ #define UI_GFX_X_EVENT_H_ -#include <X11/Xlib.h> -#include <xcb/xcb.h> - #include <cstdint> #include <utility> @@ -29,11 +26,12 @@ public: template <typename T> explicit Event(T&& xproto_event) { + using DecayT = std::decay_t<T>; sequence_valid_ = true; sequence_ = xproto_event.sequence; - type_id_ = T::type_id; - deleter_ = [](void* event) { delete reinterpret_cast<T*>(event); }; - T* event = new T(std::forward<T>(xproto_event)); + type_id_ = DecayT::type_id; + deleter_ = [](void* event) { delete reinterpret_cast<DecayT*>(event); }; + auto* event = new DecayT(std::forward<T>(xproto_event)); event_ = event; window_ = event->GetWindow(); }
diff --git a/ui/gfx/x/x11.h b/ui/gfx/x/x11.h index b19efad6..ed5dccd 100644 --- a/ui/gfx/x/x11.h +++ b/ui/gfx/x/x11.h
@@ -64,6 +64,8 @@ #include <X11/keysym.h> } +#include "ui/gfx/x/xproto_undef.h" + #include "ui/gfx/x/connection.h" // These commonly used names are undefined and if necessary recreated @@ -75,18 +77,18 @@ // headers than initially expected, including system headers like // those from X11. -#undef Status // Defined by X11/Xlib.h to int -#undef Bool // Defined by X11/Xlib.h to int -#undef RootWindow // Defined by X11/Xlib.h -#undef DestroyAll // Defined by X11/X.h to 0 -#undef Always // Defined by X11/X.h to 2 -#undef FocusIn // Defined by X.h to 9 -#undef FocusOut // Defined by X.h to 10 -#undef None // Defined by X11/X.h to 0L -#undef True // Defined by X11/Xlib.h to 1 -#undef False // Defined by X11/Xlib.h to 0 -#undef CurrentTime // Defined by X11/X.h to 0L -#undef Success // Defined by X11/X.h to 0 +#undef Status // Defined by X11/Xlib.h to int +#undef Bool // Defined by X11/Xlib.h to int +#undef RootWindow // Defined by X11/Xlib.h +#undef DestroyAll // Defined by X11/X.h to 0 +#undef Always // Defined by X11/X.h to 2 +#undef FocusIn // Defined by X.h to 9 +#undef FocusOut // Defined by X.h to 10 +#undef None // Defined by X11/X.h to 0L +#undef True // Defined by X11/Xlib.h to 1 +#undef False // Defined by X11/Xlib.h to 0 +#undef CurrentTime // Defined by X11/X.h to 0L +#undef Success // Defined by X11/X.h to 0 // The x11 namespace allows to scope X11 constants and types that // would be problematic at the default preprocessor level.
diff --git a/ui/gfx/x/x11_atom_cache.cc b/ui/gfx/x/x11_atom_cache.cc index 2e09c095..70be123 100644 --- a/ui/gfx/x/x11_atom_cache.cc +++ b/ui/gfx/x/x11_atom_cache.cc
@@ -4,9 +4,6 @@ #include "ui/gfx/x/x11_atom_cache.h" -#include <X11/Xatom.h> -#include <X11/Xlib.h> - #include <utility> #include <vector>
diff --git a/ui/gfx/x/x11_error_tracker.cc b/ui/gfx/x/x11_error_tracker.cc index 6592ae0..2e6addc 100644 --- a/ui/gfx/x/x11_error_tracker.cc +++ b/ui/gfx/x/x11_error_tracker.cc
@@ -5,6 +5,7 @@ #include "ui/gfx/x/x11_error_tracker.h" #include "base/check.h" +#include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11_types.h" namespace { @@ -26,18 +27,18 @@ // X11ErrorTracker instances on the same thread. DCHECK(g_handler == nullptr); g_handler = this; - XSync(GetXDisplay(), False); - old_handler_ = XSetErrorHandler(X11ErrorHandler); + XSync(GetXDisplay(), x11::False); + old_handler_ = reinterpret_cast<void*>(XSetErrorHandler(X11ErrorHandler)); g_x11_error_code = 0; } X11ErrorTracker::~X11ErrorTracker() { g_handler = nullptr; - XSetErrorHandler(old_handler_); + XSetErrorHandler(reinterpret_cast<XErrorHandler>(old_handler_)); } bool X11ErrorTracker::FoundNewError() { - XSync(GetXDisplay(), False); + XSync(GetXDisplay(), x11::False); unsigned char error = g_x11_error_code; g_x11_error_code = 0; return error != 0;
diff --git a/ui/gfx/x/x11_error_tracker.h b/ui/gfx/x/x11_error_tracker.h index 21031be..df06bef 100644 --- a/ui/gfx/x/x11_error_tracker.h +++ b/ui/gfx/x/x11_error_tracker.h
@@ -5,8 +5,6 @@ #ifndef UI_GFX_X_X11_ERROR_TRACKER_H_ #define UI_GFX_X_X11_ERROR_TRACKER_H_ -#include <X11/Xlib.h> - #include "base/macros.h" #include "ui/gfx/gfx_export.h" @@ -26,7 +24,10 @@ bool FoundNewError(); private: - XErrorHandler old_handler_; + // The real type of |old_handler_| is XErrorHandler, or "int + // (*handler)(Display *, XErrorEvent *)". However, XErrorEvent cannot be + // forward declared, so void* is necessary here. + void* old_handler_ = nullptr; DISALLOW_COPY_AND_ASSIGN(X11ErrorTracker); };
diff --git a/ui/gfx/x/x11_types.cc b/ui/gfx/x/x11_types.cc index 756a1f5..7bdea78 100644 --- a/ui/gfx/x/x11_types.cc +++ b/ui/gfx/x/x11_types.cc
@@ -4,13 +4,13 @@ #include "ui/gfx/x/x11_types.h" -#include <X11/Xlib.h> #include <string.h> #include "base/command_line.h" #include "base/logging.h" #include "build/build_config.h" #include "ui/gfx/x/connection.h" +#include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11_switches.h" namespace gfx { @@ -24,4 +24,3 @@ } } // namespace gfx -
diff --git a/ui/gfx/x/x11_types.h b/ui/gfx/x/x11_types.h index 9bede0e..149bb88 100644 --- a/ui/gfx/x/x11_types.h +++ b/ui/gfx/x/x11_types.h
@@ -12,6 +12,7 @@ #include "ui/gfx/gfx_export.h" #include "ui/gfx/x/connection.h" +typedef unsigned long XID; typedef unsigned long VisualID; typedef union _XEvent XEvent; typedef struct _XImage XImage;
diff --git a/ui/gfx/x/xproto_internal.cc b/ui/gfx/x/xproto_internal.cc index 4abf422..f3a891d 100644 --- a/ui/gfx/x/xproto_internal.cc +++ b/ui/gfx/x/xproto_internal.cc
@@ -4,6 +4,12 @@ #include "ui/gfx/x/xproto_internal.h" +#include <stdint.h> +#include <xcb/xcb.h> +#include <xcb/xcbext.h> + +#include "ui/gfx/x/x11.h" + // XCB used to send requests with FDs by sending each FD individually with // xcb_send_fd(), then the request with xcb_send_request(). However, there's a // race condition -- FDs can get mixed up if multiple threads are sending them
diff --git a/ui/gfx/x/xproto_internal.h b/ui/gfx/x/xproto_internal.h index f278ea8..61b93010 100644 --- a/ui/gfx/x/xproto_internal.h +++ b/ui/gfx/x/xproto_internal.h
@@ -9,14 +9,7 @@ #error "This file should only be included by //ui/gfx/x:xprotos" #endif -#include <X11/Xlib-xcb.h> -#include <stdint.h> -#include <string.h> -#include <xcb/xcb.h> -#include <xcb/xcbext.h> - #include <bitset> -#include <limits> #include <type_traits> #include "base/component_export.h"
diff --git a/ui/gfx/x/xproto_types.cc b/ui/gfx/x/xproto_types.cc index 296862e8..62303be 100644 --- a/ui/gfx/x/xproto_types.cc +++ b/ui/gfx/x/xproto_types.cc
@@ -4,6 +4,8 @@ #include "ui/gfx/x/xproto_types.h" +#include <xcb/xcbext.h> + #include "base/memory/scoped_refptr.h" #include "ui/gfx/x/connection.h" #include "ui/gfx/x/xproto_internal.h" @@ -92,15 +94,8 @@ if (!error) return; - x11::LogErrorEventDescription(XErrorEvent({ - .type = error->response_type, - .display = connection->display(), - .resourceid = error->resource_id, - .serial = error->full_sequence, - .error_code = error->error_code, - .request_code = error->major_code, - .minor_code = error->minor_code, - })); + x11::LogErrorEventDescription(error->full_sequence, error->error_code, + error->major_code, error->minor_code); }, connection_)); }
diff --git a/ui/gfx/x/xproto_types.h b/ui/gfx/x/xproto_types.h index 9e8e04d..971d8cd 100644 --- a/ui/gfx/x/xproto_types.h +++ b/ui/gfx/x/xproto_types.h
@@ -6,7 +6,6 @@ #define UI_GFX_X_XPROTO_TYPES_H_ #include <xcb/xcb.h> -#include <xcb/xcbext.h> #include <cstdint> #include <memory>
diff --git a/ui/gfx/x/xproto_util.cc b/ui/gfx/x/xproto_util.cc index e08bf4f..705d1d7 100644 --- a/ui/gfx/x/xproto_util.cc +++ b/ui/gfx/x/xproto_util.cc
@@ -8,11 +8,15 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "ui/gfx/x/connection.h" +#include "ui/gfx/x/x11.h" #include "ui/gfx/x/xproto.h" namespace x11 { -void LogErrorEventDescription(const XErrorEvent& error_event) { +void LogErrorEventDescription(unsigned long serial, + uint8_t error_code, + uint8_t request_code, + uint8_t minor_code) { // This function may make some expensive round trips (XListExtensions, // XQueryExtension), but the only effect this function has is LOG(WARNING), // so early-return if the log would never be sent anyway. @@ -22,13 +26,13 @@ char error_str[256]; char request_str[256]; - XDisplay* dpy = error_event.display; x11::Connection* conn = x11::Connection::Get(); - XGetErrorText(dpy, error_event.error_code, error_str, sizeof(error_str)); + auto* dpy = conn->display(); + XGetErrorText(dpy, error_code, error_str, sizeof(error_str)); strncpy(request_str, "Unknown", sizeof(request_str)); - if (error_event.request_code < 128) { - std::string num = base::NumberToString(error_event.request_code); + if (request_code < 128) { + std::string num = base::NumberToString(request_code); XGetErrorDatabaseText(dpy, "XRequest", num.c_str(), "Unknown", request_str, sizeof(request_str)); } else { @@ -37,9 +41,8 @@ int ext_code, first_event, first_error; const char* name = str.name.c_str(); XQueryExtension(dpy, name, &ext_code, &first_event, &first_error); - if (error_event.request_code == ext_code) { - std::string msg = - base::StringPrintf("%s.%d", name, error_event.minor_code); + if (request_code == ext_code) { + std::string msg = base::StringPrintf("%s.%d", name, minor_code); XGetErrorDatabaseText(dpy, "XRequest", msg.c_str(), "Unknown", request_str, sizeof(request_str)); break; @@ -49,13 +52,12 @@ } LOG(WARNING) << "X error received: " - << "serial " << error_event.serial << ", " - << "error_code " << static_cast<int>(error_event.error_code) - << " (" << error_str << "), " - << "request_code " << static_cast<int>(error_event.request_code) - << ", " - << "minor_code " << static_cast<int>(error_event.minor_code) - << " (" << request_str << ")"; + << "serial " << serial << ", " + << "error_code " << static_cast<int>(error_code) << " (" + << error_str << "), " + << "request_code " << static_cast<int>(request_code) << ", " + << "minor_code " << static_cast<int>(minor_code) << " (" + << request_str << ")"; } } // namespace x11
diff --git a/ui/gfx/x/xproto_util.h b/ui/gfx/x/xproto_util.h index baf2aaa..2179803 100644 --- a/ui/gfx/x/xproto_util.h +++ b/ui/gfx/x/xproto_util.h
@@ -5,14 +5,17 @@ #ifndef UI_GFX_X_XPROTO_UTIL_H_ #define UI_GFX_X_XPROTO_UTIL_H_ -#include <X11/Xlib.h> +#include <cstdint> #include "base/component_export.h" namespace x11 { COMPONENT_EXPORT(X11) -void LogErrorEventDescription(const XErrorEvent& error_event); +void LogErrorEventDescription(unsigned long serial, + uint8_t error_code, + uint8_t request_code, + uint8_t minor_code); } // namespace x11
diff --git a/ui/gtk/x/gtk_ui_delegate_x11.cc b/ui/gtk/x/gtk_ui_delegate_x11.cc index 16a3ae2e..70b1839 100644 --- a/ui/gtk/x/gtk_ui_delegate_x11.cc +++ b/ui/gtk/x/gtk_ui_delegate_x11.cc
@@ -7,6 +7,10 @@ #include <gdk/gdkx.h> #include <gtk/gtk.h> +// gdkx.h includes Xlib.h directly, so we need to manually undef any macros +// that conflict with the below includes. +#undef None + #include "base/check.h" #include "ui/base/x/x11_util.h" #include "ui/events/platform/x11/x11_event_source.h"
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_manager.cc b/ui/ozone/platform/drm/gpu/drm_overlay_manager.cc index 686e663..231d172 100644 --- a/ui/ozone/platform/drm/gpu/drm_overlay_manager.cc +++ b/ui/ozone/platform/drm/gpu/drm_overlay_manager.cc
@@ -149,6 +149,15 @@ if (!gfx::IsNearestRectWithinDistance(candidate.display_rect, 0.01f)) return false; + // DRM supposedly supports subpixel source crop. However, according to + // drm_plane_funcs.update_plane, devices which don't support that are + // free to ignore the fractional part, and every device seems to do that as + // of 5.4. So reject candidates that require subpixel source crop. + gfx::RectF crop(candidate.crop_rect); + crop.Scale(candidate.buffer_size.width(), candidate.buffer_size.height()); + if (!gfx::IsNearestRectWithinDistance(crop, 0.01f)) + return false; + if (candidate.is_clipped && !candidate.clip_rect.Contains( gfx::ToNearestRect(candidate.display_rect))) { return false;
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc b/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc index 6f4eaf9..79d9c95 100644 --- a/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc +++ b/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc
@@ -30,9 +30,9 @@ namespace { -// Mode of size 6x4. -const drmModeModeInfo kDefaultMode = {0, 6, 0, 0, 0, 0, 4, 0, - 0, 0, 0, 0, 0, 0, {'\0'}}; +// Mode of size 12x8. +const drmModeModeInfo kDefaultMode = {0, 12, 0, 0, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, {'\0'}}; const gfx::AcceleratedWidget kDefaultWidgetHandle = 1; constexpr uint32_t kCrtcIdBase = 1;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc index 0cdaaca..b6132216 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
@@ -12,17 +12,13 @@ #include "base/logging.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/rect_conversions.h" #include "ui/ozone/platform/drm/gpu/drm_device.h" #include "ui/ozone/platform/drm/gpu/drm_framebuffer.h" #include "ui/ozone/platform/drm/gpu/drm_gpu_util.h" #include "ui/ozone/platform/drm/gpu/hardware_display_plane.h" namespace ui { -namespace { - -constexpr float kFixedPointScaleValue = 1 << 16; - -} // namespace HardwareDisplayPlaneList::HardwareDisplayPlaneList() { atomic_property_set.reset(drmModeAtomicAlloc()); @@ -184,18 +180,14 @@ gfx::Rect fixed_point_rect; if (hw_plane->type() != HardwareDisplayPlane::kDummy) { const gfx::Size& size = plane.buffer->size(); - gfx::RectF crop_rect = plane.crop_rect; - crop_rect.Scale(size.width(), size.height()); - - // This returns a number in 16.16 fixed point, required by the DRM overlay - // APIs. - auto to_fixed_point = [](double v) -> uint32_t { - return v * kFixedPointScaleValue; - }; - fixed_point_rect = gfx::Rect(to_fixed_point(crop_rect.x()), - to_fixed_point(crop_rect.y()), - to_fixed_point(crop_rect.width()), - to_fixed_point(crop_rect.height())); + gfx::RectF crop_rectf = plane.crop_rect; + crop_rectf.Scale(size.width(), size.height()); + // DrmOverlayManager::CanHandleCandidate guarantees this is safe. + gfx::Rect crop_rect = gfx::ToNearestRect(crop_rectf); + // Convert to 16.16 fixed point required by the DRM overlay APIs. + fixed_point_rect = + gfx::Rect(crop_rect.x() << 16, crop_rect.y() << 16, + crop_rect.width() << 16, crop_rect.height() << 16); } if (!SetPlaneData(plane_list, hw_plane, plane, crtc_id, fixed_point_rect)) {
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc index 798ed11..4fcfa24 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
@@ -1141,6 +1141,72 @@ EXPECT_TRUE(callback_called); } +TEST_P(HardwareDisplayPlaneManagerAtomicTest, OverlaySourceCrop) { + InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1); + fake_drm_->InitializeState(crtc_properties_, connector_properties_, + plane_properties_, property_names_, use_atomic_); + + { + ui::DrmOverlayPlaneList assigns; + assigns.push_back(ui::DrmOverlayPlane(fake_buffer_, 0)); + + fake_drm_->plane_manager()->BeginFrame(&state_); + EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes( + &state_, assigns, crtc_properties_[0].id)); + + std::unique_ptr<gfx::GpuFence> out_fence; + scoped_refptr<ui::PageFlipRequest> page_flip_request = + base::MakeRefCounted<ui::PageFlipRequest>(base::TimeDelta()); + EXPECT_TRUE(fake_drm_->plane_manager()->Commit(&state_, page_flip_request, + &out_fence)); + + EXPECT_EQ(2u << 16, GetPlanePropertyValue(kPlaneOffset, "SRC_W")); + EXPECT_EQ(2u << 16, GetPlanePropertyValue(kPlaneOffset, "SRC_H")); + } + + { + ui::DrmOverlayPlaneList assigns; + assigns.push_back(ui::DrmOverlayPlane( + fake_buffer_, 0, gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE, + gfx::Rect(kDefaultBufferSize), gfx::RectF(0, 0, .5, 1), false, + nullptr)); + + fake_drm_->plane_manager()->BeginFrame(&state_); + EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes( + &state_, assigns, crtc_properties_[0].id)); + + scoped_refptr<ui::PageFlipRequest> page_flip_request = + base::MakeRefCounted<ui::PageFlipRequest>(base::TimeDelta()); + std::unique_ptr<gfx::GpuFence> out_fence; + EXPECT_TRUE(fake_drm_->plane_manager()->Commit(&state_, page_flip_request, + &out_fence)); + + EXPECT_EQ(1u << 16, GetPlanePropertyValue(kPlaneOffset, "SRC_W")); + EXPECT_EQ(2u << 16, GetPlanePropertyValue(kPlaneOffset, "SRC_H")); + } + + { + ui::DrmOverlayPlaneList assigns; + assigns.push_back(ui::DrmOverlayPlane( + fake_buffer_, 0, gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE, + gfx::Rect(kDefaultBufferSize), gfx::RectF(0, 0, .999, .501), false, + nullptr)); + + fake_drm_->plane_manager()->BeginFrame(&state_); + EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes( + &state_, assigns, crtc_properties_[0].id)); + + scoped_refptr<ui::PageFlipRequest> page_flip_request = + base::MakeRefCounted<ui::PageFlipRequest>(base::TimeDelta()); + std::unique_ptr<gfx::GpuFence> out_fence; + EXPECT_TRUE(fake_drm_->plane_manager()->Commit(&state_, page_flip_request, + &out_fence)); + + EXPECT_EQ(2u << 16, GetPlanePropertyValue(kPlaneOffset, "SRC_W")); + EXPECT_EQ(1u << 16, GetPlanePropertyValue(kPlaneOffset, "SRC_H")); + } +} + class HardwareDisplayPlaneAtomicMock : public ui::HardwareDisplayPlaneAtomic { public: HardwareDisplayPlaneAtomicMock() : ui::HardwareDisplayPlaneAtomic(1) {}
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index 6b87d5c..2561fa5b 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -150,6 +150,7 @@ "//third_party/wayland-protocols:gtk_primary_selection_protocol", "//third_party/wayland-protocols:keyboard_extension_protocol", "//third_party/wayland-protocols:linux_dmabuf_protocol", + "//third_party/wayland-protocols:linux_explicit_synchronization_protocol", "//third_party/wayland-protocols:presentation_time_protocol", "//third_party/wayland-protocols:text_input_protocol", "//third_party/wayland-protocols:wayland_drm_protocol",
diff --git a/ui/ozone/platform/wayland/common/wayland_object.cc b/ui/ozone/platform/wayland/common/wayland_object.cc index a71f25d..2bfe79e 100644 --- a/ui/ozone/platform/wayland/common/wayland_object.cc +++ b/ui/ozone/platform/wayland/common/wayland_object.cc
@@ -8,6 +8,7 @@ #include <gtk-primary-selection-client-protocol.h> #include <keyboard-extension-unstable-v1-client-protocol.h> #include <linux-dmabuf-unstable-v1-client-protocol.h> +#include <linux-explicit-synchronization-unstable-v1-client-protocol.h> #include <presentation-time-client-protocol.h> #include <text-input-unstable-v1-client-protocol.h> #include <wayland-client.h> @@ -215,6 +216,25 @@ void (*ObjectTraits<zwp_linux_dmabuf_v1>::deleter)(zwp_linux_dmabuf_v1*) = &zwp_linux_dmabuf_v1_destroy; +const wl_interface* ObjectTraits<zwp_linux_buffer_release_v1>::interface = + &zwp_linux_buffer_release_v1_interface; +void (*ObjectTraits<zwp_linux_buffer_release_v1>::deleter)( + zwp_linux_buffer_release_v1*) = &zwp_linux_buffer_release_v1_destroy; + +const wl_interface* + ObjectTraits<zwp_linux_explicit_synchronization_v1>::interface = + &zwp_linux_explicit_synchronization_v1_interface; +void (*ObjectTraits<zwp_linux_explicit_synchronization_v1>::deleter)( + zwp_linux_explicit_synchronization_v1*) = + &zwp_linux_explicit_synchronization_v1_destroy; + +const wl_interface* + ObjectTraits<zwp_linux_surface_synchronization_v1>::interface = + &zwp_linux_surface_synchronization_v1_interface; +void (*ObjectTraits<zwp_linux_surface_synchronization_v1>::deleter)( + zwp_linux_surface_synchronization_v1*) = + &zwp_linux_surface_synchronization_v1_destroy; + const wl_interface* ObjectTraits<zxdg_shell_v6>::interface = &zxdg_shell_v6_interface; void (*ObjectTraits<zxdg_shell_v6>::deleter)(zxdg_shell_v6*) =
diff --git a/ui/ozone/platform/wayland/common/wayland_object.h b/ui/ozone/platform/wayland/common/wayland_object.h index faabaed..9578e4bc 100644 --- a/ui/ozone/platform/wayland/common/wayland_object.h +++ b/ui/ozone/platform/wayland/common/wayland_object.h
@@ -44,6 +44,9 @@ struct zcr_keyboard_extension_v1; struct zcr_extended_keyboard_v1; struct zwp_linux_dmabuf_v1; +struct zwp_linux_buffer_release_v1; +struct zwp_linux_explicit_synchronization_v1; +struct zwp_linux_surface_synchronization_v1; struct zxdg_shell_v6; struct zxdg_surface_v6; struct zxdg_toplevel_v6; @@ -280,6 +283,24 @@ }; template <> +struct ObjectTraits<zwp_linux_buffer_release_v1> { + static const wl_interface* interface; + static void (*deleter)(zwp_linux_buffer_release_v1*); +}; + +template <> +struct ObjectTraits<zwp_linux_explicit_synchronization_v1> { + static const wl_interface* interface; + static void (*deleter)(zwp_linux_explicit_synchronization_v1*); +}; + +template <> +struct ObjectTraits<zwp_linux_surface_synchronization_v1> { + static const wl_interface* interface; + static void (*deleter)(zwp_linux_surface_synchronization_v1*); +}; + +template <> struct ObjectTraits<zxdg_shell_v6> { static const wl_interface* interface; static void (*deleter)(zxdg_shell_v6*);
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc index febebef..134c30b6 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.cc +++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
@@ -52,6 +52,7 @@ constexpr uint32_t kMaxDeviceManagerVersion = 3; constexpr uint32_t kMaxWpPresentationVersion = 1; constexpr uint32_t kMaxTextInputManagerVersion = 1; +constexpr uint32_t kMaxExplicitSyncVersion = 2; constexpr uint32_t kMinAuraShellVersion = 10; constexpr uint32_t kMinWlDrmVersion = 2; constexpr uint32_t kMinWlOutputVersion = 2; @@ -331,6 +332,12 @@ connection->primary_selection_device_manager_ = std::make_unique<GtkPrimarySelectionDeviceManager>(manager.release(), connection); + } else if (!connection->linux_explicit_synchronization_ && + (strcmp(interface, "zwp_linux_explicit_synchronization_v1") == + 0)) { + connection->linux_explicit_synchronization_ = + wl::Bind<zwp_linux_explicit_synchronization_v1>( + registry, name, std::min(version, kMaxExplicitSyncVersion)); } else if (!connection->zwp_dmabuf_ && (strcmp(interface, "zwp_linux_dmabuf_v1") == 0)) { wl::Object<zwp_linux_dmabuf_v1> zwp_linux_dmabuf =
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h index 6dfc5b7a..1c13c06 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.h +++ b/ui/ozone/platform/wayland/host/wayland_connection.h
@@ -60,6 +60,10 @@ zwp_text_input_manager_v1* text_input_manager_v1() const { return text_input_manager_v1_.get(); } + zwp_linux_explicit_synchronization_v1* linux_explicit_synchronization_v1() + const { + return linux_explicit_synchronization_.get(); + } void set_serial(uint32_t serial) { serial_ = serial; } uint32_t serial() const { return serial_; } @@ -167,6 +171,8 @@ wl::Object<zcr_keyboard_extension_v1> keyboard_extension_v1_; wl::Object<zwp_text_input_manager_v1> text_input_manager_v1_; wl::Object<zaura_shell> aura_shell_; + wl::Object<zwp_linux_explicit_synchronization_v1> + linux_explicit_synchronization_; // Event source instance. Must be declared before input objects so it // outlives them so thus being able to properly handle their destruction.
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index 2dc2850..97205b1 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -1393,6 +1393,9 @@ sources += [ "widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc", ] + if (use_ozone) { + deps += [ "//ui/ozone" ] + } } if (use_x11 || ozone_platform_x11) {
diff --git a/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc b/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc index 55259bd..788c308d 100644 --- a/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc +++ b/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
@@ -29,6 +29,11 @@ #include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h" #include "ui/views/widget/widget.h" +#if defined(USE_OZONE) +#include "ui/base/ui_base_features.h" +#include "ui/ozone/public/ozone_platform.h" +#endif + namespace views { namespace { @@ -99,6 +104,17 @@ // DesktopWidgetTestInteractive void SetUp() override { +#if defined(USE_OZONE) + // Run tests only for X11 (ozone or not Ozone). + if (features::IsUsingOzonePlatform() && + std::strcmp(ui::OzonePlatform::GetInstance()->GetPlatformName(), + "x11") != 0) { + // SetUp still is required to be run. Otherwise, ViewsTestBase CHECKs in + // the dtor. + DesktopWidgetTestInteractive::SetUp(); + GTEST_SKIP(); + } +#endif // Make X11 synchronous for our display connection. This does not force the // window manager to behave synchronously. XSynchronize(xdisplay(), x11::True); @@ -106,7 +122,8 @@ } void TearDown() override { - XSynchronize(xdisplay(), x11::False); + if (!IsSkipped()) + XSynchronize(xdisplay(), x11::False); DesktopWidgetTestInteractive::TearDown(); }
diff --git a/ui/webui/resources/cr_elements/chromeos/os_cr_elements.gni b/ui/webui/resources/cr_elements/chromeos/os_cr_elements.gni index ad32b62..d8068b1 100644 --- a/ui/webui/resources/cr_elements/chromeos/os_cr_elements.gni +++ b/ui/webui/resources/cr_elements/chromeos/os_cr_elements.gni
@@ -12,4 +12,5 @@ cr_elements_chromeos_auto_imports = [ "ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_types.html|CrPicture", "ui/webui/resources/cr_elements/chromeos/cr_picture/png.html|convertImageSequenceToPng,isEncodedPngDataUrlAnimated", + "ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.html|CrPolicyIndicatorType", ]
diff --git a/weblayer/browser/android/metrics/metrics_test_helper.cc b/weblayer/browser/android/metrics/metrics_test_helper.cc index bd0eb5b..d41b1eb 100644 --- a/weblayer/browser/android/metrics/metrics_test_helper.cc +++ b/weblayer/browser/android/metrics/metrics_test_helper.cc
@@ -7,7 +7,7 @@ #include "base/android/jni_android.h" #include "base/android/jni_string.h" #include "base/no_destructor.h" -#include "base/run_loop.h" +#include "content/public/test/test_utils.h" #include "weblayer/browser/profile_impl.h" #include "weblayer/test/weblayer_browsertests_jni/MetricsTestHelper_jni.h" @@ -52,7 +52,7 @@ ProfileImpl* profile = GetProfileByName(name); // Creating a profile may involve storage partition initialization. Wait for // the initialization to be completed. - base::RunLoop().RunUntilIdle(); + content::RunAllTasksUntilIdle(); return profile; } void DestroyProfile(const std::string& name) {