diff --git a/.gn b/.gn index 17bf869..e29a1249 100644 --- a/.gn +++ b/.gn
@@ -91,7 +91,6 @@ "//chrome/services/qrcode_generator:*", # 1 error "//chrome/services/removable_storage_writer:*", # 1 error "//chrome/services/sharing/public/cpp:*", # 2 errors - "//chrome/services/sharing:*", # 1 error "//chrome/services/speech:*", # 5 errors "//chrome/services/util_win:*", # 1 error "//chrome/test/chromedriver:*", # 115 errors
diff --git a/DEPS b/DEPS index ba22a36d..f620cd0 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': '68e5f29d849a36edd9e9243dc05b88e4b288dd9b', + 'skia_revision': 'c1eb58de32c016eb60e7a46046321ffe351e8222', # 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': 'df4466baeaf037b9985c5f82f56aa9e1788e4600', + 'v8_revision': 'df76b72ef7394d85badaacaecf6e1a0beb986db7', # 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. @@ -207,15 +207,15 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'cd5489ad46bd1a3f9e80073a8cb1760ed8b17f96', + 'angle_revision': '0dd63428948f70f03566665007819d326f937b72', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '97f9923235cf5a24d8ce49f93bd22429d2a68548', + 'swiftshader_revision': 'c5d08140dbebcdb01cd8debc7fcc2647599d0bb3', # 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': '9a3f345ba7c49cdc78e8caf4e667d94da8fcbbd9', + 'pdfium_revision': '75efd91227ebf7cfbaffc82935e27632b0c40ea5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -266,7 +266,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '270e6f332c4179801c60551c828c07c69104e594', + 'devtools_frontend_revision': '62ab4833a6a13ab1c863fa8a2682afea87447c77', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -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': '717e7877cac15d393fd3bb1bd872679de8b59add', + 'spv_tools_revision': 'a3b0adc306c5e7df43ecfd56d8f41b6b7e39ca18', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -545,7 +545,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '0a0f7347fac7639ac132934705e88f69d7fedc6b', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '3132beea793356e3b0f6cb77c32c9c5a1a23e68b', 'condition': 'checkout_ios', }, @@ -946,7 +946,7 @@ Var('chromium_git') + '/codecs/libgav1.git' + '@' + 'e46493b9148e0d1e63f55b5890bff503822616e5', 'src/third_party/glslang/src': - Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '9eef54b2513ca6b40b47b07d24f453848b65c0df', + Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + 'b99a6a7273181deeb08859c0fdb0c77c7e8a4500', 'src/third_party/google_toolbox_for_mac/src': { 'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'), @@ -1326,7 +1326,7 @@ 'packages': [ { 'package': 'fuchsia/third_party/aemu/linux-amd64', - 'version': '53Ps2Qo0mizBNjRI9qS90a_RTYhxglcY6H9yccc0ckcC' + 'version': 'dOv-cP7Iqrr9QqppeGdHqAO3EEhTVVBb_hVADr88ZJQC' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -1476,7 +1476,7 @@ }, 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '539e8783de6228a56ec3ea5d84ce348082352210', + Var('webrtc_git') + '/src.git' + '@' + '0bc68bd1648454f5ac2987cdf2014b71d1a80e07', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1548,7 +1548,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@f9491204a8a8d6e82c4c6efc53a982dc6e1aafb9', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@86079a48c1576f04239c4de46a1efcdd86d858d0', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index ebcb96a..daf0366 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -360,6 +360,11 @@ "//android_webview/nonembedded:nonembedded_java", "//android_webview/support_library:support_lib_glue_java", ] + + # If the R SDK isn't public yet, include the downstream code to support R. + if (!public_android_sdk && android_sdk_release == "r") { + deps += [ "//clank/android_webview/next:r_sdk_java" ] + } } # Contains all Java dependencies used by WebView.
diff --git a/android_webview/browser/gfx/output_surface_provider_webview.cc b/android_webview/browser/gfx/output_surface_provider_webview.cc index b867948..6d0a268 100644 --- a/android_webview/browser/gfx/output_surface_provider_webview.cc +++ b/android_webview/browser/gfx/output_surface_provider_webview.cc
@@ -28,7 +28,7 @@ namespace { -void OnContextLost() { +void OnContextLost(bool synthetic_loss) { NOTREACHED() << "Non owned context lost!"; }
diff --git a/android_webview/system_webview_apk_tmpl.gni b/android_webview/system_webview_apk_tmpl.gni index 33e7fe36..4d556b3d 100644 --- a/android_webview/system_webview_apk_tmpl.gni +++ b/android_webview/system_webview_apk_tmpl.gni
@@ -48,11 +48,6 @@ "//android_webview:pak_file_assets", ] - # If the R SDK isn't public yet, include the downstream code to support R. - if (!public_android_sdk && android_sdk_release == "r") { - deps += [ "//clank/android_webview/next:r_sdk_java" ] - } - if (_exclude_weblayer_java) { deps += [ "//android_webview:android_webview_no_weblayer_java" ] } else {
diff --git a/base/files/file_enumerator.h b/base/files/file_enumerator.h index b2bd5ab..9554f2a 100644 --- a/base/files/file_enumerator.h +++ b/base/files/file_enumerator.h
@@ -57,6 +57,8 @@ FilePath GetName() const; int64_t GetSize() const; + + // On POSIX systems, this is rounded down to the second. Time GetLastModifiedTime() const; #if defined(OS_WIN)
diff --git a/base/files/file_enumerator_unittest.cc b/base/files/file_enumerator_unittest.cc index ccd15113..362d4bf 100644 --- a/base/files/file_enumerator_unittest.cc +++ b/base/files/file_enumerator_unittest.cc
@@ -4,6 +4,7 @@ #include "base/files/file_enumerator.h" +#include <string> #include <utility> #include <vector> @@ -11,6 +12,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" +#include "base/logging.h" #include "build/build_config.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -28,6 +30,57 @@ FileEnumerator::FolderSearchPolicy::MATCH_ONLY, FileEnumerator::FolderSearchPolicy::ALL}; +struct TestFile { + TestFile(const FilePath::CharType* file_name, const char* c) + : path(file_name), contents(c) {} + + TestFile(const FilePath::CharType* directory, + const FilePath::CharType* file_name, + const char* c) + : path(FilePath(directory).Append(file_name)), contents(c) {} + + const FilePath path; + const std::string contents; + File::Info info; + bool found = false; +}; + +struct TestDirectory { + explicit TestDirectory(const FilePath::CharType* n) : name(n) {} + const FilePath name; + File::Info info; + bool found = false; +}; + +void CheckModificationTime(const FileEnumerator::FileInfo& actual, + Time expected_last_modified_time) { +#if defined(OS_POSIX) || defined(OS_FUCHSIA) + // On POSIX, GetLastModifiedTime() rounds down to the second, but + // File::GetInfo() does not. + Time::Exploded exploded; + expected_last_modified_time.UTCExplode(&exploded); + exploded.millisecond = 0; + EXPECT_TRUE(Time::FromUTCExploded(exploded, &expected_last_modified_time)); +#endif + EXPECT_EQ(actual.GetLastModifiedTime(), expected_last_modified_time); +} + +void CheckFileAgainstInfo(const FileEnumerator::FileInfo& actual, + TestFile& expected) { + EXPECT_FALSE(expected.found) + << "Got " << expected.path.BaseName().value() << " twice"; + expected.found = true; + EXPECT_EQ(actual.GetSize(), int64_t(expected.contents.size())); + CheckModificationTime(actual, expected.info.last_modified); +} + +void CheckDirectoryAgainstInfo(const FileEnumerator::FileInfo& actual, + TestDirectory& expected) { + EXPECT_FALSE(expected.found) << "Got " << expected.name.value() << " twice"; + expected.found = true; + CheckModificationTime(actual, expected.info.last_modified); +} + circular_deque<FilePath> RunEnumerator( const FilePath& root_path, bool recursive, @@ -47,6 +100,34 @@ return WriteFile(path, "42", sizeof("42")) == sizeof("42"); } +bool GetFileInfo(const FilePath& file_path, File::Info& info) { + // FLAG_BACKUP_SEMANTICS: Needed to open directories on Windows. + File f(file_path, + File::FLAG_OPEN | File::FLAG_READ | File::FLAG_BACKUP_SEMANTICS); + if (!f.IsValid()) { + LOG(ERROR) << "Could not open " << file_path.value() << ": " + << File::ErrorToString(f.error_details()); + return false; + } + if (!f.GetInfo(&info)) { + std::string last_error = File::ErrorToString(File::GetLastFileError()); + LOG(ERROR) << "Could not get info about " << file_path.value() << ": " + << last_error; + return false; + } + + return true; +} + +void SetUpTestFiles(const ScopedTempDir& temp_dir, + std::vector<TestFile>& files) { + for (TestFile& file : files) { + const FilePath file_path = temp_dir.GetPath().Append(file.path); + ASSERT_TRUE(WriteFile(file_path, file.contents)); + ASSERT_TRUE(GetFileInfo(file_path, file.info)); + } +} + } // namespace TEST(FileEnumerator, NotExistingPath) { @@ -365,4 +446,163 @@ } #endif +// Test FileEnumerator::GetInfo() on some files and ensure all the returned +// information is correct. +TEST(FileEnumerator, GetInfo) { + ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + + std::vector<TestFile> files = { + TestFile(FILE_PATH_LITERAL("file1"), "First"), + TestFile(FILE_PATH_LITERAL("file2"), "Second"), + TestFile(FILE_PATH_LITERAL("file3"), "Third-third-third")}; + SetUpTestFiles(temp_dir, files); + + FileEnumerator file_enumerator(temp_dir.GetPath(), false, + FileEnumerator::FILES); + while (!file_enumerator.Next().empty()) { + auto info = file_enumerator.GetInfo(); + bool found = false; + for (TestFile& file : files) { + if (info.GetName() == file.path.BaseName()) { + CheckFileAgainstInfo(info, file); + found = true; + break; + } + } + + EXPECT_TRUE(found) << "Got unexpected result " << info.GetName().value(); + } + + for (const TestFile& file : files) { + EXPECT_TRUE(file.found) + << "File " << file.path.value() << " was not returned"; + } +} + +// Test that FileEnumerator::GetInfo() works when searching recursively. It also +// tests that it returns the correct information about directories. +TEST(FileEnumerator, GetInfoRecursive) { + ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + + TestDirectory directories[] = {TestDirectory(FILE_PATH_LITERAL("dir1")), + TestDirectory(FILE_PATH_LITERAL("dir2")), + TestDirectory(FILE_PATH_LITERAL("dir3")), + TestDirectory(FILE_PATH_LITERAL("dirempty"))}; + + for (const TestDirectory& dir : directories) { + const FilePath dir_path = temp_dir.GetPath().Append(dir.name); + ASSERT_TRUE(CreateDirectory(dir_path)); + } + + std::vector<TestFile> files = { + TestFile(FILE_PATH_LITERAL("dir1"), FILE_PATH_LITERAL("file1"), "First"), + TestFile(FILE_PATH_LITERAL("dir1"), FILE_PATH_LITERAL("file2"), "Second"), + TestFile(FILE_PATH_LITERAL("dir2"), FILE_PATH_LITERAL("fileA"), + "Third-third-3"), + TestFile(FILE_PATH_LITERAL("dir3"), FILE_PATH_LITERAL(".file"), "Dot")}; + SetUpTestFiles(temp_dir, files); + + // Get last-modification times for directories. Must be done after we create + // all the files. + for (TestDirectory& dir : directories) { + const FilePath dir_path = temp_dir.GetPath().Append(dir.name); + ASSERT_TRUE(GetFileInfo(dir_path, dir.info)); + } + + FileEnumerator file_enumerator( + temp_dir.GetPath(), true, + FileEnumerator::FILES | FileEnumerator::DIRECTORIES); + while (!file_enumerator.Next().empty()) { + auto info = file_enumerator.GetInfo(); + bool found = false; + if (info.IsDirectory()) { + for (TestDirectory& dir : directories) { + if (info.GetName() == dir.name) { + CheckDirectoryAgainstInfo(info, dir); + found = true; + break; + } + } + } else { + for (TestFile& file : files) { + if (info.GetName() == file.path.BaseName()) { + CheckFileAgainstInfo(info, file); + found = true; + break; + } + } + } + + EXPECT_TRUE(found) << "Got unexpected result " << info.GetName().value(); + } + + for (const TestDirectory& dir : directories) { + EXPECT_TRUE(dir.found) << "Directory " << dir.name.value() + << " was not returned"; + } + for (const TestFile& file : files) { + EXPECT_TRUE(file.found) + << "File " << file.path.value() << " was not returned"; + } +} + +#if defined(OS_FUCHSIA) +// FileEnumerator::GetInfo does not work correctly with INCLUDE_DOT_DOT. +// https://crbug.com/1106172 +#else +// Tests that FileEnumerator::GetInfo() returns the correct info for the .. +// directory. +TEST(FileEnumerator, GetInfoDotDot) { + ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + + const FilePath::CharType kSubdir[] = FILE_PATH_LITERAL("subdir"); + const FilePath subdir_path = temp_dir.GetPath().Append(kSubdir); + ASSERT_TRUE(CreateDirectory(subdir_path)); + + std::vector<TestFile> files = { + TestFile(kSubdir, FILE_PATH_LITERAL("file1"), "First"), + TestFile(kSubdir, FILE_PATH_LITERAL("file2"), "Second"), + TestFile(kSubdir, FILE_PATH_LITERAL("file3"), "Third-third-third")}; + SetUpTestFiles(temp_dir, files); + + TestDirectory dotdot(FILE_PATH_LITERAL("..")); + // test_dir/subdir/.. is just test_dir. + ASSERT_TRUE(GetFileInfo(temp_dir.GetPath(), dotdot.info)); + + FileEnumerator file_enumerator(subdir_path, false, + FileEnumerator::FILES | + FileEnumerator::DIRECTORIES | + FileEnumerator::INCLUDE_DOT_DOT); + while (!file_enumerator.Next().empty()) { + auto info = file_enumerator.GetInfo(); + bool found = false; + if (info.IsDirectory()) { + EXPECT_EQ(info.GetName(), FilePath(FILE_PATH_LITERAL(".."))); + CheckDirectoryAgainstInfo(info, dotdot); + found = true; + } else { + for (TestFile& file : files) { + if (info.GetName() == file.path.BaseName()) { + CheckFileAgainstInfo(info, file); + found = true; + break; + } + } + } + + EXPECT_TRUE(found) << "Got unexpected result " << info.GetName().value(); + } + + EXPECT_TRUE(dotdot.found) << "Directory .. was not returned"; + + for (const TestFile& file : files) { + EXPECT_TRUE(file.found) + << "File " << file.path.value() << " was not returned"; + } +} +#endif // !defined(OS_FUCHSIA) + } // namespace base
diff --git a/base/location.h b/base/location.h index c9057b2..a5d3a92 100644 --- a/base/location.h +++ b/base/location.h
@@ -18,7 +18,7 @@ namespace base { -#if defined(__has_builtin) +#if defined(__clang__) // Clang allows detection of these builtins. #define SUPPORTS_LOCATION_BUILTINS \ (__has_builtin(__builtin_FUNCTION) && __has_builtin(__builtin_FILE) && \
diff --git a/base/memory/checked_ptr.h b/base/memory/checked_ptr.h index 46f0c4ba..6fc02d1f 100644 --- a/base/memory/checked_ptr.h +++ b/base/memory/checked_ptr.h
@@ -343,15 +343,6 @@ #endif // defined(ARCH_CPU_64_BITS) && !defined(OS_NACL) -template <typename T> -struct DereferencedPointerType { - using Type = decltype(*std::declval<T*>()); -}; -// This explicitly doesn't define any type aliases, since dereferencing void is -// invalid. -template <> -struct DereferencedPointerType<void> {}; - } // namespace internal // DO NOT USE! EXPERIMENTAL ONLY! This is helpful for local testing! @@ -423,11 +414,10 @@ return wrapped_ptr_ != Impl::GetWrappedNullPtr(); } - // Use SFINAE to avoid defining |operator*| for T=void, which wouldn't compile - // due to |void&|. template <typename U = T, - typename V = typename internal::DereferencedPointerType<U>::Type> - ALWAYS_INLINE V& operator*() const { + typename Unused = std::enable_if_t< + !std::is_void<typename std::remove_cv<U>::type>::value>> + ALWAYS_INLINE U& operator*() const { return *GetForDereference(); } ALWAYS_INLINE T* operator->() const { return GetForDereference(); }
diff --git a/base/memory/checked_ptr_unittest.nc b/base/memory/checked_ptr_unittest.nc index c19b4779..f0e37de4 100644 --- a/base/memory/checked_ptr_unittest.nc +++ b/base/memory/checked_ptr_unittest.nc
@@ -73,7 +73,7 @@ std::ignore = static_cast<Unrelated*>(ptr); } -#elif defined(NCTEST_VOID_DEREFERENCE) // [r"ISO C\+\+ does not allow indirection on operand of type 'const void \*' \[-Wvoid-ptr-dereference\]"] +#elif defined(NCTEST_VOID_DEREFERENCE) // [r"indirection requires pointer operand \('CheckedPtr<const void>' invalid\)"] void WontCompile() { const char foo[] = "42";
diff --git a/base/util/ranges/algorithm.h b/base/util/ranges/algorithm.h index 48e3e15..2c95a02 100644 --- a/base/util/ranges/algorithm.h +++ b/base/util/ranges/algorithm.h
@@ -2222,17 +2222,227 @@ // [alg.reverse] Reverse // Reference: https://wg21.link/alg.reverse -// TODO(crbug.com/1071094): Implement. +// Effects: For each non-negative integer `i < (last - first) / 2`, applies +// `std::iter_swap` to all pairs of iterators `first + i, (last - i) - 1`. +// +// Returns: `last`. +// +// Complexity: Exactly `(last - first)/2` swaps. +// +// Reference: https://wg21.link/alg.reverse#:~:text=ranges::reverse(I +template <typename BidirectionalIterator, + typename = internal::iterator_category_t<BidirectionalIterator>> +constexpr auto reverse(BidirectionalIterator first, + BidirectionalIterator last) { + std::reverse(first, last); + return last; +} + +// Effects: For each non-negative integer `i < size(range) / 2`, applies +// `std::iter_swap` to all pairs of iterators +// `begin(range) + i, (end(range) - i) - 1`. +// +// Returns: `end(range)`. +// +// Complexity: Exactly `size(range)/2` swaps. +// +// Reference: https://wg21.link/alg.reverse#:~:text=ranges::reverse(R +template <typename Range, typename = internal::range_category_t<Range>> +constexpr auto reverse(Range&& range) { + return ranges::reverse(ranges::begin(range), ranges::end(range)); +} + +// Let `N` be `last - first`. +// +// Preconditions: The ranges `[first, last)` and `[result, result + N)` do not +// overlap. +// +// Effects: Copies the range `[first, last)` to the range `[result, result + N)` +// such that for every non-negative integer `i < N` the following assignment +// takes place: `*(result + N - 1 - i) = *(first + i)`. +// +// Returns: `result + N`. +// +// Complexity: Exactly `N` assignments. +// +// Reference: https://wg21.link/alg.reverse#:~:text=ranges::reverse_copy(I +template <typename BidirectionalIterator, + typename OutputIterator, + typename = internal::iterator_category_t<BidirectionalIterator>, + typename = internal::iterator_category_t<OutputIterator>> +constexpr auto reverse_copy(BidirectionalIterator first, + BidirectionalIterator last, + OutputIterator result) { + return std::reverse_copy(first, last, result); +} + +// Let `N` be `size(range)`. +// +// Preconditions: The ranges `range` and `[result, result + N)` do not +// overlap. +// +// Effects: Copies `range` to the range `[result, result + N)` such that for +// every non-negative integer `i < N` the following assignment takes place: +// `*(result + N - 1 - i) = *(begin(range) + i)`. +// +// Returns: `result + N`. +// +// Complexity: Exactly `N` assignments. +// +// Reference: https://wg21.link/alg.reverse#:~:text=ranges::reverse_copy(R +template <typename Range, + typename OutputIterator, + typename = internal::range_category_t<Range>, + typename = internal::iterator_category_t<OutputIterator>> +constexpr auto reverse_copy(Range&& range, OutputIterator result) { + return ranges::reverse_copy(ranges::begin(range), ranges::end(range), result); +} // [alg.rotate] Rotate // Reference: https://wg21.link/alg.rotate -// TODO(crbug.com/1071094): Implement. +// Preconditions: `[first, middle)` and `[middle, last)` are valid ranges. +// +// Effects: For each non-negative integer `i < (last - first)`, places the +// element from the position `first + i` into position +// `first + (i + (last - middle)) % (last - first)`. +// +// Returns: `first + (last - middle)`. +// +// Complexity: At most `last - first` swaps. +// +// Reference: https://wg21.link/alg.rotate#:~:text=ranges::rotate(I +template <typename ForwardIterator, + typename = internal::iterator_category_t<ForwardIterator>> +constexpr auto rotate(ForwardIterator first, + ForwardIterator middle, + ForwardIterator last) { + return std::rotate(first, middle, last); +} + +// Preconditions: `[begin(range), middle)` and `[middle, end(range))` are valid +// ranges. +// +// Effects: For each non-negative integer `i < size(range)`, places the element +// from the position `begin(range) + i` into position +// `begin(range) + (i + (end(range) - middle)) % size(range)`. +// +// Returns: `begin(range) + (end(range) - middle)`. +// +// Complexity: At most `size(range)` swaps. +// +// Reference: https://wg21.link/alg.rotate#:~:text=ranges::rotate(R +template <typename Range, typename = internal::range_category_t<Range>> +constexpr auto rotate(Range&& range, iterator_t<Range> middle) { + return ranges::rotate(ranges::begin(range), middle, ranges::end(range)); +} + +// Let `N` be `last - first`. +// +// Preconditions: `[first, middle)` and `[middle, last)` are valid ranges. The +// ranges `[first, last)` and `[result, result + N)` do not overlap. +// +// Effects: Copies the range `[first, last)` to the range `[result, result + N)` +// such that for each non-negative integer `i < N` the following assignment +// takes place: `*(result + i) = *(first + (i + (middle - first)) % N)`. +// +// Returns: `result + N`. +// +// Complexity: Exactly `N` assignments. +// +// Reference: https://wg21.link/alg.rotate#:~:text=ranges::rotate_copy(I +template <typename ForwardIterator, + typename OutputIterator, + typename = internal::iterator_category_t<ForwardIterator>, + typename = internal::iterator_category_t<OutputIterator>> +constexpr auto rotate_copy(ForwardIterator first, + ForwardIterator middle, + ForwardIterator last, + OutputIterator result) { + return std::rotate_copy(first, middle, last, result); +} + +// Let `N` be `size(range)`. +// +// Preconditions: `[begin(range), middle)` and `[middle, end(range))` are valid +// ranges. The ranges `range` and `[result, result + N)` do not overlap. +// +// Effects: Copies `range` to the range `[result, result + N)` such that for +// each non-negative integer `i < N` the following assignment takes place: +// `*(result + i) = *(begin(range) + (i + (middle - begin(range))) % N)`. +// +// Returns: `result + N`. +// +// Complexity: Exactly `N` assignments. +// +// Reference: https://wg21.link/alg.rotate#:~:text=ranges::rotate_copy(R +template <typename Range, + typename OutputIterator, + typename = internal::range_category_t<Range>, + typename = internal::iterator_category_t<OutputIterator>> +constexpr auto rotate_copy(Range&& range, + iterator_t<Range> middle, + OutputIterator result) { + return ranges::rotate_copy(ranges::begin(range), middle, ranges::end(range), + result); +} + +// [alg.random.sample] Sample +// Reference: https://wg21.link/alg.random.sample + +// Currently not implemented due to lack of std::sample in C++14. +// TODO(crbug.com/1071094): Consider implementing a hand-rolled version. // [alg.random.shuffle] Shuffle // Reference: https://wg21.link/alg.random.shuffle -// TODO(crbug.com/1071094): Implement. +// Preconditions: The type `std::remove_reference_t<UniformRandomBitGenerator>` +// meets the uniform random bit generator requirements. +// +// Effects: Permutes the elements in the range `[first, last)` such that each +// possible permutation of those elements has equal probability of appearance. +// +// Returns: `last`. +// +// Complexity: Exactly `(last - first) - 1` swaps. +// +// Remarks: To the extent that the implementation of this function makes use of +// random numbers, the object referenced by g shall serve as the +// implementation's source of randomness. +// +// Reference: https://wg21.link/alg.random.shuffle#:~:text=ranges::shuffle(I +template <typename RandomAccessIterator, + typename UniformRandomBitGenerator, + typename = internal::iterator_category_t<RandomAccessIterator>> +constexpr auto shuffle(RandomAccessIterator first, + RandomAccessIterator last, + UniformRandomBitGenerator&& g) { + std::shuffle(first, last, std::forward<UniformRandomBitGenerator>(g)); + return last; +} + +// Preconditions: The type `std::remove_reference_t<UniformRandomBitGenerator>` +// meets the uniform random bit generator requirements. +// +// Effects: Permutes the elements in `range` such that each possible permutation +// of those elements has equal probability of appearance. +// +// Returns: `end(range)`. +// +// Complexity: Exactly `size(range) - 1` swaps. +// +// Remarks: To the extent that the implementation of this function makes use of +// random numbers, the object referenced by g shall serve as the +// implementation's source of randomness. +// +// Reference: https://wg21.link/alg.random.shuffle#:~:text=ranges::shuffle(R +template <typename Range, + typename UniformRandomBitGenerator, + typename = internal::range_category_t<Range>> +constexpr auto shuffle(Range&& range, UniformRandomBitGenerator&& g) { + return ranges::shuffle(ranges::begin(range), ranges::end(range), + std::forward<UniformRandomBitGenerator>(g)); +} // [alg.nonmodifying] Sorting and related operations // Reference: https://wg21.link/alg.sorting
diff --git a/base/util/ranges/algorithm_unittest.cc b/base/util/ranges/algorithm_unittest.cc index 67af53c6..e018502 100644 --- a/base/util/ranges/algorithm_unittest.cc +++ b/base/util/ranges/algorithm_unittest.cc
@@ -6,6 +6,7 @@ #include <algorithm> #include <functional> +#include <random> #include <utility> #include "base/util/ranges/functional.h" @@ -672,6 +673,69 @@ EXPECT_THAT(output, ElementsAre(0, 1, 2, 0, 0)); } +TEST(RangesTest, Reverse) { + int input[] = {0, 1, 2, 3, 4}; + + EXPECT_EQ(input + 4, ranges::reverse(input + 2, input + 4)); + EXPECT_THAT(input, ElementsAre(0, 1, 3, 2, 4)); + + EXPECT_EQ(input + 5, ranges::reverse(input)); + EXPECT_THAT(input, ElementsAre(4, 2, 3, 1, 0)); +} + +TEST(RangesTest, ReverseCopy) { + int input[] = {0, 1, 2, 3, 4}; + int output[] = {0, 0, 0, 0, 0}; + + EXPECT_EQ(output + 2, ranges::reverse_copy(input + 2, input + 4, output)); + EXPECT_THAT(input, ElementsAre(0, 1, 2, 3, 4)); + EXPECT_THAT(output, ElementsAre(3, 2, 0, 0, 0)); + + EXPECT_EQ(output + 5, ranges::reverse_copy(input, output)); + EXPECT_THAT(input, ElementsAre(0, 1, 2, 3, 4)); + EXPECT_THAT(output, ElementsAre(4, 3, 2, 1, 0)); +} + +TEST(RangesTest, Rotate) { + int input[] = {0, 1, 2, 3, 4}; + + EXPECT_EQ(input + 3, ranges::rotate(input + 2, input + 3, input + 4)); + EXPECT_THAT(input, ElementsAre(0, 1, 3, 2, 4)); + + EXPECT_EQ(input + 3, ranges::rotate(input, input + 2)); + EXPECT_THAT(input, ElementsAre(3, 2, 4, 0, 1)); +} + +TEST(RangesTest, RotateCopy) { + int input[] = {0, 1, 2, 3, 4}; + int output[] = {0, 0, 0, 0, 0}; + + EXPECT_EQ(output + 2, + ranges::rotate_copy(input + 2, input + 3, input + 4, output)); + EXPECT_THAT(input, ElementsAre(0, 1, 2, 3, 4)); + EXPECT_THAT(output, ElementsAre(3, 2, 0, 0, 0)); + + EXPECT_EQ(output + 5, ranges::rotate_copy(input, input + 3, output)); + EXPECT_THAT(input, ElementsAre(0, 1, 2, 3, 4)); + EXPECT_THAT(output, ElementsAre(3, 4, 0, 1, 2)); +} + +TEST(RangesTest, Shuffle) { + int input[] = {0, 1, 2, 3, 4}; + + // Shuffles input[2] and input[3], thus we can't be certain about their + // positions. + EXPECT_EQ(input + 4, ranges::shuffle(input + 2, input + 4, + std::default_random_engine())); + EXPECT_EQ(input[0], 0); + EXPECT_EQ(input[1], 1); + EXPECT_EQ(input[4], 4); + EXPECT_THAT(input, ::testing::UnorderedElementsAre(0, 1, 2, 3, 4)); + + EXPECT_EQ(input + 5, ranges::shuffle(input, std::default_random_engine())); + EXPECT_THAT(input, ::testing::UnorderedElementsAre(0, 1, 2, 3, 4)); +} + TEST(RangesTest, LowerBound) { int array[] = {0, 0, 1, 1, 2, 2};
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 9357ea1..7feab25 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20200720.3.1 +0.20200721.1.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 9357ea1..7feab25 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20200720.3.1 +0.20200721.1.1
diff --git a/cc/trees/layer_tree_host_unittest_copyrequest.cc b/cc/trees/layer_tree_host_unittest_copyrequest.cc index 054bd6a..a0191d0e 100644 --- a/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -7,6 +7,8 @@ #include "base/bind.h" #include "base/location.h" #include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" +#include "base/test/test_timeouts.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "cc/layers/effect_tree_layer_list_iterator.h" @@ -39,11 +41,6 @@ ::testing::tuple<TestRendererType, CompositorMode>> { public: LayerTreeHostCopyRequestTest() : LayerTreeTest(renderer_type()) {} - ~LayerTreeHostCopyRequestTest() { - // To prevent any tasks posted from previous tests from interfering wait for - // the task environment to empty. - CCTestSuite::RunUntilIdle(); - } TestRendererType renderer_type() const { return ::testing::get<0>(GetParam()); @@ -231,9 +228,7 @@ client_.set_bounds(root_->bounds()); } - void BeginTest() override { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DidCommit() override { int frame = layer_tree_host()->SourceFrameNumber(); @@ -294,10 +289,7 @@ client_.set_bounds(root_->bounds()); } - void BeginTest() override { - callback_count_ = 0; - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DidCommit() override { int frame = layer_tree_host()->SourceFrameNumber(); @@ -308,68 +300,69 @@ viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP, base::BindOnce( &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback, - base::Unretained(this)))); + base::Unretained(this), &main_destroyed_event_))); impl_destroyed_->RequestCopyOfOutput(std::make_unique< viz::CopyOutputRequest>( viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP, base::BindOnce( &LayerTreeHostCopyRequestTestLayerDestroyed::CopyOutputCallback, - base::Unretained(this)))); - // We expect that the RequestCopyOfOutput won't yet return results until - // the main is destroyed. So we RunUntilIdle to ensure no PostTask is - // currently queued to return the result. - CCTestSuite::RunUntilIdle(); - EXPECT_EQ(0, callback_count_); + base::Unretained(this), &impl_destroyed_event_))); + EXPECT_FALSE(main_destroyed_event_.IsSignaled()); + EXPECT_FALSE(impl_destroyed_event_.IsSignaled()); // Destroy the main thread layer right away. main_destroyed_->RemoveFromParent(); main_destroyed_.reset(); - // Should callback with a NULL bitmap, result will be in a PostTask so - // RunUntilIdle(). - CCTestSuite::RunUntilIdle(); - EXPECT_EQ(1, callback_count_); - // Prevent drawing so we can't make a copy of the impl_destroyed layer. layer_tree_host()->SetViewportRectAndScale( gfx::Rect(), 1.f, GetCurrentLocalSurfaceIdAllocation()); break; case 2: - // Flush the message loops and make sure the callbacks run. + // Flush the message loops. layer_tree_host()->SetNeedsCommit(); break; case 3: - // No drawing means no readback yet. - EXPECT_EQ(1, callback_count_); + // There is no timing promise of when we'll get the main callback but if + // we wait for it, we should receive it before we destroy the impl and + // before the impl callback. The resulting bitmap will be empty because + // we destroyed it in the first frame before it got a chance to draw. + EXPECT_TRUE( + main_destroyed_event_.TimedWait(TestTimeouts::action_timeout())); + EXPECT_FALSE(impl_destroyed_event_.IsSignaled()); // Destroy the impl thread layer. impl_destroyed_->RemoveFromParent(); impl_destroyed_.reset(); - - // No callback yet because it's on the impl side. - EXPECT_EQ(1, callback_count_); break; case 4: - // Flush the message loops and make sure the callbacks run. + // Flush the message loops. layer_tree_host()->SetNeedsCommit(); break; case 5: - // We should get another callback with a NULL bitmap. - EXPECT_EQ(2, callback_count_); + // There is no timing promise of when we'll get the impl callback but if + // we wait for it, we should receive it before the end of the test. + // The resulting bitmap will be empty because we called + // SetViewportRectAndScale() in the first frame before it got a chance + // to draw. + EXPECT_TRUE( + impl_destroyed_event_.TimedWait(TestTimeouts::action_timeout())); EndTest(); break; } } - void CopyOutputCallback(std::unique_ptr<viz::CopyOutputResult> result) { + void CopyOutputCallback(base::WaitableEvent* event, + std::unique_ptr<viz::CopyOutputResult> result) { EXPECT_TRUE(result->IsEmpty()); - ++callback_count_; + event->Signal(); } - int callback_count_; FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_; + base::WaitableEvent main_destroyed_event_; scoped_refptr<FakePictureLayer> main_destroyed_; + base::WaitableEvent impl_destroyed_event_; scoped_refptr<FakePictureLayer> impl_destroyed_; }; @@ -379,8 +372,7 @@ CombineWithCompositorModes({TestRendererType::kGL, TestRendererType::kSkiaGL})); -// TODO(crbug/1096962): Investigate flakiness and reenable test once fixed. -TEST_P(LayerTreeHostCopyRequestTestLayerDestroyed, DISABLED_Test) { +TEST_P(LayerTreeHostCopyRequestTestLayerDestroyed, Test) { RunTest(compositor_mode()); } @@ -1012,9 +1004,7 @@ LayerTreeHostCopyRequestTest::SetupTree(); } - void BeginTest() override { - PostSetNeedsCommitToMainThread(); - } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } virtual void RequestCopy(Layer* layer) = 0;
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni index bd310eb..2b30e20 100644 --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni
@@ -990,6 +990,7 @@ "java/res/layout/photo_picker_toolbar.xml", "java/res/layout/powered_by_chrome_footer.xml", "java/res/layout/preference_text_scale.xml", + "java/res/layout/preference_turn_off_sync.xml", "java/res/layout/radio_button_group_homepage_preference.xml", "java/res/layout/radio_button_group_theme_preference.xml", "java/res/layout/recent_tabs_group_item.xml",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index b973434..63248da 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -513,6 +513,7 @@ "java/src/org/chromium/chrome/browser/directactions/MenuDirectActionHandler.java", "java/src/org/chromium/chrome/browser/directactions/SimpleDirectActionHandler.java", "java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutController.java", + "java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java", "java/src/org/chromium/chrome/browser/document/ChromeIntentUtil.java", "java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java", "java/src/org/chromium/chrome/browser/document/DocumentWebContentsDelegate.java", @@ -1484,6 +1485,7 @@ "java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java", "java/src/org/chromium/chrome/browser/sync/settings/SignInPreference.java", "java/src/org/chromium/chrome/browser/sync/settings/SyncAndServicesSettings.java", + "java/src/org/chromium/chrome/browser/sync/settings/SyncOffPreference.java", "java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java", "java/src/org/chromium/chrome/browser/sync/ui/PassphraseActivity.java", "java/src/org/chromium/chrome/browser/sync/ui/PassphraseCreationDialogFragment.java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index 78c6176..34a5395 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -195,6 +195,7 @@ "junit/src/org/chromium/chrome/browser/photo_picker/FileEnumWorkerTaskTest.java", "junit/src/org/chromium/chrome/browser/photo_picker/PickerBitmapViewTest.java", "junit/src/org/chromium/chrome/browser/policy/EnterpriseInfoTest.java", + "junit/src/org/chromium/chrome/browser/preferences/PrefServiceBridgeTest.java", "junit/src/org/chromium/chrome/browser/privacy/settings/PrivacyPreferencesManagerTest.java", "junit/src/org/chromium/chrome/browser/search_engines/SearchEngineChoiceMetricsTest.java", "junit/src/org/chromium/chrome/browser/search_engines/SearchEngineChoiceNotificationTest.java",
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java index 920c8947..ca92f80 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantClient.java
@@ -284,7 +284,9 @@ return; } - IdentityServicesProvider.get().getIdentityManager().getAccessToken( + IdentityManager identityManager = IdentityServicesProvider.get().getIdentityManager( + AutofillAssistantUiController.getProfile()); + identityManager.getAccessToken( mAccount, AUTH_TOKEN_TYPE, new IdentityManager.GetAccessTokenCallback() { @Override public void onGetTokenSuccess(AccessTokenData token) { @@ -310,7 +312,9 @@ return; } - IdentityServicesProvider.get().getIdentityManager().invalidateAccessToken(accessToken); + IdentityManager identityManager = IdentityServicesProvider.get().getIdentityManager( + AutofillAssistantUiController.getProfile()); + identityManager.invalidateAccessToken(accessToken); } /** Returns the e-mail address that corresponds to the access token or an empty string. */
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderCoordinator.java index 0eb091c..7653718e 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderCoordinator.java
@@ -11,12 +11,14 @@ import android.widget.ImageView; import org.chromium.chrome.autofill_assistant.R; +import org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiController; import org.chromium.chrome.browser.autofill_assistant.header.AssistantHeaderViewBinder.ViewHolder; import org.chromium.chrome.browser.signin.DisplayableProfileData; import org.chromium.chrome.browser.signin.IdentityServicesProvider; import org.chromium.chrome.browser.signin.ProfileDataCache; import org.chromium.components.signin.base.CoreAccountInfo; import org.chromium.components.signin.identitymanager.ConsentLevel; +import org.chromium.components.signin.identitymanager.IdentityManager; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; import java.util.Collections; @@ -48,9 +50,10 @@ R.dimen.autofill_assistant_profile_size); mProfileCache = new ProfileDataCache(context, imageSize); mProfileView = mView.findViewById(R.id.profile_image); + IdentityManager identityManager = IdentityServicesProvider.get().getIdentityManager( + AutofillAssistantUiController.getProfile()); mSignedInAccountName = CoreAccountInfo.getEmailFrom( - IdentityServicesProvider.get().getIdentityManager().getPrimaryAccountInfo( - ConsentLevel.SYNC)); + identityManager.getPrimaryAccountInfo(ConsentLevel.SYNC)); setupProfileImage(); // Bind view and mediator through the model.
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java index eb63c607..40de2ae 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayIntegrationTest.java
@@ -7,6 +7,7 @@ import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription; import static androidx.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.MatcherAssert.assertThat; @@ -123,6 +124,74 @@ } /** + * Showcasts the same element twice in a row, and taps it the second time. Tests that the second + * showcast works correctly, even though the showcasted area hasn't changed (see b/161471176). + */ + @Test + @MediumTest + public void testRepeatedShowCastOnSameElement() throws Exception { + SelectorProto element = + (SelectorProto) SelectorProto.newBuilder() + .addFilters( + SelectorProto.Filter.newBuilder().setCssSelector("#touch_area_one")) + .build(); + + ArrayList<ActionProto> list = new ArrayList<>(); + list.add( + (ActionProto) ActionProto.newBuilder() + .setFocusElement(FocusElementProto.newBuilder() + .setElement(element) + .setTouchableElementArea( + ElementAreaProto.newBuilder().addTouchable( + Rectangle.newBuilder().addElements( + element)))) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder() + .setMessage("First Prompt") + .addChoices(PromptProto.Choice.newBuilder().setChip( + ChipProto.newBuilder().setText("Continue")))) + .build()); + list.add( + (ActionProto) ActionProto.newBuilder() + .setFocusElement(FocusElementProto.newBuilder() + .setElement(element) + .setTouchableElementArea( + ElementAreaProto.newBuilder().addTouchable( + Rectangle.newBuilder().addElements( + element)))) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder() + .setMessage("Second Prompt") + .addChoices(PromptProto.Choice.newBuilder().setChip( + ChipProto.newBuilder().setText("Done")))) + .build()); + + AutofillAssistantTestScript script = new AutofillAssistantTestScript( + (SupportedScriptProto) SupportedScriptProto.newBuilder() + .setPath("autofill_assistant_target_website.html") + .setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip( + ChipProto.newBuilder().setText("Done"))) + .build(), + list); + runScript(script); + + waitUntil(() -> checkElementOnScreen(mTestRule, "touch_area_one")); + waitUntilViewMatchesCondition(withText("First Prompt"), isCompletelyDisplayed()); + onView(withContentDescription("Continue")).perform(click()); + waitUntilViewMatchesCondition(withText("Second Prompt"), isCompletelyDisplayed()); + + // Tapping on the element should remove it from the DOM. + assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_one"), is(true)); + tapElement(mTestRule, "touch_area_one"); + waitUntil(() -> !checkElementExists(mTestRule.getWebContents(), "touch_area_one")); + // Tapping on the element should be blocked by the overlay. + tapElement(mTestRule, "touch_area_four"); + assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_four"), is(true)); + } + + /** * Tests that clicking on a document element requiring scrolling works with a showcast. */ @Test
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java index 0175e79..d31be8f 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java
@@ -33,10 +33,12 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.lessThan; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.getElementValue; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.isNextAfterSibling; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.startAutofillAssistant; +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewInRootMatchesCondition; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewMatchesCondition; import android.support.test.InstrumentationRegistry; @@ -857,6 +859,20 @@ onView(withContentDescription("ZIP code*")).perform(scrollTo(), typeText("1234")); onView(withContentDescription("Phone*")).perform(scrollTo(), typeText("8008080808")); onView(withText("Done")).perform(scrollTo(), click()); + + addCreditCardAndSelectAddress(); + int tryNumber = 0; + int maxRetries = 3; + while (!hasAddress() && tryNumber++ < maxRetries) { + // If the new address is not yet present, we first need to close the popup dialog. + Espresso.pressBack(); + onView(withText("Cancel")).perform(scrollTo(), click()); + addCreditCardAndSelectAddress(); + } + assertThat(tryNumber, lessThan(maxRetries)); + } + + private void addCreditCardAndSelectAddress() { waitUntilViewMatchesCondition( allOf(withId(R.id.section_title_add_button_label), withText("Add card")), isCompletelyDisplayed()); @@ -867,11 +883,16 @@ Espresso.closeSoftKeyboard(); onView(allOf(withId(org.chromium.chrome.R.id.spinner), withChild(withText("Select")))) .perform(scrollTo(), click()); - onData(anything()) - .atPosition(1 /* address of John, 0 is SELECT (empty) */) - .inRoot(withDecorView(withClassName(containsString("Popup")))) - .perform(click()); - waitUntilViewMatchesCondition(withText(containsString("John Doe")), isDisplayed()); + } + + private boolean hasAddress() { + try { + waitUntilViewInRootMatchesCondition(withText(containsString("John Doe")), + withDecorView(withClassName(containsString("Popup"))), isDisplayed()); + return true; + } catch (AssertionError e) { + return false; + } } private void runScript(AutofillAssistantTestScript script) {
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java index 2320dbcd..17d46367 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
@@ -31,6 +31,7 @@ import androidx.annotation.Nullable; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.test.espresso.NoMatchingViewException; +import androidx.test.espresso.Root; import androidx.test.espresso.UiController; import androidx.test.espresso.ViewAction; import androidx.test.espresso.ViewAssertion; @@ -397,6 +398,24 @@ waitUntilViewMatchesCondition(matcher, condition, DEFAULT_MAX_TIME_TO_POLL); } + /** + * Same as {@link #waitUntilViewMatchesCondition(Matcher, Matcher)} but also uses {@code + * rootMatcher} to select the correct window. + */ + public static void waitUntilViewInRootMatchesCondition( + Matcher<View> matcher, Matcher<Root> rootMatcher, Matcher<View> condition) { + CriteriaHelper.pollInstrumentationThread(() -> { + try { + onView(matcher).inRoot(rootMatcher).check(matches(condition)); + } catch (NoMatchingViewException | AssertionError e) { + // Note: all other exceptions are let through, in particular + // AmbiguousViewMatcherException. + throw new CriteriaNotSatisfiedException( + "Timeout while waiting for " + matcher + " to satisfy " + condition); + } + }, DEFAULT_MAX_TIME_TO_POLL, DEFAULT_POLLING_INTERVAL); + } + /** @see {@link #waitUntilViewMatchesCondition(Matcher, Matcher)} */ public static void waitUntilViewMatchesCondition( Matcher<View> matcher, Matcher<View> condition, long maxTimeoutMs) {
diff --git a/chrome/android/java/res/layout/preference_turn_off_sync.xml b/chrome/android/java/res/layout/preference_turn_off_sync.xml new file mode 100644 index 0000000..6a82ab9 --- /dev/null +++ b/chrome/android/java/res/layout/preference_turn_off_sync.xml
@@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2020 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + style="@style/PreferenceLayout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center"> + + <TextView + android:id="@+id/turn_off_sync" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/turn_off_sync" + android:textAppearance="@style/TextAppearance.TextMediumThick.Blue" + android:gravity="center"/> + +</LinearLayout>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutController.java b/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutController.java index fe0f63c..6334e63 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutController.java
@@ -14,29 +14,21 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; -import org.chromium.base.UserData; -import org.chromium.base.UserDataHost; import org.chromium.blink.mojom.ViewportFit; -import org.chromium.chrome.browser.ChromeActivity; -import org.chromium.chrome.browser.tab.EmptyTabObserver; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tab.TabObserver; -import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.components.browser_ui.widget.InsetObserverView; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsObserver; import org.chromium.ui.base.WindowAndroid; /** - * Controls the display cutout state for the tab. + * Controls the display safe area for a {@link WebContents} and the cutout mode for an {@link + * Activity} window. + * + * The WebContents is updated with the safe area continuously, as long as {@link + * Delegate#getAttachedActivity()} returns a non-null value. The cutout mode is set on the + * Activity's window only in P+, and only when the associated WebContents is fullscreen. */ -public class DisplayCutoutController implements InsetObserverView.WindowInsetObserver, UserData { - private static final Class<DisplayCutoutController> USER_DATA_KEY = - DisplayCutoutController.class; - - /** The tab that this controller belongs to. */ - private Tab mTab; - +public class DisplayCutoutController implements InsetObserverView.WindowInsetObserver { /** {@link Window} of the current {@link Activity}. */ private Window mWindow; @@ -49,73 +41,47 @@ */ private @Nullable InsetObserverView mInsetObserverView; - /** Listens to various Tab events. */ - private final TabObserver mTabObserver = new EmptyTabObserver() { - @Override - public void onShown(Tab tab, @TabSelectionType int type) { - assert tab == mTab; + /** An interface for providing embedder-specific behavior to the controller. */ + interface Delegate { + /** Returns the activity this controller is associated with, if there is one. */ + @Nullable + Activity getAttachedActivity(); - // Force a layout update if we are now being shown. - maybeUpdateLayout(); - } + /** + * Returns the {@link WebContents} this controller should update the safe area for, if + * there is one. + */ + @Nullable + WebContents getWebContents(); - @Override - public void onInteractabilityChanged(Tab tab, boolean interactable) { - // Force a layout update if the tab is now in the foreground. - maybeUpdateLayout(); - } + /** Returns the view this controller uses for safe area updates, if there is one. */ + @Nullable + InsetObserverView getInsetObserverView(); - @Override - public void onActivityAttachmentChanged(Tab tab, @Nullable WindowAndroid window) { - assert tab == mTab; + /** Returns whether the user can interact with the associated WebContents/UI element. */ + boolean isInteractable(); + } + private final Delegate mDelegate; - if (window != null) { - maybeAddInsetObserver(tab.getWindowAndroid().getActivity().get()); - } else { - maybeRemoveInsetObserver(); - } - } - }; - - public static DisplayCutoutController from(Tab tab) { - UserDataHost host = tab.getUserDataHost(); - DisplayCutoutController controller = host.getUserData(USER_DATA_KEY); - return controller == null - ? host.setUserData(USER_DATA_KEY, new DisplayCutoutController(tab)) - : controller; + public DisplayCutoutController(Delegate delegate) { + mDelegate = delegate; + maybeAddInsetObserver(); } - /** - * Constructs a new DisplayCutoutController for a specific tab. - * @param tab The tab that this controller belongs to. - */ - @VisibleForTesting - DisplayCutoutController(Tab tab) { - mTab = tab; - - tab.addObserver(mTabObserver); - maybeAddInsetObserver(tab.getWindowAndroid().getActivity().get()); - } - - /** - * Add an observer to {@link InsetObserverView} if we have not already added - * one. - */ - private void maybeAddInsetObserver(Activity activity) { + /** Add an observer to {@link InsetObserverView} if we have not already added one. */ + void maybeAddInsetObserver() { + Activity activity = mDelegate.getAttachedActivity(); if (mInsetObserverView != null || activity == null) return; - mInsetObserverView = ((ChromeActivity) activity).getInsetObserverView(); + mInsetObserverView = mDelegate.getInsetObserverView(); if (mInsetObserverView == null) return; mInsetObserverView.addObserver(this); mWindow = activity.getWindow(); } - /** - * Remove the observer added to {@link InsetObserverView} if we have added - * one. - */ - private void maybeRemoveInsetObserver() { + /** Remove the observer added to {@link InsetObserverView} if we have added one. */ + void maybeRemoveInsetObserver() { if (mInsetObserverView == null) return; mInsetObserverView.removeObserver(this); @@ -123,9 +89,7 @@ mWindow = null; } - @Override public void destroy() { - mTab.removeObserver(mTabObserver); maybeRemoveInsetObserver(); } @@ -134,6 +98,10 @@ * @param value The new viewport fit value. */ public void setViewportFit(@WebContentsObserver.ViewportFitType int value) { + if (value != ViewportFit.AUTO) { + assert mDelegate.getWebContents().isFullscreenForCurrentTab(); + } + if (value == mViewportFit) return; mViewportFit = value; @@ -143,7 +111,7 @@ /** Implements {@link WindowInsetsObserver}. */ @Override public void onSafeAreaChanged(Rect area) { - WebContents webContents = mTab.getWebContents(); + WebContents webContents = mDelegate.getWebContents(); if (webContents == null) return; float dipScale = getDipScale(); @@ -163,18 +131,13 @@ * @param dipScale The devices dip scale as an integer. * @return The CSS pixel value adjusted for scale. */ - private int adjustInsetForScale(int inset, float dipScale) { + private static int adjustInsetForScale(int inset, float dipScale) { return (int) Math.ceil(inset / dipScale); } @VisibleForTesting - static void initForTesting(UserDataHost host, DisplayCutoutController controller) { - host.setUserData(USER_DATA_KEY, controller); - } - - @VisibleForTesting protected float getDipScale() { - return mTab.getWindowAndroid().getDisplay().getDipScale(); + return mDelegate.getWebContents().getTopLevelNativeWindow().getDisplay().getDipScale(); } /** @@ -186,7 +149,7 @@ @TargetApi(Build.VERSION_CODES.P) protected int getDisplayCutoutMode() { // If we are not interactable then force the default mode. - if (!mTab.isUserInteractable()) { + if (!mDelegate.isInteractable()) { return LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT; } @@ -223,4 +186,12 @@ attributes.layoutInDisplayCutoutMode = getDisplayCutoutMode(); setWindowAttributes(attributes); } + + void onActivityAttachmentChanged(@Nullable WindowAndroid window) { + if (window == null) { + maybeRemoveInsetObserver(); + } else { + maybeAddInsetObserver(); + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java new file mode 100644 index 0000000..ca3eb370 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java
@@ -0,0 +1,127 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.display_cutout; + +import android.app.Activity; + +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; + +import org.chromium.base.UserData; +import org.chromium.base.UserDataHost; +import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.tab.EmptyTabObserver; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabObserver; +import org.chromium.chrome.browser.tab.TabSelectionType; +import org.chromium.components.browser_ui.widget.InsetObserverView; +import org.chromium.content_public.browser.WebContents; +import org.chromium.content_public.browser.WebContentsObserver; +import org.chromium.ui.base.WindowAndroid; + +/** + * Wraps a {@link DisplayCutoutController} for a Chrome {@link Tab}. + * + * This will only be created once the tab sets a non-default viewport fit. + */ +public class DisplayCutoutTabHelper implements UserData { + private static final Class<DisplayCutoutTabHelper> USER_DATA_KEY = DisplayCutoutTabHelper.class; + + /** The tab that this object belongs to. */ + private Tab mTab; + + @VisibleForTesting + DisplayCutoutController mCutoutController; + + /** Listens to various Tab events. */ + private final TabObserver mTabObserver = new EmptyTabObserver() { + @Override + public void onShown(Tab tab, @TabSelectionType int type) { + assert tab == mTab; + + // Force a layout update if we are now being shown. + mCutoutController.maybeUpdateLayout(); + } + + @Override + public void onInteractabilityChanged(Tab tab, boolean interactable) { + // Force a layout update if the tab is now in the foreground. + mCutoutController.maybeUpdateLayout(); + } + + @Override + public void onActivityAttachmentChanged(Tab tab, @Nullable WindowAndroid window) { + assert tab == mTab; + + mCutoutController.onActivityAttachmentChanged(window); + } + }; + + public static DisplayCutoutTabHelper from(Tab tab) { + UserDataHost host = tab.getUserDataHost(); + DisplayCutoutTabHelper tabHelper = host.getUserData(USER_DATA_KEY); + return tabHelper == null ? host.setUserData(USER_DATA_KEY, new DisplayCutoutTabHelper(tab)) + : tabHelper; + } + + @VisibleForTesting + static class ChromeDisplayCutoutDelegate implements DisplayCutoutController.Delegate { + private Tab mTab; + + ChromeDisplayCutoutDelegate(Tab tab) { + mTab = tab; + } + + @Override + public Activity getAttachedActivity() { + return mTab.getWindowAndroid().getActivity().get(); + } + @Override + public WebContents getWebContents() { + return mTab.getWebContents(); + } + @Override + public InsetObserverView getInsetObserverView() { + Activity activity = getAttachedActivity(); + return activity == null ? null : ((ChromeActivity) activity).getInsetObserverView(); + } + @Override + public boolean isInteractable() { + return mTab.isUserInteractable(); + } + } + + /** + * Constructs a new DisplayCutoutTabHelper for a specific tab. + * @param tab The tab that this object belongs to. + */ + @VisibleForTesting + DisplayCutoutTabHelper(Tab tab) { + mTab = tab; + tab.addObserver(mTabObserver); + mCutoutController = new DisplayCutoutController(new ChromeDisplayCutoutDelegate(mTab)); + } + + /** + * Set the viewport fit value for the tab. + * @param value The new viewport fit value. + */ + public void setViewportFit(@WebContentsObserver.ViewportFitType int value) { + mCutoutController.setViewportFit(value); + } + + @Override + public void destroy() { + mTab.removeObserver(mTabObserver); + mCutoutController.destroy(); + } + + @VisibleForTesting + static void initForTesting(Tab tab, DisplayCutoutController controller) { + DisplayCutoutTabHelper tabHelper = new DisplayCutoutTabHelper(tab); + tabHelper.mCutoutController = controller; + tab.getUserDataHost().setUserData(USER_DATA_KEY, tabHelper); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncOffPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncOffPreference.java new file mode 100644 index 0000000..6084f9ec --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncOffPreference.java
@@ -0,0 +1,23 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.sync.settings; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.preference.DialogPreference; + +import org.chromium.chrome.R; + +/** + * A preference that displays "Sign out and turn off sync" button in {@link ManageSyncSettings}. + */ +public class SyncOffPreference extends DialogPreference { + public SyncOffPreference(Context context, AttributeSet attrs) { + super(context, attrs); + + setLayoutResource(R.layout.preference_turn_off_sync); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS b/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS index 6720286d..766b6a96 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS
@@ -76,5 +76,8 @@ ], 'TabViewManagerImpl\.java': [ "+chrome/browser/browser_controls/android/java/src/org/chromium/chrome/browser/browser_controls/BrowserControlsMarginSupplier.java", + ], + 'TabWebContentsObserver\.java': [ + "+chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java", ] }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java index b319303f..8ba6590 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
@@ -20,7 +20,7 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.SwipeRefreshHandler; -import org.chromium.chrome.browser.display_cutout.DisplayCutoutController; +import org.chromium.chrome.browser.display_cutout.DisplayCutoutTabHelper; import org.chromium.chrome.browser.media.MediaCaptureNotificationService; import org.chromium.chrome.browser.policy.PolicyAuditor; import org.chromium.chrome.browser.policy.PolicyAuditor.AuditEvent; @@ -347,7 +347,7 @@ @Override public void viewportFitChanged(@WebContentsObserver.ViewportFitType int value) { - DisplayCutoutController.from(mTab).setViewportFit(value); + DisplayCutoutTabHelper.from(mTab).setViewportFit(value); } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTestRule.java index 96369ce9..8b1b782 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTestRule.java
@@ -59,8 +59,8 @@ private boolean mDeviceHasCutout = true; private float mDipScale = 1; - TestDisplayCutoutController(Tab tab) { - super(tab); + TestDisplayCutoutController(DisplayCutoutController.Delegate delegate) { + super(delegate); } @Override @@ -159,10 +159,11 @@ protected void setUp() { mTab = getActivity().getActivityTab(); - mTestController = new TestDisplayCutoutController(mTab); + mTestController = new TestDisplayCutoutController( + new DisplayCutoutTabHelper.ChromeDisplayCutoutDelegate(mTab)); + TestThreadUtils.runOnUiThreadBlocking( - () -> DisplayCutoutController.initForTesting( - mTab.getUserDataHost(), mTestController)); + () -> DisplayCutoutTabHelper.initForTesting(mTab, mTestController)); mListener = new FullscreenToggleObserver(); getActivity().getFullscreenManager().addObserver(mListener);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AndroidSyncSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AndroidSyncSettingsTest.java index 353a873..db74470 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AndroidSyncSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AndroidSyncSettingsTest.java
@@ -19,15 +19,15 @@ import org.junit.runner.RunWith; import org.chromium.base.Callback; +import org.chromium.base.FeatureList; import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.sync.AndroidSyncSettings.AndroidSyncSettingsObserver; -import org.chromium.chrome.test.util.browser.Features.DisableFeatures; -import org.chromium.chrome.test.util.browser.Features.EnableFeatures; -import org.chromium.chrome.test.util.browser.Features.JUnitProcessor; +import org.chromium.chrome.test.ChromeBrowserTestRule; +import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.signin.AccountManagerFacadeProvider; import org.chromium.components.signin.AccountUtils; import org.chromium.components.signin.test.util.FakeAccountManagerFacade; @@ -41,7 +41,6 @@ * Tests for AndroidSyncSettings. */ @RunWith(BaseJUnit4ClassRunner.class) -@DisableFeatures(ChromeFeatureList.DECOUPLE_SYNC_FROM_ANDROID_MASTER_SYNC) public class AndroidSyncSettingsTest { private static class CountingMockSyncContentResolverDelegate extends MockSyncContentResolverDelegate { @@ -106,8 +105,11 @@ } } + // |mChromeBrowserRule| is used to wait for the native feature list to initialize. @Rule - public TestRule mProcessorRule = new JUnitProcessor(); + public TestRule mChromeBrowserRule = new ChromeBrowserTestRule(); + @Rule + public TestRule mProcessorRule = new Features.JUnitProcessor(); private AndroidSyncSettings mAndroidSyncSettings; private CountingMockSyncContentResolverDelegate mSyncContentResolverDelegate; @@ -120,6 +122,8 @@ @Before public void setUp() throws Exception { + FeatureList.setTestCanUseDefaultsForTesting(); + mNumberOfCallsToWait = 0; mCallbackHelper = new CallbackHelper(); setupTestAccounts(); @@ -148,6 +152,16 @@ fakeAccountManagerFacade.addAccount(mAlternateAccount); } + private void setMasterSyncAllowsChromeSync() throws InterruptedException { + if (!ChromeFeatureList.isEnabled( + ChromeFeatureList.DECOUPLE_SYNC_FROM_ANDROID_MASTER_SYNC)) { + mSyncContentResolverDelegate.setMasterSyncAutomatically(true); + mSyncContentResolverDelegate.waitForLastNotificationCompleted(); + } + // If DecoupleSyncFromAndroidMasterSync is enabled, no need for any + // setup since master sync doesn't influence sync. + } + @After public void tearDown() throws Exception { if (mNumberOfCallsToWait > 0) mCallbackHelper.waitForCallback(0, mNumberOfCallsToWait); @@ -213,22 +227,28 @@ public void testToggleMasterSyncFromSettings() throws InterruptedException { mSyncContentResolverDelegate.setMasterSyncAutomatically(true); mSyncContentResolverDelegate.waitForLastNotificationCompleted(); - Assert.assertTrue("master sync should be set", - mAndroidSyncSettings.doesMasterSyncSettingAllowChromeSync()); + Assert.assertTrue(mAndroidSyncSettings.doesMasterSyncSettingAllowChromeSync()); mSyncContentResolverDelegate.setMasterSyncAutomatically(false); mSyncContentResolverDelegate.waitForLastNotificationCompleted(); - Assert.assertFalse("master sync should be unset", - mAndroidSyncSettings.doesMasterSyncSettingAllowChromeSync()); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.DECOUPLE_SYNC_FROM_ANDROID_MASTER_SYNC)) { + Assert.assertTrue( + "when DecoupleSyncFromAndroidMasterSync is enabled, sync should be allowed " + + "even though master sync is disabled", + mAndroidSyncSettings.doesMasterSyncSettingAllowChromeSync()); + } else { + Assert.assertFalse( + "when DecoupleSyncFromAndroidMasterSync is disabled, sync shouldn't be allowed " + + "if master sync is disabled", + mAndroidSyncSettings.doesMasterSyncSettingAllowChromeSync()); + } } @Test @SmallTest @Feature({"Sync"}) public void testToggleChromeSyncFromSettings() throws InterruptedException { - // Turn on syncability. - mSyncContentResolverDelegate.setMasterSyncAutomatically(true); - mSyncContentResolverDelegate.waitForLastNotificationCompleted(); + setMasterSyncAllowsChromeSync(); // First sync mSyncContentResolverDelegate.setIsSyncable(mAccount, mAuthority, 1); @@ -253,24 +273,29 @@ Assert.assertTrue( "sync should be set for chrome app", mAndroidSyncSettings.isChromeSyncEnabled()); - // Disabled from master sync + // Disable master sync mSyncContentResolverDelegate.setMasterSyncAutomatically(false); mSyncContentResolverDelegate.waitForLastNotificationCompleted(); - Assert.assertFalse( - "sync should be disabled due to master sync", mAndroidSyncSettings.isSyncEnabled()); - Assert.assertFalse("master sync should be disabled", - mAndroidSyncSettings.doesMasterSyncSettingAllowChromeSync()); Assert.assertTrue( "sync should be set for chrome app", mAndroidSyncSettings.isChromeSyncEnabled()); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.DECOUPLE_SYNC_FROM_ANDROID_MASTER_SYNC)) { + Assert.assertTrue("sync should be enabled despite master sync being disabled", + mAndroidSyncSettings.isSyncEnabled()); + Assert.assertTrue("master sync should allow sync", + mAndroidSyncSettings.doesMasterSyncSettingAllowChromeSync()); + } else { + Assert.assertFalse("sync should be disabled due to master sync disabled", + mAndroidSyncSettings.isSyncEnabled()); + Assert.assertFalse("master sync should not allow sync", + mAndroidSyncSettings.doesMasterSyncSettingAllowChromeSync()); + } } @Test @SmallTest @Feature({"Sync"}) public void testToggleAccountSyncFromApplication() throws InterruptedException { - // Turn on syncability. - mSyncContentResolverDelegate.setMasterSyncAutomatically(true); - mSyncContentResolverDelegate.waitForLastNotificationCompleted(); + setMasterSyncAllowsChromeSync(); enableChromeSyncOnUiThread(); mSyncContentResolverDelegate.waitForLastNotificationCompleted(); @@ -285,9 +310,7 @@ @SmallTest @Feature({"Sync"}) public void testToggleSyncabilityForMultipleAccounts() throws InterruptedException { - // Turn on syncability. - mSyncContentResolverDelegate.setMasterSyncAutomatically(true); - mSyncContentResolverDelegate.waitForLastNotificationCompleted(); + setMasterSyncAllowsChromeSync(); enableChromeSyncOnUiThread(); mSyncContentResolverDelegate.waitForLastNotificationCompleted(); @@ -316,9 +339,7 @@ @SmallTest @Feature({"Sync"}) public void testSyncSettingsCaching() throws InterruptedException { - // Turn on syncability. - mSyncContentResolverDelegate.setMasterSyncAutomatically(true); - mSyncContentResolverDelegate.waitForLastNotificationCompleted(); + setMasterSyncAllowsChromeSync(); enableChromeSyncOnUiThread(); mSyncContentResolverDelegate.waitForLastNotificationCompleted(); @@ -371,9 +392,7 @@ @SmallTest @Feature({"Sync"}) public void testAndroidSyncSettingsPostsNotifications() throws InterruptedException { - // Turn on syncability. - mSyncContentResolverDelegate.setMasterSyncAutomatically(true); - mSyncContentResolverDelegate.waitForLastNotificationCompleted(); + setMasterSyncAllowsChromeSync(); mSyncSettingsObserver.clearNotification(); mAndroidSyncSettings.enableChromeSync(); @@ -452,7 +471,9 @@ @Test @SmallTest @Feature({"Sync"}) - @EnableFeatures(ChromeFeatureList.DECOUPLE_SYNC_FROM_ANDROID_MASTER_SYNC) + @Features.EnableFeatures(ChromeFeatureList.DECOUPLE_SYNC_FROM_ANDROID_MASTER_SYNC) + // TODO(crbug.com/1105795): Remove this test after DecoupleSyncFromAndroidMasterSync has + // launched, since testToggleChromeSyncFromSettings() covers the same functionality. public void testSyncStateDoesNotDependOnMasterSync() throws InterruptedException { mSyncContentResolverDelegate.setSyncAutomatically(mAccount, mAuthority, true); mSyncContentResolverDelegate.setMasterSyncAutomatically(false);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java index 7ad70be..4fd6dcfb 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java
@@ -12,16 +12,19 @@ import org.junit.Assert; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.IdentityServicesProvider; import org.chromium.chrome.browser.signin.SigninHelper; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.signin.MockChangeEventChecker; import org.chromium.chrome.test.util.browser.sync.SyncTestUtil; import org.chromium.content_public.browser.test.util.Criteria; @@ -36,6 +39,8 @@ public class SyncTest { @Rule public SyncTestRule mSyncTestRule = new SyncTestRule(); + @Rule + public TestRule mProcessorRule = new Features.JUnitProcessor(); private static final String TAG = "SyncTest"; @@ -152,6 +157,7 @@ @Test @LargeTest + @Features.DisableFeatures(ChromeFeatureList.DECOUPLE_SYNC_FROM_ANDROID_MASTER_SYNC) @Feature({"Sync"}) public void testStopAndStartSyncThroughAndroidMasterSync() { mSyncTestRule.setUpAccountAndSignInForTesting(); @@ -171,6 +177,7 @@ @Test @LargeTest @Feature({"Sync"}) + @Features.DisableFeatures(ChromeFeatureList.DECOUPLE_SYNC_FROM_ANDROID_MASTER_SYNC) @DisabledTest(message = "Test is flaky crbug.com/1100890") public void testReenableMasterSyncFirst() { Account account = mSyncTestRule.setUpAccountAndSignInForTesting(); @@ -203,6 +210,7 @@ @Test @LargeTest + @Features.DisableFeatures(ChromeFeatureList.DECOUPLE_SYNC_FROM_ANDROID_MASTER_SYNC) @Feature({"Sync"}) public void testReenableChromeSyncFirst() { Account account = mSyncTestRule.setUpAccountAndSignInForTesting(); @@ -240,6 +248,7 @@ @Test @LargeTest + @Features.DisableFeatures(ChromeFeatureList.DECOUPLE_SYNC_FROM_ANDROID_MASTER_SYNC) @Feature({"Sync"}) public void testMasterSyncBlocksSyncStart() { mSyncTestRule.setUpAccountAndSignInForTesting();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutControllerTest.java index d12451b7..6accbf56 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutControllerTest.java
@@ -31,6 +31,7 @@ import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.components.browser_ui.widget.InsetObserverView; +import org.chromium.content_public.browser.WebContents; import org.chromium.testing.local.LocalRobolectricTestRunner; import org.chromium.ui.base.WindowAndroid; @@ -46,6 +47,9 @@ private TabImpl mTab; @Mock + private WebContents mWebContents; + + @Mock private WindowAndroid mWindowAndroid; @Mock @@ -60,7 +64,8 @@ @Mock private InsetObserverView mInsetObserver; - private DisplayCutoutController mDisplayCutoutController; + private DisplayCutoutTabHelper mDisplayCutoutTabHelper; + private DisplayCutoutController mController; private WeakReference<Activity> mActivityRef; @@ -75,28 +80,32 @@ when(mChromeActivity.getWindow()).thenReturn(mWindow); when(mWindow.getAttributes()).thenReturn(new LayoutParams()); when(mTab.getWindowAndroid()).thenReturn(mWindowAndroid); + when(mTab.getWebContents()).thenReturn(mWebContents); + when(mWebContents.isFullscreenForCurrentTab()).thenReturn(true); when(mWindowAndroid.getActivity()).thenReturn(mActivityRef); when(mChromeActivity.getInsetObserverView()).thenReturn(mInsetObserver); - mDisplayCutoutController = spy(new DisplayCutoutController(mTab)); + mDisplayCutoutTabHelper = spy(new DisplayCutoutTabHelper(mTab)); + mController = spy(mDisplayCutoutTabHelper.mCutoutController); + mDisplayCutoutTabHelper.mCutoutController = mController; } @Test @SmallTest public void testViewportFitUpdate() { - verify(mDisplayCutoutController, never()).maybeUpdateLayout(); + verify(mController, never()).maybeUpdateLayout(); - mDisplayCutoutController.setViewportFit(ViewportFit.COVER); - verify(mDisplayCutoutController).maybeUpdateLayout(); + mDisplayCutoutTabHelper.setViewportFit(ViewportFit.COVER); + verify(mController).maybeUpdateLayout(); } @Test @SmallTest public void testViewportFitUpdateNotChanged() { - verify(mDisplayCutoutController, never()).maybeUpdateLayout(); + verify(mController, never()).maybeUpdateLayout(); - mDisplayCutoutController.setViewportFit(ViewportFit.AUTO); - verify(mDisplayCutoutController, never()).maybeUpdateLayout(); + mDisplayCutoutTabHelper.setViewportFit(ViewportFit.AUTO); + verify(mController, never()).maybeUpdateLayout(); } @Test @@ -104,9 +113,9 @@ public void testCutoutModeWhenAutoAndInteractable() { when(mTab.isUserInteractable()).thenReturn(true); - mDisplayCutoutController.setViewportFit(ViewportFit.AUTO); + mDisplayCutoutTabHelper.setViewportFit(ViewportFit.AUTO); Assert.assertEquals(LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT, - mDisplayCutoutController.getDisplayCutoutMode()); + mController.getDisplayCutoutMode()); } @Test @@ -114,9 +123,9 @@ public void testCutoutModeWhenCoverAndInteractable() { when(mTab.isUserInteractable()).thenReturn(true); - mDisplayCutoutController.setViewportFit(ViewportFit.COVER); + mDisplayCutoutTabHelper.setViewportFit(ViewportFit.COVER); Assert.assertEquals(LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES, - mDisplayCutoutController.getDisplayCutoutMode()); + mController.getDisplayCutoutMode()); } @Test @@ -124,9 +133,9 @@ public void testCutoutModeWhenCoverForcedAndInteractable() { when(mTab.isUserInteractable()).thenReturn(true); - mDisplayCutoutController.setViewportFit(ViewportFit.COVER_FORCED_BY_USER_AGENT); + mDisplayCutoutTabHelper.setViewportFit(ViewportFit.COVER_FORCED_BY_USER_AGENT); Assert.assertEquals(LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES, - mDisplayCutoutController.getDisplayCutoutMode()); + mController.getDisplayCutoutMode()); } @Test @@ -134,41 +143,41 @@ public void testCutoutModeWhenContainAndInteractable() { when(mTab.isUserInteractable()).thenReturn(true); - mDisplayCutoutController.setViewportFit(ViewportFit.CONTAIN); + mDisplayCutoutTabHelper.setViewportFit(ViewportFit.CONTAIN); Assert.assertEquals(LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER, - mDisplayCutoutController.getDisplayCutoutMode()); + mController.getDisplayCutoutMode()); } @Test @SmallTest public void testCutoutModeWhenAutoAndNotInteractable() { - mDisplayCutoutController.setViewportFit(ViewportFit.AUTO); + mDisplayCutoutTabHelper.setViewportFit(ViewportFit.AUTO); Assert.assertEquals(LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT, - mDisplayCutoutController.getDisplayCutoutMode()); + mController.getDisplayCutoutMode()); } @Test @SmallTest public void testCutoutModeWhenCoverAndNotInteractable() { - mDisplayCutoutController.setViewportFit(ViewportFit.COVER); + mDisplayCutoutTabHelper.setViewportFit(ViewportFit.COVER); Assert.assertEquals(LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT, - mDisplayCutoutController.getDisplayCutoutMode()); + mController.getDisplayCutoutMode()); } @Test @SmallTest public void testCutoutModeWhenCoverForcedAndNotInteractable() { - mDisplayCutoutController.setViewportFit(ViewportFit.COVER_FORCED_BY_USER_AGENT); + mDisplayCutoutTabHelper.setViewportFit(ViewportFit.COVER_FORCED_BY_USER_AGENT); Assert.assertEquals(LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT, - mDisplayCutoutController.getDisplayCutoutMode()); + mController.getDisplayCutoutMode()); } @Test @SmallTest public void testCutoutModeWhenContainAndNotInteractable() { - mDisplayCutoutController.setViewportFit(ViewportFit.CONTAIN); + mDisplayCutoutTabHelper.setViewportFit(ViewportFit.CONTAIN); Assert.assertEquals(LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT, - mDisplayCutoutController.getDisplayCutoutMode()); + mController.getDisplayCutoutMode()); } @Test @@ -176,7 +185,7 @@ public void testLayoutOnInteractability_True() { // In this test we are checking for a side effect of maybeUpdateLayout. // This is because the tab observer holds a reference to the original - // mDisplayCutoutController and not the spied one. + // mDisplayCutoutTabHelper and not the spied one. verify(mTab).addObserver(mTabObserverCaptor.capture()); reset(mTab); @@ -189,7 +198,7 @@ public void testLayoutOnInteractability_False() { // In this test we are checking for a side effect of maybeUpdateLayout. // This is because the tab observer holds a reference to the original - // mDisplayCutoutController and not the spied one. + // mDisplayCutoutTabHelper and not the spied one. verify(mTab).addObserver(mTabObserverCaptor.capture()); reset(mTab); @@ -214,7 +223,7 @@ public void testLayoutOnShown() { // In this test we are checking for a side effect of maybeUpdateLayout. // This is because the tab observer holds a reference to the original - // mDisplayCutoutController and not the spied one. + // mDisplayCutoutTabHelper and not the spied one. verify(mTab).addObserver(mTabObserverCaptor.capture()); reset(mTab);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/preferences/PrefServiceBridgeTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/preferences/PrefServiceBridgeTest.java new file mode 100644 index 0000000..706b1cb --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/preferences/PrefServiceBridgeTest.java
@@ -0,0 +1,111 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// generate_java_test.py + +package org.chromium.chrome.browser.preferences; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.JniMocker; + +/** Unit tests for {@link PrefServiceBridge}. */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class PrefServiceBridgeTest { + private static final String PREF = "42"; + + @Rule + public JniMocker mocker = new JniMocker(); + @Mock + private PrefServiceBridge.Natives mNativeMock; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mocker.mock(PrefServiceBridgeJni.TEST_HOOKS, mNativeMock); + } + + @Test + public void testGetBoolean() { + boolean expected = false; + + PrefServiceBridge prefServiceBridge = new PrefServiceBridge(); + doReturn(expected).when(mNativeMock).getBoolean(PREF); + + assertEquals(expected, prefServiceBridge.getBoolean(PREF)); + } + + @Test + public void testSetBoolean() { + boolean value = true; + + PrefServiceBridge prefServiceBridge = new PrefServiceBridge(); + prefServiceBridge.setBoolean(PREF, value); + + verify(mNativeMock).setBoolean(eq(PREF), eq(value)); + } + + @Test + public void testGetInteger() { + int expected = 26; + + PrefServiceBridge prefServiceBridge = new PrefServiceBridge(); + doReturn(expected).when(mNativeMock).getInteger(PREF); + + assertEquals(expected, prefServiceBridge.getInteger(PREF)); + } + + @Test + public void testSetInteger() { + int value = 62; + + PrefServiceBridge prefServiceBridge = new PrefServiceBridge(); + prefServiceBridge.setInteger(PREF, value); + + verify(mNativeMock).setInteger(eq(PREF), eq(value)); + } + + @Test + public void testGetString() { + String expected = "foo"; + + PrefServiceBridge prefServiceBridge = new PrefServiceBridge(); + doReturn(expected).when(mNativeMock).getString(PREF); + + assertEquals(expected, prefServiceBridge.getString(PREF)); + } + + @Test + public void testSetString() { + String value = "bar"; + + PrefServiceBridge prefServiceBridge = new PrefServiceBridge(); + prefServiceBridge.setString(PREF, value); + + verify(mNativeMock).setString(eq(PREF), eq(value)); + } + + @Test + public void testIsManaged() { + boolean expected = true; + + PrefServiceBridge prefServiceBridge = new PrefServiceBridge(); + doReturn(expected).when(mNativeMock).isManagedPreference(PREF); + + assertEquals(expected, prefServiceBridge.isManagedPreference(PREF)); + } +}
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 71080e2..527e35c0 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -2824,7 +2824,7 @@ Use metered connection </message> <message name="IDS_UPDATE_REQUIRED_SCREEN_NO_NETWORK_MESSAGE" desc="The message on the dialog shown to the user in Chrome OS before forced update is attempted if the Chrome OS device is not connected to a network."> - <ph name="DOMAIN">$1<ex>example.com</ex></ph> requires you to connect to Wi-Fi now and download an update. The update will download automatically when you connect to the internet. + <ph name="DOMAIN">$1<ex>example.com</ex></ph> requires you to connect to Wi-Fi now and download an update. </message> <message name="IDS_UPDATE_REQUIRED_SCREEN_OPEN_NETWORK_SETTINGS" desc="Label for network configuration button on the update required dialog on the login screen to open network settings so that the user can connect to a network."> Open network settings
diff --git a/chrome/app/chromeos_strings_grdp/IDS_UPDATE_REQUIRED_SCREEN_NO_NETWORK_MESSAGE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_UPDATE_REQUIRED_SCREEN_NO_NETWORK_MESSAGE.png.sha1 new file mode 100644 index 0000000..7603f6b0 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_UPDATE_REQUIRED_SCREEN_NO_NETWORK_MESSAGE.png.sha1
@@ -0,0 +1 @@ +ac79ba6f1aaaf62f545c3cac72469d40bbb67016 \ No newline at end of file
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index 4fa34571..4b6b685 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -1145,6 +1145,16 @@ </if> + <!-- Profile Picker --> + <if expr="not chromeos and not is_android"> + <message name="IDS_PROFILE_PICKER_MAIN_VIEW_TITLE" desc="Profile picker main view title"> + Pick your Chromium Space + </message> + <message name="IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE" desc="Profile picker main view subtitle"> + Use Chromium Spaces to keep your browsing organized on this device + </message> + </if> + </messages> </release> </grit>
diff --git a/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1 new file mode 100644 index 0000000..cbd5f67 --- /dev/null +++ b/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1
@@ -0,0 +1 @@ +c3d7fda79021a7aced9e44521ec13b3d450f9e59 \ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1 b/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1 new file mode 100644 index 0000000..cbd5f67 --- /dev/null +++ b/chrome/app/chromium_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1
@@ -0,0 +1 @@ +c3d7fda79021a7aced9e44521ec13b3d450f9e59 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index c9a3fa55..66d9128 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -1160,6 +1160,17 @@ Your parent has turned off "Permissions for sites, apps and extensions" for Chrome. Enabling this <ph name="EXTENSION_TYPE_PARAMETER">$1<ex>extension</ex></ph> is not allowed. </message> </if> + + <!-- Profile Picker --> + <if expr="not chromeos and not is_android"> + <message name="IDS_PROFILE_PICKER_MAIN_VIEW_TITLE" desc="Profile picker main view title"> + Pick your Chrome Space + </message> + <message name="IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE" desc="Profile picker main view subtitle"> + Use Chrome Spaces to keep your browsing organized on this device + </message> + </if> + </messages> </release> </grit>
diff --git a/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1 new file mode 100644 index 0000000..cbd5f67 --- /dev/null +++ b/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE.png.sha1
@@ -0,0 +1 @@ +c3d7fda79021a7aced9e44521ec13b3d450f9e59 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1 new file mode 100644 index 0000000..cbd5f67 --- /dev/null +++ b/chrome/app/google_chrome_strings_grd/IDS_PROFILE_PICKER_MAIN_VIEW_TITLE.png.sha1
@@ -0,0 +1 @@ +c3d7fda79021a7aced9e44521ec13b3d450f9e59 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index c7f3e14..1a430439 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2501,6 +2501,7 @@ "android/preferences/cookie_controls_service_bridge.h", "android/preferences/pref_change_registrar_android.cc", "android/preferences/pref_change_registrar_android.h", + "android/preferences/pref_service_bridge.cc", "android/preferences/privacy_preferences_manager.cc", "android/profile_key_startup_accessor.cc", "android/profile_key_startup_accessor.h",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index e6bfcd6..1fcbc991 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4861,7 +4861,7 @@ {"enable-skia-renderer", flag_descriptions::kSkiaRendererName, flag_descriptions::kSkiaRendererDescription, - kOsLinux | kOsWin | kOsAndroid, + kOsLinux | kOsWin | kOsAndroid | kOsMac, FEATURE_VALUE_TYPE(features::kUseSkiaRenderer)}, #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc b/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc index 8e168b53..87bd7f5 100644 --- a/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc +++ b/chrome/browser/android/bookmarks/partner_bookmarks_shim_unittest.cc
@@ -11,6 +11,7 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/android/bookmarks/partner_bookmarks_reader.h" +#include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/test/base/testing_profile.h" #include "components/bookmarks/test/bookmark_test_helpers.h" #include "content/public/browser/browser_thread.h" @@ -43,8 +44,11 @@ protected: // testing::Test void SetUp() override { - profile_.reset(new TestingProfile()); - profile_->CreateBookmarkModel(true); + TestingProfile::Builder profile_builder; + profile_builder.AddTestingFactory( + BookmarkModelFactory::GetInstance(), + BookmarkModelFactory::GetDefaultFactory()); + profile_ = profile_builder.Build(); } void TearDown() override {
diff --git a/chrome/browser/android/preferences/OWNERS b/chrome/browser/android/preferences/OWNERS index b54eef54..2299408 100644 --- a/chrome/browser/android/preferences/OWNERS +++ b/chrome/browser/android/preferences/OWNERS
@@ -1,4 +1,5 @@ -file://components/prefs/android/OWNERS +twellington@chromium.org +chouinard@chromium.org per-file cookie_controls*=dullweber@chromium.org
diff --git a/chrome/browser/android/preferences/pref_service_bridge.cc b/chrome/browser/android/preferences/pref_service_bridge.cc new file mode 100644 index 0000000..727e9b1 --- /dev/null +++ b/chrome/browser/android/preferences/pref_service_bridge.cc
@@ -0,0 +1,90 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <jni.h> + +#include <string> + +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "chrome/browser/preferences/jni_headers/PrefServiceBridge_jni.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "components/prefs/pref_service.h" + +namespace { + +using base::android::JavaParamRef; + +PrefService* GetPrefService() { + return ProfileManager::GetActiveUserProfile() + ->GetOriginalProfile() + ->GetPrefs(); +} + +} // namespace + +// ---------------------------------------------------------------------------- +// Native JNI methods +// ---------------------------------------------------------------------------- + +static void JNI_PrefServiceBridge_ClearPref( + JNIEnv* env, + const JavaParamRef<jstring>& j_preference) { + GetPrefService()->ClearPref( + base::android::ConvertJavaStringToUTF8(env, j_preference)); +} + +static jboolean JNI_PrefServiceBridge_GetBoolean( + JNIEnv* env, + const JavaParamRef<jstring>& j_preference) { + return GetPrefService()->GetBoolean( + base::android::ConvertJavaStringToUTF8(env, j_preference)); +} + +static void JNI_PrefServiceBridge_SetBoolean( + JNIEnv* env, + const JavaParamRef<jstring>& j_preference, + const jboolean j_value) { + GetPrefService()->SetBoolean( + base::android::ConvertJavaStringToUTF8(env, j_preference), j_value); +} + +static jint JNI_PrefServiceBridge_GetInteger( + JNIEnv* env, + const JavaParamRef<jstring>& j_preference) { + return GetPrefService()->GetInteger( + base::android::ConvertJavaStringToUTF8(env, j_preference)); +} + +static void JNI_PrefServiceBridge_SetInteger( + JNIEnv* env, + const JavaParamRef<jstring>& j_preference, + const jint j_value) { + GetPrefService()->SetInteger( + base::android::ConvertJavaStringToUTF8(env, j_preference), j_value); +} + +static base::android::ScopedJavaLocalRef<jstring> +JNI_PrefServiceBridge_GetString(JNIEnv* env, + const JavaParamRef<jstring>& j_preference) { + return base::android::ConvertUTF8ToJavaString( + env, GetPrefService()->GetString( + base::android::ConvertJavaStringToUTF8(env, j_preference))); +} + +static void JNI_PrefServiceBridge_SetString( + JNIEnv* env, + const JavaParamRef<jstring>& j_preference, + const base::android::JavaParamRef<jstring>& j_value) { + GetPrefService()->SetString( + base::android::ConvertJavaStringToUTF8(env, j_preference), + base::android::ConvertJavaStringToUTF8(env, j_value)); +} + +static jboolean JNI_PrefServiceBridge_IsManagedPreference( + JNIEnv* env, + const JavaParamRef<jstring>& j_preference) { + return GetPrefService()->IsManagedPreference( + base::android::ConvertJavaStringToUTF8(env, j_preference)); +}
diff --git a/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc b/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc index 5fd0e32..3d258c24 100644 --- a/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc +++ b/chrome/browser/bookmarks/bookmark_html_writer_unittest.cc
@@ -154,13 +154,19 @@ TEST_F(BookmarkHTMLWriterTest, Test) { content::BrowserTaskEnvironment task_environment; - TestingProfile profile; - ASSERT_TRUE(profile.CreateHistoryService(true, false)); - profile.BlockUntilHistoryProcessesPendingRequests(); - profile.CreateFaviconService(); - profile.CreateBookmarkModel(true); + TestingProfile::Builder profile_builder; + profile_builder.AddTestingFactory(BookmarkModelFactory::GetInstance(), + BookmarkModelFactory::GetDefaultFactory()); + profile_builder.AddTestingFactory(FaviconServiceFactory::GetInstance(), + FaviconServiceFactory::GetDefaultFactory()); + profile_builder.AddTestingFactory(HistoryServiceFactory::GetInstance(), + HistoryServiceFactory::GetDefaultFactory()); - BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(&profile); + std::unique_ptr<TestingProfile> profile = profile_builder.Build(); + profile->BlockUntilHistoryProcessesPendingRequests(); + + BookmarkModel* model = + BookmarkModelFactory::GetForBrowserContext(profile.get()); bookmarks::test::WaitForBookmarkModelToLoad(model); // Create test PNG representing favicon for url1. @@ -208,10 +214,10 @@ const BookmarkNode* f1 = model->AddFolder( model->bookmark_bar_node(), 0, f1_title); model->AddURL(f1, 0, url1_title, url1, nullptr, t1); - HistoryServiceFactory::GetForProfile(&profile, + HistoryServiceFactory::GetForProfile(profile.get(), ServiceAccessType::EXPLICIT_ACCESS) ->AddPage(url1, base::Time::Now(), history::SOURCE_BROWSED); - FaviconServiceFactory::GetForProfile(&profile, + FaviconServiceFactory::GetForProfile(profile.get(), ServiceAccessType::EXPLICIT_ACCESS) ->SetFavicons({url1}, url1_favicon, favicon_base::IconType::kFavicon, gfx::Image::CreateFrom1xBitmap(bitmap)); @@ -233,7 +239,7 @@ // Write to a temp file. BookmarksObserver observer(&run_loop); - bookmark_html_writer::WriteBookmarks(&profile, path_, &observer); + bookmark_html_writer::WriteBookmarks(profile.get(), path_, &observer); run_loop.Run(); if (HasFailure()) { // WriteBookmarks has failed, no point in trying to read the file. @@ -241,7 +247,7 @@ } // Clear favicon so that it would be read from file. - FaviconServiceFactory::GetForProfile(&profile, + FaviconServiceFactory::GetForProfile(profile.get(), ServiceAccessType::EXPLICIT_ACCESS) ->SetFavicons({url1}, url1_favicon, favicon_base::IconType::kFavicon, gfx::Image());
diff --git a/chrome/browser/bookmarks/bookmark_model_factory.cc b/chrome/browser/bookmarks/bookmark_model_factory.cc index 6aff6bc..7bbee08 100644 --- a/chrome/browser/bookmarks/bookmark_model_factory.cc +++ b/chrome/browser/bookmarks/bookmark_model_factory.cc
@@ -28,8 +28,35 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +namespace { + using bookmarks::BookmarkModel; +std::unique_ptr<KeyedService> BuildBookmarkModel( + content::BrowserContext* context, + const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) { + Profile* profile = Profile::FromBrowserContext(context); + auto bookmark_model = + std::make_unique<BookmarkModel>(std::make_unique<ChromeBookmarkClient>( + profile, ManagedBookmarkServiceFactory::GetForProfile(profile), + BookmarkSyncServiceFactory::GetForProfile(profile))); + bookmark_model->Load(profile->GetPrefs(), profile->GetPath(), io_task_runner, + content::GetUIThreadTaskRunner({})); + BookmarkUndoServiceFactory::GetForProfile(profile)->Start( + bookmark_model.get()); + return bookmark_model; +} + +std::unique_ptr<KeyedService> BuildBookmarkModelForTesting( + content::BrowserContext* context) { + Profile* profile = Profile::FromBrowserContext(context); + // During testing, avoid deferring I/O tasks and having to explicitly + // invoke StartupTaskRunnerService:: StartDeferredTaskRunners(). + return BuildBookmarkModel(context, profile->GetIOTaskRunner()); +} + +} // namespace + // static BookmarkModel* BookmarkModelFactory::GetForBrowserContext( content::BrowserContext* context) { @@ -49,6 +76,12 @@ return base::Singleton<BookmarkModelFactory>::get(); } +// static +BrowserContextKeyedServiceFactory::TestingFactory +BookmarkModelFactory::GetDefaultFactory() { + return base::BindRepeating(&BuildBookmarkModelForTesting); +} + BookmarkModelFactory::BookmarkModelFactory() : BrowserContextKeyedServiceFactory( "BookmarkModel", @@ -65,17 +98,10 @@ KeyedService* BookmarkModelFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); - BookmarkModel* bookmark_model = - new BookmarkModel(std::make_unique<ChromeBookmarkClient>( - profile, ManagedBookmarkServiceFactory::GetForProfile(profile), - BookmarkSyncServiceFactory::GetForProfile(profile))); - bookmark_model->Load(profile->GetPrefs(), profile->GetPath(), - StartupTaskRunnerServiceFactory::GetForProfile(profile) - ->GetBookmarkTaskRunner(), - content::GetUIThreadTaskRunner({})); - BookmarkUndoServiceFactory::GetForProfile(profile)->Start(bookmark_model); - - return bookmark_model; + return BuildBookmarkModel( + context, StartupTaskRunnerServiceFactory::GetForProfile(profile) + ->GetBookmarkTaskRunner()) + .release(); } void BookmarkModelFactory::RegisterProfilePrefs(
diff --git a/chrome/browser/bookmarks/bookmark_model_factory.h b/chrome/browser/bookmarks/bookmark_model_factory.h index bd388e3..55af05f 100644 --- a/chrome/browser/bookmarks/bookmark_model_factory.h +++ b/chrome/browser/bookmarks/bookmark_model_factory.h
@@ -28,6 +28,9 @@ static BookmarkModelFactory* GetInstance(); + // Returns the default factory, useful in tests where it's null by default. + static TestingFactory GetDefaultFactory(); + private: friend struct base::DefaultSingletonTraits<BookmarkModelFactory>;
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 506a6f7..9819d8d 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -169,7 +169,6 @@ #include "chrome/common/logging_chrome.h" #include "chrome/common/pepper_permission_util.h" #include "chrome/common/pref_names.h" -#include "chrome/common/prerender_url_loader_throttle.h" #include "chrome/common/profiler/stack_sampling_configuration.h" #include "chrome/common/render_messages.h" #include "chrome/common/renderer_configuration.mojom.h" @@ -226,6 +225,7 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" +#include "components/prerender//common/prerender_url_loader_throttle.h" #include "components/prerender/common/prerender_final_status.h" #include "components/prerender/common/prerender_types.mojom.h" #include "components/prerender/common/prerender_util.h"
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.cc b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.cc index 77a17d9..9a21d841 100644 --- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.cc +++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.cc
@@ -9,7 +9,9 @@ #include "base/optional.h" #include "base/time/time.h" #include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" +#include "chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" #include "chromeos/cryptohome/cryptohome_parameters.h" #include "chromeos/dbus/cryptohome/cryptohome_client.h" @@ -207,5 +209,17 @@ return cert_list[0]; } +platform_keys::PlatformKeysService* GetPlatformKeysService(CertScope scope, + Profile* profile) { + switch (scope) { + case CertScope::kUser: + return platform_keys::PlatformKeysServiceFactory::GetForBrowserContext( + profile); + case CertScope::kDevice: + return platform_keys::PlatformKeysServiceFactory::GetInstance() + ->GetDeviceWideService(); + } +} + } // namespace cert_provisioning } // namespace chromeos
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.h b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.h index 9d2a6ad6..b497dc1 100644 --- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.h +++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.h
@@ -21,6 +21,11 @@ class Profile; namespace chromeos { + +namespace platform_keys { +class PlatformKeysService; +} // namespace platform_keys + namespace cert_provisioning { // Used for both DeleteVaKey and DeleteVaKeysByPrefix @@ -131,6 +136,16 @@ const char* data, size_t length); +// Returns the PlatformKeysService to be used. +// If |scope| is CertScope::kDevice, |profile| is ignored and the +// device-wide PlatformKeysService is returned. +// If |scope| is CertScope::kUser, returns the service for |profile|. +// The returned object is owned by the Profile (user-specific) or globally +// (device-wide) and may only be used until it notifies its observers that it is +// being shut down. +platform_keys::PlatformKeysService* GetPlatformKeysService(CertScope scope, + Profile* profile); + } // namespace cert_provisioning } // namespace chromeos
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.cc b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.cc index ee9a443..51c18bd7 100644 --- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.cc +++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.cc
@@ -105,7 +105,7 @@ policy::CloudPolicyClient* cloud_policy_client = GetCloudPolicyClientForUser(profile); platform_keys::PlatformKeysService* platform_keys_service = - platform_keys::PlatformKeysServiceFactory::GetForBrowserContext(profile); + GetPlatformKeysService(CertScope::kUser, profile); NetworkStateHandler* network_state_handler = GetNetworkStateHandler(); if (!profile || !pref_service || !cloud_policy_client || @@ -130,7 +130,7 @@ policy::CloudPolicyClient* cloud_policy_client = GetCloudPolicyClientForDevice(); platform_keys::PlatformKeysService* platform_keys_service = - platform_keys::PlatformKeysServiceFactory::GetForBrowserContext(profile); + GetPlatformKeysService(CertScope::kDevice, profile); NetworkStateHandler* network_state_handler = GetNetworkStateHandler(); if (!profile || !pref_service || !cloud_policy_client || @@ -173,6 +173,8 @@ pref_name_ = GetPrefNameForCertProfiles(cert_scope); CHECK(pref_name_); + scoped_platform_keys_service_observer_.Add(platform_keys_service_); + network_state_handler_->AddObserver(this, FROM_HERE); ScheduleInitialUpdate(); @@ -238,6 +240,10 @@ void CertProvisioningSchedulerImpl::DeleteCertsWithoutPolicy() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // No-op if the PlatformKeysService has already been shut down. + if (!platform_keys_service_) { + return; + } base::flat_set<CertProfileId> cert_profile_ids_to_keep; { @@ -391,6 +397,11 @@ std::vector<CertProfile> profiles) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // No-op if the PlatformKeysService has already been shut down. + if (!platform_keys_service_) { + return; + } + if (!MaybeWaitForInternetConnection()) { return; } @@ -677,6 +688,23 @@ failed_cert_profiles_[worker.GetCertProfile().profile_id] = std::move(info); } +void CertProvisioningSchedulerImpl::OnPlatformKeysServiceShutDown() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + // The |platform_keys_service_| will only return errors going forward, so + // stop using it. Shutdown all workers, as if this CertProvisioningScheduler + // was destroyed, and stop pending tasks that may depend on + // |platform_keys_service_|. + workers_.clear(); + certs_with_ids_getter_.Cancel(); + cert_deleter_.Cancel(); + pref_change_registrar_.RemoveAll(); + weak_factory_.InvalidateWeakPtrs(); + + scoped_platform_keys_service_observer_.RemoveAll(); + platform_keys_service_ = nullptr; +} + void CertProvisioningSchedulerImpl::CancelWorkersWithoutPolicy( const std::vector<CertProfile>& profiles) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.h b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.h index 5fadcce6..d94b76c3 100644 --- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.h +++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler.h
@@ -10,11 +10,13 @@ #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" #include "base/memory/weak_ptr.h" +#include "base/scoped_observer.h" #include "base/sequence_checker.h" #include "base/time/time.h" #include "chrome/browser/chromeos/cert_provisioning/cert_provisioning_common.h" #include "chrome/browser/chromeos/cert_provisioning/cert_provisioning_invalidator.h" #include "chrome/browser/chromeos/cert_provisioning/cert_provisioning_platform_keys_helpers.h" +#include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" #include "chromeos/network/network_state_handler_observer.h" #include "components/prefs/pref_change_registrar.h" @@ -29,10 +31,6 @@ class NetworkStateHandler; -namespace platform_keys { -class PlatformKeysService; -} // namespace platform_keys - namespace cert_provisioning { class CertProvisioningWorker; @@ -82,8 +80,10 @@ // Should work on the UI thread because it interacts with PlatformKeysService // and some methods are called from the UI to populate certificate manager // settings page. -class CertProvisioningSchedulerImpl : public CertProvisioningScheduler, - public NetworkStateHandlerObserver { +class CertProvisioningSchedulerImpl + : public CertProvisioningScheduler, + public NetworkStateHandlerObserver, + public platform_keys::PlatformKeysServiceObserver { public: static std::unique_ptr<CertProvisioningScheduler> CreateUserCertProvisioningScheduler(Profile* profile); @@ -167,11 +167,15 @@ void UpdateFailedCertProfiles(const CertProvisioningWorker& worker); + // PlatformKeysServiceObserver + void OnPlatformKeysServiceShutDown() override; + CertScope cert_scope_ = CertScope::kUser; Profile* profile_ = nullptr; PrefService* pref_service_ = nullptr; const char* pref_name_ = nullptr; policy::CloudPolicyClient* cloud_policy_client_ = nullptr; + // |platform_keys_service_| can be nullptr if it has been shut down. platform_keys::PlatformKeysService* platform_keys_service_ = nullptr; NetworkStateHandler* network_state_handler_ = nullptr; PrefChangeRegistrar pref_change_registrar_; @@ -197,6 +201,10 @@ CertDeleter cert_deleter_; std::unique_ptr<CertProvisioningInvalidatorFactory> invalidator_factory_; + ScopedObserver<platform_keys::PlatformKeysService, + platform_keys::PlatformKeysServiceObserver> + scoped_platform_keys_service_observer_{this}; + base::WeakPtrFactory<CertProvisioningSchedulerImpl> weak_factory_{this}; };
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_unittest.cc b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_unittest.cc index b6e8c30..22a65c3 100644 --- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_unittest.cc +++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_scheduler_unittest.cc
@@ -14,7 +14,6 @@ #include "chrome/browser/chromeos/cert_provisioning/mock_cert_provisioning_worker.h" #include "chrome/browser/chromeos/platform_keys/mock_platform_keys_service.h" #include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" -#include "chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h" #include "chrome/common/pref_names.h" #include "chromeos/network/network_state_test_helper.h" #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" @@ -33,6 +32,7 @@ using testing::Mock; using testing::Return; using testing::ReturnRef; +using testing::SaveArg; using testing::StrictMock; namespace chromeos { @@ -900,6 +900,56 @@ ASSERT_EQ(scheduler.GetWorkers().size(), 1U); } +TEST_F(CertProvisioningSchedulerTest, PlatformKeysServiceShutDown) { + CertScope kCertScope = CertScope::kDevice; + + platform_keys::PlatformKeysServiceObserver* observer = nullptr; + EXPECT_CALL(platform_keys_service_, AddObserver(_)) + .WillOnce(SaveArg<0>(&observer)); + CertProvisioningSchedulerImpl scheduler( + kCertScope, GetProfile(), &pref_service_, &cloud_policy_client_, + &platform_keys_service_, + network_state_test_helper_.network_state_handler(), + MakeFakeInvalidationFactory()); + + ASSERT_TRUE(observer); + + // Add 1 certificate profile to the policy. + base::Value config = ParseJson( + R"([{"name": "Certificate Profile 1", + "cert_profile_id":"cert_profile_id_1", + "policy_version":"cert_profile_version_1", + "key_algorithm":"rsa" }])"); + pref_service_.Set(prefs::kRequiredClientCertificateForDevice, config); + + // Same as in the policy. + const char kCertProfileId[] = "cert_profile_id_1"; + const char kCertProfileVersion[] = "cert_profile_version_1"; + CertProfile cert_profile{kCertProfileId, kCertProfileVersion, + /*is_va_enabled=*/true, kCertProfileRenewalPeriod}; + + MockCertProvisioningWorker* worker = + mock_factory_.ExpectCreateReturnMock(kCertScope, cert_profile); + worker->SetExpectations(/*do_step_times=*/AtLeast(1), /*is_waiting=*/false, + cert_profile); + scheduler.UpdateAllCerts(); + + // Now 1 worker should be created. + EXPECT_EQ(scheduler.GetWorkers().size(), 1U); + + // PlatformKeysService notifies that it is shutting down. + EXPECT_CALL(platform_keys_service_, RemoveObserver(observer)); + observer->OnPlatformKeysServiceShutDown(); + + // The worker should be deleted. + EXPECT_EQ(scheduler.GetWorkers().size(), 0U); + + // Check one more time that scheduler doesn't create new workers after + // PlatformKeysService has been shut down (the factory will fail on an attempt + // to do so). + scheduler.UpdateAllCerts(); +} + } // namespace } // namespace cert_provisioning } // namespace chromeos
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker.cc b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker.cc index 0c2bfbdc..bd00ee03 100644 --- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker.cc +++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker.cc
@@ -187,8 +187,7 @@ cloud_policy_client_(cloud_policy_client), invalidator_(std::move(invalidator)) { CHECK(profile); - platform_keys_service_ = - platform_keys::PlatformKeysServiceFactory::GetForBrowserContext(profile); + platform_keys_service_ = GetPlatformKeysService(cert_scope, profile); CHECK(platform_keys_service_); CHECK(pref_service);
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker.h b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker.h index d4c8c32..3bd6b29 100644 --- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker.h +++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker.h
@@ -254,6 +254,10 @@ // because of it). static constexpr int kVersion = 1; + // Unowned PlatformKeysService. Note that the CertProvisioningWorker does not + // observe the PlatformKeysService for shutdown events. Instead, it relies on + // the CertProvisioningScheduler to destroy all CertProvisioningWorker + // instances when the corresponding PlatformKeysService is shutting down. platform_keys::PlatformKeysService* platform_keys_service_ = nullptr; std::unique_ptr<attestation::TpmChallengeKeySubtle> tpm_challenge_key_subtle_impl_;
diff --git a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker_unittest.cc b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker_unittest.cc index 1d63f26..5164369 100644 --- a/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker_unittest.cc +++ b/chrome/browser/chromeos/cert_provisioning/cert_provisioning_worker_unittest.cc
@@ -344,6 +344,9 @@ base::BindRepeating( &platform_keys::BuildMockPlatformKeysService))); ASSERT_TRUE(platform_keys_service_); + platform_keys::PlatformKeysServiceFactory::GetInstance() + ->SetDeviceWideServiceForTesting(platform_keys_service_); + // Only explicitly expected removals are allowed. EXPECT_CALL(*platform_keys_service_, RemoveCertificate).Times(0); EXPECT_CALL(*platform_keys_service_, RemoveKey).Times(0);
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc b/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc index c93e161..7032c75 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc +++ b/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc
@@ -741,8 +741,7 @@ // Zero touch with attestation authentication fail. Attestation fails because we // send empty cert request. Should switch to interactive authentication. -IN_PROC_BROWSER_TEST_F(InitialEnrollmentTest, - DISABLED_ZeroTouchForcedAttestationFail) { +IN_PROC_BROWSER_TEST_F(InitialEnrollmentTest, ZeroTouchForcedAttestationFail) { auto initial_enrollment = enterprise_management::DeviceInitialEnrollmentStateResponse:: INITIAL_ENROLLMENT_MODE_ZERO_TOUCH_ENFORCED;
diff --git a/chrome/browser/chromeos/platform_keys/mock_platform_keys_service.h b/chrome/browser/chromeos/platform_keys/mock_platform_keys_service.h index 3499fd0..bb635f7 100644 --- a/chrome/browser/chromeos/platform_keys/mock_platform_keys_service.h +++ b/chrome/browser/chromeos/platform_keys/mock_platform_keys_service.h
@@ -11,6 +11,10 @@ #include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" #include "testing/gmock/include/gmock/gmock.h" +namespace content { +class BrowserContext; +} + namespace chromeos { namespace platform_keys { @@ -22,6 +26,16 @@ ~MockPlatformKeysService() override; MOCK_METHOD(void, + AddObserver, + (PlatformKeysServiceObserver * observer), + (override)); + + MOCK_METHOD(void, + RemoveObserver, + (PlatformKeysServiceObserver * observer), + (override)); + + MOCK_METHOD(void, GenerateRSAKey, (TokenId token_id, unsigned int modulus_length_bits,
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service.cc b/chrome/browser/chromeos/platform_keys/platform_keys_service.cc index 6daf920d..e212b24 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_service.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys_service.cc
@@ -5,12 +5,14 @@ #include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" #include <map> +#include <utility> #include "base/bind.h" #include "base/bind_helpers.h" #include "base/location.h" #include "base/task/post_task.h" #include "base/task/thread_pool.h" +#include "content/public/browser/browser_thread.h" #include "net/base/hash_value.h" #include "net/cert/x509_certificate.h" @@ -75,14 +77,65 @@ ClientCertificateRequest::~ClientCertificateRequest() = default; +// =============== PlatformKeysServiceImplDelegate ============================= + +PlatformKeysServiceImplDelegate::PlatformKeysServiceImplDelegate() = default; + +PlatformKeysServiceImplDelegate::~PlatformKeysServiceImplDelegate() { + ShutDown(); +} + +void PlatformKeysServiceImplDelegate::SetOnShutdownCallback( + base::OnceClosure on_shutdown_callback) { + DCHECK(!shut_down_); + DCHECK(!on_shutdown_callback_); + on_shutdown_callback_ = std::move(on_shutdown_callback); +} + +bool PlatformKeysServiceImplDelegate::IsShutDown() const { + return shut_down_; +} + +void PlatformKeysServiceImplDelegate::ShutDown() { + if (shut_down_) + return; + + shut_down_ = true; + if (on_shutdown_callback_) + std::move(on_shutdown_callback_).Run(); +} + // =================== PlatformKeysServiceImpl ================================= PlatformKeysServiceImpl::PlatformKeysServiceImpl( - content::BrowserContext* context) - : browser_context_(context) {} + std::unique_ptr<PlatformKeysServiceImplDelegate> delegate) + : delegate_(std::move(delegate)) { + // base::Unretained is OK because |delegate_| is owned by this and can + // only call the callback before it is destroyed. + delegate_->SetOnShutdownCallback(base::BindOnce( + &PlatformKeysServiceImpl::OnDelegateShutDown, base::Unretained(this))); +} PlatformKeysServiceImpl::~PlatformKeysServiceImpl() = default; +void PlatformKeysServiceImpl::AddObserver( + PlatformKeysServiceObserver* observer) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + observers_.AddObserver(observer); +} + +void PlatformKeysServiceImpl::RemoveObserver( + PlatformKeysServiceObserver* observer) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + observers_.RemoveObserver(observer); +} + +void PlatformKeysServiceImpl::OnDelegateShutDown() { + for (auto& observer : observers_) { + observer.OnPlatformKeysServiceShutDown(); + } +} + // The rest of the methods - the NSS-specific part of the implementation - // resides in the platform_keys_service_nss.cc file.
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service.h b/chrome/browser/chromeos/platform_keys/platform_keys_service.h index 21bbf9e..0cf42a0 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_service.h +++ b/chrome/browser/chromeos/platform_keys/platform_keys_service.h
@@ -11,16 +11,19 @@ #include <string> #include <vector> -#include "base/callback_forward.h" +#include "base/callback.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "base/observer_list_types.h" #include "base/optional.h" #include "components/keyed_service/core/keyed_service.h" #include "net/cert/x509_certificate.h" -namespace content { -class BrowserContext; -} +namespace net { +class NSSCertDatabase; +class ClientCertStore; +} // namespace net namespace chromeos { namespace platform_keys { @@ -178,10 +181,27 @@ base::OnceCallback<void(const base::Optional<std::string>& attribute_value, const std::string& error_message)>; +// An observer that gets notified when the PlatformKeysService is being shut +// down. +class PlatformKeysServiceObserver : public base::CheckedObserver { + public: + // Called when the PlatformKeysService is being shut down. + // It may not be used after this call - any usage except for removing the + // observer will DCHECK. + virtual void OnPlatformKeysServiceShutDown() = 0; +}; + // Functions of this class shouldn't be called directly from the context of // an extension. Instead use ExtensionPlatformKeysService which enforces // restrictions upon extensions. // All public methods of this class should be called on the UI thread. +// When the underlying key store is not available anymore, a PlatformKeysService +// is shut down. Any function called after that will fail with an error. +// For a Profile-specific PlatformKeysService, this will be when the Profile is +// being destroyed. +// For a device-wide PlatformKeysService, this will be at some point during +// chrome shut down. +// Use AddObserver to get a notification when the service shuts down. class PlatformKeysService : public KeyedService { public: PlatformKeysService() = default; @@ -189,6 +209,12 @@ PlatformKeysService& operator=(const PlatformKeysService&) = delete; ~PlatformKeysService() override = default; + // Adds |observer| which will be notified when this service is being shut + // down. + virtual void AddObserver(PlatformKeysServiceObserver* observer) = 0; + // Removes a previously added |observer|. + virtual void RemoveObserver(PlatformKeysServiceObserver* observer) = 0; + // Generates a RSA key pair with |modulus_length_bits|. |token_id| specifies // the token to store the key pair on. |callback| will be invoked with the // resulting public key @@ -328,12 +354,55 @@ const bool map_to_softoken_attrs_for_testing) = 0; }; +class PlatformKeysServiceImplDelegate { + public: + PlatformKeysServiceImplDelegate(); + virtual ~PlatformKeysServiceImplDelegate(); + PlatformKeysServiceImplDelegate( + const PlatformKeysServiceImplDelegate& other) = delete; + PlatformKeysServiceImplDelegate& operator=( + const PlatformKeysServiceImplDelegate& other) = delete; + + // |on_shutdown_callback| will be called when the underlying key/certificate + // store is shut down. It is an error to call this twice, or after the + // delegate has been shut down. + void SetOnShutdownCallback(base::OnceClosure on_shutdown_callback); + + // This callback is invoked by GetNSSCertDatabase. + using OnGotNSSCertDatabase = base::OnceCallback<void(net::NSSCertDatabase*)>; + + // Retrieves the NSSCertDatabase that should be used for certificate + // operations. |callback| will be called on the thread that GetNSSCertDatabase + // has been called on. + virtual void GetNSSCertDatabase(OnGotNSSCertDatabase callback) = 0; + + // Creates a ClientCertStore that should be used to list / operate on client + // certificates. + virtual std::unique_ptr<net::ClientCertStore> CreateClientCertStore() = 0; + + bool IsShutDown() const; + + protected: + void ShutDown(); + + private: + // A callback that should be called when the underlying key/certificate store + // is shut down. + base::OnceClosure on_shutdown_callback_; + + // True if the underlying key/certificate store has already been shut down. + bool shut_down_ = false; +}; + class PlatformKeysServiceImpl final : public PlatformKeysService { public: - explicit PlatformKeysServiceImpl(content::BrowserContext* context); + explicit PlatformKeysServiceImpl( + std::unique_ptr<PlatformKeysServiceImplDelegate> delegate); ~PlatformKeysServiceImpl() override; // PlatformKeysService + void AddObserver(PlatformKeysServiceObserver* observer) override; + void RemoveObserver(PlatformKeysServiceObserver* observer) override; void GenerateRSAKey(TokenId token_id, unsigned int modulus_length_bits, const GenerateKeyCallback& callback) override; @@ -386,7 +455,11 @@ bool IsSetMapToSoftokenAttrsForTesting(); private: - content::BrowserContext* const browser_context_; + void OnDelegateShutDown(); + + std::unique_ptr<PlatformKeysServiceImplDelegate> const delegate_; + // List of observers that will be notified when the service is shut down. + base::ObserverList<PlatformKeysServiceObserver> observers_; bool map_to_softoken_attrs_for_testing_ = false; base::WeakPtrFactory<PlatformKeysServiceImpl> weak_factory_{this}; };
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service_factory.cc b/chrome/browser/chromeos/platform_keys/platform_keys_service_factory.cc index 796ee5b..0d1ae549 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_service_factory.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys_service_factory.cc
@@ -4,14 +4,129 @@ #include "chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h" +#include "base/callback_helpers.h" +#include "base/memory/scoped_refptr.h" #include "base/memory/singleton.h" +#include "base/scoped_observer.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "chrome/browser/chromeos/certificate_provider/certificate_provider.h" +#include "chrome/browser/chromeos/net/client_cert_store_chromeos.h" #include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/system_token_cert_db_initializer.h" +#include "chrome/browser/net/nss_context.h" #include "chrome/browser/profiles/incognito_helpers.h" +#include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/user_manager/user.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/resource_context.h" +#include "net/cert/nss_cert_database.h" namespace chromeos { namespace platform_keys { +namespace { + +// Invoked on the IO thread when a NSSCertDatabase is available, delegates back +// to origin thread. +void DidGetCertDbOnIoThread( + const scoped_refptr<base::SingleThreadTaskRunner>& origin_task_runner, + base::OnceCallback<void(net::NSSCertDatabase*)> callback, + net::NSSCertDatabase* cert_db) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + origin_task_runner->PostTask(FROM_HERE, + base::BindOnce(std::move(callback), cert_db)); +} + +// Retrieves the NSSCertDatabase for |context|. Must be called on the IO thread. +void GetCertDatabaseOnIoThread( + const scoped_refptr<base::SingleThreadTaskRunner>& origin_task_runner, + PlatformKeysServiceImplDelegate::OnGotNSSCertDatabase callback, + content::ResourceContext* context) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + base::RepeatingCallback<void(net::NSSCertDatabase*)> on_got_on_io_thread = + base::BindRepeating(&DidGetCertDbOnIoThread, origin_task_runner, + base::AdaptCallbackForRepeating(std::move(callback))); + net::NSSCertDatabase* cert_db = + GetNSSCertDatabaseForResourceContext(context, on_got_on_io_thread); + + if (cert_db) + on_got_on_io_thread.Run(cert_db); +} + +class DelegateForUser : public PlatformKeysServiceImplDelegate { + public: + explicit DelegateForUser(content::BrowserContext* browser_context) + : browser_context_(browser_context) {} + ~DelegateForUser() override = default; + + void GetNSSCertDatabase(OnGotNSSCertDatabase callback) override { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(&GetCertDatabaseOnIoThread, + base::ThreadTaskRunnerHandle::Get(), std::move(callback), + browser_context_->GetResourceContext())); + } + + std::unique_ptr<net::ClientCertStore> CreateClientCertStore() override { + const user_manager::User* user = + chromeos::ProfileHelper::Get()->GetUserByProfile( + Profile::FromBrowserContext(browser_context_)); + + // Use the device-wide system key slot only if the user is affiliated on the + // device. + const bool use_system_key_slot = user->IsAffiliated(); + return std::make_unique<ClientCertStoreChromeOS>( + nullptr, // no additional provider + use_system_key_slot, user->username_hash(), + ClientCertStoreChromeOS::PasswordDelegateFactory()); + } + + private: + content::BrowserContext* browser_context_; +}; + +class DelegateForDevice : public PlatformKeysServiceImplDelegate, + public SystemTokenCertDBObserver { + public: + DelegateForDevice() { + scoped_observer_.Add(SystemTokenCertDBInitializer::Get()); + } + + ~DelegateForDevice() override = default; + + void GetNSSCertDatabase(OnGotNSSCertDatabase callback) override { + SystemTokenCertDBInitializer::Get()->GetSystemTokenCertDb( + std::move(callback)); + } + + std::unique_ptr<net::ClientCertStore> CreateClientCertStore() override { + return std::make_unique<ClientCertStoreChromeOS>( + nullptr, // no additional provider + /*use_system_key_slot=*/true, /*username_hash=*/std::string(), + ClientCertStoreChromeOS::PasswordDelegateFactory()); + } + + private: + ScopedObserver<SystemTokenCertDBInitializer, SystemTokenCertDBObserver> + scoped_observer_{this}; + + // SystemTokenCertDBObserver: + void OnSystemTokenCertDBDestroyed() override { + scoped_observer_.RemoveAll(); + ShutDown(); + } +}; + +} // namespace + // static PlatformKeysService* PlatformKeysServiceFactory::GetForBrowserContext( content::BrowserContext* context) { @@ -24,6 +139,23 @@ return base::Singleton<PlatformKeysServiceFactory>::get(); } +// static +PlatformKeysService* PlatformKeysServiceFactory::GetDeviceWideService() { + if (device_wide_service_for_testing_) + return device_wide_service_for_testing_; + + if (!device_wide_service_) { + device_wide_service_ = std::make_unique<PlatformKeysServiceImpl>( + std::make_unique<DelegateForDevice>()); + } + return device_wide_service_.get(); +} + +void PlatformKeysServiceFactory::SetDeviceWideServiceForTesting( + PlatformKeysService* device_wide_service_for_testing) { + device_wide_service_for_testing_ = device_wide_service_for_testing; +} + PlatformKeysServiceFactory::PlatformKeysServiceFactory() : BrowserContextKeyedServiceFactory( "PlatformKeysService", @@ -33,7 +165,16 @@ KeyedService* PlatformKeysServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - return new PlatformKeysServiceImpl(context); + std::unique_ptr<PlatformKeysServiceImplDelegate> delegate; + Profile* profile = Profile::FromBrowserContext(context); + if (ProfileHelper::IsSigninProfile(profile) || + ProfileHelper::IsLockScreenAppProfile(profile)) { + delegate = std::make_unique<DelegateForDevice>(); + } else { + delegate = std::make_unique<DelegateForUser>(context); + } + + return new PlatformKeysServiceImpl(std::move(delegate)); } content::BrowserContext* PlatformKeysServiceFactory::GetBrowserContextToUse(
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h b/chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h index bd2902a..cf97e46 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h +++ b/chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h
@@ -25,6 +25,21 @@ static PlatformKeysServiceFactory* GetInstance(); + // Returns an instance of PlatformKeysService that allows operations on the + // device-wide key store and is not tied to a user. + // The lifetime of the returned service is tied to the + // PlatformKeysServiceFactory itself. + PlatformKeysService* GetDeviceWideService(); + + // When call with a nun-nullptr |device_wide_service_for_testing|, subsequent + // calls to GetDeviceWideService() will return the passed pointer. + // When called with nullptr, subsequent calls to GetDeviceWideService() will + // return the default device-wide PlatformKeysService again. + // The caller is responsible that this is called with nullptr before an object + // previously passed in is destroyed. + void SetDeviceWideServiceForTesting( + PlatformKeysService* device_wide_service_for_testing); + private: friend struct base::DefaultSingletonTraits<PlatformKeysServiceFactory>; @@ -39,6 +54,15 @@ content::BrowserContext* context) const override; KeyedService* BuildServiceInstanceFor( content::BrowserContext* context) const override; + + PlatformKeysService* GetOrCreateDeviceWideService(); + + // A PlatformKeysService that is not tied to a Profile/User and only has + // access to the system token. + // Initialized lazily. + std::unique_ptr<PlatformKeysService> device_wide_service_; + + PlatformKeysService* device_wide_service_for_testing_ = nullptr; }; } // namespace platform_keys } // namespace chromeos
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service_nss.cc b/chrome/browser/chromeos/platform_keys/platform_keys_service_nss.cc index 86408df8..40d5b0e 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_service_nss.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys_service_nss.cc
@@ -31,18 +31,12 @@ #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part_chromeos.h" -#include "chrome/browser/chromeos/certificate_provider/certificate_provider.h" #include "chrome/browser/chromeos/net/client_cert_store_chromeos.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/system_token_cert_db_initializer.h" #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h" -#include "chrome/browser/net/nss_context.h" -#include "chrome/browser/profiles/profile.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/resource_context.h" #include "crypto/nss_key_util.h" #include "crypto/openssl_util.h" #include "crypto/scoped_nss_types.h" @@ -71,6 +65,7 @@ const char kErrorKeyNotFound[] = "Key not found."; const char kErrorCertificateNotFound[] = "Certificate could not be found."; const char kErrorAlgorithmNotSupported[] = "Algorithm not supported."; +const char kErrorShutDown[] = "Delegate shut down."; // The current maximal RSA modulus length that ChromeOS's TPM supports for key // generation. @@ -116,17 +111,16 @@ DISALLOW_COPY_AND_ASSIGN(NSSOperationState); }; -using GetCertDBCallback = base::Callback<void(net::NSSCertDatabase* cert_db)>; +using GetCertDBCallback = + base::OnceCallback<void(net::NSSCertDatabase* cert_db)>; -// Used by GetCertDatabaseOnIoThread and called back with the requested -// NSSCertDatabase. -// If |token_id| is provided, sets |slot_| of |state| accordingly and calls -// |callback| if the database was successfully retrieved. -void DidGetCertDbOnIoThread(base::Optional<TokenId> token_id, - const GetCertDBCallback& callback, +// Called on the UI thread with certificate database. +void DidGetCertDbOnUiThread(base::Optional<TokenId> token_id, + GetCertDBCallback callback, NSSOperationState* state, net::NSSCertDatabase* cert_db) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!cert_db) { LOG(ERROR) << "Couldn't get NSSCertDatabase."; state->OnError(FROM_HERE, kErrorInternal); @@ -151,63 +145,25 @@ } } - callback.Run(cert_db); -} - -// Retrieves the NSSCertDatabase from |context| and, if |token_id| is provided, -// the slot for |token_id|. -// Must be called on the IO thread. -void GetCertDatabaseOnIoThread(base::Optional<TokenId> token_id, - const GetCertDBCallback& callback, - content::ResourceContext* context, - NSSOperationState* state) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - net::NSSCertDatabase* cert_db = GetNSSCertDatabaseForResourceContext( - context, base::Bind(&DidGetCertDbOnIoThread, token_id, callback, state)); - - if (cert_db) - DidGetCertDbOnIoThread(token_id, callback, state, cert_db); -} - -// Called by SystemTokenCertDBInitializer on the UI thread with the system token -// certificate database when it is initialized. -void DidGetSystemTokenCertDbOnUiThread(base::Optional<TokenId> token_id, - const GetCertDBCallback& callback, - NSSOperationState* state, - net::NSSCertDatabase* cert_db) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - // Sets |slot_| of |state| accordingly and calls |callback| on the IO thread // if the database was successfully retrieved. content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&DidGetCertDbOnIoThread, token_id, callback, - state, cert_db)); + FROM_HERE, base::BindOnce(std::move(callback), cert_db)); } -// Asynchronously fetches the NSSCertDatabase for |browser_context| and, if -// |token_id| is provided, the slot for |token_id|. Stores the slot in |state| +// Asynchronously fetches the NSSCertDatabase using |delegate| and, if +// |token_id| is not empty, the slot for |token_id|. Stores the slot in |state| // and passes the database to |callback|. Will run |callback| on the IO thread. // TODO(omorsi): Introduce timeout for retrieving certificate database in // platform keys. void GetCertDatabase(base::Optional<TokenId> token_id, - const GetCertDBCallback& callback, - BrowserContext* browser_context, + GetCertDBCallback callback, + PlatformKeysServiceImplDelegate* delegate, NSSOperationState* state) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - Profile* profile = Profile::FromBrowserContext(browser_context); - // There will be no public or private slots initialized if no user is logged - // in. In this case, an NSS certificate database that has the system slot - // should be used for system token operations. - if (ProfileHelper::IsSigninProfile(profile)) { - SystemTokenCertDBInitializer::Get()->GetSystemTokenCertDb(base::BindOnce( - &DidGetSystemTokenCertDbOnUiThread, token_id, callback, state)); - return; - } - - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&GetCertDatabaseOnIoThread, token_id, callback, - browser_context->GetResourceContext(), state)); + delegate->GetNSSCertDatabase(base::BindOnce(&DidGetCertDbOnUiThread, token_id, + std::move(callback), state)); } class GenerateRSAKeyState : public NSSOperationState { @@ -1422,7 +1378,10 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); auto state = std::make_unique<GenerateRSAKeyState>( weak_factory_.GetWeakPtr(), modulus_length_bits, callback); - + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } if (modulus_length_bits > kMaxRSAModulusLengthBits) { state->OnError(FROM_HERE, kErrorAlgorithmNotSupported); return; @@ -1431,8 +1390,8 @@ // Get the pointer to |state| before base::Passed releases |state|. NSSOperationState* state_ptr = state.get(); GetCertDatabase(token_id, - base::Bind(&GenerateRSAKeyWithDB, base::Passed(&state)), - browser_context_, state_ptr); + base::BindOnce(&GenerateRSAKeyWithDB, base::Passed(&state)), + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::GenerateECKey( @@ -1442,12 +1401,15 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); auto state = std::make_unique<GenerateECKeyState>(weak_factory_.GetWeakPtr(), named_curve, callback); - + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } // Get the pointer to |state| before base::Passed releases |state|. NSSOperationState* state_ptr = state.get(); GetCertDatabase(token_id, - base::Bind(&GenerateECKeyWithDB, base::Passed(&state)), - browser_context_, state_ptr); + base::BindOnce(&GenerateECKeyWithDB, base::Passed(&state)), + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::SignRSAPKCS1Digest( @@ -1461,6 +1423,10 @@ weak_factory_.GetWeakPtr(), data, public_key_spki_der, /*raw_pkcs1=*/false, hash_algorithm, /*key_type=*/KeyType::kRsassaPkcs1V15, callback); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } // Get the pointer to |state| before base::Passed releases |state|. NSSOperationState* state_ptr = state.get(); @@ -1468,8 +1434,8 @@ // The NSSCertDatabase object is not required. But in case it's not available // we would get more informative error messages and we can double check that // we use a key of the correct token. - GetCertDatabase(token_id, base::Bind(&SignWithDB, base::Passed(&state)), - browser_context_, state_ptr); + GetCertDatabase(token_id, base::BindOnce(&SignWithDB, base::Passed(&state)), + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::SignRSAPKCS1Raw( @@ -1482,6 +1448,10 @@ weak_factory_.GetWeakPtr(), data, public_key_spki_der, /*raw_pkcs1=*/true, HASH_ALGORITHM_NONE, /*key_type=*/KeyType::kRsassaPkcs1V15, callback); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } // Get the pointer to |state| before base::Passed releases |state|. NSSOperationState* state_ptr = state.get(); @@ -1489,8 +1459,8 @@ // The NSSCertDatabase object is not required. But in case it's not available // we would get more informative error messages and we can double check that // we use a key of the correct token. - GetCertDatabase(token_id, base::Bind(&SignWithDB, base::Passed(&state)), - browser_context_, state_ptr); + GetCertDatabase(token_id, base::BindOnce(&SignWithDB, base::Passed(&state)), + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::SignECDSADigest( @@ -1504,6 +1474,10 @@ weak_factory_.GetWeakPtr(), data, public_key_spki_der, /*raw_pkcs1=*/false, hash_algorithm, /*key_type=*/KeyType::kEcdsa, callback); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } // Get the pointer to |state| before base::Passed releases |state|. NSSOperationState* state_ptr = state.get(); @@ -1511,8 +1485,8 @@ // The NSSCertDatabase object is not required. But in case it's not available // we would get more informative error messages and we can double check that // we use a key of the correct token. - GetCertDatabase(token_id, base::Bind(&SignWithDB, base::Passed(&state)), - browser_context_, state_ptr); + GetCertDatabase(token_id, base::BindOnce(&SignWithDB, base::Passed(&state)), + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::SelectClientCertificates( @@ -1528,21 +1502,14 @@ // filtering afterwards. cert_request_info->cert_authorities = certificate_authorities; - const user_manager::User* user = - chromeos::ProfileHelper::Get()->GetUserByProfile( - Profile::FromBrowserContext(browser_context_)); - - // Use the device-wide system key slot only if the user is affiliated on the - // device. - const bool use_system_key_slot = user->IsAffiliated(); - auto state = std::make_unique<SelectCertificatesState>( weak_factory_.GetWeakPtr(), cert_request_info, callback); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } - state->cert_store_ = std::make_unique<ClientCertStoreChromeOS>( - nullptr, // no additional provider - use_system_key_slot, user->username_hash(), - ClientCertStoreChromeOS::PasswordDelegateFactory()); + state->cert_store_ = delegate_->CreateClientCertStore(); // Note DidSelectCertificates() may be called synchronously. SelectCertificatesState* state_ptr = state.get(); @@ -1683,11 +1650,15 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); auto state = std::make_unique<GetCertificatesState>( weak_factory_.GetWeakPtr(), callback); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } // Get the pointer to |state| before base::Passed releases |state|. NSSOperationState* state_ptr = state.get(); GetCertDatabase(token_id, - base::Bind(&GetCertificatesWithDB, base::Passed(&state)), - browser_context_, state_ptr); + base::BindOnce(&GetCertificatesWithDB, base::Passed(&state)), + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::GetAllKeys(TokenId token_id, @@ -1696,11 +1667,15 @@ auto state = std::make_unique<GetAllKeysState>(weak_factory_.GetWeakPtr(), std::move(callback)); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } NSSOperationState* state_ptr = state.get(); GetCertDatabase(token_id, - base::BindRepeating(&GetAllKeysWithDb, base::Passed(&state)), - browser_context_, state_ptr); + base::BindOnce(&GetAllKeysWithDb, base::Passed(&state)), + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::ImportCertificate( @@ -1710,15 +1685,19 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); auto state = std::make_unique<ImportCertificateState>( weak_factory_.GetWeakPtr(), certificate, callback); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } // Get the pointer to |state| before base::Passed releases |state|. NSSOperationState* state_ptr = state.get(); // The NSSCertDatabase object is not required. But in case it's not available // we would get more informative error messages and we can double check that // we use a key of the correct token. - GetCertDatabase(token_id, - base::Bind(&ImportCertificateWithDB, base::Passed(&state)), - browser_context_, state_ptr); + GetCertDatabase( + token_id, base::BindOnce(&ImportCertificateWithDB, base::Passed(&state)), + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::RemoveCertificate( @@ -1728,14 +1707,18 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); auto state = std::make_unique<RemoveCertificateState>( weak_factory_.GetWeakPtr(), certificate, callback); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } // Get the pointer to |state| before base::Passed releases |state|. NSSOperationState* state_ptr = state.get(); // The NSSCertDatabase object is not required. But in case it's not available // we would get more informative error messages. - GetCertDatabase(token_id, - base::Bind(&RemoveCertificateWithDB, base::Passed(&state)), - browser_context_, state_ptr); + GetCertDatabase( + token_id, base::BindOnce(&RemoveCertificateWithDB, base::Passed(&state)), + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::RemoveKey(TokenId token_id, @@ -1745,25 +1728,34 @@ auto state = std::make_unique<RemoveKeyState>( weak_factory_.GetWeakPtr(), public_key_spki_der, std::move(callback)); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } // Get the pointer to |state| before base::Passed releases |state|. NSSOperationState* state_ptr = state.get(); // The NSSCertDatabase object is not required. But in case it's not available // we would get more informative error messages. - GetCertDatabase(token_id, base::Bind(&RemoveKeyWithDb, base::Passed(&state)), - browser_context_, state_ptr); + GetCertDatabase(token_id, + base::BindOnce(&RemoveKeyWithDb, base::Passed(&state)), + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::GetTokens(const GetTokensCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); auto state = std::make_unique<GetTokensState>(weak_factory_.GetWeakPtr(), callback); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } // Get the pointer to |state| before base::Passed releases |state|. NSSOperationState* state_ptr = state.get(); GetCertDatabase(/*token_id=*/base::nullopt /* don't get any specific slot */, base::Bind(&GetTokensWithDB, base::Passed(&state)), - browser_context_, state_ptr); + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::GetKeyLocations( @@ -1772,12 +1764,16 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); auto state = std::make_unique<GetKeyLocationsState>( weak_factory_.GetWeakPtr(), public_key_spki_der, callback); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } NSSOperationState* state_ptr = state.get(); GetCertDatabase( /*token_id=*/base::nullopt /* don't get any specific slot */, base::BindRepeating(&GetKeyLocationsWithDB, base::Passed(&state)), - browser_context_, state_ptr); + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::SetAttributeForKey( @@ -1795,6 +1791,10 @@ auto state = std::make_unique<SetAttributeForKeyState>( weak_factory_.GetWeakPtr(), public_key_spki_der, ck_attribute_type, attribute_value, std::move(callback)); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } // Get the pointer to |state| before base::Passed releases |state|. NSSOperationState* state_ptr = state.get(); @@ -1802,9 +1802,8 @@ // The NSSCertDatabase object is not required. Only setting the state slot is // required. GetCertDatabase( - token_id, - base::BindRepeating(&SetAttributeForKeyWithDb, base::Passed(&state)), - browser_context_, state_ptr); + token_id, base::BindOnce(&SetAttributeForKeyWithDb, base::Passed(&state)), + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::GetAttributeForKey( @@ -1821,6 +1820,10 @@ auto state = std::make_unique<GetAttributeForKeyState>( weak_factory_.GetWeakPtr(), public_key_spki_der, ck_attribute_type, std::move(callback)); + if (delegate_->IsShutDown()) { + state->OnError(FROM_HERE, kErrorShutDown); + return; + } // Get the pointer to |state| before base::Passed releases |state|. NSSOperationState* state_ptr = state.get(); @@ -1828,9 +1831,8 @@ // The NSSCertDatabase object is not required. Only setting the state slot is // required. GetCertDatabase( - token_id, - base::BindRepeating(&GetAttributeForKeyWithDb, base::Passed(&state)), - browser_context_, state_ptr); + token_id, base::BindOnce(&GetAttributeForKeyWithDb, base::Passed(&state)), + delegate_.get(), state_ptr); } void PlatformKeysServiceImpl::SetMapToSoftokenAttrsForTesting(
diff --git a/chrome/browser/chromeos/policy/system_proxy_manager.cc b/chrome/browser/chromeos/policy/system_proxy_manager.cc index e5500e551..da1efdd 100644 --- a/chrome/browser/chromeos/policy/system_proxy_manager.cc +++ b/chrome/browser/chromeos/policy/system_proxy_manager.cc
@@ -20,7 +20,12 @@ #include "components/prefs/pref_service.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" +#include "content/public/browser/storage_partition.h" +#include "net/base/host_port_pair.h" +#include "net/base/proxy_server.h" #include "net/http/http_auth_scheme.h" +#include "net/http/http_util.h" +#include "services/network/public/mojom/network_context.mojom.h" namespace { const char kSystemProxyService[] = "system-proxy-service"; @@ -205,11 +210,33 @@ const system_proxy::AuthenticationRequiredDetails& details) { system_proxy::ProtectionSpace protection_space = details.proxy_protection_space(); + if (!primary_profile_) { + LookupProxyAuthCredentialsCallback(protection_space, + /* credentials = */ base::nullopt); + return; + } - // TODO(acostinas, crbug.com/1098216): Get credentials from the network - // service. - LookupProxyAuthCredentialsCallback(protection_space, - /* credentials = */ base::nullopt); + // TODO(acostinas,chromium:1104818) |protection_space.origin()| is in a + // URI-like format which may be incompatible between Chrome and libcurl, which + // is used on the Chrome OS side. We should change |origin()| to be a PAC + // string (a more "standard" way of representing proxies) and call + // |FromPacString()| to create |proxy_server|. + net::ProxyServer proxy_server = net::ProxyServer::FromURI( + protection_space.origin(), net::ProxyServer::Scheme::SCHEME_HTTP); + + if (!proxy_server.is_valid()) { + LookupProxyAuthCredentialsCallback(protection_space, + /* credentials = */ base::nullopt); + return; + } + content::BrowserContext::GetDefaultStoragePartition(primary_profile_) + ->GetNetworkContext() + ->LookupProxyAuthCredentials( + proxy_server, protection_space.scheme(), + net::HttpUtil::Unquote(protection_space.realm()), + base::BindOnce( + &SystemProxyManager::LookupProxyAuthCredentialsCallback, + weak_factory_.GetWeakPtr(), protection_space)); } void SystemProxyManager::LookupProxyAuthCredentialsCallback(
diff --git a/chrome/browser/chromeos/policy/system_proxy_manager.h b/chrome/browser/chromeos/policy/system_proxy_manager.h index 0397f08..078920a6 100644 --- a/chrome/browser/chromeos/policy/system_proxy_manager.h +++ b/chrome/browser/chromeos/policy/system_proxy_manager.h
@@ -11,6 +11,7 @@ #include "base/callback_forward.h" #include "base/gtest_prod_util.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chromeos/dbus/system_proxy/system_proxy_service.pb.h" #include "net/base/auth.h" @@ -70,8 +71,9 @@ // This function is called when the |WorkerActive| dbus signal is received. void OnWorkerActive(const system_proxy::WorkerActiveSignalDetails& details); - // This function is called when the |AuthenticationRequired| dbus signal is - // received. + // Requests from the NetworkService the user credentials associated with the + // protection space specified in |details|. This function is called when the + // |AuthenticationRequired| dbus signal is received. void OnAuthenticationRequired( const system_proxy::AuthenticationRequiredDetails& details);
diff --git a/chrome/browser/chromeos/policy/system_proxy_manager_unittest.cc b/chrome/browser/chromeos/policy/system_proxy_manager_unittest.cc index ae89f3d..dc1912b 100644 --- a/chrome/browser/chromeos/policy/system_proxy_manager_unittest.cc +++ b/chrome/browser/chromeos/policy/system_proxy_manager_unittest.cc
@@ -17,7 +17,19 @@ #include "chromeos/dbus/system_proxy/system_proxy_client.h" #include "chromeos/dbus/system_proxy/system_proxy_service.pb.h" #include "components/prefs/pref_service.h" +#include "content/public/browser/network_service_instance.h" +#include "content/public/browser/storage_partition.h" #include "content/public/test/browser_task_environment.h" +#include "content/public/test/test_utils.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "net/http/http_auth.h" +#include "net/http/http_auth_cache.h" +#include "net/http/http_network_session.h" +#include "net/http/http_transaction_factory.h" +#include "net/url_request/url_request_context.h" +#include "services/network/network_context.h" +#include "services/network/network_service.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -28,13 +40,40 @@ namespace { constexpr char kSystemServicesUsername[] = "test_username"; constexpr char kSystemServicesPassword[] = "test_password"; +constexpr char kBrowserUsername[] = "browser_username"; +constexpr char kBrowserPassword[] = "browser_password"; constexpr char kKerberosActivePrincipalName[] = "kerberos_princ_name"; constexpr char kProxyAuthUrl[] = "http://example.com:3128"; +constexpr char kProxyAuthEmptyPath[] = "http://example.com:3128/"; constexpr char kRealm[] = "My proxy"; -constexpr char kScheme[] = "BaSiC"; +constexpr char kScheme[] = "dIgEsT"; +constexpr char kProxyAuthChallenge[] = "challenge"; + +std::unique_ptr<network::NetworkContext> +CreateNetworkContextForDefaultStoragePartition( + network::NetworkService* network_service, + content::BrowserContext* browser_context) { + mojo::PendingRemote<network::mojom::NetworkContext> network_context_remote; + auto network_context = std::make_unique<network::NetworkContext>( + network_service, network_context_remote.InitWithNewPipeAndPassReceiver(), + network::mojom::NetworkContextParams::New()); + content::BrowserContext::GetDefaultStoragePartition(browser_context) + ->SetNetworkContextForTesting(std::move(network_context_remote)); + return network_context; +} + +network::NetworkService* GetNetworkService() { + content::GetNetworkService(); + // Wait for the Network Service to initialize on the IO thread. + content::RunAllPendingInMessageLoop(content::BrowserThread::IO); + return network::NetworkService::GetNetworkServiceForTesting(); +} + } // namespace namespace policy { +// TODO(acostinas, https://crbug.com/1102351) Replace RunUntilIdle() in tests +// with RunLoop::Run() with explicit RunLoop::QuitClosure(). class SystemProxyManagerTest : public testing::Test { public: SystemProxyManagerTest() : local_state_(TestingBrowserProcess::GetGlobal()) {} @@ -158,7 +197,7 @@ } // Tests that when no user is signed in, credential requests are resolved to a -// d-bus call which sends back to System-proxy empty credentials for the +// D-Bus call which sends back to System-proxy empty credentials for the // specified protection space. TEST_F(SystemProxyManagerTest, UserCredentialsRequiredNoUser) { SystemProxyManager system_proxy_manager(chromeos::CrosSettings::Get(), @@ -190,4 +229,56 @@ EXPECT_EQ("", request.credentials().username()); EXPECT_EQ("", request.credentials().password()); } + +// Tests that credential requests are resolved to a D-Bus call which sends back +// to System-proxy credentials acquired from the NetworkService. +TEST_F(SystemProxyManagerTest, UserCredentialsRequestedFromNetworkService) { + SystemProxyManager system_proxy_manager(chromeos::CrosSettings::Get(), + local_state_.Get()); + SetPolicy(true /* system_proxy_enabled */, "" /* system_services_username */, + "" /* system_services_password */); + system_proxy_manager.StartObservingPrimaryProfilePrefs(profile_.get()); + + // Setup the NetworkContext with credentials. + std::unique_ptr<network::NetworkContext> network_context = + CreateNetworkContextForDefaultStoragePartition(GetNetworkService(), + profile_.get()); + network_context->url_request_context() + ->http_transaction_factory() + ->GetSession() + ->http_auth_cache() + ->Add(GURL(kProxyAuthEmptyPath), net::HttpAuth::AUTH_PROXY, kRealm, + net::HttpAuth::AUTH_SCHEME_DIGEST, net::NetworkIsolationKey(), + kProxyAuthChallenge, + net::AuthCredentials(base::ASCIIToUTF16(kBrowserUsername), + base::ASCIIToUTF16(kBrowserPassword)), + std::string() /* path */); + + system_proxy::ProtectionSpace protection_space; + protection_space.set_origin(kProxyAuthUrl); + protection_space.set_scheme(kScheme); + protection_space.set_realm(kRealm); + + system_proxy::AuthenticationRequiredDetails details; + *details.mutable_proxy_protection_space() = protection_space; + + EXPECT_EQ(1, client_test_interface()->GetSetAuthenticationDetailsCallCount()); + + client_test_interface()->SendAuthenticationRequiredSignal(details); + task_environment_.RunUntilIdle(); + + EXPECT_EQ(2, client_test_interface()->GetSetAuthenticationDetailsCallCount()); + + system_proxy::SetAuthenticationDetailsRequest request = + client_test_interface()->GetLastAuthenticationDetailsRequest(); + + ASSERT_TRUE(request.has_protection_space()); + EXPECT_EQ(protection_space.SerializeAsString(), + request.protection_space().SerializeAsString()); + + ASSERT_TRUE(request.has_credentials()); + EXPECT_EQ(kBrowserUsername, request.credentials().username()); + EXPECT_EQ(kBrowserPassword, request.credentials().password()); + system_proxy_manager.StopObservingPrimaryProfilePrefs(); +} } // namespace policy
diff --git a/chrome/browser/chromeos/system_token_cert_db_initializer.cc b/chrome/browser/chromeos/system_token_cert_db_initializer.cc index d5010017..3376299 100644 --- a/chrome/browser/chromeos/system_token_cert_db_initializer.cc +++ b/chrome/browser/chromeos/system_token_cert_db_initializer.cc
@@ -108,6 +108,17 @@ // Note that the observer could potentially not be added yet, but // RemoveObserver() is a no-op in that case. CryptohomeClient::Get()->RemoveObserver(this); + + // Cancel any in-progress initialization sequence. + weak_ptr_factory_.InvalidateWeakPtrs(); + + // Notify observers that the SystemTokenCertDBInitializer and the + // NSSCertDatabase it provides can not be used anymore. + for (auto& observer : observers_) + observer.OnSystemTokenCertDBDestroyed(); + + // Now it's safe to destroy the NSSCertDatabase. + system_token_cert_database_.reset(); } void SystemTokenCertDBInitializer::TpmInitStatusUpdated( @@ -134,6 +145,18 @@ get_system_token_cert_db_callback_list_.push_back(std::move(callback)); } +void SystemTokenCertDBInitializer::AddObserver( + SystemTokenCertDBObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + observers_.AddObserver(observer); +} + +void SystemTokenCertDBInitializer::RemoveObserver( + SystemTokenCertDBObserver* observer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + observers_.RemoveObserver(observer); +} + void SystemTokenCertDBInitializer::OnCryptohomeAvailable(bool available) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/chrome/browser/chromeos/system_token_cert_db_initializer.h b/chrome/browser/chromeos/system_token_cert_db_initializer.h index cfd08ad..1950607 100644 --- a/chrome/browser/chromeos/system_token_cert_db_initializer.h +++ b/chrome/browser/chromeos/system_token_cert_db_initializer.h
@@ -11,6 +11,8 @@ #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "base/observer_list_types.h" #include "base/optional.h" #include "base/sequence_checker.h" #include "chromeos/dbus/cryptohome/cryptohome_client.h" @@ -22,6 +24,16 @@ namespace chromeos { +// An observer that gets notified when the global NSSCertDatabase is about to be +// destroyed. +class SystemTokenCertDBObserver : public base::CheckedObserver { + public: + // Called when the global NSSCertDatabase is about to be destroyed. + // Consumers of that database should drop any reference to it and stop using + // it. + virtual void OnSystemTokenCertDBDestroyed() = 0; +}; + // Initializes a global NSSCertDatabase for the system token and starts // NetworkCertLoader with that database. // @@ -50,10 +62,17 @@ // |callback|. If the database is already initialized, calls |callback| // immediately. Otherwise, |callback| will be called when the database is // initialized. + // To be notified when the returned NSSCertDatabase becomes invalid, callers + // should register as SystemTokenCertDBObserver. using GetSystemTokenCertDbCallback = base::OnceCallback<void(net::NSSCertDatabase*)>; void GetSystemTokenCertDb(GetSystemTokenCertDbCallback callback); + // Adds |observer| as SystemTokenCertDBObserver. + void AddObserver(SystemTokenCertDBObserver* observer); + // Removes |observer| as SystemTokenCertDBObserver. + void RemoveObserver(SystemTokenCertDBObserver* observer); + private: // Called once the cryptohome service is available. void OnCryptohomeAvailable(bool available); @@ -86,6 +105,10 @@ std::vector<GetSystemTokenCertDbCallback> get_system_token_cert_db_callback_list_; + // List of observers that will be notified when the global system token + // NSSCertDatabase is destroyed. + base::ObserverList<SystemTokenCertDBObserver> observers_; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<SystemTokenCertDBInitializer> weak_ptr_factory_{this};
diff --git a/chrome/browser/client_hints/OWNERS b/chrome/browser/client_hints/OWNERS index 22542699..6908cd0a 100644 --- a/chrome/browser/client_hints/OWNERS +++ b/chrome/browser/client_hints/OWNERS
@@ -1,6 +1,7 @@ yoavweiss@chromium.org tbansal@chromium.org ryansturm@chromium.org +aarontag@chromium.org # For IPC security review per-file *.mojom=set noparent
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc index c66d330..b80275d 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc
@@ -316,6 +316,12 @@ *args_); EXTENSION_FUNCTION_VALIDATE(parameters); + if (parameters->new_password.empty()) { + return RespondNow( + Error("Could not change the compromised credential. The new password " + "can't be empty.")); + } + if (!GetDelegate(browser_context()) ->ChangeCompromisedCredential(parameters->credential, parameters->new_password)) {
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_apitest.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_apitest.cc index 45337a9..ec2f6b27 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_apitest.cc +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_apitest.cc
@@ -214,6 +214,13 @@ } IN_PROC_BROWSER_TEST_F(PasswordsPrivateApiTest, + ChangeCompromisedCredentialWithEmptyPasswordFails) { + EXPECT_TRUE( + RunPasswordsSubtest("changeCompromisedCredentialWithEmptyPasswordFails")) + << message_; +} + +IN_PROC_BROWSER_TEST_F(PasswordsPrivateApiTest, ChangeCompromisedCredentialFails) { EXPECT_TRUE(RunPasswordsSubtest("changeCompromisedCredentialFails")) << message_;
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_api.cc b/chrome/browser/extensions/api/streams_private/streams_private_api.cc index bb4af72..70a275c8 100644 --- a/chrome/browser/extensions/api/streams_private/streams_private_api.cc +++ b/chrome/browser/extensions/api/streams_private/streams_private_api.cc
@@ -26,7 +26,7 @@ int frame_tree_node_id, int render_process_id, int render_frame_id, - content::mojom::TransferrableURLLoaderPtr transferrable_loader, + blink::mojom::TransferrableURLLoaderPtr transferrable_loader, const GURL& original_url) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_api.h b/chrome/browser/extensions/api/streams_private/streams_private_api.h index 01197a0..1fd16ff4 100644 --- a/chrome/browser/extensions/api/streams_private/streams_private_api.h +++ b/chrome/browser/extensions/api/streams_private/streams_private_api.h
@@ -9,7 +9,7 @@ #include <string> #include "base/macros.h" -#include "content/public/common/transferrable_url_loader.mojom.h" +#include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h" namespace extensions { @@ -35,7 +35,7 @@ int frame_tree_node_id, int render_process_id, int render_frame_id, - content::mojom::TransferrableURLLoaderPtr transferrable_loader, + blink::mojom::TransferrableURLLoaderPtr transferrable_loader, const GURL& original_url); };
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index cf12dab0..1f885c9d 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc
@@ -51,6 +51,7 @@ #include "extensions/browser/install/crx_install_error.h" #include "extensions/browser/install/extension_install_ui.h" #include "extensions/browser/install_flag.h" +#include "extensions/browser/install_stage.h" #include "extensions/browser/notification_types.h" #include "extensions/browser/policy_check.h" #include "extensions/browser/preload_check_group.h" @@ -523,6 +524,7 @@ extension_ = extension; temp_dir_ = temp_dir; ruleset_checksums_ = std::move(ruleset_checksums); + ReportInstallationStage(InstallationStage::kFinalizing); if (!install_icon.empty()) install_icon_ = std::make_unique<SkBitmap>(install_icon); @@ -574,6 +576,10 @@ NOTREACHED(); } +void CrxInstaller::OnStageChanged(InstallationStage stage) { + ReportInstallationStage(stage); +} + void CrxInstaller::CheckInstall() { DCHECK_CURRENTLY_ON(BrowserThread::UI); ExtensionService* service = service_weak_.get(); @@ -716,6 +722,7 @@ void CrxInstaller::ConfirmInstall() { DCHECK_CURRENTLY_ON(BrowserThread::UI); + ReportInstallationStage(InstallationStage::kComplete); ExtensionService* service = service_weak_.get(); if (!service || service->browser_terminating()) return; @@ -1011,6 +1018,28 @@ NotifyCrxInstallComplete(base::nullopt); } +void CrxInstaller::ReportInstallationStage(InstallationStage stage) { + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { + DCHECK(installer_task_runner_->RunsTasksInCurrentSequence()); + if (!content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&CrxInstaller::ReportInstallationStage, + this, stage))) { + NOTREACHED(); + } + return; + } + + if (!service_weak_.get() || service_weak_->browser_terminating()) + return; + // In case of force installed extensions, expected_id_ should always be set. + // We do not want to report in case of other extensions. + if (expected_id_.empty()) + return; + InstallStageTracker* install_stage_tracker = + InstallStageTracker::Get(profile_); + install_stage_tracker->ReportCRXInstallationStage(expected_id_, stage); +} + void CrxInstaller::NotifyCrxInstallBegin() { InstallTrackerFactory::GetForBrowserContext(profile()) ->OnBeginCrxInstall(expected_id_);
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index b5ad3618..c1b7795 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h
@@ -42,6 +42,7 @@ class CrxInstallError; class ExtensionService; class ExtensionUpdaterTest; +enum class InstallationStage; class PreloadCheckGroup; // This class installs a crx file into a profile. @@ -297,6 +298,7 @@ const Extension* extension, const SkBitmap& install_icon, declarative_net_request::RulesetChecksums ruleset_checksums) override; + void OnStageChanged(InstallationStage stage) override; // Called on the UI thread to start the requirements, policy and blocklist // checks on the extension. @@ -326,6 +328,8 @@ void ReportFailureFromUIThread(const CrxInstallError& error); void ReportSuccessFromFileThread(); void ReportSuccessFromUIThread(); + // Always report from the UI thread. + void ReportInstallationStage(InstallationStage stage); void NotifyCrxInstallBegin(); void NotifyCrxInstallComplete(const base::Optional<CrxInstallError>& error);
diff --git a/chrome/browser/extensions/forced_extensions/install_stage_tracker.cc b/chrome/browser/extensions/forced_extensions/install_stage_tracker.cc index d783a7b..52dc4fef 100644 --- a/chrome/browser/extensions/forced_extensions/install_stage_tracker.cc +++ b/chrome/browser/extensions/forced_extensions/install_stage_tracker.cc
@@ -152,6 +152,16 @@ } } +void InstallStageTracker::ReportCRXInstallationStage(const ExtensionId& id, + InstallationStage stage) { + DCHECK(!id.empty()); + InstallationData& data = installation_data_map_[id]; + data.installation_stage = stage; + for (auto& observer : observers_) { + observer.OnExtensionDataChangedForTesting(id, browser_context_, data); + } +} + void InstallStageTracker::ReportDownloadingCacheStatus( const ExtensionId& id, ExtensionDownloaderDelegate::CacheStatus cache_status) {
diff --git a/chrome/browser/extensions/forced_extensions/install_stage_tracker.h b/chrome/browser/extensions/forced_extensions/install_stage_tracker.h index 08922be..2b4fc09 100644 --- a/chrome/browser/extensions/forced_extensions/install_stage_tracker.h +++ b/chrome/browser/extensions/forced_extensions/install_stage_tracker.h
@@ -14,6 +14,7 @@ #include "components/keyed_service/core/keyed_service.h" #include "extensions/browser/install/crx_install_error.h" #include "extensions/browser/install/sandboxed_unpacker_failure_reason.h" +#include "extensions/browser/install_stage.h" #include "extensions/browser/updater/extension_downloader_delegate.h" #include "extensions/browser/updater/safe_manifest_parser.h" #include "extensions/common/extension_id.h" @@ -295,6 +296,8 @@ // Time at which the update manifest is downloaded and successfully parsed // from the server. base::Optional<base::Time> download_manifest_finish_time; + // See InstallationStage enum. + base::Optional<InstallationStage> installation_stage; }; class Observer : public base::CheckedObserver { @@ -347,6 +350,8 @@ void ReportFailure(const ExtensionId& id, FailureReason reason); void ReportDownloadingStage(const ExtensionId& id, ExtensionDownloaderDelegate::Stage stage); + void ReportCRXInstallationStage(const ExtensionId& id, + InstallationStage stage); void ReportDownloadingCacheStatus( const ExtensionId& id, ExtensionDownloaderDelegate::CacheStatus cache_status);
diff --git a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc index 2a444e8..7570d1d 100644 --- a/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc +++ b/chrome/browser/guest_view/mime_handler_view/chrome_mime_handler_view_browsertest.cc
@@ -151,7 +151,7 @@ const GURL& url, std::string* view_id) { *view_id = base::GenerateGUID(); - auto transferrable_loader = content::mojom::TransferrableURLLoader::New(); + auto transferrable_loader = blink::mojom::TransferrableURLLoader::New(); transferrable_loader->url = url; transferrable_loader->head = network::mojom::URLResponseHead::New(); transferrable_loader->head->mime_type = "application/pdf";
diff --git a/chrome/browser/history/history_service_factory.cc b/chrome/browser/history/history_service_factory.cc index 3ef673e..8ae55f1 100644 --- a/chrome/browser/history/history_service_factory.cc +++ b/chrome/browser/history/history_service_factory.cc
@@ -19,6 +19,23 @@ #include "components/keyed_service/core/service_access_type.h" #include "components/prefs/pref_service.h" +namespace { + +std::unique_ptr<KeyedService> BuildHistoryService( + content::BrowserContext* context) { + auto history_service = std::make_unique<history::HistoryService>( + std::make_unique<ChromeHistoryClient>( + BookmarkModelFactory::GetForBrowserContext(context)), + std::make_unique<history::ContentVisitDelegate>(context)); + if (!history_service->Init( + history::HistoryDatabaseParamsForPath(context->GetPath()))) { + return nullptr; + } + return history_service; +} + +} // namespace + // static history::HistoryService* HistoryServiceFactory::GetForProfile( Profile* profile, @@ -65,6 +82,12 @@ factory->BrowserContextDestroyed(profile); } +// static +BrowserContextKeyedServiceFactory::TestingFactory +HistoryServiceFactory::GetDefaultFactory() { + return base::BindRepeating(&BuildHistoryService); +} + HistoryServiceFactory::HistoryServiceFactory() : BrowserContextKeyedServiceFactory( "HistoryService", @@ -77,16 +100,7 @@ KeyedService* HistoryServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - std::unique_ptr<history::HistoryService> history_service( - new history::HistoryService( - std::make_unique<ChromeHistoryClient>( - BookmarkModelFactory::GetForBrowserContext(context)), - std::make_unique<history::ContentVisitDelegate>(context))); - if (!history_service->Init( - history::HistoryDatabaseParamsForPath(context->GetPath()))) { - return nullptr; - } - return history_service.release(); + return BuildHistoryService(context).release(); } content::BrowserContext* HistoryServiceFactory::GetBrowserContextToUse(
diff --git a/chrome/browser/history/history_service_factory.h b/chrome/browser/history/history_service_factory.h index e11fb29..1af52d61 100644 --- a/chrome/browser/history/history_service_factory.h +++ b/chrome/browser/history/history_service_factory.h
@@ -36,6 +36,9 @@ // calling test is expected to do the cleanup before calling this function. static void ShutdownForProfile(Profile* profile); + // Returns the default factory, useful in tests where it's null by default. + static TestingFactory GetDefaultFactory(); + private: friend struct base::DefaultSingletonTraits<HistoryServiceFactory>;
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service.h b/chrome/browser/nearby_sharing/nearby_sharing_service.h index 894f925..cb5a094 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service.h +++ b/chrome/browser/nearby_sharing/nearby_sharing_service.h
@@ -41,16 +41,14 @@ // Registers a send surface for handling payload transfer status and device // discovery. - virtual void RegisterSendSurface( + virtual StatusCodes RegisterSendSurface( TransferUpdateCallback* transfer_callback, - ShareTargetDiscoveredCallback* discovery_callback, - StatusCodesCallback status_codes_callback) = 0; + ShareTargetDiscoveredCallback* discovery_callback) = 0; // Unregisters the current send surface. - virtual void UnregisterSendSurface( + virtual StatusCodes UnregisterSendSurface( TransferUpdateCallback* transfer_callback, - ShareTargetDiscoveredCallback* discovery_callback, - StatusCodesCallback status_codes_callback) = 0; + ShareTargetDiscoveredCallback* discovery_callback) = 0; // Registers a receiver surface for handling payload transfer status. virtual StatusCodes RegisterReceiveSurface(
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc index 220c408..dae2abc8 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/bind.h" +#include "base/task_runner_util.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/nearby_sharing/fast_initiation_manager.h" #include "chrome/browser/nearby_sharing/logging/logging.h" @@ -150,26 +151,28 @@ bluetooth_adapter_->RemoveObserver(this); } -void NearbySharingServiceImpl::RegisterSendSurface( +NearbySharingService::StatusCodes NearbySharingServiceImpl::RegisterSendSurface( TransferUpdateCallback* transfer_callback, - ShareTargetDiscoveredCallback* discovery_callback, - StatusCodesCallback status_codes_callback) { - register_send_surface_callback_ = std::move(status_codes_callback); + ShareTargetDiscoveredCallback* discovery_callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); StartFastInitiationAdvertising(); + return StatusCodes::kOk; } -void NearbySharingServiceImpl::UnregisterSendSurface( +NearbySharingService::StatusCodes +NearbySharingServiceImpl::UnregisterSendSurface( TransferUpdateCallback* transfer_callback, - ShareTargetDiscoveredCallback* discovery_callback, - StatusCodesCallback status_codes_callback) { - unregister_send_surface_callback_ = std::move(status_codes_callback); + ShareTargetDiscoveredCallback* discovery_callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); StopFastInitiationAdvertising(); + return StatusCodes::kOk; } NearbySharingService::StatusCodes NearbySharingServiceImpl::RegisterReceiveSurface( TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(transfer_callback); DCHECK_NE(state, ReceiveSurfaceState::kUnknown); if (foreground_receive_callbacks_.HasObserver(transfer_callback) || @@ -202,6 +205,7 @@ NearbySharingService::StatusCodes NearbySharingServiceImpl::UnregisterReceiveSurface( TransferUpdateCallback* transfer_callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(transfer_callback); bool is_foreground = foreground_receive_callbacks_.HasObserver(transfer_callback); @@ -307,6 +311,7 @@ const std::string& endpoint_id, const std::vector<uint8_t>& endpoint_info, std::unique_ptr<NearbyConnection> connection) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // TODO(crbug/1085068): Handle incoming connection; use CertificateManager } @@ -384,15 +389,13 @@ void NearbySharingServiceImpl::StartFastInitiationAdvertising() { if (!IsBluetoothPresent() || !IsBluetoothPowered()) { - std::move(register_send_surface_callback_).Run(StatusCodes::kError); + NS_LOG(INFO) << "Failed to advertise FastInitiation. Bluetooth is not " + "present or powered."; return; } if (fast_initiation_manager_) { - // TODO(hansenmichael): Do not invoke - // |register_send_surface_callback_| until Nearby Connections - // scanning is kicked off. - std::move(register_send_surface_callback_).Run(StatusCodes::kOk); + NS_LOG(INFO) << "Failed to advertise FastInitiation. Already advertising."; return; } @@ -413,8 +416,7 @@ void NearbySharingServiceImpl::StopFastInitiationAdvertising() { if (!fast_initiation_manager_) { - if (unregister_send_surface_callback_) - std::move(unregister_send_surface_callback_).Run(StatusCodes::kOk); + NS_LOG(INFO) << "Can't stop advertising FastInitiation. Not advertising."; return; } @@ -431,7 +433,7 @@ // Because this will be called from the constructor, GetAdapter() may call // OnGetBluetoothAdapter() immediately which can cause problems during tests // since the class is not fully constructed yet. - base::ThreadTaskRunnerHandle::Get()->PostTask( + base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce( &device::BluetoothAdapterFactory::GetAdapter, @@ -450,22 +452,17 @@ // TODO(hansenmichael): Do not invoke // |register_send_surface_callback_| until Nearby Connections // scanning is kicked off. - std::move(register_send_surface_callback_).Run(StatusCodes::kOk); + NS_LOG(VERBOSE) << "Started advertising FastInitiation."; } void NearbySharingServiceImpl::OnStartFastInitiationAdvertisingError() { fast_initiation_manager_.reset(); - std::move(register_send_surface_callback_).Run(StatusCodes::kError); + NS_LOG(ERROR) << "Failed to start FastInitiation advertising."; } void NearbySharingServiceImpl::OnStopFastInitiationAdvertising() { fast_initiation_manager_.reset(); - - // TODO(hansenmichael): Do not invoke - // |unregister_send_surface_callback_| until Nearby Connections - // scanning is stopped. - if (unregister_send_surface_callback_) - std::move(unregister_send_surface_callback_).Run(StatusCodes::kOk); + NS_LOG(VERBOSE) << "Stopped advertising FastInitiation"; } bool NearbySharingServiceImpl::IsBluetoothPresent() const {
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h index a6d9eaf0..1b18f47 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h
@@ -13,6 +13,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observer.h" +#include "base/sequence_checker.h" #include "chrome/browser/nearby_sharing/nearby_connections_manager.h" #include "chrome/browser/nearby_sharing/nearby_constants.h" #include "chrome/browser/nearby_sharing/nearby_notification_manager.h" @@ -26,6 +27,7 @@ class PrefService; class Profile; +// All methods should be called from the same sequence that created the service. class NearbySharingServiceImpl : public NearbySharingService, public KeyedService, @@ -40,13 +42,12 @@ ~NearbySharingServiceImpl() override; // NearbySharingService: - void RegisterSendSurface(TransferUpdateCallback* transfer_callback, - ShareTargetDiscoveredCallback* discovery_callback, - StatusCodesCallback status_codes_callback) override; - void UnregisterSendSurface( + StatusCodes RegisterSendSurface( TransferUpdateCallback* transfer_callback, - ShareTargetDiscoveredCallback* discovery_callback, - StatusCodesCallback status_codes_callback) override; + ShareTargetDiscoveredCallback* discovery_callback) override; + StatusCodes UnregisterSendSurface( + TransferUpdateCallback* transfer_callback, + ShareTargetDiscoveredCallback* discovery_callback) override; StatusCodes RegisterReceiveSurface(TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state) override; StatusCodes UnregisterReceiveSurface( @@ -110,8 +111,6 @@ nearby_process_observer_{this}; scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_; std::unique_ptr<FastInitiationManager> fast_initiation_manager_; - StatusCodesCallback register_send_surface_callback_; - StatusCodesCallback unregister_send_surface_callback_; NearbyNotificationManager nearby_notification_manager_; // A list of foreground receivers. @@ -143,6 +142,7 @@ // True if we're currently sending or receiving a file. bool is_transferring_files_ = false; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<NearbySharingServiceImpl> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc index cf106d0..fe105f2d 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" +#include "base/test/bind_test_util.h" #include "chrome/browser/nearby_sharing/fake_nearby_connections_manager.h" #include "chrome/browser/nearby_sharing/fast_initiation_manager.h" #include "chrome/browser/nearby_sharing/nearby_connections_manager.h" @@ -181,40 +182,6 @@ fast_initiation_manager_factory_.get()); } - NearbySharingService::StatusCodes RegisterSendSurfaceAndWait() { - base::RunLoop run_loop; - NearbySharingService::StatusCodes result; - service_->RegisterSendSurface( - /*transfer_callback=*/nullptr, /*discovery_callback=*/nullptr, - base::BindOnce( - [](base::OnceClosure quit_closure, - NearbySharingService::StatusCodes* result, - NearbySharingService::StatusCodes code) { - *result = code; - std::move(quit_closure).Run(); - }, - run_loop.QuitClosure(), &result)); - run_loop.Run(); - return result; - } - - NearbySharingService::StatusCodes UnregisterSendSurfaceAndWait() { - base::RunLoop run_loop; - NearbySharingService::StatusCodes result; - service_->UnregisterSendSurface( - /*transfer_callback=*/nullptr, /*discovery_callback=*/nullptr, - base::BindOnce( - [](base::OnceClosure quit_closure, - NearbySharingService::StatusCodes* result, - NearbySharingService::StatusCodes code) { - *result = code; - std::move(quit_closure).Run(); - }, - run_loop.QuitClosure(), &result)); - run_loop.Run(); - return result; - } - bool IsBluetoothPresent() { return is_bluetooth_present_; } bool IsBluetoothPowered() { return is_bluetooth_powered_; } @@ -265,42 +232,49 @@ TEST_F(NearbySharingServiceImplTest, StartFastInitiationAdvertising) { EXPECT_EQ(NearbySharingService::StatusCodes::kOk, - RegisterSendSurfaceAndWait()); + service_->RegisterSendSurface(/*transfer_callback=*/nullptr, + /*discovery_callback=*/nullptr)); EXPECT_EQ(1u, fast_initiation_manager_factory_->StartAdvertisingCount()); // Call RegisterSendSurface() a second time and make sure StartAdvertising is // not called again. EXPECT_EQ(NearbySharingService::StatusCodes::kOk, - RegisterSendSurfaceAndWait()); + service_->RegisterSendSurface(/*transfer_callback=*/nullptr, + /*discovery_callback=*/nullptr)); EXPECT_EQ(1u, fast_initiation_manager_factory_->StartAdvertisingCount()); } TEST_F(NearbySharingServiceImplTest, StartFastInitiationAdvertisingError) { SetFakeFastInitiationManagerFactory(/*should_succeed_on_start=*/false); - EXPECT_EQ(NearbySharingService::StatusCodes::kError, - RegisterSendSurfaceAndWait()); + EXPECT_EQ(NearbySharingService::StatusCodes::kOk, + service_->RegisterSendSurface(/*transfer_callback=*/nullptr, + /*discovery_callback=*/nullptr)); } TEST_F(NearbySharingServiceImplTest, StartFastInitiationAdvertising_BluetoothNotPresent) { is_bluetooth_present_ = false; - EXPECT_EQ(NearbySharingService::StatusCodes::kError, - RegisterSendSurfaceAndWait()); + EXPECT_EQ(NearbySharingService::StatusCodes::kOk, + service_->RegisterSendSurface(/*transfer_callback=*/nullptr, + /*discovery_callback=*/nullptr)); } TEST_F(NearbySharingServiceImplTest, StartFastInitiationAdvertising_BluetoothNotPowered) { is_bluetooth_powered_ = false; - EXPECT_EQ(NearbySharingService::StatusCodes::kError, - RegisterSendSurfaceAndWait()); + EXPECT_EQ(NearbySharingService::StatusCodes::kOk, + service_->RegisterSendSurface(/*transfer_callback=*/nullptr, + /*discovery_callback=*/nullptr)); } TEST_F(NearbySharingServiceImplTest, StopFastInitiationAdvertising) { EXPECT_EQ(NearbySharingService::StatusCodes::kOk, - RegisterSendSurfaceAndWait()); + service_->RegisterSendSurface(/*transfer_callback=*/nullptr, + /*discovery_callback=*/nullptr)); EXPECT_EQ(1u, fast_initiation_manager_factory_->StartAdvertisingCount()); EXPECT_EQ(NearbySharingService::StatusCodes::kOk, - UnregisterSendSurfaceAndWait()); + service_->UnregisterSendSurface(/*transfer_callback=*/nullptr, + /*discovery_callback=*/nullptr)); EXPECT_TRUE(fast_initiation_manager_factory_ ->StopAdvertisingCalledAndManagerDestroyed()); } @@ -308,7 +282,8 @@ TEST_F(NearbySharingServiceImplTest, StopFastInitiationAdvertising_BluetoothBecomesNotPresent) { EXPECT_EQ(NearbySharingService::StatusCodes::kOk, - RegisterSendSurfaceAndWait()); + service_->RegisterSendSurface(/*transfer_callback=*/nullptr, + /*discovery_callback=*/nullptr)); adapter_observer_->AdapterPresentChanged(mock_bluetooth_adapter_.get(), false); EXPECT_TRUE(fast_initiation_manager_factory_ @@ -318,7 +293,8 @@ TEST_F(NearbySharingServiceImplTest, StopFastInitiationAdvertising_BluetoothBecomesNotPowered) { EXPECT_EQ(NearbySharingService::StatusCodes::kOk, - RegisterSendSurfaceAndWait()); + service_->RegisterSendSurface(/*transfer_callback=*/nullptr, + /*discovery_callback=*/nullptr)); adapter_observer_->AdapterPoweredChanged(mock_bluetooth_adapter_.get(), false); EXPECT_TRUE(fast_initiation_manager_factory_
diff --git a/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc b/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc index a692d5e3..f8693f1 100644 --- a/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc +++ b/chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.cc
@@ -15,7 +15,6 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/download_utils.h" #include "content/public/browser/web_contents.h" -#include "content/public/common/transferrable_url_loader.mojom.h" #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_attach_helper.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" @@ -26,6 +25,7 @@ #include "mojo/public/cpp/system/data_pipe.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" +#include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h" PluginResponseInterceptorURLLoaderThrottle:: PluginResponseInterceptorURLLoaderThrottle(int resource_type, @@ -114,7 +114,7 @@ response_head->headers->raw_headers()); } - auto transferrable_loader = content::mojom::TransferrableURLLoader::New(); + auto transferrable_loader = blink::mojom::TransferrableURLLoader::New(); transferrable_loader->url = GURL( extensions::Extension::GetBaseURLFromExtensionId(extension_id).spec() + base::GenerateGUID());
diff --git a/chrome/browser/predictors/preconnect_manager.cc b/chrome/browser/predictors/preconnect_manager.cc index d7e470b..3f363b5 100644 --- a/chrome/browser/predictors/preconnect_manager.cc +++ b/chrome/browser/predictors/preconnect_manager.cc
@@ -231,7 +231,8 @@ weak_factory_.GetWeakPtr(), job_id)); if (info) { ++info->inflight_count; - delegate_->PreconnectInitiated(info->url, job->url); + if (delegate_) + delegate_->PreconnectInitiated(info->url, job->url); } ++inflight_preresolves_count_; } else {
diff --git a/chrome/browser/preferences/BUILD.gn b/chrome/browser/preferences/BUILD.gn index f06f098b..903dba6 100644 --- a/chrome/browser/preferences/BUILD.gn +++ b/chrome/browser/preferences/BUILD.gn
@@ -13,6 +13,7 @@ "android/java/src/org/chromium/chrome/browser/preferences/GrandfatheredChromePreferenceKeys.java", "android/java/src/org/chromium/chrome/browser/preferences/KeyPrefix.java", "android/java/src/org/chromium/chrome/browser/preferences/PrefChangeRegistrar.java", + "android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java", "android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManager.java", ] deps = [ @@ -44,7 +45,10 @@ } generate_jni("jni_headers") { - sources = [ "android/java/src/org/chromium/chrome/browser/preferences/PrefChangeRegistrar.java" ] + sources = [ + "android/java/src/org/chromium/chrome/browser/preferences/PrefChangeRegistrar.java", + "android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java", + ] } java_library("preferences_junit_tests") {
diff --git a/chrome/browser/preferences/android/README.md b/chrome/browser/preferences/android/README.md index ac7edf6f..9368c8d 100644 --- a/chrome/browser/preferences/android/README.md +++ b/chrome/browser/preferences/android/README.md
@@ -10,12 +10,12 @@ supports reading and writing simple key-value pairs to a file that is saved across app sessions. -## PrefService +## PrefServiceBridge -[`PrefService`][2] is a JNI bridge providing access to a native Chrome -[PrefService][3] instance associated. This interface can be used to read and -write prefs once they're registered through the `PrefRegistry` and exposed to -Java by way of a `java_cpp_strings` build target such as [this one][4]. +[`PrefServiceBridge`][2] is a JNI bridge providing access to the native Chrome +[PrefService][3] instance associated with the active user profile. This +interface can be used to read and write prefs once they're registered through +the `PrefRegistry` and added to the [`@Pref` enum][4]. ## FAQ @@ -33,24 +33,26 @@ No, then SharedPreferences should be preferred. **What if the PrefService type I need to access is not supported by -PrefService (i.e. double, Time, etc.)?** +PrefServiceBridge (i.e. double, Time, etc.)?** -If a base value type is supported by PrefService, then PrefService should +If a base value type is supported by PrefService, then PrefServiceBridge should be extended to support it once it's needed. **How do I access a PrefService pref associated with local state rather than browser profile?** Most Chrome for Android preferences should be associated with a specific -profile. If your preference should instead be associated with [local state][5] +profile. If your preference should instead be associated with [local state][6] (for example, if it is related to the First Run Experience), then you should not -use PrefService and should instead create your own feature-specific JNI -bridge to access the correct PrefService instance (see [`first_run_utils.cc`][6]). +use PrefServiceBridge and should instead create your own feature-specific JNI +bridge to access the correct PrefService instance (see +[`first_run_utils.cc`][7]). [0]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/SharedPreferencesManager.java [1]: https://developer.android.com/reference/android/content/SharedPreferences -[2]: https://source.chromium.org/chromium/chromium/src/+/master:components/prefs/android/java/src/org/chromium/components/prefs/PrefService.java +[2]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java [3]: https://chromium.googlesource.com/chromium/src/+/master/services/preferences/README.md -[4]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/preferences/BUILD.gn;drc=4ae1b7be67cd9b470ebcc90f2747a9f31f155b00;l=28 -[5]: https://www.chromium.org/developers/design-documents/preferences#TOC-Introduction -[6]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/first_run/android/first_run_utils.cc +[4]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/android/preferences/prefs.h +[5]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/preferences/OWNERS +[6]: https://www.chromium.org/developers/design-documents/preferences#TOC-Introduction +[7]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/first_run/android/first_run_utils.cc
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java new file mode 100644 index 0000000..260aed0 --- /dev/null +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java
@@ -0,0 +1,115 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.preferences; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; + +import org.chromium.base.ThreadUtils; +import org.chromium.base.annotations.NativeMethods; + +/** + * PrefServiceBridge is a singleton which provides read and write access to native PrefService. + */ +public class PrefServiceBridge { + // Singleton constructor. Do not call directly unless for testing purpose. + @VisibleForTesting + protected PrefServiceBridge() {} + + private static PrefServiceBridge sInstance; + + /** + * @return The singleton PrefServiceBridge instance. + */ + public static PrefServiceBridge getInstance() { + ThreadUtils.assertOnUiThread(); + if (sInstance == null) { + sInstance = new PrefServiceBridge(); + } + return sInstance; + } + + /** + * @param preference The name of the preference. + */ + public void clearPref(@NonNull String preference) { + PrefServiceBridgeJni.get().clearPref(preference); + } + + /** + * @param preference The name of the preference. + * @return Whether the specified preference is enabled. + */ + public boolean getBoolean(@NonNull String preference) { + return PrefServiceBridgeJni.get().getBoolean(preference); + } + + /** + * @param preference The name of the preference. + * @param value The value the specified preference will be set to. + */ + public void setBoolean(@NonNull String preference, boolean value) { + PrefServiceBridgeJni.get().setBoolean(preference, value); + } + + /** + * @param preference The name of the preference. + * @return value The value of the specified preference. + */ + public int getInteger(@NonNull String preference) { + return PrefServiceBridgeJni.get().getInteger(preference); + } + + /** + * @param preference The name of the preference. + * @param value The value the specified preference will be set to. + */ + public void setInteger(@NonNull String preference, int value) { + PrefServiceBridgeJni.get().setInteger(preference, value); + } + + /** + * @param preference The name of the preference. + * @return value The value of the specified preference. + */ + @NonNull + public String getString(@NonNull String preference) { + return PrefServiceBridgeJni.get().getString(preference); + } + + /** + * @param preference The name of the preference. + * @param value The value the specified preference will be set to. + */ + public void setString(@NonNull String preference, @NonNull String value) { + PrefServiceBridgeJni.get().setString(preference, value); + } + + /** + * @param preference The name of the preference. + * @return Whether the specified preference is managed. + */ + public boolean isManagedPreference(@NonNull String preference) { + return PrefServiceBridgeJni.get().isManagedPreference(preference); + } + + @VisibleForTesting + public static void setInstanceForTesting(@Nullable PrefServiceBridge instanceForTesting) { + sInstance = instanceForTesting; + } + + @NativeMethods + interface Natives { + void clearPref(String preference); + boolean getBoolean(String preference); + void setBoolean(String preference, boolean value); + int getInteger(String preference); + void setInteger(String preference, int value); + String getString(String preference); + void setString(String preference, String value); + boolean isManagedPreference(String preference); + } +}
diff --git a/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html b/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html index 904acf3..18bae8c5 100644 --- a/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html +++ b/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html
@@ -100,7 +100,8 @@ width: 100%; } </style> -<div id="destination-dropdown" on-keydown="onKeyDown_" tabindex="0"> +<div id="destination-dropdown" on-keydown="onKeyDown_" tabindex="0" + on-blur="onBlur_" on-click="onClick_"> <div id="destination-display-container"> <div id="destination-icon-box"> <iron-icon icon="[[destinationIcon]]" @@ -122,7 +123,7 @@ <div slot="dropdown-content"> <template is="dom-repeat" items="[[itemList]]"> <button id="[[item.key]]" tabindex="-1" value="[[item.key]]" - on-click="onSelect_" + on-click="onSelect_" on-blur="onBlur_" class$="list-item [[getHighlightedClass_(item.key, highlightedIndex_)]]"> <printer-status-icon-cros icon-location="[[IconLocation.DROPDOWN]]" @@ -134,25 +135,25 @@ </button> </template> <button on-click="onSelect_" tabindex="-1" value="[[pdfDestinationKey]]" - hidden$="[[pdfPrinterDisabled]]" + hidden$="[[pdfPrinterDisabled]]" on-blur="onBlur_" class$="list-item [[getHighlightedClass_(pdfDestinationKey, highlightedIndex_)]]"> $i18n{printToPDF} </button> - <button on-click="onSelect_" tabindex="-1" + <button on-click="onSelect_" tabindex="-1" on-blur="onBlur_" value="[[driveDestinationKey]]" hidden$="[[!driveDestinationKey]]" class$="list-item [[getHighlightedClass_(driveDestinationKey, highlightedIndex_)]]"> $i18n{printToGoogleDrive} </button> <button on-click="onSelect_" tabindex="-1" value="noDestinations" - hidden$="[[!noDestinations]]" + hidden$="[[!noDestinations]]" on-blur="onBlur_" class$="list-item [[getHighlightedClass_('noDestinations', highlightedIndex_)]]"> $i18n{noDestinationsMessage} </button> <button on-click="onSelect_" tabindex="-1" value="seeMore" - aria-label$="[[i18n(seeMoreDestinationsLabel)]]" + aria-label$="[[i18n(seeMoreDestinationsLabel)]]" on-blur="onBlur_" class$="list-item [[getHighlightedClass_('seeMore', highlightedIndex_)]]"> $i18n{seeMore}
diff --git a/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js b/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js index 24ac4990..f2c3e89 100644 --- a/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js +++ b/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js
@@ -68,17 +68,10 @@ /** @override */ attached() { - this.pointerDownListener_ = event => this.onPointerDown_(event); - document.addEventListener('pointerdown', this.pointerDownListener_); this.updateTabIndex_(); this.IconLocation = IconLocation; }, - /** @override */ - detached() { - document.removeEventListener('pointerdown', this.pointerDownListener_); - }, - /** * Enqueues a task to refit the iron-dropdown if it is open. * @private @@ -130,28 +123,20 @@ this.highlightedIndex_ = this.getButtonListFromDropdown_().indexOf(item); }, - /** - * @param {!Event} event - * @private - */ - onPointerDown_(event) { - const paths = event.composedPath(); + /** @private */ + onClick_(event) { const dropdown = /** @type {!IronDropdownElement} */ (this.$$('iron-dropdown')); - const destinationDropdown = - /** @type {!Element} */ (this.$$('#destination-dropdown')); - // Exit if path includes |dropdown| because event will be handled by // onSelect_. - if (paths.includes(dropdown)) { + if (event.composedPath().includes(dropdown)) { return; } - if (!paths.includes(destinationDropdown) || dropdown.opened) { + if (dropdown.opened) { this.closeDropdown_(); return; } - this.openDropdown_(); }, @@ -171,9 +156,6 @@ event.stopPropagation(); const dropdown = this.$$('iron-dropdown'); switch (event.code) { - case 'Tab': - this.closeDropdown_(); - break; case 'ArrowUp': case 'ArrowDown': this.onArrowKeyPress_(event.code); @@ -307,4 +289,17 @@ 'highlighted' : ''; }, + + /** + * Close the dropdown when focus is lost except when an item in the dropdown + * is the element that received the focus. + * @param {!Event} event + * @private + */ + onBlur_(event) { + if (!this.getButtonListFromDropdown_().includes( + /** @type {!Element} */ (event.relatedTarget))) { + this.closeDropdown_(); + } + }, });
diff --git a/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.html b/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.html index bea9c3c..eae831f4 100644 --- a/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.html +++ b/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.html
@@ -29,7 +29,8 @@ </cr-input> <cr-input id="passwordInput" value="[[item.password]]" class="password-input" label="$i18n{editPasswordPasswordLabel}" - type="[[getPasswordInputType_(visible)]]"> + type="[[getPasswordInputType_(visible)]]" required auto-validate + invalid="{{inputInvalid_}}"> <cr-icon-button id="showPasswordButton" class$="[[showPasswordIcon_(visible)]]" slot="suffix" on-click="onShowPasswordButtonClick_" @@ -42,7 +43,8 @@ <cr-button id="cancel" class="cancel-button" on-click="onCancel_"> $i18n{cancel} </cr-button> - <cr-button id="save" class="action-button" on-click="onSave_"> + <cr-button id="save" class="action-button" on-click="onSave_" + disabled="[[inputInvalid_]]"> $i18n{save} </cr-button> </div>
diff --git a/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.js b/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.js index 0e18db6..1c25550 100644 --- a/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.js +++ b/chrome/browser/resources/settings/autofill_page/password_check_edit_dialog.js
@@ -48,6 +48,12 @@ type: Boolean, value: false, }, + + /** + * Whether the input is invalid. + * @private + */ + inputInvalid_: Boolean, }, /** @private {?PasswordManagerProxy} */ @@ -84,7 +90,7 @@ this.passwordManager_ .changeCompromisedCredential( assert(this.item), this.$.passwordInput.value) - .then(() => { + .finally(() => { this.close(); }); },
diff --git a/chrome/browser/resources/settings/autofill_page/passwords_section.js b/chrome/browser/resources/settings/autofill_page/passwords_section.js index fe52381493..9c4287a 100644 --- a/chrome/browser/resources/settings/autofill_page/passwords_section.js +++ b/chrome/browser/resources/settings/autofill_page/passwords_section.js
@@ -138,7 +138,8 @@ eligibleForAccountStorage_: { type: Boolean, value: false, - computed: 'computeEligibleForAccountStorage_(syncStatus_, signedIn_)', + computed: 'computeEligibleForAccountStorage_(' + + 'syncStatus_, signedIn_, syncPrefs_)', }, /** @private */ @@ -375,8 +376,8 @@ this.addWebUIListener('sync-status-changed', syncStatusChanged); const syncPrefsChanged = syncPrefs => this.syncPrefs_ = syncPrefs; - syncBrowserProxy.sendSyncPrefsChanged(); this.addWebUIListener('sync-prefs-changed', syncPrefsChanged); + syncBrowserProxy.sendSyncPrefsChanged(); // For non-ChromeOS, also check whether accounts are available. // <if expr="not chromeos"> @@ -461,10 +462,13 @@ * @private */ computeEligibleForAccountStorage_() { - // |this.syncStatus_.signedIn| means the user has sync enabled, while - // |this.signedIn_| means they have signed in, in the content area. + // The user must have signed in but should have sync disabled + // (|!this.syncStatus_.signedin|). They should not be using a custom + // passphrase to encrypt their sync data, since there's no way for account + // storage users to input their passphrase and decrypt the passwords. return this.accountStorageFeatureEnabled_ && - (!!this.syncStatus_ && !this.syncStatus_.signedIn) && this.signedIn_; + (!!this.syncStatus_ && !this.syncStatus_.signedIn) && this.signedIn_ && + (!this.syncPrefs_ || !this.syncPrefs_.encryptAllData); }, /**
diff --git a/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.html b/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.html index 80a8df3..81c6219 100644 --- a/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.html +++ b/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.html
@@ -1,11 +1,11 @@ - <style include="settings-shared"></style> +<style include="settings-shared"></style> - <cr-dialog id="dialog" close-text="$i18n{close}"> - <div slot="title">$i18n{historyDeletionDialogTitle}</div> - <div slot="body">$i18nRaw{historyDeletionDialogBody}</div> - <div slot="button-container"> - <cr-button class="action-button" on-click="onOkTap_"> - $i18n{historyDeletionDialogOK} - </cr-button> - </div> - </cr-dialog> +<cr-dialog id="dialog" close-text="$i18n{close}" show-on-attach> + <div slot="title">$i18n{historyDeletionDialogTitle}</div> + <div slot="body">$i18nRaw{historyDeletionDialogBody}</div> + <div slot="button-container"> + <cr-button class="action-button" on-click="onOkClick_"> + $i18n{historyDeletionDialogOK} + </cr-button> + </div> +</cr-dialog>
diff --git a/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.js b/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.js index 234766e..3d0e1f1 100644 --- a/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.js +++ b/chrome/browser/resources/settings/clear_browsing_data_dialog/history_deletion_dialog.js
@@ -19,16 +19,11 @@ _template: html`{__html_template__}`, - /** @override */ - attached() { - this.$.dialog.showModal(); - }, - /** - * Tap handler for the "OK" button. + * Click handler for the "OK" button. * @private */ - onOkTap_() { + onOkClick_() { this.$.dialog.close(); }, });
diff --git a/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept.html b/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept.html index b9a1ff69..d2dfd14 100644 --- a/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept.html +++ b/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept.html
@@ -2,6 +2,20 @@ <html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> + <link rel="stylesheet" href="chrome://resources/css/md_colors.css"> + <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> + <style> + body { + height: 100vh; + margin: 0; + width: 100vw; + } + @media (prefers-color-scheme: dark) { + body { + background-color: var(--md-background-color); + } + } + </style> </head> <body> <dice-web-signin-intercept-app></dice-web-signin-intercept-app>
diff --git a/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.html b/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.html index 95dfaa3c..e86eb02 100644 --- a/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.html +++ b/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.html
@@ -1,13 +1,53 @@ -<div> - <h1>$i18n{diceWebSigninInterceptTitle}</h1> +<style include="signin-dialog-shared"> + :host { + color: var(--cr-primary-text-color); + display: flex; + flex-direction: column; + height: 100%; + } + + #header { + /** + * TODO(crbug.com/1076880): replace the hardcoded background color with the + * browser-provided one. + */ + background-color: rgb(206, 234, 214); + border-radius: 8px; + margin: 8px; + min-height: 128px; + } + + #body { + flex-grow: 1; + font-size: 13px; + line-height: 20px; + margin: 0 16px; + } + + #title { + font-size: 15px; + font-weight: 500; + line-height: 22px; + margin: 0 0 8px; + } + + cr-button { + font-size: 12px; + } +</style> +<div id="header"></div> + +<div id="body"> + <div id="title">$i18n{diceWebSigninInterceptTitle}</div> <div>$i18n{diceWebSigninInterceptDesc}</div> </div> -<div> - <cr-button id="cancelButton" on-click="onCancel_"> - $i18n{diceWebSigninInterceptCancelLabel} - </cr-button> + +<div class="action-container"> <cr-button id="acceptButton" class="action-button" on-click="onAccept_" autofocus> $i18n{diceWebSigninInterceptAcceptLabel} </cr-button> + <cr-button id="cancelButton" on-click="onCancel_"> + $i18n{diceWebSigninInterceptCancelLabel} + </cr-button> </div>
diff --git a/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.js b/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.js index aa425c84..1bd902bf8 100644 --- a/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.js +++ b/chrome/browser/resources/signin/dice_web_signin_intercept/dice_web_signin_intercept_app.js
@@ -4,6 +4,7 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import './strings.m.js'; +import './signin_shared_css.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/signin/profile_picker/BUILD.gn b/chrome/browser/resources/signin/profile_picker/BUILD.gn index 20917e62..d25ff689 100644 --- a/chrome/browser/resources/signin/profile_picker/BUILD.gn +++ b/chrome/browser/resources/signin/profile_picker/BUILD.gn
@@ -69,5 +69,6 @@ "profile_picker_app.js", "profile_picker_main_view.js", "profile_card.js", + "profile_picker_shared_css.js", ] }
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_app.html b/chrome/browser/resources/signin/profile_picker/profile_picker_app.html index baab767..e688916e6 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_picker_app.html +++ b/chrome/browser/resources/signin/profile_picker/profile_picker_app.html
@@ -1,4 +1,4 @@ -<style> +<style include="profile-picker-shared"> cr-view-manager { display: flex; font-size: 100%;
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_app.js b/chrome/browser/resources/signin/profile_picker/profile_picker_app.js index de201ded..ad7f08e 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_picker_app.js +++ b/chrome/browser/resources/signin/profile_picker/profile_picker_app.js
@@ -5,6 +5,7 @@ import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.m.js'; import 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.m.js'; import './profile_picker_main_view.js'; +import './profile_picker_shared_css.js'; import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html b/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html index 7d55024..023267f 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html +++ b/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.html
@@ -1,4 +1,4 @@ -<style> +<style include="profile-picker-shared"> :host { --avatar-icon-size: 74px; --banner-img-height: 628px; @@ -26,6 +26,11 @@ right: 0; } + .title-container { + margin: 30px auto; + text-align: center; + } + .profiles-container { --grid-gutter: 24px; --profile-item-height:178px; @@ -92,6 +97,14 @@ </style> <div id="leftBanner" class="banner"></div> +<div class="title-container"> + <img id="product-logo" on-click="onProductLogoTap_" + srcset="chrome://theme/current-channel-logo@1x 1x, + chrome://theme/current-channel-logo@2x 2x" + role="presentation"> + <h2>$i18n{mainViewTitle}</h2> + <h3>$i18n{mainViewSubtitle}</h3> +</div> <div class="profiles-container"> <template is="dom-repeat" hidden="[[!profilesList_]]" items="[[profilesList_]]">
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js b/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js index 06c8708..b1ec2b7f0 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js +++ b/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js
@@ -6,6 +6,7 @@ import 'chrome://resources/cr_elements/shared_vars_css.m.js'; import './icons.js'; import './profile_card.js'; +import './profile_picker_shared_css.js'; import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -47,6 +48,18 @@ this.manageProfilesBrowserProxy_.initializeMainView(); }, + /** @private */ + onProductLogoTap_() { + this.$['product-logo'].animate( + { + transform: ['none', 'rotate(-10turn)'], + }, + { + duration: 500, + easing: 'cubic-bezier(1, 0, 0, 1)', + }); + }, + /** * Handler for when the profiles list are updated. * @param {!Array<!ProfileState>} profilesList
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_resources.grd b/chrome/browser/resources/signin/profile_picker/profile_picker_resources.grd index 194e84cc..dc7acf1 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_picker_resources.grd +++ b/chrome/browser/resources/signin/profile_picker/profile_picker_resources.grd
@@ -21,16 +21,19 @@ <!-- Generated Polymer 3 elements --> <include name="IDR_PROFILE_PICKER_PROFILE_PICKER_MAIN_VIEW_JS" file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_picker_main_view.js" - use_base_dir="false" type="BINDATA" preprocess="true"/> + use_base_dir="false" type="BINDATA"/> <include name="IDR_PROFILE_PICKER_PROFILE_PICKER_APP_JS" file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_picker_app.js" - use_base_dir="false" type="BINDATA" preprocess="true"/> + use_base_dir="false" type="BINDATA"/> <include name="IDR_PROFILE_PICKER_PROFILE_CARD_JS" file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_card.js" use_base_dir="false" type="BINDATA" preprocess="true"/> <include name="IDR_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_JS" file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js" use_base_dir="false" type="BINDATA"/> + <include name="IDR_PROFILE_PICKER_PROFILE_PICKER_SHARED_CSS_JS" + file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.js" + use_base_dir="false" type="BINDATA"/> </includes> <structures> <structure
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.html b/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.html new file mode 100644 index 0000000..508c280 --- /dev/null +++ b/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.html
@@ -0,0 +1,8 @@ +<template> + <style> + h3 { + color: var(--google-grey-refresh-700); + font-weight: 500; + } + </style> +</template>
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.js b/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.js new file mode 100644 index 0000000..2134465 --- /dev/null +++ b/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.js
@@ -0,0 +1,13 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; + +import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +const template = document.createElement('template'); +template.innerHTML = ` +<dom-module id="profile-picker-shared">{__html_template__}</dom-module> +`; +document.body.appendChild(template.content.cloneNode(true));
diff --git a/chrome/browser/sharesheet/sharesheet_service.cc b/chrome/browser/sharesheet/sharesheet_service.cc index 6fcf2477..3627518 100644 --- a/chrome/browser/sharesheet/sharesheet_service.cc +++ b/chrome/browser/sharesheet/sharesheet_service.cc
@@ -39,10 +39,17 @@ } // Cleanup delegate when bubble closes. -void SharesheetService::OnBubbleClosed(uint32_t id) { +void SharesheetService::OnBubbleClosed(uint32_t id, + const base::string16& active_action) { auto iter = active_delegates_.begin(); while (iter != active_delegates_.end()) { if ((*iter)->GetId() == id) { + if (!active_action.empty()) { + ShareAction* share_action = + sharesheet_action_cache_->GetActionFromName(active_action); + if (share_action != nullptr) + share_action->OnClosing(iter->get()); + } active_delegates_.erase(iter); break; } @@ -50,4 +57,35 @@ } } +void SharesheetService::OnTargetSelected(uint32_t delegate_id, + const base::string16& target_name, + const TargetType type, + views::View* share_action_view) { + if (type == TargetType::kAction) { + ShareAction* share_action = + sharesheet_action_cache_->GetActionFromName(target_name); + if (share_action == nullptr) + return; + + SharesheetServiceDelegate* delegate = GetDelegate(delegate_id); + if (delegate == nullptr) + return; + + delegate->OnActionLaunched(); + share_action->LaunchAction(delegate, share_action_view); + } +} + +SharesheetServiceDelegate* SharesheetService::GetDelegate( + uint32_t delegate_id) { + auto iter = active_delegates_.begin(); + while (iter != active_delegates_.end()) { + if ((*iter)->GetId() == delegate_id) { + return iter->get(); + } + ++iter; + } + return nullptr; +} + } // namespace sharesheet
diff --git a/chrome/browser/sharesheet/sharesheet_service.h b/chrome/browser/sharesheet/sharesheet_service.h index 0c5606b..cf850f26 100644 --- a/chrome/browser/sharesheet/sharesheet_service.h +++ b/chrome/browser/sharesheet/sharesheet_service.h
@@ -8,7 +8,9 @@ #include <memory> #include <vector> +#include "base/strings/string16.h" #include "chrome/browser/sharesheet/sharesheet_action_cache.h" +#include "chrome/browser/sharesheet/sharesheet_types.h" #include "components/keyed_service/core/keyed_service.h" class Profile; @@ -32,7 +34,12 @@ SharesheetService& operator=(const SharesheetService&) = delete; void ShowBubble(views::View* bubble_anchor_view); - void OnBubbleClosed(uint32_t id); + void OnBubbleClosed(uint32_t id, const base::string16& active_action); + void OnTargetSelected(uint32_t delegate_id, + const base::string16& target_name, + const TargetType type, + views::View* share_action_view); + SharesheetServiceDelegate* GetDelegate(uint32_t delegate_id); private: uint32_t delegate_counter_ = 0;
diff --git a/chrome/browser/sharesheet/sharesheet_service_delegate.cc b/chrome/browser/sharesheet/sharesheet_service_delegate.cc index 46d2b0e..67b8a9ae 100644 --- a/chrome/browser/sharesheet/sharesheet_service_delegate.cc +++ b/chrome/browser/sharesheet/sharesheet_service_delegate.cc
@@ -30,9 +30,22 @@ sharesheet_bubble_view_->ShowBubble(std::move(targets)); } -void SharesheetServiceDelegate::OnBubbleClosed() { +void SharesheetServiceDelegate::OnBubbleClosed( + const base::string16& active_action) { sharesheet_bubble_view_.release(); - sharesheet_service_->OnBubbleClosed(id_); + sharesheet_service_->OnBubbleClosed(id_, active_action); +} + +void SharesheetServiceDelegate::OnTargetSelected( + const base::string16& target_name, + const TargetType type, + views::View* share_action_view) { + sharesheet_service_->OnTargetSelected(id_, target_name, type, + share_action_view); +} + +void SharesheetServiceDelegate::OnActionLaunched() { + sharesheet_bubble_view_->ShowActionView(); } uint32_t SharesheetServiceDelegate::GetId() {
diff --git a/chrome/browser/sharesheet/sharesheet_service_delegate.h b/chrome/browser/sharesheet/sharesheet_service_delegate.h index 3fed3e2d..dec5933 100644 --- a/chrome/browser/sharesheet/sharesheet_service_delegate.h +++ b/chrome/browser/sharesheet/sharesheet_service_delegate.h
@@ -7,6 +7,7 @@ #include <memory> +#include "base/strings/string16.h" #include "chrome/browser/sharesheet/sharesheet_controller.h" #include "chrome/browser/sharesheet/sharesheet_types.h" @@ -33,7 +34,11 @@ delete; void ShowBubble(std::vector<TargetInfo> targets); - void OnBubbleClosed(); + void OnBubbleClosed(const base::string16& active_action); + void OnTargetSelected(const base::string16& target_name, + const TargetType type, + views::View* share_action_view); + void OnActionLaunched(); // SharesheetController overrides uint32_t GetId() override; @@ -41,6 +46,7 @@ private: const uint32_t id_; + base::string16 active_action_; std::unique_ptr<SharesheetBubbleView> sharesheet_bubble_view_; SharesheetService* sharesheet_service_; };
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 4edf8eb..d0aa5fb7 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -1438,6 +1438,9 @@ <message name="IDS_SYNC_SETTINGS" desc="Title for preference which enables sync'ing of settings. [CHAR-LIMT=32]"> Settings </message> + <message name="IDS_TURN_OFF_SYNC" desc="Button that user can press to turn off sync and sign out. [CHAR-LIMT=32]"> + Sign out and turn off sync + </message> <message name="IDS_SYNC_PAYMENTS_INTEGRATION" desc="Title for preference which enables import of Google Pay data for Autofill. 'Google Pay' should not be translated as it is the product name."> Credit cards and addresses using Google Pay </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_TURN_OFF_SYNC.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_TURN_OFF_SYNC.png.sha1 new file mode 100644 index 0000000..64bfc87 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_TURN_OFF_SYNC.png.sha1
@@ -0,0 +1 @@ +635b9fa291786e0e5ac3ce2d5ac2a0022f42aed1 \ No newline at end of file
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index ac3ccf1..37836b0 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc
@@ -1152,24 +1152,6 @@ } } -// Test that get_process_idle_time() returns reasonable values when compared -// with time deltas measured locally. -IN_PROC_BROWSER_TEST_F(BrowserTest, RenderIdleTime) { - base::TimeTicks start = base::TimeTicks::Now(); - ui_test_utils::NavigateToURL( - browser(), ui_test_utils::GetTestUrl( - base::FilePath(base::FilePath::kCurrentDirectory), - base::FilePath(kTitle1File))); - base::TimeDelta renderer_td = browser() - ->tab_strip_model() - ->GetActiveWebContents() - ->GetMainFrame() - ->GetProcess() - ->GetChildProcessIdleTime(); - base::TimeDelta browser_td = base::TimeTicks::Now() - start; - EXPECT_TRUE(browser_td >= renderer_td); -} - // Test RenderView correctly send back favicon url for web page that redirects // to an anchor in javascript body.onload handler. IN_PROC_BROWSER_TEST_F(BrowserTest,
diff --git a/chrome/browser/ui/views/extensions/extension_popup.cc b/chrome/browser/ui/views/extensions/extension_popup.cc index 0d3fa1e..7d96b50 100644 --- a/chrome/browser/ui/views/extensions/extension_popup.cc +++ b/chrome/browser/ui/views/extensions/extension_popup.cc
@@ -128,12 +128,17 @@ content::BrowserContext* browser_context, const extensions::Extension* extension, extensions::UnloadedExtensionReason reason) { + CHECK(host_); if (extension->id() == host_->extension_id()) { // To ensure |extension_view_| cannot receive any messages that cause it to // try to access the host during Widget closure, destroy it immediately. RemoveChildViewT(extension_view_); host_.reset(); + // Stop observing the registry immediately to prevent any subsequent + // notifications, since Widget::Close is asynchronous. + extension_registry_observer_.RemoveAll(); + GetWidget()->Close(); } }
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view_browsertest.cc b/chrome/browser/ui/views/extensions/extensions_menu_view_browsertest.cc index f50d405..93df095 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_view_browsertest.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_view_browsertest.cc
@@ -201,13 +201,20 @@ container->GetViewForId(extensions()[0]->id())->GetVisible()); } } + void TriggerSingleExtensionButton() { + ASSERT_EQ(1u, GetExtensionsMenuItemViews().size()); + TriggerExtensionButton(0u); + } + + void TriggerExtensionButton(size_t item_index) { auto menu_items = GetExtensionsMenuItemViews(); - ASSERT_EQ(1u, menu_items.size()); + ASSERT_LT(item_index, menu_items.size()); + ui::MouseEvent click_event(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, 0); - menu_items[0] + menu_items[item_index] ->primary_action_button_for_testing() ->button_controller() ->OnMouseReleased(click_event); @@ -477,6 +484,33 @@ EXPECT_TRUE(GetVisibleToolbarActionViews().empty()); } +// Test for crbug.com/1099456. +IN_PROC_BROWSER_TEST_F(ExtensionsMenuViewBrowserTest, + RemoveMultipleExtensionsWhileShowingPopup) { + auto& id1 = LoadTestExtension("extensions/simple_with_popup")->id(); + auto& id2 = LoadTestExtension("extensions/uitest/window_open")->id(); + ShowUi(""); + VerifyUi(); + TriggerExtensionButton(0u); + + ExtensionsContainer* const extensions_container = + BrowserView::GetBrowserViewForBrowser(browser()) + ->toolbar() + ->extensions_container(); + ASSERT_NE(nullptr, extensions_container->GetPoppedOutAction()); + + auto* extension_service = + extensions::ExtensionSystem::Get(browser()->profile()) + ->extension_service(); + + extension_service->DisableExtension( + id1, extensions::disable_reason::DISABLE_USER_ACTION); + extension_service->DisableExtension( + id2, extensions::disable_reason::DISABLE_USER_ACTION); + + EXPECT_EQ(nullptr, extensions_container->GetPoppedOutAction()); +} + IN_PROC_BROWSER_TEST_F(ExtensionsMenuViewBrowserTest, TriggeringExtensionClosesMenu) { LoadTestExtension("extensions/trigger_actions/browser_action");
diff --git a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc index c2cd93f8..0e1afa4d 100644 --- a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc +++ b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc
@@ -25,7 +25,7 @@ #include "ui/views/widget/widget.h" namespace { -constexpr int kInterceptionBubbleHeight = 362; +constexpr int kInterceptionBubbleHeight = 342; constexpr int kInterceptionBubbleWidth = 290; } // namespace
diff --git a/chrome/browser/ui/views/sharesheet_bubble_view.cc b/chrome/browser/ui/views/sharesheet_bubble_view.cc index 0278e17..20a72526 100644 --- a/chrome/browser/ui/views/sharesheet_bubble_view.cc +++ b/chrome/browser/ui/views/sharesheet_bubble_view.cc
@@ -6,11 +6,17 @@ #include <utility> +#include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/sharesheet/sharesheet_service_delegate.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/size.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/views/controls/button/image_button.h" +#include "ui/views/controls/button/image_button_factory.h" +#include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/controls/styled_label.h" #include "ui/views/layout/box_layout.h" @@ -18,12 +24,54 @@ namespace { -constexpr int kColumnSetIdTitle = 0; -constexpr int kVerticalSpacing = 24; +constexpr int kButtonSize = 64; +constexpr int kMaxTargetRowSize = 4; +constexpr int kSpacing = 24; constexpr char kTitle[] = "Share"; +enum { COLUMN_SET_ID_TITLE, COLUMN_SET_ID_TARGETS }; + } // namespace +// ShareSheetTargetButton + +// A button that represents a candidate share target. +class ShareSheetTargetButton : public views::Button { + public: + ShareSheetTargetButton(views::ButtonListener* listener, + const base::string16& display_name, + const gfx::Image* icon) + : Button(listener) { + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical, gfx::Insets(), + ChromeLayoutProvider::Get()->GetDistanceMetric( + views::DISTANCE_RELATED_CONTROL_VERTICAL))); + + auto* image = AddChildView(std::make_unique<views::ImageView>()); + image->set_can_process_events_within_subtree(false); + + if (!icon->IsEmpty()) { + image->SetImage(*icon->ToImageSkia()); + } + + auto* label = AddChildView(std::make_unique<views::Label>(display_name)); + label->SetBackgroundColor(SK_ColorTRANSPARENT); + label->SetHandlesTooltips(false); + label->SetMultiLine(true); + label->SetAutoColorReadabilityEnabled(false); + label->SetHorizontalAlignment(gfx::ALIGN_CENTER); + + SetFocusForPlatform(); + } + + ShareSheetTargetButton(const ShareSheetTargetButton&) = delete; + ShareSheetTargetButton& operator=(const ShareSheetTargetButton&) = delete; + + gfx::Size CalculatePreferredSize() const override { + return gfx::Size(kButtonSize, kButtonSize); + } +}; + SharesheetBubbleView::SharesheetBubbleView( views::View* anchor_view, sharesheet::SharesheetServiceDelegate* delegate) @@ -65,34 +113,82 @@ main_view_->SetLayoutManager(std::make_unique<views::GridLayout>()); // Set up columnsets - views::ColumnSet* cs = main_layout->AddColumnSet(kColumnSetIdTitle); + views::ColumnSet* cs = main_layout->AddColumnSet(COLUMN_SET_ID_TITLE); cs->AddColumn(/* h_align */ views::GridLayout::FILL, /* v_align */ views::GridLayout::CENTER, /* resize_percent */ 1.0, views::GridLayout::ColumnSize::kUsePreferred, /* fixed_width */ 0, /*min_width*/ 0); + views::ColumnSet* cs_buttons = + main_layout->AddColumnSet(COLUMN_SET_ID_TARGETS); + cs_buttons->AddPaddingColumn(/* resize_percent */ 1, kSpacing); + cs_buttons->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, + 1.0, views::GridLayout::ColumnSize::kFixed, kButtonSize, + 0); + cs_buttons->AddPaddingColumn(/* resize_percent */ 1, kSpacing); + cs_buttons->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, + 1.0, views::GridLayout::ColumnSize::kFixed, kButtonSize, + 0); + cs_buttons->AddPaddingColumn(/* resize_percent */ 1, kSpacing); + cs_buttons->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, + 1.0, views::GridLayout::ColumnSize::kFixed, kButtonSize, + 0); + cs_buttons->AddPaddingColumn(/* resize_percent */ 1, kSpacing); + cs_buttons->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, + 1.0, views::GridLayout::ColumnSize::kFixed, kButtonSize, + 0); + cs_buttons->AddPaddingColumn(/* resize_percent */ 1, kSpacing); + // Add Title label - main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kVerticalSpacing); - main_layout->StartRow(views::GridLayout::kFixedSize, kColumnSetIdTitle, - /* height */ kVerticalSpacing); + main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kSpacing); + main_layout->StartRow(views::GridLayout::kFixedSize, COLUMN_SET_ID_TITLE, + /* height */ kSpacing); auto* title = main_layout->AddView(std::make_unique<views::Label>( base::UTF8ToUTF16(base::StringPiece(kTitle)), views::style::CONTEXT_DIALOG_TITLE, views::style::STYLE_PRIMARY)); title->SetHorizontalAlignment(gfx::ALIGN_CENTER); + // Add Targets + size_t i = 0; + for (const auto& target : targets_) { + if (i % kMaxTargetRowSize == 0) { + main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kSpacing); + main_layout->StartRow(views::GridLayout::kFixedSize, + COLUMN_SET_ID_TARGETS); + } + auto target_view = std::make_unique<ShareSheetTargetButton>( + this, target.display_name, &target.icon); + target_view->set_tag(i++); + main_layout->AddView(std::move(target_view)); + } + main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kSpacing); + views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(this); GetWidget()->GetRootView()->Layout(); widget->Show(); } +void SharesheetBubbleView::ShowActionView() { + main_view_->SetVisible(false); + share_action_view_->SetVisible(true); +} + void SharesheetBubbleView::CloseBubble() { views::Widget* widget = View::GetWidget(); widget->CloseWithReason(views::Widget::ClosedReason::kAcceptButtonClicked); } +void SharesheetBubbleView::ButtonPressed(views::Button* sender, + const ui::Event& event) { + active_target_ = targets_[sender->tag()].launch_name; + delegate_->OnTargetSelected(active_target_, targets_[sender->tag()].type, + share_action_view_); + RequestFocus(); +} + void SharesheetBubbleView::OnWidgetDestroyed(views::Widget* widget) { - delegate_->OnBubbleClosed(); + delegate_->OnBubbleClosed(active_target_); } gfx::Size SharesheetBubbleView::CalculatePreferredSize() const {
diff --git a/chrome/browser/ui/views/sharesheet_bubble_view.h b/chrome/browser/ui/views/sharesheet_bubble_view.h index 1c7083d..94d4987 100644 --- a/chrome/browser/ui/views/sharesheet_bubble_view.h +++ b/chrome/browser/ui/views/sharesheet_bubble_view.h
@@ -9,12 +9,14 @@ #include "chrome/browser/sharesheet/sharesheet_types.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" +#include "ui/views/controls/button/button.h" namespace sharesheet { class SharesheetServiceDelegate; } -class SharesheetBubbleView : public views::BubbleDialogDelegateView { +class SharesheetBubbleView : public views::BubbleDialogDelegateView, + public views::ButtonListener { public: using TargetInfo = sharesheet::TargetInfo; @@ -25,8 +27,12 @@ ~SharesheetBubbleView() override; void ShowBubble(std::vector<TargetInfo> targets); + void ShowActionView(); void CloseBubble(); + // views::ButtonListener overrides + void ButtonPressed(views::Button* sender, const ui::Event& event) override; + // views::BubbleDialogDelegateView overrides gfx::Size CalculatePreferredSize() const override; void OnWidgetDestroyed(views::Widget* widget) override; @@ -35,6 +41,7 @@ // Owns this class. sharesheet::SharesheetServiceDelegate* delegate_; std::vector<TargetInfo> targets_; + base::string16 active_target_; views::View* root_view_ = nullptr; views::View* main_view_ = nullptr;
diff --git a/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc b/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc index 002d68e..b5dce67 100644 --- a/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc +++ b/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc
@@ -26,6 +26,7 @@ IDR_SIGNIN_DICE_WEB_INTERCEPT_APP_JS); source->AddResourcePath("dice_web_signin_intercept_browser_proxy.js", IDR_SIGNIN_DICE_WEB_INTERCEPT_BROWSER_PROXY_JS); + source->AddResourcePath("signin_shared_css.js", IDR_SIGNIN_SHARED_CSS_JS); // Localized strings. source->UseStringsJs();
diff --git a/chrome/browser/ui/webui/signin/profile_picker_ui.cc b/chrome/browser/ui/webui/signin/profile_picker_ui.cc index 7a86f88c..ac09d8d 100644 --- a/chrome/browser/ui/webui/signin/profile_picker_ui.cc +++ b/chrome/browser/ui/webui/signin/profile_picker_ui.cc
@@ -8,9 +8,23 @@ #include "chrome/browser/ui/webui/signin/profile_picker_handler.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/webui_url_constants.h" +#include "chrome/grit/chromium_strings.h" #include "chrome/grit/profile_picker_resources.h" #include "chrome/grit/profile_picker_resources_map.h" #include "content/public/browser/web_ui_data_source.h" +#include "ui/base/webui/web_ui_util.h" + +namespace { + +void AddStrings(content::WebUIDataSource* html_source) { + static constexpr webui::LocalizedString kLocalizedStrings[] = { + {"mainViewTitle", IDS_PROFILE_PICKER_MAIN_VIEW_TITLE}, + {"mainViewSubtitle", IDS_PROFILE_PICKER_MAIN_VIEW_SUBTITLE}, + }; + AddLocalizedStringsBulk(html_source, kLocalizedStrings); +} + +} // namespace ProfilePickerUI::ProfilePickerUI(content::WebUI* web_ui) : content::WebUIController(web_ui) { @@ -27,6 +41,7 @@ base::make_span(kProfilePickerResources, kProfilePickerResourcesSize), generated_path, IDR_PROFILE_PICKER_PROFILE_PICKER_HTML); + AddStrings(html_source); content::WebUIDataSource::Add(profile, html_source); }
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 85ab78e..db62691 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1595289228-e5c2a2241b190531533d778f2dcf9ff98ced1901.profdata +chrome-mac-master-1595330901-a1487ea0e73c84091ecbf3f0440329cfe99905ef.profdata
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index 5d975e5..83c7e15 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -124,8 +124,6 @@ "pdf_util.h", "pref_names_util.cc", "pref_names_util.h", - "prerender_url_loader_throttle.cc", - "prerender_url_loader_throttle.h", "ref_counted_util.h", "render_messages.h", "search/instant_mojom_traits.h",
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn index c35fa9d7..3e44aa1 100644 --- a/chrome/renderer/BUILD.gn +++ b/chrome/renderer/BUILD.gn
@@ -92,8 +92,6 @@ "plugins/pdf_plugin_placeholder.h", "plugins/plugin_uma.cc", "plugins/plugin_uma.h", - "prerender/prerender_helper.cc", - "prerender/prerender_helper.h", "prerender/prerender_observer.h", "prerender/prerender_observer_list.cc", "prerender/prerender_observer_list.h", @@ -159,6 +157,7 @@ "//components/page_load_metrics/renderer", "//components/paint_preview/buildflags", "//components/plugins/renderer", + "//components/prerender/renderer", "//components/resources:components_resources", "//components/safe_browsing:buildflags", "//components/safe_browsing/content/renderer:throttles",
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 018bffa3..7330a66 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -34,7 +34,6 @@ #include "chrome/common/crash_keys.h" #include "chrome/common/pdf_util.h" #include "chrome/common/pepper_permission_util.h" -#include "chrome/common/prerender_url_loader_throttle.h" #include "chrome/common/privacy_budget/privacy_budget_settings_provider.h" #include "chrome/common/profiler/thread_profiler.h" #include "chrome/common/render_messages.h" @@ -60,7 +59,6 @@ #include "chrome/renderer/plugins/pdf_plugin_placeholder.h" #include "chrome/renderer/plugins/plugin_preroller.h" #include "chrome/renderer/plugins/plugin_uma.h" -#include "chrome/renderer/prerender/prerender_helper.h" #include "chrome/renderer/prerender/prerenderer_client.h" #include "chrome/renderer/previews/resource_loading_hints_agent.h" #include "chrome/renderer/sync_encryption_keys_extension.h" @@ -90,7 +88,9 @@ #include "components/page_load_metrics/renderer/metrics_render_frame_observer.h" #include "components/paint_preview/buildflags/buildflags.h" #include "components/pdf/renderer/pepper_pdf_host.h" +#include "components/prerender//common/prerender_url_loader_throttle.h" #include "components/prerender/common/prerender_types.mojom.h" +#include "components/prerender/renderer/prerender_helper.h" #include "components/safe_browsing/buildflags.h" #include "components/safe_browsing/content/renderer/threat_dom_details.h" #include "components/spellcheck/spellcheck_buildflags.h"
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc index 971fe93..339d8a6 100644 --- a/chrome/renderer/chrome_render_frame_observer.cc +++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -24,11 +24,11 @@ #include "chrome/common/open_search_description_document_handler.mojom.h" #include "chrome/common/render_messages.h" #include "chrome/renderer/media/media_feeds.h" -#include "chrome/renderer/prerender/prerender_helper.h" #include "chrome/renderer/prerender/prerender_observer_list.h" #include "chrome/renderer/web_apps.h" #include "components/crash/core/common/crash_key.h" #include "components/offline_pages/buildflags/buildflags.h" +#include "components/prerender/renderer/prerender_helper.h" #include "components/translate/content/renderer/translate_agent.h" #include "components/translate/core/common/translate_util.h" #include "components/web_cache/renderer/web_cache_impl.h"
diff --git a/chrome/renderer/prerender/prerenderer_client.cc b/chrome/renderer/prerender/prerenderer_client.cc index 76c809f..7afb98b 100644 --- a/chrome/renderer/prerender/prerenderer_client.cc +++ b/chrome/renderer/prerender/prerenderer_client.cc
@@ -5,7 +5,7 @@ #include "chrome/renderer/prerender/prerenderer_client.h" #include "base/logging.h" -#include "chrome/renderer/prerender/prerender_helper.h" +#include "components/prerender/renderer/prerender_helper.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" #include "third_party/blink/public/web/web_view.h"
diff --git a/chrome/renderer/url_loader_throttle_provider_impl.cc b/chrome/renderer/url_loader_throttle_provider_impl.cc index 8a4536d..d179bc04 100644 --- a/chrome/renderer/url_loader_throttle_provider_impl.cc +++ b/chrome/renderer/url_loader_throttle_provider_impl.cc
@@ -17,9 +17,9 @@ #include "chrome/renderer/chrome_render_frame_observer.h" #include "chrome/renderer/chrome_render_thread_observer.h" #include "chrome/renderer/lite_video/lite_video_url_loader_throttle.h" -#include "chrome/renderer/prerender/prerender_helper.h" #include "chrome/renderer/subresource_redirect/subresource_redirect_params.h" #include "chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h" +#include "components/prerender/renderer/prerender_helper.h" #include "components/safe_browsing/content/renderer/renderer_url_loader_throttle.h" #include "components/safe_browsing/core/features.h" #include "content/public/common/content_features.h"
diff --git a/chrome/services/sharing/BUILD.gn b/chrome/services/sharing/BUILD.gn index 29953ab7..f8277ee 100644 --- a/chrome/services/sharing/BUILD.gn +++ b/chrome/services/sharing/BUILD.gn
@@ -31,6 +31,7 @@ deps = [ ":sharing", + "nearby", "nearby/test_support", "webrtc/test", "//base/test:test_support",
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h index c574bbc..6a1b333 100644 --- a/chrome/test/base/testing_profile.h +++ b/chrome/test/base/testing_profile.h
@@ -221,6 +221,7 @@ ~TestingProfile() override; // Creates the favicon service. Consequent calls would recreate the service. + // TODO(crbug.com/1106699): Remove this API and adopt the Builder instead. void CreateFaviconService(); // !!!!!!!! WARNING: THIS IS GENERALLY NOT SAFE TO CALL! !!!!!!!! @@ -236,6 +237,7 @@ // only matters if you're recreating the HistoryService. If |no_db| is true, // the history backend will fail to initialize its database; this is useful // for testing error conditions. Returns true on success. + // TODO(crbug.com/1106699): Remove this API and adopt the Builder instead. bool CreateHistoryService(bool delete_file, bool no_db) WARN_UNUSED_RESULT; // Creates the BookmarkBarModel. If not invoked the bookmark bar model is @@ -246,9 +248,14 @@ // // NOTE: this does not block until the bookmarks are loaded. For that use // WaitForBookmarkModelToLoad(). + // + // DEPRECATED: Use Builder::AddTestingProfile() together with + // BookmarkModelFactory::GetDefaultFactory() in new code. + // TODO(crbug.com/1106699): Remove this API and adopt the Builder instead. void CreateBookmarkModel(bool delete_file); // Creates a WebDataService. If not invoked, the web data service is NULL. + // TODO(crbug.com/1106699): Remove this API and adopt the Builder instead. void CreateWebDataService(); // Blocks until the HistoryService finishes restoring its in-memory cache.
diff --git a/chrome/test/data/extensions/api_test/passwords_private/test.js b/chrome/test/data/extensions/api_test/passwords_private/test.js index 12e0af50..174d084 100644 --- a/chrome/test/data/extensions/api_test/passwords_private/test.js +++ b/chrome/test/data/extensions/api_test/passwords_private/test.js
@@ -351,6 +351,27 @@ }); }, + function changeCompromisedCredentialWithEmptyPasswordFails() { + chrome.passwordsPrivate.changeCompromisedCredential( + { + id: 0, + formattedOrigin: 'example.com', + detailedOrigin: 'https://example.com', + isAndroidCredential: false, + signonRealm: 'https://example.com', + username: 'alice', + compromiseTime: COMPROMISE_TIME, + elapsedTimeSinceCompromise: '3 days ago', + compromiseType: 'LEAKED', + }, + '', () => { + chrome.test.assertLastError( + 'Could not change the compromised credential. The new password ' + + 'can\'t be empty.'); + chrome.test.succeed(); + }); + }, + function changeCompromisedCredentialFails() { chrome.passwordsPrivate.changeCompromisedCredential( {
diff --git a/chrome/test/data/webui/print_preview/destination_dropdown_cros_test.js b/chrome/test/data/webui/print_preview/destination_dropdown_cros_test.js index 8198689..4a093e9 100644 --- a/chrome/test/data/webui/print_preview/destination_dropdown_cros_test.js +++ b/chrome/test/data/webui/print_preview/destination_dropdown_cros_test.js
@@ -20,7 +20,6 @@ destination_dropdown_cros_test.TestNames = { CorrectListItems: 'correct list items', ClickCloses: 'click closes dropdown', - TabCloses: 'tab closes dropdown', HighlightedAfterUpDown: 'highlighted after keyboard press up and down', DestinationChangeAfterUpDown: 'destination changes after keyboard press up and down', @@ -48,22 +47,17 @@ } function clickDropdown() { - dropdown.$$('#destination-dropdown') - .dispatchEvent(new PointerEvent('pointerdown', { - bubbles: true, - cancelable: true, - composed: true, - buttons: 1, - })); + dropdown.$$('#destination-dropdown').click(); + } + + function clickDropdownFocus() { + dropdown.$$('#destination-dropdown').click(); + dropdown.$$('#destination-dropdown').focus(); } function clickOutsideDropdown() { - document.body.dispatchEvent(new PointerEvent('pointerdown', { - bubbles: true, - cancelable: true, - composed: true, - buttons: 1, - })); + document.body.click(); + dropdown.$$('#destination-dropdown').blur(); } function down() { @@ -79,10 +73,6 @@ keyDownOn(dropdown.$$('#destination-dropdown'), 'Enter', [], 'Enter'); } - function tab() { - keyDownOn(dropdown.$$('#destination-dropdown'), 'Tab', [], 'Tab'); - } - /** @return {?Element} */ function getHighlightedElement() { return dropdown.$$('.highlighted'); @@ -140,33 +130,21 @@ dropdown.value = destinationOne; const ironDropdown = dropdown.$$('iron-dropdown'); - clickDropdown(); + clickDropdownFocus(); assertTrue(ironDropdown.opened); getList()[0].click(); assertFalse(ironDropdown.opened); - clickDropdown(); + clickDropdownFocus(); assertTrue(ironDropdown.opened); - // Click outside dropdown to close the dropdown. + // Clicking outside the dropdown will cause it to lose focus and close. + // This will verify on-blur closes the dropdown. clickOutsideDropdown(); assertFalse(ironDropdown.opened); }); - test(assert(destination_dropdown_cros_test.TestNames.TabCloses), function() { - const destinationOne = createDestination('One', DestinationOrigin.CROS); - setItemList([destinationOne]); - dropdown.value = destinationOne; - const ironDropdown = dropdown.$$('iron-dropdown'); - - clickDropdown(); - assertTrue(ironDropdown.opened); - - tab(); - assertFalse(ironDropdown.opened); - }); - test( assert(destination_dropdown_cros_test.TestNames.HighlightedAfterUpDown), function() {
diff --git a/chrome/test/data/webui/print_preview/print_preview_interactive_ui_tests.js b/chrome/test/data/webui/print_preview/print_preview_interactive_ui_tests.js index 99a89f03..bc3c24b 100644 --- a/chrome/test/data/webui/print_preview/print_preview_interactive_ui_tests.js +++ b/chrome/test/data/webui/print_preview/print_preview_interactive_ui_tests.js
@@ -181,3 +181,23 @@ this.runMochaTest( scaling_settings_interactive_test.TestNames.AutoFocusInput); }); + +GEN('#if defined(OS_CHROMEOS)'); +// eslint-disable-next-line no-var +var PrintPreviewDestinationDropdownCrosTest = + class extends PrintPreviewInteractiveUITest { + /** @override */ + get browsePreload() { + return 'chrome://print/test_loader.html?module=print_preview/destination_dropdown_cros_test.js'; + } + + /** @override */ + get suiteName() { + return destination_dropdown_cros_test.suiteName; + } +}; + +TEST_F('PrintPreviewDestinationDropdownCrosTest', 'ClickCloses', function() { + this.runMochaTest(destination_dropdown_cros_test.TestNames.ClickCloses); +}); +GEN('#endif');
diff --git a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js index 703bcc3c5..32973c5 100644 --- a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js +++ b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
@@ -1142,14 +1142,6 @@ destination_dropdown_cros_test.TestNames.CorrectListItems); }); -TEST_F('PrintPreviewDestinationDropdownCrosTest', 'ClickCloses', function() { - this.runMochaTest(destination_dropdown_cros_test.TestNames.ClickCloses); -}); - -TEST_F('PrintPreviewDestinationDropdownCrosTest', 'TabCloses', function() { - this.runMochaTest(destination_dropdown_cros_test.TestNames.TabCloses); -}); - TEST_F( 'PrintPreviewDestinationDropdownCrosTest', 'HighlightedAfterUpDown', function() {
diff --git a/chrome/test/data/webui/settings/cr_settings_v3_browsertest.js b/chrome/test/data/webui/settings/cr_settings_v3_browsertest.js index 30c39f5..85c59a5 100644 --- a/chrome/test/data/webui/settings/cr_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_v3_browsertest.js
@@ -227,8 +227,8 @@ } }; -// Flaky on Mac and Debug builds https://crbug.com/1090931 -GEN('#if defined(OS_MACOSX) || !defined(NDEBUG)'); +// Flaky on Debug builds https://crbug.com/1090931 +GEN('#if !defined(NDEBUG)'); GEN('#define MAYBE_All DISABLED_All'); GEN('#else'); GEN('#define MAYBE_All All');
diff --git a/chrome/test/data/webui/settings/password_check_test.js b/chrome/test/data/webui/settings/password_check_test.js index 8ea90796f..b4a7ca5 100644 --- a/chrome/test/data/webui/settings/password_check_test.js +++ b/chrome/test/data/webui/settings/password_check_test.js
@@ -1039,7 +1039,16 @@ const editDialog = createEditDialog(leakedPassword); assertEquals(leakedPassword.password, editDialog.$.passwordInput.value); + + // Test that an empty password is considered invalid and disables the change + // button. + editDialog.$.passwordInput.value = ''; + assertTrue(editDialog.$.passwordInput.invalid); + assertTrue(editDialog.$.save.disabled); + editDialog.$.passwordInput.value = 'yadhtribym'; + assertFalse(editDialog.$.passwordInput.invalid); + assertFalse(editDialog.$.save.disabled); editDialog.$.save.click(); const interaction =
diff --git a/chrome/test/data/webui/settings/passwords_device_section_test.js b/chrome/test/data/webui/settings/passwords_device_section_test.js index 85dac58e..c383576 100644 --- a/chrome/test/data/webui/settings/passwords_device_section_test.js +++ b/chrome/test/data/webui/settings/passwords_device_section_test.js
@@ -74,11 +74,7 @@ // The user only enters this page when they are eligible (signed-in but not // syncing) and opted-in to account storage. - syncBrowserProxy.storedAccounts = [{ - fullName: 'john doe', - givenName: 'john', - email: 'john@gmail.com', - }]; + syncBrowserProxy.storedAccounts = [{email: 'john@gmail.com'}]; simulateStoredAccounts(syncBrowserProxy.storedAccounts); syncBrowserProxy.syncStatus = {signedIn: false}; simulateSyncStatus(syncBrowserProxy.syncStatus);
diff --git a/chrome/test/data/webui/settings/passwords_section_test.js b/chrome/test/data/webui/settings/passwords_section_test.js index a7742000..499dc8b 100644 --- a/chrome/test/data/webui/settings/passwords_section_test.js +++ b/chrome/test/data/webui/settings/passwords_section_test.js
@@ -150,11 +150,7 @@ */ function simulateAccountStorageUser(passwordManager) { simulateSyncStatus({signedIn: false}); - simulateStoredAccounts([{ - fullName: 'john doe', - givenName: 'john', - email: 'john@gmail.com', - }]); + simulateStoredAccounts([{email: 'john@gmail.com'}]); passwordManager.setIsOptedInForAccountStorageAndNotify(true); flush(); @@ -1109,11 +1105,7 @@ isDisplayed(passwordsSection.$.accountStorageButtonsContainer)); // User signs in but is not opted in yet. - simulateStoredAccounts([{ - fullName: 'john doe', - givenName: 'john', - email: 'john@gmail.com', - }]); + simulateStoredAccounts([{email: 'john@gmail.com'}]); passwordManager.setIsOptedInForAccountStorageAndNotify(false); flush(); assertTrue( @@ -1140,6 +1132,27 @@ isDisplayed(passwordsSection.$.accountStorageButtonsContainer)); }); + // Test verifies the the account storage buttons are not shown for custom + // passphrase users. + test('accountStorageButonsNotShownForCustomPassphraseUser', function() { + loadTimeData.overrideValues({enableAccountStorage: true}); + + const passwordsSection = + elementFactory.createPasswordsSection(passwordManager, [], []); + + simulateSyncStatus({signedIn: false}); + simulateStoredAccounts([{email: 'john@gmail.com'}]); + // Simulate custom passphrase. + const syncPrefs = getSyncAllPrefs(); + syncPrefs.encryptAllData = true; + webUIListenerCallback('sync-prefs-changed', syncPrefs); + flush(); + + assertTrue( + !passwordsSection.$.accountStorageButtonsContainer || + passwordsSection.$.accountStorageButtonsContainer.hidden); + }); + // Test verifies that enabling sync hides the buttons for account storage // opt-in/out and the 'device passwords' page. test('enablingSyncHidesAccountStorageButtons', function() { @@ -1172,11 +1185,7 @@ const passwordsSection = elementFactory.createPasswordsSection( passwordManager, passwordList, []); simulateSyncStatus({signedIn: false}); - simulateStoredAccounts([{ - fullName: 'john doe', - givenName: 'john', - email: 'john@gmail.com', - }]); + simulateStoredAccounts([{email: 'john@gmail.com'}]); assertTrue(passwordsSection.$.devicePasswordsLink.hidden); // Opting in still doesn't display it because the user has no device
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn index 80cb93eb..9c6d709 100644 --- a/chrome/updater/BUILD.gn +++ b/chrome/updater/BUILD.gn
@@ -41,7 +41,6 @@ "action_handler.h", "constants.cc", "constants.h", - "control_service.h", "crash_client.cc", "crash_client.h", "crash_reporter.cc", @@ -90,8 +89,6 @@ "app/app_wake.h", "configurator.cc", "configurator.h", - "control_service_in_process.cc", - "control_service_in_process.h", "dm_cached_policy_info.cc", "dm_cached_policy_info.h", "dm_message.cc", @@ -111,6 +108,7 @@ "prefs_impl.h", "tag.cc", "tag.h", + "update_apps.h", "update_service_in_process.cc", "update_service_in_process.h", "updater.cc", @@ -131,8 +129,6 @@ "external_constants_mac.mm", "installer_mac.cc", "lib_util_mac.mm", - "mac/control_service_out_of_process.h", - "mac/control_service_out_of_process.mm", "mac/update_service_out_of_process.h", "mac/update_service_out_of_process.mm", "prefs_mac.mm", @@ -142,7 +138,6 @@ if (is_win) { sources += [ - "app/app_wake_win.cc", "app/server/win/com_classes.cc", "app/server/win/com_classes.h", "app/server/win/com_classes_legacy.cc",
diff --git a/chrome/updater/app/app_wake.cc b/chrome/updater/app/app_wake.cc index 7f3fe3e..c6d17fe 100644 --- a/chrome/updater/app/app_wake.cc +++ b/chrome/updater/app/app_wake.cc
@@ -4,20 +4,18 @@ #include "chrome/updater/app/app_wake.h" +#include <utility> + #include "base/bind.h" #include "base/logging.h" -#include "build/build_config.h" #include "chrome/updater/app/app.h" -#include "chrome/updater/control_service.h" +#include "chrome/updater/configurator.h" +#include "chrome/updater/prefs.h" +#include "chrome/updater/update_apps.h" +#include "chrome/updater/update_service.h" namespace updater { -// TODO(sorin): Implement the control service for Windows. crbug.com/1105589. -#if !defined(OS_WIN) - -// AppWake is a simple client which dials the same-versioned server via RPC and -// tells that server to run its control tasks. This is done via the -// ControlService interface. class AppWake : public App { public: AppWake() = default; @@ -27,16 +25,37 @@ // Overrides for App. void FirstTaskRun() override; + void Initialize() override; + void Uninitialize() override; + + scoped_refptr<Configurator> config_; + scoped_refptr<UpdateService> update_service_; }; +void AppWake::Initialize() { + config_ = base::MakeRefCounted<Configurator>(CreateGlobalPrefs()); +} + +void AppWake::Uninitialize() { + update_service_->Uninitialize(); +} + +// AppWake triggers an update of all registered applications. void AppWake::FirstTaskRun() { - CreateControlService()->Run(base::BindOnce(&AppWake::Shutdown, this, 0)); + update_service_ = CreateUpdateService(config_); + update_service_->UpdateAll( + base::BindRepeating([](UpdateService::UpdateState) {}), + base::BindOnce( + [](base::OnceCallback<void(int)> quit, UpdateService::Result result) { + const int exit_code = static_cast<int>(result); + VLOG(0) << "UpdateAll complete: exit_code = " << exit_code; + std::move(quit).Run(exit_code); + }, + base::BindOnce(&AppWake::Shutdown, this))); } scoped_refptr<App> MakeAppWake() { return base::MakeRefCounted<AppWake>(); } -#endif - } // namespace updater
diff --git a/chrome/updater/app/app_wake_win.cc b/chrome/updater/app/app_wake_win.cc deleted file mode 100644 index 542934a..0000000 --- a/chrome/updater/app/app_wake_win.cc +++ /dev/null
@@ -1,63 +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/updater/app/app_wake.h" - -#include <utility> - -#include "base/bind.h" -#include "base/logging.h" -#include "chrome/updater/app/app.h" -#include "chrome/updater/configurator.h" -#include "chrome/updater/prefs.h" -#include "chrome/updater/update_service.h" - -namespace updater { - -class AppWake : public App { - public: - AppWake() = default; - - private: - ~AppWake() override = default; - - // Overrides for App. - void FirstTaskRun() override; - void Initialize() override; - void Uninitialize() override; - - scoped_refptr<Configurator> config_; - scoped_refptr<UpdateService> update_service_; -}; - -void AppWake::Initialize() { - config_ = base::MakeRefCounted<Configurator>(CreateGlobalPrefs()); -} - -void AppWake::Uninitialize() { - update_service_->Uninitialize(); -} - -// AppWake triggers an update of all registered applications. -// TODO(sorin): Implement the control service for Windows. crbug.com/1105589. -// This means that this code goes away, use the platform neutral implementation -// of AppWake, which delegates to the control service. -void AppWake::FirstTaskRun() { - update_service_ = CreateUpdateService(config_); - update_service_->UpdateAll( - base::BindRepeating([](UpdateService::UpdateState) {}), - base::BindOnce( - [](base::OnceCallback<void(int)> quit, UpdateService::Result result) { - const int exit_code = static_cast<int>(result); - VLOG(0) << "UpdateAll complete: exit_code = " << exit_code; - std::move(quit).Run(exit_code); - }, - base::BindOnce(&AppWake::Shutdown, this))); -} - -scoped_refptr<App> MakeAppWake() { - return base::MakeRefCounted<AppWake>(); -} - -} // namespace updater
diff --git a/chrome/updater/app/server/mac/app_server.h b/chrome/updater/app/server/mac/app_server.h index 90baa943..d0fa1447 100644 --- a/chrome/updater/app/server/mac/app_server.h +++ b/chrome/updater/app/server/mac/app_server.h
@@ -49,11 +49,12 @@ SEQUENCE_CHECKER(sequence_checker_); - base::scoped_nsobject<CRUUpdateCheckServiceXPCDelegate> + base::scoped_nsobject<CRUUpdateCheckXPCServiceDelegate> update_check_delegate_; base::scoped_nsobject<NSXPCListener> update_check_listener_; - base::scoped_nsobject<CRUControlServiceXPCDelegate> control_service_delegate_; - base::scoped_nsobject<NSXPCListener> control_service_listener_; + base::scoped_nsobject<CRUAdministrationXPCServiceDelegate> + administration_delegate_; + base::scoped_nsobject<NSXPCListener> administration_listener_; // Task runner bound to the main sequence and the update service instance. scoped_refptr<base::SequencedTaskRunner> main_task_runner_;
diff --git a/chrome/updater/app/server/mac/server.mm b/chrome/updater/app/server/mac/server.mm index d34c7aec..0998bda 100644 --- a/chrome/updater/app/server/mac/server.mm +++ b/chrome/updater/app/server/mac/server.mm
@@ -19,7 +19,6 @@ #import "chrome/updater/app/server/mac/app_server.h" #include "chrome/updater/app/server/mac/service_delegate.h" #include "chrome/updater/configurator.h" -#include "chrome/updater/control_service_in_process.h" #include "chrome/updater/mac/setup/setup.h" #import "chrome/updater/mac/xpc_service_names.h" #include "chrome/updater/prefs.h" @@ -35,7 +34,7 @@ // These delegates need to have a reference to the AppServer. To break the // circular reference, we need to reset them. update_check_delegate_.reset(); - control_service_delegate_.reset(); + administration_delegate_.reset(); AppServer::Uninitialize(); } @@ -50,7 +49,7 @@ @autoreleasepool { // Sets up a listener and delegate for the CRUUpdateChecking XPC // connection - update_check_delegate_.reset([[CRUUpdateCheckServiceXPCDelegate alloc] + update_check_delegate_.reset([[CRUUpdateCheckXPCServiceDelegate alloc] initWithUpdateService:base::MakeRefCounted<UpdateServiceInProcess>( config_) appServer:scoped_refptr<AppServerMac>(this)]); @@ -61,17 +60,18 @@ [update_check_listener_ resume]; - // Sets up a listener and delegate for the CRUControlling XPC connection - control_service_delegate_.reset([[CRUControlServiceXPCDelegate alloc] - initWithControlService:base::MakeRefCounted<ControlServiceInProcess>() - appServer:scoped_refptr<AppServerMac>(this)]); + // Sets up a listener and delegate for the CRUAdministering XPC connection + administration_delegate_.reset([[CRUAdministrationXPCServiceDelegate alloc] + initWithUpdateService:base::MakeRefCounted<UpdateServiceInProcess>( + config_) + appServer:scoped_refptr<AppServerMac>(this)]); - control_service_listener_.reset([[NSXPCListener alloc] + administration_listener_.reset([[NSXPCListener alloc] initWithMachServiceName:base::mac::CFToNSCast( - CopyControlLaunchdName().get())]); - control_service_listener_.get().delegate = control_service_delegate_.get(); + CopyAdministrationLaunchDName().get())]); + administration_listener_.get().delegate = administration_delegate_.get(); - [control_service_listener_ resume]; + [administration_listener_ resume]; } }
diff --git a/chrome/updater/app/server/mac/service_delegate.h b/chrome/updater/app/server/mac/service_delegate.h index f134037..a65f5b5 100644 --- a/chrome/updater/app/server/mac/service_delegate.h +++ b/chrome/updater/app/server/mac/service_delegate.h
@@ -10,12 +10,11 @@ #include "base/memory/scoped_refptr.h" namespace updater { -class ControlService; class UpdateService; class AppServerMac; } -@interface CRUUpdateCheckServiceXPCDelegate : NSObject <NSXPCListenerDelegate> +@interface CRUUpdateCheckXPCServiceDelegate : NSObject <NSXPCListenerDelegate> - (instancetype)init NS_UNAVAILABLE; @@ -27,14 +26,15 @@ @end -@interface CRUControlServiceXPCDelegate : NSObject <NSXPCListenerDelegate> +@interface CRUAdministrationXPCServiceDelegate + : NSObject <NSXPCListenerDelegate> - (instancetype)init NS_UNAVAILABLE; // Designated initializer. - (instancetype) - initWithControlService:(scoped_refptr<updater::ControlService>)service - appServer:(scoped_refptr<updater::AppServerMac>)appServer + initWithUpdateService:(scoped_refptr<updater::UpdateService>)service + appServer:(scoped_refptr<updater::AppServerMac>)appServer NS_DESIGNATED_INITIALIZER; @end
diff --git a/chrome/updater/app/server/mac/service_delegate.mm b/chrome/updater/app/server/mac/service_delegate.mm index dc33469..72e1ea86 100644 --- a/chrome/updater/app/server/mac/service_delegate.mm +++ b/chrome/updater/app/server/mac/service_delegate.mm
@@ -21,13 +21,13 @@ #import "chrome/updater/app/server/mac/server.h" #import "chrome/updater/app/server/mac/service_protocol.h" #import "chrome/updater/app/server/mac/update_service_wrappers.h" -#include "chrome/updater/control_service.h" #include "chrome/updater/mac/setup/setup.h" #import "chrome/updater/mac/xpc_service_names.h" #include "chrome/updater/update_service.h" #include "chrome/updater/updater_version.h" -@interface CRUUpdateCheckServiceXPCImpl : NSObject <CRUUpdateChecking> +@interface CRUUpdateCheckXPCServiceImpl + : NSObject <CRUUpdateChecking, CRUAdministering> - (instancetype)init NS_UNAVAILABLE; @@ -39,12 +39,22 @@ (scoped_refptr<base::SequencedTaskRunner>)callbackRunner NS_DESIGNATED_INITIALIZER; +- (instancetype) + initWithUpdateService:(updater::UpdateService*)service + appServer:(scoped_refptr<updater::AppServerMac>)appServer + updaterConnectionOptions:(NSXPCConnectionOptions)options + callbackRunner: + (scoped_refptr<base::SequencedTaskRunner>)callbackRunner; + @end -@implementation CRUUpdateCheckServiceXPCImpl { +@implementation CRUUpdateCheckXPCServiceImpl { updater::UpdateService* _service; scoped_refptr<updater::AppServerMac> _appServer; scoped_refptr<base::SequencedTaskRunner> _callbackRunner; + NSXPCConnectionOptions _updateCheckXPCConnectionOptions; + base::scoped_nsobject<NSXPCConnection> _updateCheckXPCConnection; + NSInteger _redialAttempts; } - (instancetype) @@ -60,6 +70,38 @@ return self; } +- (instancetype) + initWithUpdateService:(updater::UpdateService*)service + appServer:(scoped_refptr<updater::AppServerMac>)appServer + updaterConnectionOptions:(NSXPCConnectionOptions)options + callbackRunner: + (scoped_refptr<base::SequencedTaskRunner>)callbackRunner { + [self initWithUpdateService:service + appServer:appServer + callbackRunner:callbackRunner]; + _updateCheckXPCConnectionOptions = options; + [self dialUpdateCheckXPCConnection]; + return self; +} + +- (void)dialUpdateCheckXPCConnection { + _updateCheckXPCConnection.reset([[NSXPCConnection alloc] + initWithMachServiceName:updater::GetServiceMachName().get() + options:_updateCheckXPCConnectionOptions]); + + _updateCheckXPCConnection.get().remoteObjectInterface = + updater::GetXPCUpdateCheckingInterface(); + + _updateCheckXPCConnection.get().interruptionHandler = ^{ + LOG(WARNING) << "CRUUpdateCheckingService: XPC connection interrupted."; + }; + + _updateCheckXPCConnection.get().invalidationHandler = ^{ + LOG(WARNING) << "CRUUpdateCheckingService: XPC connection invalidated."; + }; + [_updateCheckXPCConnection resume]; +} + #pragma mark CRUUpdateChecking - (void)checkForUpdatesWithUpdateState:(id<CRUUpdateStateObserving>)updateState reply:(void (^_Nonnull)(int rc))reply { @@ -185,57 +227,14 @@ request, std::move(cb))); } -@end +#pragma mark CRUAdministering -@interface CRUControlServiceXPCImpl : NSObject <CRUControlling> - -- (instancetype)init NS_UNAVAILABLE; - -// Designated initializers. -- (instancetype) - initWithControlService:(updater::ControlService*)service - appServer:(scoped_refptr<updater::AppServerMac>)appServer - callbackRunner: - (scoped_refptr<base::SequencedTaskRunner>)callbackRunner - NS_DESIGNATED_INITIALIZER; - -@end - -@implementation CRUControlServiceXPCImpl { - updater::ControlService* _service; - scoped_refptr<updater::AppServerMac> _appServer; - scoped_refptr<base::SequencedTaskRunner> _callbackRunner; -} - -- (instancetype) - initWithControlService:(updater::ControlService*)service - appServer:(scoped_refptr<updater::AppServerMac>)appServer - callbackRunner: - (scoped_refptr<base::SequencedTaskRunner>)callbackRunner { - if (self = [super init]) { - _service = service; - _appServer = appServer; - _callbackRunner = callbackRunner; - } - return self; -} - -#pragma mark CRUControlling -- (void)performControlTasksWithReply:(void (^)(void))reply { - auto cb = base::BindOnce(base::RetainBlock(^(void) { - VLOG(0) << "performControlTasks complete."; - if (reply) - reply(); - })); - - _callbackRunner->PostTask( - FROM_HERE, - base::BindOnce(&updater::ControlService::Run, _service, std::move(cb))); +- (void)performAdminTasks { } @end -@implementation CRUUpdateCheckServiceXPCDelegate { +@implementation CRUUpdateCheckXPCServiceDelegate { scoped_refptr<updater::UpdateService> _service; scoped_refptr<updater::AppServerMac> _appServer; scoped_refptr<base::SequencedTaskRunner> _callbackRunner; @@ -259,8 +258,8 @@ newConnection.exportedInterface = updater::GetXPCUpdateCheckingInterface(); - base::scoped_nsobject<CRUUpdateCheckServiceXPCImpl> object( - [[CRUUpdateCheckServiceXPCImpl alloc] + base::scoped_nsobject<CRUUpdateCheckXPCServiceImpl> object( + [[CRUUpdateCheckXPCServiceImpl alloc] initWithUpdateService:_service.get() appServer:_appServer callbackRunner:_callbackRunner.get()]); @@ -271,15 +270,15 @@ @end -@implementation CRUControlServiceXPCDelegate { - scoped_refptr<updater::ControlService> _service; +@implementation CRUAdministrationXPCServiceDelegate { + scoped_refptr<updater::UpdateService> _service; scoped_refptr<updater::AppServerMac> _appServer; scoped_refptr<base::SequencedTaskRunner> _callbackRunner; } - (instancetype) - initWithControlService:(scoped_refptr<updater::ControlService>)service - appServer:(scoped_refptr<updater::AppServerMac>)appServer { + initWithUpdateService:(scoped_refptr<updater::UpdateService>)service + appServer:(scoped_refptr<updater::AppServerMac>)appServer { if (self = [super init]) { _service = service; _callbackRunner = base::SequencedTaskRunnerHandle::Get(); @@ -292,13 +291,19 @@ // Check to see if the other side of the connection is "okay"; // if not, invalidate newConnection and return NO. - newConnection.exportedInterface = updater::GetXPCControllingInterface(); + base::CommandLine* cmdLine = base::CommandLine::ForCurrentProcess(); + NSXPCConnectionOptions options = cmdLine->HasSwitch(updater::kSystemSwitch) + ? NSXPCConnectionPrivileged + : 0; - base::scoped_nsobject<CRUControlServiceXPCImpl> object( - [[CRUControlServiceXPCImpl alloc] - initWithControlService:_service.get() - appServer:_appServer - callbackRunner:_callbackRunner.get()]); + newConnection.exportedInterface = updater::GetXPCAdministeringInterface(); + + base::scoped_nsobject<CRUUpdateCheckXPCServiceImpl> object( + [[CRUUpdateCheckXPCServiceImpl alloc] + initWithUpdateService:_service.get() + appServer:_appServer + updaterConnectionOptions:options + callbackRunner:_callbackRunner.get()]); newConnection.exportedObject = object.get(); [newConnection resume]; return YES;
diff --git a/chrome/updater/app/server/mac/service_protocol.h b/chrome/updater/app/server/mac/service_protocol.h index c6007de..3f0c4520 100644 --- a/chrome/updater/app/server/mac/service_protocol.h +++ b/chrome/updater/app/server/mac/service_protocol.h
@@ -47,12 +47,12 @@ @end -// Protocol for the XPC control tasks of the Updater. -@protocol CRUControlling <NSObject> +// Protocol for the XPC administration tasks of the Updater. +@protocol CRUAdministering <NSObject> -// Performs the control task (activate service, uninstall service, or no-op) -// that is relevant to the state of the Updater. -- (void)performControlTasksWithReply:(void (^_Nullable)(void))reply; +// Performs the admin task (activate service, uninstall service, or no opp) that +// is relevant to the state of the Updater. +- (void)performAdminTasks; @end @@ -62,9 +62,9 @@ // CRUUpdateStateObserving protocols. NSXPCInterface* _Nonnull GetXPCUpdateCheckingInterface(); -// Constructs an NSXPCInterface for a connection using CRUControlling +// Constructs an NSXPCInterface for a connection using CRUAdministering // protocol. -NSXPCInterface* _Nonnull GetXPCControllingInterface(); +NSXPCInterface* _Nonnull GetXPCAdministeringInterface(); } // namespace updater
diff --git a/chrome/updater/app/server/mac/service_protocol.mm b/chrome/updater/app/server/mac/service_protocol.mm index c0c6c9a..8cf57dc 100644 --- a/chrome/updater/app/server/mac/service_protocol.mm +++ b/chrome/updater/app/server/mac/service_protocol.mm
@@ -30,8 +30,8 @@ return updateCheckingInterface; } -NSXPCInterface* GetXPCControllingInterface() { - return [NSXPCInterface interfaceWithProtocol:@protocol(CRUControlling)]; +NSXPCInterface* GetXPCAdministeringInterface() { + return [NSXPCInterface interfaceWithProtocol:@protocol(CRUAdministering)]; } } // namespace updater
diff --git a/chrome/updater/control_service.h b/chrome/updater/control_service.h deleted file mode 100644 index df5cb2b..0000000 --- a/chrome/updater/control_service.h +++ /dev/null
@@ -1,34 +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_UPDATER_CONTROL_SERVICE_H_ -#define CHROME_UPDATER_CONTROL_SERVICE_H_ - -#include "base/callback_forward.h" -#include "base/memory/ref_counted.h" - -namespace updater { - -// The ControlService is the cross-platform abstraction for performing admin -// tasks on the updater. -class ControlService : public base::RefCountedThreadSafe<ControlService> { - public: - virtual void Run(base::OnceClosure callback) = 0; - - // Provides a way to commit data or clean up resources before the task - // scheduler is shutting down. - virtual void Uninitialize() = 0; - - protected: - friend class base::RefCountedThreadSafe<ControlService>; - - virtual ~ControlService() = default; -}; - -// A factory method to create a ControlService class instance. -scoped_refptr<ControlService> CreateControlService(); - -} // namespace updater - -#endif // CHROME_UPDATER_CONTROL_SERVICE_H_
diff --git a/chrome/updater/control_service_in_process.cc b/chrome/updater/control_service_in_process.cc deleted file mode 100644 index d0dd10f..0000000 --- a/chrome/updater/control_service_in_process.cc +++ /dev/null
@@ -1,29 +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/updater/control_service_in_process.h" - -#include "base/callback.h" -#include "base/threading/sequenced_task_runner_handle.h" - -namespace updater { - -ControlServiceInProcess::ControlServiceInProcess() - : main_task_runner_(base::SequencedTaskRunnerHandle::Get()) {} - -void ControlServiceInProcess::Run(base::OnceClosure callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - // TODO(crbug.com/1107586): Implement. -} - -void ControlServiceInProcess::Uninitialize() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -} - -ControlServiceInProcess::~ControlServiceInProcess() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -} - -} // namespace updater
diff --git a/chrome/updater/control_service_in_process.h b/chrome/updater/control_service_in_process.h deleted file mode 100644 index 7e9bc2d..0000000 --- a/chrome/updater/control_service_in_process.h +++ /dev/null
@@ -1,39 +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_UPDATER_CONTROL_SERVICE_IN_PROCESS_H_ -#define CHROME_UPDATER_CONTROL_SERVICE_IN_PROCESS_H_ - -#include "base/callback_forward.h" -#include "base/memory/scoped_refptr.h" -#include "base/sequence_checker.h" -#include "chrome/updater/control_service.h" - -namespace base { -class SequencedTaskRunner; -} - -namespace updater { - -// All functions and callbacks must be called on the same sequence. -class ControlServiceInProcess : public ControlService { - public: - ControlServiceInProcess(); - - // Overrides for updater::ControlService. - void Run(base::OnceClosure callback) override; - - void Uninitialize() override; - - private: - ~ControlServiceInProcess() override; - - SEQUENCE_CHECKER(sequence_checker_); - - scoped_refptr<base::SequencedTaskRunner> main_task_runner_; -}; - -} // namespace updater - -#endif // CHROME_UPDATER_CONTROL_SERVICE_IN_PROCESS_H_
diff --git a/chrome/updater/mac/control_service_out_of_process.h b/chrome/updater/mac/control_service_out_of_process.h deleted file mode 100644 index d95d2c6..0000000 --- a/chrome/updater/mac/control_service_out_of_process.h +++ /dev/null
@@ -1,45 +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_UPDATER_MAC_CONTROL_SERVICE_OUT_OF_PROCESS_H_ -#define CHROME_UPDATER_MAC_CONTROL_SERVICE_OUT_OF_PROCESS_H_ - -#import <Foundation/Foundation.h> - -#include "base/callback_forward.h" -#include "base/mac/scoped_nsobject.h" -#include "base/memory/scoped_refptr.h" -#include "base/sequence_checker.h" -#include "chrome/updater/control_service.h" -#include "chrome/updater/update_service.h" - -@class CRUControlServiceOutOfProcessImpl; - -namespace base { -class SequencedTaskRunner; -} // namespace base - -namespace updater { - -// All functions and callbacks must be called on the same sequence. -class ControlServiceOutOfProcess : public ControlService { - public: - explicit ControlServiceOutOfProcess(UpdateService::Scope scope); - - // Overrides for ControlService. - void Run(base::OnceClosure callback) override; - void Uninitialize() override; - - private: - ~ControlServiceOutOfProcess() override; - - SEQUENCE_CHECKER(sequence_checker_); - - base::scoped_nsobject<CRUControlServiceOutOfProcessImpl> client_; - scoped_refptr<base::SequencedTaskRunner> callback_runner_; -}; - -} // namespace updater - -#endif // CHROME_UPDATER_MAC_CONTROL_SERVICE_OUT_OF_PROCESS_H_
diff --git a/chrome/updater/mac/control_service_out_of_process.mm b/chrome/updater/mac/control_service_out_of_process.mm deleted file mode 100644 index 215bdee..0000000 --- a/chrome/updater/mac/control_service_out_of_process.mm +++ /dev/null
@@ -1,113 +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/updater/mac/control_service_out_of_process.h" - -#import <Foundation/Foundation.h> - -#include "base/callback.h" -#include "base/logging.h" -#include "base/mac/scoped_nsobject.h" -#include "base/strings/sys_string_conversions.h" -#include "base/threading/sequenced_task_runner_handle.h" -#import "chrome/updater/app/server/mac/service_protocol.h" -#import "chrome/updater/mac/xpc_service_names.h" -#include "chrome/updater/update_service.h" - -// Interface to communicate with the XPC Control Service. -@interface CRUControlServiceOutOfProcessImpl : NSObject <CRUControlling> - -- (instancetype)initPrivileged; - -@end - -@implementation CRUControlServiceOutOfProcessImpl { - base::scoped_nsobject<NSXPCConnection> _controlXPCConnection; -} - -- (instancetype)init { - return [self initWithConnectionOptions:0]; -} - -- (instancetype)initPrivileged { - return [self initWithConnectionOptions:NSXPCConnectionPrivileged]; -} - -- (instancetype)initWithConnectionOptions:(NSXPCConnectionOptions)options { - if ((self = [super init])) { - _controlXPCConnection.reset([[NSXPCConnection alloc] - initWithMachServiceName:updater::GetVersionedServiceMachName().get() - options:options]); - - _controlXPCConnection.get().remoteObjectInterface = - updater::GetXPCControllingInterface(); - - _controlXPCConnection.get().interruptionHandler = ^{ - LOG(WARNING) << "CRUControlling: XPC connection interrupted."; - }; - - _controlXPCConnection.get().invalidationHandler = ^{ - LOG(WARNING) << "CRUControlling: XPC connection invalidated."; - }; - - [_controlXPCConnection resume]; - } - - return self; -} - -- (void)dealloc { - [_controlXPCConnection invalidate]; - [super dealloc]; -} - -- (void)performControlTasksWithReply:(void (^)(void))reply { - auto errorHandler = ^(NSError* xpcError) { - LOG(ERROR) << "XPC connection failed: " - << base::SysNSStringToUTF8([xpcError description]); - reply(); - }; - - [[_controlXPCConnection remoteObjectProxyWithErrorHandler:errorHandler] - performControlTasksWithReply:reply]; -} - -@end - -namespace updater { - -ControlServiceOutOfProcess::ControlServiceOutOfProcess( - UpdateService::Scope scope) - : callback_runner_(base::SequencedTaskRunnerHandle::Get()) { - switch (scope) { - case UpdateService::Scope::kSystem: - client_.reset([[CRUControlServiceOutOfProcessImpl alloc] initPrivileged]); - break; - case UpdateService::Scope::kUser: - client_.reset([[CRUControlServiceOutOfProcessImpl alloc] init]); - break; - } -} - -void ControlServiceOutOfProcess::Run(base::OnceClosure callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - __block base::OnceClosure block_callback = std::move(callback); - auto reply = ^() { - callback_runner_->PostTask(FROM_HERE, - base::BindOnce(std::move(block_callback))); - }; - - [client_ performControlTasksWithReply:reply]; -} - -void ControlServiceOutOfProcess::Uninitialize() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -} - -ControlServiceOutOfProcess::~ControlServiceOutOfProcess() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -} - -} // namespace updater
diff --git a/chrome/updater/mac/setup/setup.h b/chrome/updater/mac/setup/setup.h index 297d9d6..4bfd8dad 100644 --- a/chrome/updater/mac/setup/setup.h +++ b/chrome/updater/mac/setup/setup.h
@@ -24,11 +24,8 @@ // Failed to remove versioned update service job from Launchd. constexpr int kFailedToRemoveCandidateUpdateServiceJobFromLaunchd = 21; -// Failed to remove versioned control job from Launchd. -constexpr int kFailedToRemoveControlJobFromLaunchd = 22; - -// Failed to remove versioned wake job from Launchd. -constexpr int kFailedToRemoveWakeJobFromLaunchd = 23; +// Failed to remove versioned administration job from Launchd. +constexpr int kFailedToRemoveAdministrationJobFromLaunchd = 22; // Failed to create the active(unversioned) update service Launchd plist. constexpr int kFailedToCreateUpdateServiceLaunchdJobPlist = 30; @@ -36,11 +33,8 @@ // Failed to create the versioned update service Launchd plist. constexpr int kFailedToCreateVersionedUpdateServiceLaunchdJobPlist = 31; -// Failed to create the versioned control Launchd plist. -constexpr int kFailedToCreateControlLaunchdJobPlist = 32; - -// Failed to create the versioned wake Launchd plist. -constexpr int kFailedToCreateWakeLaunchdJobPlist = 33; +// Failed to create the versioned administration Launchd plist. +constexpr int kFailedToCreateAdministrationLaunchdJobPlist = 32; // Failed to start the active(unversioned) update service job. constexpr int kFailedToStartLaunchdActiveServiceJob = 40; @@ -48,11 +42,8 @@ // Failed to start the versioned update service job. constexpr int kFailedToStartLaunchdVersionedServiceJob = 41; -// Failed to start the control job. -constexpr int kFailedToStartLaunchdControlJob = 42; - -// Failed to start the wake job. -constexpr int kFailedToStartLaunchdWakeJob = 43; +// Failed to start the administration job. +constexpr int kFailedToStartLaunchdAdministrationJob = 42; } // namespace setup_exit_codes
diff --git a/chrome/updater/mac/setup/setup.mm b/chrome/updater/mac/setup/setup.mm index 6c7e188..15aa171 100644 --- a/chrome/updater/mac/setup/setup.mm +++ b/chrome/updater/mac/setup/setup.mm
@@ -114,15 +114,17 @@ } base::ScopedCFTypeRef<CFDictionaryRef> CreateServiceLaunchdPlist( + const base::ScopedCFTypeRef<CFStringRef> label, const base::FilePath& updater_path) { // See the man page for launchd.plist. NSDictionary<NSString*, id>* launchd_plist = @{ - @LAUNCH_JOBKEY_LABEL : GetServiceLaunchdLabel(), + @LAUNCH_JOBKEY_LABEL : base::mac::CFToNSCast(label), @LAUNCH_JOBKEY_PROGRAMARGUMENTS : @[ base::SysUTF8ToNSString(updater_path.value()), MakeProgramArgument(kServerSwitch) ], - @LAUNCH_JOBKEY_MACHSERVICES : @{GetServiceMachName() : @YES}, + @LAUNCH_JOBKEY_MACHSERVICES : + @{GetServiceMachName(base::mac::CFToNSCast(label)) : @YES}, @LAUNCH_JOBKEY_ABANDONPROCESSGROUP : @NO, @LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE : @"Aqua" }; @@ -132,7 +134,7 @@ base::scoped_policy::RETAIN); } -base::ScopedCFTypeRef<CFDictionaryRef> CreateWakeLaunchdPlist( +base::ScopedCFTypeRef<CFDictionaryRef> CreateAdministrationLaunchdPlist( const base::FilePath& updater_path) { // See the man page for launchd.plist. NSMutableArray<NSString*>* program_arguments = @@ -145,7 +147,8 @@ [program_arguments addObject:MakeProgramArgument(kSystemSwitch)]; NSDictionary<NSString*, id>* launchd_plist = @{ - @LAUNCH_JOBKEY_LABEL : GetWakeLaunchdLabel(), + @LAUNCH_JOBKEY_LABEL : + base::mac::CFToNSCast(CopyAdministrationLaunchDName()), @LAUNCH_JOBKEY_PROGRAMARGUMENTS : program_arguments, @LAUNCH_JOBKEY_STARTINTERVAL : @3600, @LAUNCH_JOBKEY_ABANDONPROCESSGROUP : @NO, @@ -157,56 +160,28 @@ base::scoped_policy::RETAIN); } -base::ScopedCFTypeRef<CFDictionaryRef> CreateControlLaunchdPlist( +bool CreateUpdateServiceLaunchdJobPlist( + const base::ScopedCFTypeRef<CFStringRef> name, const base::FilePath& updater_path) { - // See the man page for launchd.plist. - NSDictionary<NSString*, id>* launchd_plist = @{ - @LAUNCH_JOBKEY_LABEL : GetControlLaunchdLabel(), - @LAUNCH_JOBKEY_PROGRAMARGUMENTS : @[ - base::SysUTF8ToNSString(updater_path.value()), - MakeProgramArgument(kServerSwitch) - ], - @LAUNCH_JOBKEY_MACHSERVICES : @{GetVersionedServiceMachName() : @YES}, - @LAUNCH_JOBKEY_ABANDONPROCESSGROUP : @NO, - @LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE : @"Aqua" - }; - - return base::ScopedCFTypeRef<CFDictionaryRef>( - base::mac::CFCast<CFDictionaryRef>(launchd_plist), - base::scoped_policy::RETAIN); -} - -bool CreateUpdateServiceLaunchdJobPlist(const base::FilePath& updater_path) { // We're creating directories and writing a file. base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::BlockingType::MAY_BLOCK); base::ScopedCFTypeRef<CFDictionaryRef> plist( - CreateServiceLaunchdPlist(updater_path)); + CreateServiceLaunchdPlist(name, updater_path)); return Launchd::GetInstance()->WritePlistToFile( - LaunchdDomain(), ServiceLaunchdType(), CopyServiceLaunchdName().release(), - plist); + LaunchdDomain(), ServiceLaunchdType(), name, plist); } -bool CreateWakeLaunchdJobPlist(const base::FilePath& updater_path) { +bool CreateUpdateAdministrationLaunchdJobPlist( + const base::FilePath& updater_path) { // We're creating directories and writing a file. base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::BlockingType::MAY_BLOCK); base::ScopedCFTypeRef<CFDictionaryRef> plist( - CreateWakeLaunchdPlist(updater_path)); + CreateAdministrationLaunchdPlist(updater_path)); return Launchd::GetInstance()->WritePlistToFile( - LaunchdDomain(), ServiceLaunchdType(), CopyWakeLaunchdName().release(), - plist); -} - -bool CreateControlLaunchdJobPlist(const base::FilePath& updater_path) { - // We're creating directories and writing a file. - base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, - base::BlockingType::MAY_BLOCK); - base::ScopedCFTypeRef<CFDictionaryRef> plist( - CreateControlLaunchdPlist(updater_path)); - return Launchd::GetInstance()->WritePlistToFile( - LaunchdDomain(), ServiceLaunchdType(), CopyControlLaunchdName().release(), + LaunchdDomain(), ServiceLaunchdType(), CopyAdministrationLaunchDName(), plist); } @@ -216,20 +191,14 @@ LaunchdDomain(), ServiceLaunchdType(), name, CFSTR("Aqua")); } -bool StartUpdateWakeVersionedLaunchdJob() { +bool StartUpdateAdministrationVersionedLaunchdJob() { return Launchd::GetInstance()->RestartJob( - LaunchdDomain(), ServiceLaunchdType(), CopyWakeLaunchdName().release(), - CFSTR("Aqua")); -} - -bool StartUpdateControlVersionedLaunchdJob() { - return Launchd::GetInstance()->RestartJob( - LaunchdDomain(), ServiceLaunchdType(), CopyControlLaunchdName().release(), + LaunchdDomain(), ServiceLaunchdType(), CopyAdministrationLaunchDName(), CFSTR("Aqua")); } bool StartLaunchdServiceJob() { - return StartUpdateServiceVersionedLaunchdJob(CopyServiceLaunchdName()); + return StartUpdateServiceVersionedLaunchdJob(CopyServiceLaunchDName()); } bool RemoveJobFromLaunchd(Launchd::Domain domain, @@ -256,15 +225,11 @@ } bool RemoveUpdateServiceJobFromLaunchd() { - return RemoveUpdateServiceJobFromLaunchd(CopyServiceLaunchdName()); + return RemoveUpdateServiceJobFromLaunchd(CopyServiceLaunchDName()); } -bool RemoveUpdateWakeJobFromLaunchd() { - return RemoveClientJobFromLaunchd(CopyWakeLaunchdName()); -} - -bool RemoveUpdateControlJobFromLaunchd() { - return RemoveClientJobFromLaunchd(CopyControlLaunchdName()); +bool RemoveUpdateAdministrationJobFromLaunchd() { + return RemoveClientJobFromLaunchd(CopyAdministrationLaunchDName()); } bool DeleteInstallFolder(const base::FilePath& installed_path) { @@ -291,24 +256,20 @@ dest_path.Append(GetUpdaterAppName()) .Append(GetUpdaterAppExecutablePath()); - if (!CreateWakeLaunchdJobPlist(updater_executable_path)) - return setup_exit_codes::kFailedToCreateWakeLaunchdJobPlist; + if (!CreateUpdateAdministrationLaunchdJobPlist( + updater_executable_path)) { + return setup_exit_codes::kFailedToCreateAdministrationLaunchdJobPlist; + } - if (!CreateControlLaunchdJobPlist(updater_executable_path)) - return setup_exit_codes::kFailedToCreateControlLaunchdJobPlist; - - if (!StartUpdateControlVersionedLaunchdJob()) - return setup_exit_codes::kFailedToStartLaunchdControlJob; - - if (!StartUpdateWakeVersionedLaunchdJob()) - return setup_exit_codes::kFailedToStartLaunchdWakeJob; + if (!StartUpdateAdministrationVersionedLaunchdJob()) { + return setup_exit_codes::kFailedToStartLaunchdAdministrationJob; + } return setup_exit_codes::kSuccess; } int UninstallCandidate() { - RemoveUpdateControlJobFromLaunchd(); - RemoveUpdateWakeJobFromLaunchd(); + RemoveUpdateAdministrationJobFromLaunchd(); DeleteInstallFolder(GetVersionedUpdaterFolderPath()); return setup_exit_codes::kSuccess; } @@ -319,11 +280,14 @@ dest_path.Append(GetUpdaterAppName()) .Append(GetUpdaterAppExecutablePath()); - if (!CreateUpdateServiceLaunchdJobPlist(updater_executable_path)) + if (!CreateUpdateServiceLaunchdJobPlist(CopyServiceLaunchDName(), + updater_executable_path)) { return setup_exit_codes::kFailedToCreateUpdateServiceLaunchdJobPlist; + } - if (!StartLaunchdServiceJob()) + if (!StartLaunchdServiceJob()) { return setup_exit_codes::kFailedToStartLaunchdActiveServiceJob; + } return setup_exit_codes::kSuccess; }
diff --git a/chrome/updater/mac/update_service_out_of_process.mm b/chrome/updater/mac/update_service_out_of_process.mm index f791ddd..4c5e133 100644 --- a/chrome/updater/mac/update_service_out_of_process.mm +++ b/chrome/updater/mac/update_service_out_of_process.mm
@@ -128,6 +128,68 @@ @end +// Interface to communicate with the XPC Updater Service. +@interface CRUAdministrationServiceOutOfProcessImpl + : NSObject <CRUAdministering> + +- (instancetype)initPrivileged; + +@end + +@implementation CRUAdministrationServiceOutOfProcessImpl { + base::scoped_nsobject<NSXPCConnection> _administrationXPCConnection; +} + +- (instancetype)init { + return [self initWithConnectionOptions:0]; +} + +- (instancetype)initPrivileged { + return [self initWithConnectionOptions:NSXPCConnectionPrivileged]; +} + +- (instancetype)initWithConnectionOptions:(NSXPCConnectionOptions)options { + if ((self = [super init])) { + _administrationXPCConnection.reset([[NSXPCConnection alloc] + initWithMachServiceName:base::mac::CFToNSCast( + updater::CopyAdministrationLaunchDName() + .get()) + options:options]); + + _administrationXPCConnection.get().remoteObjectInterface = + updater::GetXPCAdministeringInterface(); + + _administrationXPCConnection.get().interruptionHandler = ^{ + LOG(WARNING) << "CRUAdministering: XPC connection interrupted."; + }; + + _administrationXPCConnection.get().invalidationHandler = ^{ + LOG(WARNING) << "CRUAdministering: XPC connection invalidated."; + }; + + [_administrationXPCConnection resume]; + } + + return self; +} + +- (void)dealloc { + [_administrationXPCConnection invalidate]; + [super dealloc]; +} + +- (void)performAdminTasks { + auto errorHandler = ^(NSError* xpcError) { + LOG(ERROR) << "XPC connection failed: " + << base::SysNSStringToUTF8([xpcError description]); + }; + + [[_administrationXPCConnection remoteObjectProxyWithErrorHandler:errorHandler] + performAdminTasks]; +} + +@end + namespace updater { UpdateServiceOutOfProcess::UpdateServiceOutOfProcess( @@ -139,6 +201,8 @@ case UpdateService::Scope::kUser: client_.reset([[CRUUpdateServiceOutOfProcessImpl alloc] init]); break; + default: + CHECK(false) << "Unexpected value for UpdateService::Scope"; } callback_runner_ = base::SequencedTaskRunnerHandle::Get(); }
diff --git a/chrome/updater/mac/xpc_service_names.h b/chrome/updater/mac/xpc_service_names.h index 6611ba8..06eb23e 100644 --- a/chrome/updater/mac/xpc_service_names.h +++ b/chrome/updater/mac/xpc_service_names.h
@@ -10,14 +10,12 @@ namespace updater { -base::ScopedCFTypeRef<CFStringRef> CopyServiceLaunchdName(); -base::ScopedCFTypeRef<CFStringRef> CopyWakeLaunchdName(); -base::ScopedCFTypeRef<CFStringRef> CopyControlLaunchdName(); -base::scoped_nsobject<NSString> GetServiceLaunchdLabel(); -base::scoped_nsobject<NSString> GetWakeLaunchdLabel(); -base::scoped_nsobject<NSString> GetControlLaunchdLabel(); +base::ScopedCFTypeRef<CFStringRef> CopyServiceLaunchDName(); +base::ScopedCFTypeRef<CFStringRef> CopyAdministrationLaunchDName(); +base::scoped_nsobject<NSString> GetServiceLaunchDLabel(); +base::scoped_nsobject<NSString> GetAdministrationLaunchDLabel(); +base::scoped_nsobject<NSString> GetServiceMachName(NSString* name); base::scoped_nsobject<NSString> GetServiceMachName(); -base::scoped_nsobject<NSString> GetVersionedServiceMachName(); } // namespace updater
diff --git a/chrome/updater/mac/xpc_service_names.mm b/chrome/updater/mac/xpc_service_names.mm index fc5ee379..fa464161 100644 --- a/chrome/updater/mac/xpc_service_names.mm +++ b/chrome/updater/mac/xpc_service_names.mm
@@ -12,33 +12,23 @@ namespace updater { -base::ScopedCFTypeRef<CFStringRef> CopyServiceLaunchdName() { +base::ScopedCFTypeRef<CFStringRef> CopyServiceLaunchDName() { return base::SysUTF8ToCFStringRef(MAC_BUNDLE_IDENTIFIER_STRING ".service"); } -base::ScopedCFTypeRef<CFStringRef> CopyWakeLaunchdName() { +base::ScopedCFTypeRef<CFStringRef> CopyAdministrationLaunchDName() { return base::SysUTF8ToCFStringRef(MAC_BUNDLE_IDENTIFIER_STRING - ".wake." UPDATER_VERSION_STRING); + ".admin." UPDATER_VERSION_STRING); } -base::ScopedCFTypeRef<CFStringRef> CopyControlLaunchdName() { - return base::SysUTF8ToCFStringRef(MAC_BUNDLE_IDENTIFIER_STRING - ".control." UPDATER_VERSION_STRING); -} - -base::scoped_nsobject<NSString> GetServiceLaunchdLabel() { +base::scoped_nsobject<NSString> GetServiceLaunchDLabel() { return base::scoped_nsobject<NSString>( - base::mac::CFToNSCast(CopyServiceLaunchdName().release())); + base::mac::CFToNSCast(CopyServiceLaunchDName().release())); } -base::scoped_nsobject<NSString> GetWakeLaunchdLabel() { +base::scoped_nsobject<NSString> GetAdministrationLaunchDLabel() { return base::scoped_nsobject<NSString>( - base::mac::CFToNSCast(CopyWakeLaunchdName().release())); -} - -base::scoped_nsobject<NSString> GetControlLaunchdLabel() { - return base::scoped_nsobject<NSString>( - base::mac::CFToNSCast(CopyControlLaunchdName().release())); + base::mac::CFToNSCast(CopyAdministrationLaunchDName().release())); } base::scoped_nsobject<NSString> GetServiceMachName(NSString* name) { @@ -49,17 +39,10 @@ base::scoped_nsobject<NSString> GetServiceMachName() { base::scoped_nsobject<NSString> name( - base::mac::CFToNSCast(CopyServiceLaunchdName().release())); - return GetServiceMachName(name); -} - -base::scoped_nsobject<NSString> GetVersionedServiceMachName() { - base::scoped_nsobject<NSString> name([NSString - stringWithFormat:@"%@.%@", - base::mac::CFToNSCast( - CopyServiceLaunchdName().release()), - base::SysUTF8ToNSString(UPDATER_VERSION_STRING)]); - return GetServiceMachName(name); + base::mac::CFToNSCast(CopyServiceLaunchDName().release())); + return base::scoped_nsobject<NSString>( + [name stringByAppendingFormat:@".%lu", [GetServiceLaunchDLabel() hash]], + base::scoped_policy::RETAIN); } } // namespace updater
diff --git a/chrome/updater/test/integration_tests_mac.mm b/chrome/updater/test/integration_tests_mac.mm index 0828279..3d83e6ce 100644 --- a/chrome/updater/test/integration_tests_mac.mm +++ b/chrome/updater/test/integration_tests_mac.mm
@@ -53,31 +53,25 @@ void Clean() { EXPECT_TRUE(base::DeletePathRecursively(GetProductPath())); EXPECT_TRUE(Launchd::GetInstance()->DeletePlist( - Launchd::User, Launchd::Agent, updater::CopyWakeLaunchdName())); + Launchd::User, Launchd::Agent, updater::CopyAdministrationLaunchDName())); EXPECT_TRUE(Launchd::GetInstance()->DeletePlist( - Launchd::User, Launchd::Agent, updater::CopyControlLaunchdName())); - EXPECT_TRUE(Launchd::GetInstance()->DeletePlist( - Launchd::User, Launchd::Agent, updater::CopyServiceLaunchdName())); + Launchd::User, Launchd::Agent, updater::CopyServiceLaunchDName())); } void ExpectClean() { // Files must not exist on the file system. EXPECT_FALSE(base::PathExists(GetProductPath())); EXPECT_FALSE(Launchd::GetInstance()->PlistExists( - Launchd::User, Launchd::Agent, updater::CopyWakeLaunchdName())); + Launchd::User, Launchd::Agent, updater::CopyAdministrationLaunchDName())); EXPECT_FALSE(Launchd::GetInstance()->PlistExists( - Launchd::User, Launchd::Agent, updater::CopyControlLaunchdName())); - EXPECT_FALSE(Launchd::GetInstance()->PlistExists( - Launchd::User, Launchd::Agent, updater::CopyServiceLaunchdName())); + Launchd::User, Launchd::Agent, updater::CopyServiceLaunchDName())); } void ExpectInstalled() { // Files must exist on the file system. EXPECT_TRUE(base::PathExists(GetProductPath())); - EXPECT_TRUE(Launchd::GetInstance()->PlistExists(Launchd::User, Launchd::Agent, - CopyWakeLaunchdName())); - EXPECT_TRUE(Launchd::GetInstance()->PlistExists(Launchd::User, Launchd::Agent, - CopyControlLaunchdName())); + EXPECT_TRUE(Launchd::GetInstance()->PlistExists( + Launchd::User, Launchd::Agent, CopyAdministrationLaunchDName())); } void Install() { @@ -94,7 +88,7 @@ // Files must exist on the file system. EXPECT_TRUE(base::PathExists(GetProductPath())); EXPECT_TRUE(Launchd::GetInstance()->PlistExists(Launchd::User, Launchd::Agent, - CopyServiceLaunchdName())); + CopyServiceLaunchDName())); } void PromoteCandidate() {
diff --git a/chrome/updater/update_apps.h b/chrome/updater/update_apps.h new file mode 100644 index 0000000..79cb6de --- /dev/null +++ b/chrome/updater/update_apps.h
@@ -0,0 +1,24 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_UPDATER_UPDATE_APPS_H_ +#define CHROME_UPDATER_UPDATE_APPS_H_ + +#include "base/memory/scoped_refptr.h" + +namespace update_client { +class Configurator; +} // namespace update_client + +namespace updater { + +class UpdateService; + +// A factory method to create an UpdateService class instance. +scoped_refptr<UpdateService> CreateUpdateService( + scoped_refptr<update_client::Configurator> config); + +} // namespace updater + +#endif // CHROME_UPDATER_UPDATE_APPS_H_
diff --git a/chrome/updater/update_apps_mac.mm b/chrome/updater/update_apps_mac.mm index 75e23de..5868121b 100644 --- a/chrome/updater/update_apps_mac.mm +++ b/chrome/updater/update_apps_mac.mm
@@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/updater/update_apps.h" + #include "base/command_line.h" #include "base/memory/ref_counted.h" #include "chrome/updater/configurator.h" #include "chrome/updater/constants.h" -#include "chrome/updater/mac/control_service_out_of_process.h" #include "chrome/updater/mac/update_service_out_of_process.h" #include "chrome/updater/update_service_in_process.h" @@ -25,13 +26,4 @@ UpdateService::Scope::kUser); } -scoped_refptr<ControlService> CreateControlService() { - base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); - return cmdline->HasSwitch(kSystemSwitch) - ? base::MakeRefCounted<ControlServiceOutOfProcess>( - UpdateService::Scope::kSystem) - : base::MakeRefCounted<ControlServiceOutOfProcess>( - UpdateService::Scope::kUser); -} - } // namespace updater
diff --git a/chrome/updater/update_apps_win.cc b/chrome/updater/update_apps_win.cc index 4b96538..36f43ef 100644 --- a/chrome/updater/update_apps_win.cc +++ b/chrome/updater/update_apps_win.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/updater/update_apps.h" + #include "base/command_line.h" #include "base/memory/ref_counted.h" #include "chrome/updater/configurator.h"
diff --git a/chrome/updater/update_service.h b/chrome/updater/update_service.h index 17dd7f2..c34e914e 100644 --- a/chrome/updater/update_service.h +++ b/chrome/updater/update_service.h
@@ -11,10 +11,6 @@ #include "base/memory/ref_counted.h" #include "base/version.h" -namespace update_client { -class Configurator; -} // namespace update_client - namespace updater { struct RegistrationRequest; @@ -200,10 +196,6 @@ virtual ~UpdateService() = default; }; -// A factory method to create an UpdateService class instance. -scoped_refptr<UpdateService> CreateUpdateService( - scoped_refptr<update_client::Configurator> config); - } // namespace updater #endif // CHROME_UPDATER_UPDATE_SERVICE_H_
diff --git a/chrome/updater/win/app_install.cc b/chrome/updater/win/app_install.cc index a15c6922..e19b4a8d 100644 --- a/chrome/updater/win/app_install.cc +++ b/chrome/updater/win/app_install.cc
@@ -62,6 +62,14 @@ class AppInstallController; +scoped_refptr<UpdateService> CreateUpdateService( + scoped_refptr<update_client::Configurator> config) { + if (base::CommandLine::ForCurrentProcess()->HasSwitch(kSingleProcessSwitch)) + return base::MakeRefCounted<UpdateServiceInProcess>(config); + else + return base::MakeRefCounted<UpdateServiceOutOfProcess>(); +} + // Implements a simple inter-thread communication protocol based on Windows // messages exchanged between the application installer and its UI. //
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCommandLineHelper.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCommandLineHelper.java index ea3a3b8..9805c0d 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCommandLineHelper.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCommandLineHelper.java
@@ -66,6 +66,7 @@ * Reads command line args from persistent storage and initializes the CommandLine with those * args. Does not initialize CommandLine if it has been already been done. */ + @SuppressWarnings("VisibleForTests") // For call to cmdline.hasSwitch() public static void initCommandLineWithSavedArgs(CommandLineInitializer commandLineInitializer) { // CommandLine is a singleton, so check whether CastCommandLineHelper has initialized it // already and do nothing if so. We keep track of this in a static variable so we can still
diff --git a/chromeos/components/account_manager/account_manager.cc b/chromeos/components/account_manager/account_manager.cc index 3d8af0e..6beaf610 100644 --- a/chromeos/components/account_manager/account_manager.cc +++ b/chromeos/components/account_manager/account_manager.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/callback_forward.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/important_file_writer.h" @@ -168,6 +169,16 @@ pref_service_ = pref_service; } +void AccountManager::InitializeInEphemeralMode( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { + Initialize(/* home_dir= */ base::FilePath(), url_loader_factory, + /* delay_network_call_runner= */ + base::BindRepeating( + [](base::OnceClosure closure) { std::move(closure).Run(); }), + /* task_runner= */ nullptr, /* initialization_callback= */ + base::DoNothing()); +} + void AccountManager::Initialize( const base::FilePath& home_dir, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, @@ -215,19 +226,28 @@ task_runner_ = task_runner; base::FilePath tokens_file_path; - if (!home_dir_.empty()) { + if (!IsEphemeralMode()) { + DCHECK(task_runner_); tokens_file_path = home_dir_.Append(kTokensFileName); writer_ = std::make_unique<base::ImportantFileWriter>(tokens_file_path, task_runner_); } initialization_callbacks_.emplace_back(std::move(initialization_callback)); - PostTaskAndReplyWithResult( - task_runner_.get(), FROM_HERE, - base::BindOnce(&AccountManager::LoadAccountsFromDisk, tokens_file_path), - base::BindOnce( - &AccountManager::InsertAccountsAndRunInitializationCallbacks, - weak_factory_.GetWeakPtr(), initialization_start_time)); + if (!IsEphemeralMode()) { + DCHECK(task_runner_); + PostTaskAndReplyWithResult( + task_runner_.get(), FROM_HERE, + base::BindOnce(&AccountManager::LoadAccountsFromDisk, tokens_file_path), + base::BindOnce( + &AccountManager::InsertAccountsAndRunInitializationCallbacks, + weak_factory_.GetWeakPtr(), initialization_start_time)); + } else { + // We are running in ephemeral mode. There is nothing to load from disk. + RecordTokenLoadStatus(TokenLoadStatus::kSuccess); + InsertAccountsAndRunInitializationCallbacks(initialization_start_time, + /* accounts= */ AccountMap{}); + } } // static @@ -520,11 +540,12 @@ } void AccountManager::PersistAccountsAsync() { - if (!writer_) { + if (IsEphemeralMode()) { return; } // Schedule (immediately) a non-blocking write. + DCHECK(writer_); writer_->WriteNow(std::make_unique<std::string>(GetSerializedAccounts())); } @@ -656,6 +677,10 @@ } } +bool AccountManager::IsEphemeralMode() const { + return home_dir_.empty(); +} + COMPONENT_EXPORT(ACCOUNT_MANAGER) std::ostream& operator<<(std::ostream& os, const AccountManager::AccountKey& account_key) {
diff --git a/chromeos/components/account_manager/account_manager.h b/chromeos/components/account_manager/account_manager.h index 1f302ddd..bcbb72a 100644 --- a/chromeos/components/account_manager/account_manager.h +++ b/chromeos/components/account_manager/account_manager.h
@@ -151,6 +151,12 @@ DelayNetworkCallRunner delay_network_call_runner, base::OnceClosure initialization_callback); + // Initializes |AccountManager| for ephemeral / in-memory usage. + // Useful for tests that cannot afford to write to disk and clean up after + // themselves. + void InitializeInEphemeralMode( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); + // Returns |true| if |AccountManager| has been fully initialized. bool IsInitialized() const; @@ -356,6 +362,10 @@ // Deletes |request| from |pending_token_revocation_requests_|, if present. void DeletePendingTokenRevocationRequest(GaiaTokenRevocationRequest* request); + // Returns |true| if |AccountManager| is operating in ephemeral / in-memory + // mode, and not persisting anything to disk. + bool IsEphemeralMode() const; + // Status of this object's initialization. InitializationState init_state_ = InitializationState::kNotStarted; @@ -371,13 +381,16 @@ PrefService* pref_service_ = nullptr; // A task runner for disk I/O. + // Will be |nullptr| if |AccountManager| is operating in ephemeral mode. scoped_refptr<base::SequencedTaskRunner> task_runner_; - // Writes |AccountManager|'s state to disk. Will be |nullptr| if - // |AccountManager| is operating in-memory only. + // Writes |AccountManager|'s state to disk. + // Will be |nullptr| if |AccountManager| is operating in ephemeral mode. std::unique_ptr<base::ImportantFileWriter> writer_; // Cryptohome root. + // Will be |base::FilePath::empty()| if |AccountManager| is operating in + // ephemeral mode. base::FilePath home_dir_; // A map from |AccountKey|s to |AccountInfo|.
diff --git a/chromeos/components/account_manager/account_manager_unittest.cc b/chromeos/components/account_manager/account_manager_unittest.cc index 9e66e4e..6e2813de 100644 --- a/chromeos/components/account_manager/account_manager_unittest.cc +++ b/chromeos/components/account_manager/account_manager_unittest.cc
@@ -151,6 +151,15 @@ std::move(initialization_callback)); } + // |account_manager| is a non-owning pointer. + void InitializeEphemeralAccountManager(AccountManager* account_manager) { + account_manager->InitializeInEphemeralMode( + test_url_loader_factory_.GetSafeWeakWrapper()); + account_manager->SetPrefService(&pref_service_); + RunAllPendingTasks(); + EXPECT_TRUE(account_manager->IsInitialized()); + } + void RunAllPendingTasks() { task_environment_.RunUntilIdle(); } // Returns an unowned pointer to |AccountManager|. @@ -358,6 +367,24 @@ EXPECT_EQ(0UL, accounts.size()); } +TEST_F(AccountManagerTest, TestEphemeralMode) { + { + // Create a scoped |AccountManager|. + AccountManager account_manager; + InitializeEphemeralAccountManager(&account_manager); + account_manager.UpsertAccount(kGaiaAccountKey, kRawUserEmail, kGaiaToken); + RunAllPendingTasks(); + } + + // Create another |AccountManager|. + AccountManager account_manager; + InitializeEphemeralAccountManager(&account_manager); + + std::vector<AccountManager::Account> accounts = + GetAccountsBlocking(&account_manager); + EXPECT_EQ(0UL, accounts.size()); +} + TEST_F(AccountManagerTest, TestAccountEmailPersistence) { account_manager()->UpsertAccount(kGaiaAccountKey, kRawUserEmail, kGaiaToken); RunAllPendingTasks();
diff --git a/chromeos/components/telemetry_extension_ui/mojom/probe_service.mojom b/chromeos/components/telemetry_extension_ui/mojom/probe_service.mojom index c55401d..ad956a56e 100644 --- a/chromeos/components/telemetry_extension_ui/mojom/probe_service.mojom +++ b/chromeos/components/telemetry_extension_ui/mojom/probe_service.mojom
@@ -37,10 +37,11 @@ // 3.2) use string to store serial in a decimal numeral system instead // of uint32 in case we want to extend serial number range. // 4) LogicalCpuInfo: -// 4.1) rename idle_time_user_hz to idle_time_user, because of typo in -// cros_healthd interface; -// 4.2) use uint64 to store idle_time_user instead of uint32, -// idle_time_user can easily be more than uint32 range. +// 4.1) rename idle_time_user_hz to idle_time_ms and use milliseconds +// instead of USER_HZ units, because USER_HZ system constant is not +// available in the web. +// 4.2) use uint64 to store idle_time_ms instead of uint32, idle_time_ms +// can easily be more than uint32 range. // 5) MemoryInfo: use uint64 to store page_faults_since_last_boot instead of // uint32, it can be more than uint32 range. @@ -252,9 +253,8 @@ UInt32Value? scaling_max_frequency_khz; // Current frequency the CPU is running at. UInt32Value? scaling_current_frequency_khz; - // Idle time since last boot. USER_HZ can be converted to seconds - // with the conversion factor given by sysconf(_SC_CLK_TCK). - UInt64Value? idle_time_user; + // Idle time since last boot, in milliseconds. + UInt64Value? idle_time_ms; // Information about the logical CPU's time in various C-states. array<CpuCStateInfo> c_states; };
diff --git a/chromeos/components/telemetry_extension_ui/probe_service_converters.cc b/chromeos/components/telemetry_extension_ui/probe_service_converters.cc index 6c3bb00..d6ec5de 100644 --- a/chromeos/components/telemetry_extension_ui/probe_service_converters.cc +++ b/chromeos/components/telemetry_extension_ui/probe_service_converters.cc
@@ -4,6 +4,7 @@ #include "chromeos/components/telemetry_extension_ui/probe_service_converters.h" +#include <unistd.h> #include <utility> #include "base/notreached.h" @@ -138,13 +139,34 @@ std::move(input->name), Convert(input->time_in_state_since_last_boot_us)); } +namespace { + +uint64_t UserHz() { + const long user_hz = sysconf(_SC_CLK_TCK); + DCHECK(user_hz >= 0); + return user_hz; +} + +} // namespace + health::mojom::LogicalCpuInfoPtr UncheckedConvertPtr( cros_healthd::mojom::LogicalCpuInfoPtr input) { + return UncheckedConvertPtr(std::move(input), UserHz()); +} + +health::mojom::LogicalCpuInfoPtr UncheckedConvertPtr( + cros_healthd::mojom::LogicalCpuInfoPtr input, + uint64_t user_hz) { + constexpr uint64_t kMillisecondsInSecond = 1000; + uint64_t idle_time_user_hz = static_cast<uint64_t>(input->idle_time_user_hz); + + DCHECK(user_hz != 0); + return health::mojom::LogicalCpuInfo::New( Convert(input->max_clock_speed_khz), Convert(input->scaling_max_frequency_khz), Convert(input->scaling_current_frequency_khz), - Convert(static_cast<uint64_t>(input->idle_time_user_hz)), + Convert(idle_time_user_hz * kMillisecondsInSecond / user_hz), ConvertPtrVector<health::mojom::CpuCStateInfoPtr>( std::move(input->c_states))); }
diff --git a/chromeos/components/telemetry_extension_ui/probe_service_converters.h b/chromeos/components/telemetry_extension_ui/probe_service_converters.h index 504dd98..dbc68967 100644 --- a/chromeos/components/telemetry_extension_ui/probe_service_converters.h +++ b/chromeos/components/telemetry_extension_ui/probe_service_converters.h
@@ -58,6 +58,10 @@ health::mojom::LogicalCpuInfoPtr UncheckedConvertPtr( cros_healthd::mojom::LogicalCpuInfoPtr input); +health::mojom::LogicalCpuInfoPtr UncheckedConvertPtr( + cros_healthd::mojom::LogicalCpuInfoPtr input, + uint64_t user_hz); + health::mojom::PhysicalCpuInfoPtr UncheckedConvertPtr( cros_healthd::mojom::PhysicalCpuInfoPtr input);
diff --git a/chromeos/components/telemetry_extension_ui/probe_service_converters_unittest.cc b/chromeos/components/telemetry_extension_ui/probe_service_converters_unittest.cc index 63bb790..09708ed 100644 --- a/chromeos/components/telemetry_extension_ui/probe_service_converters_unittest.cc +++ b/chromeos/components/telemetry_extension_ui/probe_service_converters_unittest.cc
@@ -285,7 +285,10 @@ constexpr uint32_t kMaxClockSpeedKhz = (1 << 31) + 10000; constexpr uint32_t kScalingMaxFrequencyKhz = (1 << 30) + 20000; constexpr uint32_t kScalingCurrentFrequencyKhz = (1 << 29) + 30000; - constexpr uint32_t kIdleTimeUserHz = (1 << 28) + 40000; + + // Idle time cannot be tested with ConvertPtr, because it requires USER_HZ + // system constant to convert idle_time_user_hz to milliseconds. + constexpr uint32_t kIdleTime = 0; constexpr char kCpuCStateName[] = "C1"; constexpr uint64_t kCpuCStateTime = (1 << 27) + 50000; @@ -299,7 +302,7 @@ input->max_clock_speed_khz = kMaxClockSpeedKhz; input->scaling_max_frequency_khz = kScalingMaxFrequencyKhz; input->scaling_current_frequency_khz = kScalingCurrentFrequencyKhz; - input->idle_time_user_hz = kIdleTimeUserHz; + input->idle_time_user_hz = kIdleTime; input->c_states.push_back(std::move(c_state)); } @@ -312,17 +315,33 @@ health::mojom::UInt32Value::New(kMaxClockSpeedKhz), health::mojom::UInt32Value::New(kScalingMaxFrequencyKhz), health::mojom::UInt32Value::New(kScalingCurrentFrequencyKhz), - health::mojom::UInt64Value::New(kIdleTimeUserHz), + health::mojom::UInt64Value::New(kIdleTime), std::move(expected_c_states))); } +TEST(ProbeServiceConvertors, LogicalCpuInfoPtrNonZeroIdleTime) { + constexpr uint64_t kUserHz = 100; + constexpr uint32_t kIdleTimeUserHz = 4291234295; + constexpr uint64_t kIdleTimeMs = 42912342950; + + auto input = cros_healthd::mojom::LogicalCpuInfo::New(); + input->idle_time_user_hz = kIdleTimeUserHz; + + const auto output = unchecked::UncheckedConvertPtr(std::move(input), kUserHz); + ASSERT_TRUE(output); + EXPECT_EQ(output->idle_time_ms, health::mojom::UInt64Value::New(kIdleTimeMs)); +} + TEST(ProbeServiceConvertors, PhysicalCpuInfoPtr) { constexpr char kModelName[] = "i9"; constexpr uint32_t kMaxClockSpeedKhz = (1 << 31) + 11111; constexpr uint32_t kScalingMaxFrequencyKhz = (1 << 30) + 22222; constexpr uint32_t kScalingCurrentFrequencyKhz = (1 << 29) + 33333; - constexpr uint32_t kIdleTimeUserHz = (1 << 28) + 44444; + + // Idle time cannot be tested with ConvertPtr, because it requires USER_HZ + // system constant to convert idle_time_user_hz to milliseconds. + constexpr uint32_t kIdleTime = 0; auto input = cros_healthd::mojom::PhysicalCpuInfo::New(); { @@ -330,7 +349,7 @@ logical_info->max_clock_speed_khz = kMaxClockSpeedKhz; logical_info->scaling_max_frequency_khz = kScalingMaxFrequencyKhz; logical_info->scaling_current_frequency_khz = kScalingCurrentFrequencyKhz; - logical_info->idle_time_user_hz = kIdleTimeUserHz; + logical_info->idle_time_user_hz = kIdleTime; input->model_name = kModelName; input->logical_cpus.push_back(std::move(logical_info)); @@ -341,7 +360,7 @@ health::mojom::UInt32Value::New(kMaxClockSpeedKhz), health::mojom::UInt32Value::New(kScalingMaxFrequencyKhz), health::mojom::UInt32Value::New(kScalingCurrentFrequencyKhz), - health::mojom::UInt64Value::New(kIdleTimeUserHz), + health::mojom::UInt64Value::New(kIdleTime), std::vector<health::mojom::CpuCStateInfoPtr>{})); EXPECT_EQ(ConvertPtr(std::move(input)),
diff --git a/chromeos/dbus/attestation/fake_attestation_client.h b/chromeos/dbus/attestation/fake_attestation_client.h index 207e0a6..bb2748e 100644 --- a/chromeos/dbus/attestation/fake_attestation_client.h +++ b/chromeos/dbus/attestation/fake_attestation_client.h
@@ -101,7 +101,7 @@ AttestationClient::TestInterface* GetTestInterface() override; private: - bool is_prepared_{false}; + bool is_prepared_ = true; std::deque<bool> preparation_sequences_; bool is_enrolled_ = false;
diff --git a/components/BUILD.gn b/components/BUILD.gn index 9d2ae5a..e3d8755 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -763,7 +763,6 @@ "//components/gcm_driver/android:components_gcm_driver_junit_tests", "//components/permissions/android:components_permissions_junit_tests", "//components/policy/android:components_policy_junit_tests", - "//components/prefs/android:junit", "//components/query_tiles:query_tiles_junit_tests", "//components/signin/core/browser/android:components_signin_junit_tests", "//components/variations/android:components_variations_junit_tests",
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 25070c3..7f9eb32 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -88,6 +88,8 @@ "data_model/autofill_profile.h", "data_model/autofill_profile_comparator.cc", "data_model/autofill_profile_comparator.h", + "data_model/autofill_structured_address_component.cc", + "data_model/autofill_structured_address_component.h", "data_model/autofill_structured_address_utils.cc", "data_model/autofill_structured_address_utils.h", "data_model/contact_info.cc", @@ -568,6 +570,7 @@ "data_model/autofill_data_model_unittest.cc", "data_model/autofill_profile_comparator_unittest.cc", "data_model/autofill_profile_unittest.cc", + "data_model/autofill_structured_address_component_unittest.cc", "data_model/autofill_structured_address_utils_unittest.cc", "data_model/contact_info_unittest.cc", "data_model/credit_card_unittest.cc",
diff --git a/components/autofill/core/browser/data_model/autofill_structured_address_component.cc b/components/autofill/core/browser/data_model/autofill_structured_address_component.cc new file mode 100644 index 0000000..424a182 --- /dev/null +++ b/components/autofill/core/browser/data_model/autofill_structured_address_component.cc
@@ -0,0 +1,564 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/data_model/autofill_structured_address_component.h" + +#include <algorithm> +#include <map> +#include <string> +#include <utility> + +#include "base/strings/strcat.h" +#include "base/strings/string16.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "components/autofill/core/browser/autofill_type.h" +#include "components/autofill/core/browser/data_model/autofill_structured_address_utils.h" +#include "components/autofill/core/browser/field_types.h" + +namespace autofill { + +namespace structured_address { +AddressComponent::AddressComponent(ServerFieldType storage_type) + : AddressComponent(storage_type, nullptr, {}) {} + +AddressComponent::AddressComponent(ServerFieldType storage_type, + AddressComponent* parent) + : AddressComponent(storage_type, parent, {}) {} + +AddressComponent::AddressComponent(ServerFieldType storage_type, + AddressComponent* parent, + std::vector<AddressComponent*> subcomponents) + : value_verification_status_(VerificationStatus::kNoStatus), + storage_type_(storage_type), + subcomponents_(subcomponents), + parent_(parent) {} + +AddressComponent::~AddressComponent() = default; + +ServerFieldType AddressComponent::GetStorageType() const { + return storage_type_; +} + +std::string AddressComponent::GetStorageTypeName() const { + return AutofillType(storage_type_).ToString(); +} + +AddressComponent& AddressComponent::operator=(const AddressComponent& right) { + DCHECK(GetStorageType() == right.GetStorageType()); + if (this == &right) + return *this; + + value_ = right.value_; + value_verification_status_ = right.value_verification_status_; + + DCHECK(right.subcomponents_.size() == subcomponents_.size()); + + for (size_t i = 0; i < right.subcomponents_.size(); i++) + *subcomponents_[i] = *right.subcomponents_[i]; + + return *this; +} + +bool AddressComponent::operator==(const AddressComponent& right) const { + if (this == &right) + return true; + + if (GetStorageType() != right.GetStorageType()) + return false; + + if (value_ != right.value_ || + value_verification_status_ != right.value_verification_status_) + return false; + + DCHECK(right.subcomponents_.size() == subcomponents_.size()); + for (size_t i = 0; i < right.subcomponents_.size(); i++) + if (!(*subcomponents_[i] == *right.subcomponents_[i])) + return false; + return true; +} + +bool AddressComponent::operator!=(const AddressComponent& right) const { + return !(*this == right); +} + +bool AddressComponent::IsAtomic() const { + return subcomponents_.empty(); +} + +VerificationStatus AddressComponent::GetVerificationStatus() const { + return value_verification_status_; +} + +const base::string16& AddressComponent::GetValue() const { + if (value_.has_value()) + return value_.value(); + return base::EmptyString16(); +} + +bool AddressComponent::IsValueAssigned() const { + return value_.has_value(); +} + +void AddressComponent::SetValue(base::string16 value, + VerificationStatus status) { + value_ = std::move(value); + value_verification_status_ = status; +} + +void AddressComponent::UnsetValue() { + value_.reset(); + value_verification_status_ = VerificationStatus::kNoStatus; +} + +void AddressComponent::GetSupportedTypes( + ServerFieldTypeSet* supported_types) const { + // A proper AddressComponent tree contains every type only once. + DCHECK(supported_types->find(storage_type_) == supported_types->end()) + << "The AddressComponent already contains a node that supports this " + "type: " + << storage_type_; + supported_types->insert(storage_type_); + GetAdditionalSupportedFieldTypes(supported_types); + for (auto* subcomponent : subcomponents_) + subcomponent->GetSupportedTypes(supported_types); +} + +bool AddressComponent::ConvertAndSetValueForAdditionalFieldTypeName( + const std::string& field_type_name, + const base::string16& value, + const VerificationStatus& status) { + return false; +} + +bool AddressComponent::ConvertAndGetTheValueForAdditionalFieldTypeName( + const std::string& field_type_name, + base::string16* value) const { + return false; +} + +base::string16 AddressComponent::GetBestFormatString() const { + // If the component is atomic, the format string is just the value. + if (IsAtomic()) + return base::ASCIIToUTF16(GetPlaceholderToken(GetStorageTypeName())); + + // Otherwise, the canonical format string is the concatenation of all + // subcomponents by their natural order. + std::vector<std::string> format_pieces; + for (const auto* subcomponent : subcomponents_) { + std::string format_piece = GetPlaceholderToken( + AutofillType(subcomponent->GetStorageType()).ToString()); + format_pieces.emplace_back(std::move(format_piece)); + } + return base::ASCIIToUTF16(base::JoinString(format_pieces, " ")); +} + +std::vector<ServerFieldType> AddressComponent::GetSubcomponentTypes() const { + std::vector<ServerFieldType> subcomponent_types; + subcomponent_types.reserve(subcomponents_.size()); + for (const auto* subcomponent : subcomponents_) { + subcomponent_types.emplace_back(subcomponent->GetStorageType()); + } + return subcomponent_types; +} + +bool AddressComponent::SetValueForTypeIfPossible( + const ServerFieldType& type, + const base::string16& value, + const VerificationStatus& verification_status, + bool invalidate_child_nodes, + bool invalidate_parent_nodes) { + return SetValueForTypeIfPossible(AutofillType(type).ToString(), value, + verification_status, invalidate_child_nodes, + invalidate_parent_nodes); +} + +bool AddressComponent::SetValueForTypeIfPossible( + const std::string& type_name, + const base::string16& value, + const VerificationStatus& verification_status, + bool invalidate_child_nodes, + bool invalidate_parent_nodes) { + bool value_set = false; + // If the type is the storage type of the component, it can directly be + // returned. + if (type_name == GetStorageTypeName()) { + SetValue(value, verification_status); + value_set = true; + } else if (ConvertAndSetValueForAdditionalFieldTypeName( + type_name, value, verification_status)) { + // The conversion using a field type was successful. + value_set = true; + } + + if (value_set) { + if (invalidate_child_nodes) + UnsetSubcomponents(); + return true; + } + + // Finally, probe if the type is supported by one of the subcomponents. + for (auto* subcomponent : subcomponents_) { + if (subcomponent->SetValueForTypeIfPossible( + type_name, value, verification_status, invalidate_child_nodes, + invalidate_parent_nodes)) { + if (invalidate_parent_nodes) + UnsetValue(); + return true; + } + } + + return false; +} + +void AddressComponent::UnsetAddressComponentAndItsSubcomponents() { + UnsetValue(); + UnsetSubcomponents(); +} + +void AddressComponent::UnsetSubcomponents() { + for (auto* component : subcomponents_) + component->UnsetAddressComponentAndItsSubcomponents(); +} + +bool AddressComponent::GetValueAndStatusForTypeIfPossible( + const ServerFieldType& type, + base::string16* value, + VerificationStatus* status) const { + return GetValueAndStatusForTypeIfPossible(AutofillType(type).ToString(), + value, status); +} + +bool AddressComponent::GetValueAndStatusForTypeIfPossible( + const std::string& type_name, + base::string16* value, + VerificationStatus* status) const { + // If the value is the storage type, it can be simply returned. + if (type_name == GetStorageTypeName()) { + if (value) + *value = value_.value_or(base::string16()); + if (status) + *status = GetVerificationStatus(); + return true; + } + + // Otherwise, probe if it is a supported field type that can be converted. + if (this->ConvertAndGetTheValueForAdditionalFieldTypeName(type_name, value)) { + if (status) + *status = GetVerificationStatus(); + return true; + } + + // Finally, try to retrieve the value from one of the subcomponents. + for (const auto* subcomponent : subcomponents_) { + if (subcomponent->GetValueAndStatusForTypeIfPossible(type_name, value, + status)) + return true; + } + return false; +} + +base::string16 AddressComponent::GetValueForType( + const ServerFieldType& type) const { + return GetValueForType(AutofillType(type).ToString()); +} + +base::string16 AddressComponent::GetValueForType( + const std::string& type_name) const { + base::string16 value; + bool success = GetValueAndStatusForTypeIfPossible(type_name, &value, nullptr); + DCHECK(success); + return value; +} + +VerificationStatus AddressComponent::GetVerificationStatusForType( + const ServerFieldType& type) const { + return GetVerificationStatusForType(AutofillType(type).ToString()); +} + +VerificationStatus AddressComponent::GetVerificationStatusForType( + const std::string& type_name) const { + VerificationStatus status = VerificationStatus::kNoStatus; + bool success = + GetValueAndStatusForTypeIfPossible(type_name, nullptr, &status); + DCHECK(success); + return status; +} + +bool AddressComponent::UnsetValueForTypeIfSupported( + const ServerFieldType& type) { + if (type == storage_type_) { + UnsetAddressComponentAndItsSubcomponents(); + return true; + } + + for (auto* subcomponent : subcomponents_) { + if (subcomponent->UnsetValueForTypeIfSupported(type)) + return true; + } + + return false; +} + +bool AddressComponent::ParseValueAndAssignSubcomponentsByMethod() { + return false; +} + +std::vector<const RE2*> AddressComponent::GetParseExpressionsByRelevance() + const { + return {}; +} + +void AddressComponent::ParseValueAndAssignSubcomponents() { + // Set the values of all subcomponents to the empty string and set the + // verification status to kParsed. + for (auto* subcomponent : subcomponents_) + subcomponent->SetValue(base::string16(), VerificationStatus::kParsed); + + // First attempt, try to parse by method. + if (ParseValueAndAssignSubcomponentsByMethod()) + return; + + // Second attempt, try to parse by expressions. + if (ParseValueAndAssignSubcomponentsByExpressions()) + return; + + // As a final fallback, parse using the fallback method. + ParseValueAndAssignSubcomponentsByFallbackMethod(); +} + +bool AddressComponent::ParseValueAndAssignSubcomponentsByExpressions() { + for (const auto* parse_expression : GetParseExpressionsByRelevance()) { + if (!parse_expression) + continue; + std::map<std::string, std::string> result_map; + if (ParseValueByRegularExpression(base::UTF16ToUTF8(GetValue()), + parse_expression, &result_map)) { + // Parsing was successful and results from the result map can be written + // to the structure. + for (const auto& result_entry : result_map) { + std::string field_type = result_entry.first; + base::string16 field_value = base::UTF8ToUTF16(result_entry.second); + bool success = SetValueForTypeIfPossible(field_type, field_value, + VerificationStatus::kParsed); + // Setting the value should always work unless the regular expression is + // invalid. + DCHECK(success); + } + return true; + } + } + return false; +} + +void AddressComponent::ParseValueAndAssignSubcomponentsByFallbackMethod() { + // There is nothing to do for an atomic component. + if (IsAtomic()) + return; + + // An empty string is trivially parsable. + if (GetValue().empty()) + return; + + // Split the string by spaces. + std::vector<base::string16> space_separated_tokens = + base::SplitString(GetValue(), base::UTF8ToUTF16(" "), + base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + + auto token_iterator = space_separated_tokens.begin(); + auto subcomponent_types = GetSubcomponentTypes(); + + // Assign one space-separated token each to all but the last subcomponent. + for (size_t i = 0; (i + 1) < subcomponent_types.size(); i++) { + // If there are no tokens left, parsing is done. + if (token_iterator == space_separated_tokens.end()) + return; + // Set the current token to the type and advance the token iterator. + bool success = SetValueForTypeIfPossible( + subcomponent_types[i], *token_iterator, VerificationStatus::kParsed); + // By design, setting the value should never fail. + DCHECK(success); + token_iterator++; + } + + // Collect all remaining tokens in the last subcomponent. + base::string16 remaining_tokens = base::JoinString( + std::vector<base::string16>(token_iterator, space_separated_tokens.end()), + base::ASCIIToUTF16(" ")); + // By design, it should be possible to assign the value unless the regular + // expression is wrong. + bool success = SetValueForTypeIfPossible( + subcomponent_types.back(), remaining_tokens, VerificationStatus::kParsed); + DCHECK(success); +} + +void AddressComponent::FormatValueFromSubcomponents() { + // Get the most suited format string. + base::string16 format_string = GetBestFormatString(); + + // Perform the following steps on a copy of the format string. + // * Replace all the placeholders of the form ${TYPE_NAME} with the + // corresponding value. + // * Strip away double spaces as they may occur after replacing a placeholder + // with an empty value. + + base::string16 result = ReplacePlaceholderTypesWithValues(format_string); + result = base::CollapseWhitespace(result, /*trim_line_breaks=*/false); + SetValue(result, VerificationStatus::kFormatted); +} + +base::string16 AddressComponent::ReplacePlaceholderTypesWithValues( + const base::string16& format) const { + // Replaces placeholders using the following rules. + // Assumptions: Placeholder values are not nested. + // + // * Search for a substring of the form "{$[^}]*}". + // + // * Check if this substring is a supported type of this component. + // + // * If yes, replace the substring with the corresponding value. + // + // * If the corresponding value is empty, return false. + + auto control_parmater = base::ASCIIToUTF16("$").at(0); + auto control_parmater_open_delimitor = base::ASCIIToUTF16("{").at(0); + auto control_parmater_close_delimitor = base::ASCIIToUTF16("}").at(0); + + // Create a result vector for the tokens that are joined in the end. + std::vector<base::StringPiece16> result_pieces; + // Reserve space for 10 tokens. This should be sufficient for most cases. + result_pieces.reserve(10); + + // Store the inserted values to allow the used StringPieces to stay valid. + std::vector<const base::string16> inserted_values; + inserted_values.reserve(4); + + // Use a StringPiece rather than the string since this allows for getting + // cheap views onto substrings. + const base::StringPiece16 format_piece = format; + + bool started_control_sequence = false; + // Track until which index the format string was fully processed. + size_t processed_until_index = 0; + + for (size_t i = 0; i < format_piece.size(); ++i) { + // Check if a control sequence is started by '${' + if (format_piece[i] == control_parmater && i < format_piece.size() - 1 && + format_piece[i + 1] == control_parmater_open_delimitor) { + // A control sequence is started. + started_control_sequence = true; + // Append the preceding string since it can't be a valid placeholder. + if (i > 0) { + result_pieces.emplace_back(format_piece.substr( + processed_until_index, i - processed_until_index)); + } + processed_until_index = i; + ++i; + } else if (started_control_sequence && + format_piece[i] == control_parmater_close_delimitor) { + // The control sequence came to an end. + started_control_sequence = false; + size_t placeholder_start = processed_until_index + 2; + base::string16 type_name = + format_piece.substr(placeholder_start, i - placeholder_start) + .as_string(); + base::string16 value; + if (GetValueAndStatusForTypeIfPossible(base::UTF16ToASCII(type_name), + &value, nullptr)) { + // The type is valid and should be substituted. + inserted_values.emplace_back(std::move(value)); + result_pieces.emplace_back(base::StringPiece16(inserted_values.back())); + } else { + // Append the control sequence as it is, because the type is not + // supported by the component tree. + result_pieces.emplace_back(format_piece.substr( + processed_until_index, i - processed_until_index + 1)); + } + processed_until_index = i + 1; + } + } + // Append the rest of the string. + result_pieces.emplace_back( + format_piece.substr(processed_until_index, base::string16::npos)); + + // Build the final result. + return base::JoinString(result_pieces, base::ASCIIToUTF16("")); +} + +bool AddressComponent::CompleteFullTree() { + if (!GetRootNode().IsTreeCompletable()) + return false; + GetRootNode().RecursivelyCompleteTree(); + return true; +} + +void AddressComponent::RecursivelyCompleteTree() { + if (IsAtomic()) + return; + + // If the value is assigned, parse the subcomponents from the value. + if (IsValueAssigned()) + ParseValueAndAssignSubcomponents(); + + // First call completion on all subcomponents. + for (auto* subcomponent : subcomponents_) + subcomponent->RecursivelyCompleteTree(); + + // Finally format the value from the sucomponents if it is not already + // assigned. + if (!IsValueAssigned()) + FormatValueFromSubcomponents(); +} + +int AddressComponent:: + MaximumNumberOfAssignedAddressComponentsOnNodeToLeafPaths() const { + int result = 0; + + for (auto* subcomponent : subcomponents_) { + result = std::max( + result, + subcomponent + ->MaximumNumberOfAssignedAddressComponentsOnNodeToLeafPaths()); + } + + if (IsValueAssigned()) + ++result; + + return result; +} + +bool AddressComponent::IsTreeCompletable() { + return MaximumNumberOfAssignedAddressComponentsOnNodeToLeafPaths() == 1; +} + +const AddressComponent& AddressComponent::GetRootNode() const { + if (!parent_) + return *this; + return parent_->GetRootNode(); +} + +AddressComponent& AddressComponent::GetRootNode() { + return const_cast<AddressComponent&>( + const_cast<const AddressComponent*>(this)->GetRootNode()); +} + +void AddressComponent::RecursivelyUnsetParsedAndFormattedValues() { + if (IsValueAssigned() && + (GetVerificationStatus() == VerificationStatus::kFormatted || + GetVerificationStatus() == VerificationStatus::kParsed)) + UnsetValue(); + + for (auto* component : subcomponents_) + component->RecursivelyUnsetParsedAndFormattedValues(); +} + +void AddressComponent::UnsetParsedAndFormattedValuesInEntireTree() { + GetRootNode().RecursivelyUnsetParsedAndFormattedValues(); +} + +} // namespace structured_address + +} // namespace autofill
diff --git a/components/autofill/core/browser/data_model/autofill_structured_address_component.h b/components/autofill/core/browser/data_model/autofill_structured_address_component.h new file mode 100644 index 0000000..898bbf72 --- /dev/null +++ b/components/autofill/core/browser/data_model/autofill_structured_address_component.h
@@ -0,0 +1,370 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_DATA_MODEL_AUTOFILL_STRUCTURED_ADDRESS_COMPONENT_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_DATA_MODEL_AUTOFILL_STRUCTURED_ADDRESS_COMPONENT_H_ + +#include <map> +#include <string> +#include <vector> + +#include "base/optional.h" +#include "base/strings/string_piece.h" +#include "components/autofill/core/browser/field_types.h" +#include "third_party/re2/src/re2/re2.h" + +namespace autofill { +namespace structured_address { + +enum class VerificationStatus { + // No verification status assigned. + kNoStatus, + // The user used the autofill settings to verify and store this token. + kUserVerified, + // The value was observed in a form transmission. + kObserved, + // Value was built from its subcomponents. + kFormatted, + // The value token was parsed from a parent token. + kParsed, +}; + +// An AddressComponent is a tree structure that represents a semi-structured +// address token. Such an address token can either be an atomic leaf node or +// have a set of children, each representing a more granular subtoken of the +// component. +// +// An AddressComponent has a string representation stored in |value_| and a +// VerificationStatus stored in |verification_status_|. +// The latter indicates if the value was user-verified, observed in a form +// submission event, parsed from its parent component or was formatted from its +// child components. +// +// In a proper component tree, each AddressComponent has a unique +// ServerFieldType. Additionally, an AddressComponent may be associated with a +// list of additional field types that allow for retrieving and setting the +// Component's value in specific formats. For example, NAME_MIDDLE may be the +// storage type and NAME_MIDDLE_INITIAL is an additional field type. +// +// The usage pattern of such an address tree is as follows: +// +// * Create a tree from an observed form submission or a profile editing or +// creation event in the Chrome settings. It is assumed that the created +// tree does not have values for competing field types. Two types are competing +// iff they are on a common root-to-leaf path. For example, an imported profile +// with a value for NAME_FULL and NAME_LAST has conflicting types that +// carry redundant information. +// +// * After the creation of the tree, the values of unassigned nodes in the tree +// are deducted from the values of assigned nodes. This happens by parsing +// (taking a string and splitting it into components) or by formatting (taking +// one or multiple strings and combining them into one string). +// +// * After the completion, there should be no need to modify the tree. +// +// * A tree may be mergeable with another tree of the same type. This +// operation incorporates complementing observations. For example, in the first +// tree NAME_FIRST, NAME_MIDDLE and NAME_LAST may be parsed from an observed +// unstructured name (NAME_FULL). The second tree may be built from observing +// the structured name, and contain observed NAME_FIRST, NAME_MIDDLE and +// NAME_LAST values but only a formatted NAME_FULL value. +class AddressComponent { + public: + // Constructor for an atomic root node. + explicit AddressComponent(ServerFieldType storage_type); + + // Constructor for an atomic leaf node. + explicit AddressComponent(ServerFieldType storage_type, + AddressComponent* parent); + + // Constructor for a compound child node. + AddressComponent(ServerFieldType storage_type, + AddressComponent* parent, + std::vector<AddressComponent*> subcomponents); + + // Disallows copies since they are not needed in the current Autofill design. + AddressComponent(const AddressComponent& other) = delete; + + virtual ~AddressComponent(); + + // Assignment operator that works recursively down the tree and assigns the + // |value_| and |verification_status_| of every node in right to the + // corresponding nodes in |this|. For an assignment it is required that both + // nodes have the same |storage_type_|. + AddressComponent& operator=(const AddressComponent& right); + + // Comparison operator that works recursively down the tree. + bool operator==(const AddressComponent& right) const; + + // Inequality operator that works recursively down the tree. + bool operator!=(const AddressComponent& right) const; + + // Returns the autofill storage type stored in |storage_type_|. + ServerFieldType GetStorageType() const; + + // Returns the string representation of |storage_type_|. + std::string GetStorageTypeName() const; + + // Returns the value verification status of the component's value; + VerificationStatus GetVerificationStatus() const; + + // Returns true if the component has no subcomponents. + bool IsAtomic() const; + + // Returns a constant reference to |value_.value()|. If the value is not + // assigned, an empty string is returned. + const base::string16& GetValue() const; + + // Returns true if the value of this AddressComponent is assigned. + bool IsValueAssigned() const; + + // Sets the value corresponding to the storage type of this AddressComponent. + void SetValue(base::string16 value, VerificationStatus status); + + // Sets the value to an empty string, marks it unassigned and sets the + // verification status to |kNoStatus|. + void UnsetValue(); + + // The method sets the value of the current node if its |storage_type_| is + // |type| or if |ConvertAndGetTheValueForAdditionalFieldTypeName()| supports + // retrieving |type|. Otherwise, the call is delegated recursively to the + // node's children. + // Returns true if the |value_| and |verification_status_| were successfully + // set for this or an ancestor node with the storage type |type|. If + // |invalidate_child_nodes|, all child nodes of the assigned node are + // unassigned. If |invalidate_parent_nodes|, all ancestor nodes of the + // assigned node as unassigned. + bool SetValueForTypeIfPossible(const ServerFieldType& type, + const base::string16& value, + const VerificationStatus& verification_status, + bool invalidate_child_nodes = false, + bool invalidate_parent_nodes = false); + + // Same as |SetValueForTypeIfPossible()| but the type is supplied in the + // corresponding string representation. + bool SetValueForTypeIfPossible(const std::string& type_name, + const base::string16& value, + const VerificationStatus& verification_status, + bool invalidate_child_nodes = false, + bool invalidate_parent_nodes = false); + + // Convenience method to get the value of |type|. + // Returns an empty string if |type| is not supported. + base::string16 GetValueForType(const ServerFieldType& type) const; + + // Convenience method to get the value of |type| identified by its string + // representation name. Returns an empty string if |type| is not supported. + base::string16 GetValueForType(const std::string& type) const; + + // Convenience method to get the verification status of |type|. + // Returns |VerificationStatus::kNoStatus| if |type| is not supported. + VerificationStatus GetVerificationStatusForType( + const ServerFieldType& type) const; + + // Convenience method to get the verification status of |type| identified by + // its name. Returns |VerificationStatus::kNoStatus| if |type| is not + // supported. + VerificationStatus GetVerificationStatusForType( + const std::string& type) const; + + // Get the value and status of a |type|, + // Returns false if the |type| is not supported by the structure. + // The method returns |value_| and |validation_status_| of the current node if + // its |storage_type_| is |type| or if + // |ConvertAndSetTheValueForAdditionalFieldTypeName()| supports setting + // |type|. Otherwise, the call is delegated recursively to the node's + // children. Returns false if the neither the node or one of its ancestors + // supports |type|. + bool GetValueAndStatusForTypeIfPossible(const ServerFieldType& type, + base::string16* value, + VerificationStatus* status) const; + + // Get the value and status of a |type| identified by its name. + // Returns false if the |type| is not supported by the structure. + bool GetValueAndStatusForTypeIfPossible(const std::string& type_name, + base::string16* value, + VerificationStatus* status) const; + + // Returns true if the |value| and |verification_status| were successfully + // unset for |type|. + bool UnsetValueForTypeIfSupported(const ServerFieldType& type); + + // Parses |value_| to assign values to the subcomponents. + // The method uses 3 stages: + // + // * Use |ParseValueAndAssignSubcomponentsByMethod()|. This stage exists + // to catch special cases and may fail. The method is virtual and can be + // implemented on the type level. + // + // * Use |ParseValueAndAssignSubcomponentsByExpressions()|. This stage uses a + // list of regular expressions acquired by the virtual method + // |GetParseExpressionsByRelevance()|. This stage my fail. + // + // * Use |ParseValueAndAssignSubcomponentsByFallbackMethod()| as the last + // resort to parse |value_|. This method must produce a valid result. + void ParseValueAndAssignSubcomponents(); + + // This methods populated the unassigned entries in the subtree of this node + // by either parsing unknown values for subcomponents from their parents, or + // vice versa, formatting unknown values from known subcomponents. The method + // is virtual and can be reimplemented on the type level. + virtual void RecursivelyCompleteTree(); + + // Completes the full tree by calling |RecursivelyCompleteTree()| starting + // form the root node. Returns true if the completion was successful. + bool CompleteFullTree(); + + // Checks if a tree is completable in the sense that there are no conflicting + // observed or verified types. This means that there is not more than one + // observed or verified node on any root-to-leaf path in the tree. + bool IsTreeCompletable(); + + // Recursively adds the supported types to the set. Calls + // |GetAdditionalSupportedFieldTypes()| to add field types. + void GetSupportedTypes(ServerFieldTypeSet* supported_types) const; + + // Adds the additional supported field types to |supported_types|. + // The method should DCHECK that the added types are not part of the set yet. + virtual void GetAdditionalSupportedFieldTypes( + ServerFieldTypeSet* supported_types) const {} + + // Unassigns all nodes with parsed or formatted values. + void UnsetParsedAndFormattedValuesInEntireTree(); + + // Unassigns all nodes with parsed or formatted values. + void RecursivelyUnsetParsedAndFormattedValues(); + +#ifdef UNIT_TEST + // Initiates the formatting of the values from the subcomponents. + void FormatValueFromSubcomponentsForTesting() { + FormatValueFromSubcomponents(); + } + + // Returns the best format string for testing. + base::string16 GetBestFormatStringForTesting() { + return GetBestFormatString(); + } + + // Returns the parse expressions by relevance for testing. + std::vector<const RE2*> GetParseExpressionsByRelevanceForTesting() { + return GetParseExpressionsByRelevance(); + } + + // Returns a reference to the root node of the tree for testing. + AddressComponent& GetRootNodeForTesting() { return GetRootNode(); } + + // Replaces placeholder values in the best format string with the + // corresponding values. + base::string16 GetReplacedPlaceholderTypesWithValuesForTesting() const { + return ReplacePlaceholderTypesWithValues(GetBestFormatString()); + } + + // Returns a vector containing the |storage_types_| of all direct + // subcomponents. + std::vector<ServerFieldType> GetSubcomponentTypesForTesting() const { + return GetSubcomponentTypes(); + } + +#endif + + protected: + // Returns a vector containing the |storage_types_| of all direct + // subcomponents. + std::vector<ServerFieldType> GetSubcomponentTypes() const; + + // Heuristic method to get the best suited format string. + // This method is virtual and can be reimplemented for each type. + virtual base::string16 GetBestFormatString() const; + + // Returns pointers to regular expressions sorted by their relevance. + // This method is virtual and can be reimplemented for each type. + virtual std::vector<const RE2*> GetParseExpressionsByRelevance() const; + + // Method to parse |value_| into the values of |subcomponents_|. The + // purpose of this method is to cover special cases. This method returns true + // on success and is allowed to fail. On failure, the |subcomponents_| are not + // altered. + virtual bool ParseValueAndAssignSubcomponentsByMethod(); + + // This method parses |value_| to assign values to the subcomponents. + // The method is virtual and can be reimplemented per type. + // It must succeed. + virtual void ParseValueAndAssignSubcomponentsByFallbackMethod(); + + // This method is used to set the value given by a type different than the + // storage type. It must implement the conversion logic specific to each type. + // It returns true if conversion logic exists and the type can be set. + virtual bool ConvertAndSetValueForAdditionalFieldTypeName( + const std::string& field_type_name, + const base::string16& value, + const VerificationStatus& status); + + // This method is used to retrieve the value for a supported field type + // different from the storage type. It must implement the conversion logic + // specific to each type. It returns true if the type is supported and the + // value can be written back to value. + // The method must handle |nullptr|s for both the value and status. + virtual bool ConvertAndGetTheValueForAdditionalFieldTypeName( + const std::string& field_type_name, + base::string16* value) const; + + // Clears all parsed and formatted values. + void ClearAllParsedAndFormattedValues(); + + private: + // Returns a reference to the constant root node of the tree. + const AddressComponent& GetRootNode() const; + + // Returns a reference to the root node of the tree. + AddressComponent& GetRootNode(); + + // Unsets the node and all of its children. + void UnsetAddressComponentAndItsSubcomponents(); + + // Unsets the children of a node. + void UnsetSubcomponents(); + + // Determines the |value_| from the values of the subcomponents by using the + // most suitable format string determined by |GetBestFormatString()|. + void FormatValueFromSubcomponents(); + + // Replaces placeholder values with the corresponding values. + base::string16 ReplacePlaceholderTypesWithValues( + const base::string16& format) const; + + // Replaces placeholder values with the corresponding values. + base::string16 ReplacePlaceholderTypesWithValuesRegexVersion( + const base::string16& format) const; + + // This method uses regular expressions acquired by + // |GetParseExpressionsByRelevance| to parse |value_| into the values of the + // subcomponents. Returns true on success and is allowed to fail. + bool ParseValueAndAssignSubcomponentsByExpressions(); + + // Returns the maximum number of components with assigned values on the path + // from the component to a leaf node. + int MaximumNumberOfAssignedAddressComponentsOnNodeToLeafPaths() const; + + // The unstructured value of this component. + base::Optional<base::string16> value_; + + // The verification status of |value_| indicates the certainty of the value + // to be correct. + VerificationStatus value_verification_status_; + + // The storable Autofill type of the component. + const ServerFieldType storage_type_; + + // A vector of pointers to the subcomponents. + std::vector<AddressComponent*> subcomponents_; + + // A pointer to the parent node. It is set to nullptr if the node is the root + // node of the AddressComponent tree. + AddressComponent* const parent_; +}; + +} // namespace structured_address + +} // namespace autofill +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_DATA_MODEL_AUTOFILL_STRUCTURED_ADDRESS_COMPONENT_H_
diff --git a/components/autofill/core/browser/data_model/autofill_structured_address_component_unittest.cc b/components/autofill/core/browser/data_model/autofill_structured_address_component_unittest.cc new file mode 100644 index 0000000..a585776 --- /dev/null +++ b/components/autofill/core/browser/data_model/autofill_structured_address_component_unittest.cc
@@ -0,0 +1,1109 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/data_model/autofill_structured_address_component.h" + +#include <stddef.h> +#include <map> +#include <string> +#include <vector> + +#include "base/strings/utf_string_conversions.h" +#include "base/test/gtest_util.h" +#include "components/autofill/core/browser/autofill_type.h" +#include "components/autofill/core/browser/data_model/autofill_structured_address_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::ASCIIToUTF16; + +namespace autofill { +namespace structured_address { + +// Creates an atomic name component for testing purposes. +class TestAtomicFirstNameAddressComponent : public AddressComponent { + public: + TestAtomicFirstNameAddressComponent() + : TestAtomicFirstNameAddressComponent(nullptr) {} + explicit TestAtomicFirstNameAddressComponent(AddressComponent* parent) + : AddressComponent(NAME_FIRST, parent) {} +}; + +class TestAtomicMiddleNameAddressComponent : public AddressComponent { + public: + TestAtomicMiddleNameAddressComponent() + : TestAtomicMiddleNameAddressComponent(nullptr) {} + explicit TestAtomicMiddleNameAddressComponent(AddressComponent* parent) + : AddressComponent(NAME_MIDDLE, parent) {} + + void GetAdditionalSupportedFieldTypes( + ServerFieldTypeSet* supported_types) const override { + DCHECK(supported_types->find(NAME_MIDDLE_INITIAL) == + supported_types->end()); + supported_types->insert(NAME_MIDDLE_INITIAL); + } + + bool ConvertAndSetValueForAdditionalFieldTypeName( + const std::string& field_type_name, + const base::string16& value, + const VerificationStatus& status) override { + if (field_type_name == AutofillType(NAME_MIDDLE_INITIAL).ToString()) { + SetValue(value, status); + return true; + } + return false; + } + + bool ConvertAndGetTheValueForAdditionalFieldTypeName( + const std::string& field_type_name, + base::string16* value) const override { + if (field_type_name == AutofillType(NAME_MIDDLE_INITIAL).ToString()) { + if (value) { + *value = GetValue().substr(0, 1); + } + return true; + } + return false; + } +}; + +class TestAtomicLastNameAddressComponent : public AddressComponent { + public: + TestAtomicLastNameAddressComponent() + : TestAtomicLastNameAddressComponent(nullptr) {} + explicit TestAtomicLastNameAddressComponent(AddressComponent* parent) + : AddressComponent(NAME_LAST, parent) {} +}; + +// Creates a compound name for testing purposes. +class TestCompoundNameAddressComponent : public AddressComponent { + public: + TestCompoundNameAddressComponent() + : TestCompoundNameAddressComponent(nullptr) {} + explicit TestCompoundNameAddressComponent(AddressComponent* parent) + : AddressComponent(NAME_FULL, + parent, + {&first_name_, &middle_name_, &last_name_}) {} + + AddressComponent* GetFirstNameSubComponentForTesting() { + return &first_name_; + } + + private: + TestAtomicFirstNameAddressComponent first_name_{this}; + TestAtomicMiddleNameAddressComponent middle_name_{this}; + TestAtomicLastNameAddressComponent last_name_{this}; +}; + +// Creates a compound name for testing purposes that uses a method for parsing. +class TestCompoundNameMethodParsedAddressComponent : public AddressComponent { + public: + TestCompoundNameMethodParsedAddressComponent() + : TestCompoundNameMethodParsedAddressComponent(nullptr) {} + explicit TestCompoundNameMethodParsedAddressComponent( + AddressComponent* parent) + : AddressComponent(NAME_FULL, + parent, + {&first_name_, &middle_name_, &last_name_}) {} + + bool ParseValueAndAssignSubcomponentsByMethod() override { + // Assigns everything to the first name. + first_name_.SetValue(GetValue(), VerificationStatus::kParsed); + return true; + } + + private: + TestAtomicFirstNameAddressComponent first_name_{this}; + TestAtomicMiddleNameAddressComponent middle_name_{this}; + TestAtomicLastNameAddressComponent last_name_{this}; +}; + +// Creates a compound name for testing purposes that uses an expression to +// parse. +class TestCompoundNameExpressionParsedAddressComponent + : public AddressComponent { + public: + TestCompoundNameExpressionParsedAddressComponent() + : TestCompoundNameExpressionParsedAddressComponent(nullptr) { + expression1_ = + BuildExpressionFromPattern("(?P<NAME_FULL>(?P<NAME_MIDDLE>\\d*))"); + expression2_ = + BuildExpressionFromPattern("(?P<NAME_FULL>(?P<NAME_LAST>.*))"); + } + explicit TestCompoundNameExpressionParsedAddressComponent( + AddressComponent* parent) + : AddressComponent(NAME_FULL, + parent, + {&first_name_, &middle_name_, &last_name_}) {} + + std::vector<const RE2*> GetParseExpressionsByRelevance() const override { + // The first two expressions will fail and the last one will be + // successful. + return {nullptr, expression1_.get(), expression2_.get()}; + } + + private: + std::unique_ptr<const RE2> expression1_; + std::unique_ptr<const RE2> expression2_; + TestAtomicFirstNameAddressComponent first_name_{this}; + TestAtomicMiddleNameAddressComponent middle_name_{this}; + TestAtomicLastNameAddressComponent last_name_{this}; +}; + +// Creates a compound name with a custom format for testing purposes. +class TestCompoundNameCustomFormatAddressComponent : public AddressComponent { + public: + TestCompoundNameCustomFormatAddressComponent() + : TestCompoundNameCustomFormatAddressComponent(nullptr) {} + explicit TestCompoundNameCustomFormatAddressComponent( + AddressComponent* parent) + : AddressComponent(NAME_FULL, + parent, + {&first_name, &middle_name, &last_name}) {} + + // Introduces a custom format with a leading last name. + base::string16 GetBestFormatString() const override { + return base::ASCIIToUTF16("${NAME_LAST}, ${NAME_FIRST}"); + } + + private: + TestAtomicFirstNameAddressComponent first_name{this}; + TestAtomicMiddleNameAddressComponent middle_name{this}; + TestAtomicLastNameAddressComponent last_name{this}; +}; + +// Creates a compound name with a custom format with unsupported token. +class TestCompoundNameCustomFormatWithUnsupportedTokenAddressComponent + : public AddressComponent { + public: + TestCompoundNameCustomFormatWithUnsupportedTokenAddressComponent() + : TestCompoundNameCustomFormatWithUnsupportedTokenAddressComponent( + nullptr) {} + explicit TestCompoundNameCustomFormatWithUnsupportedTokenAddressComponent( + AddressComponent* parent) + : AddressComponent(NAME_FULL, + parent, + {&first_name, &middle_name, &last_name}) {} + + // Introduce a custom format with a leading last name. + base::string16 GetBestFormatString() const override { + return base::ASCIIToUTF16("${NAME_LAST}, ${NAME_FIRST} ${NOT_SUPPORTED}"); + } + + private: + TestAtomicFirstNameAddressComponent first_name{this}; + TestAtomicMiddleNameAddressComponent middle_name{this}; + TestAtomicLastNameAddressComponent last_name{this}; +}; + +class TestAtomicTitleAddressComponent : public AddressComponent { + public: + TestAtomicTitleAddressComponent() + : TestAtomicTitleAddressComponent(nullptr) {} + explicit TestAtomicTitleAddressComponent(AddressComponent* parent) + : AddressComponent(NAME_HONORIFIC_PREFIX, parent) {} +}; + +// Creates a fictional compound component with sub- and sub subcomponents. +class TestCompoundNameWithTitleAddressComponent : public AddressComponent { + public: + TestCompoundNameWithTitleAddressComponent() + : TestCompoundNameWithTitleAddressComponent(nullptr) {} + explicit TestCompoundNameWithTitleAddressComponent(AddressComponent* parent) + : AddressComponent(CREDIT_CARD_NAME_FULL, parent, {&title, &full_name}) {} + + private: + TestAtomicTitleAddressComponent title{this}; + TestCompoundNameAddressComponent full_name{this}; +}; + +// Creates a tree that is not proper in the sense that it contains the same type +// multiple times. +class TestNonProperFirstNameAddressComponent : public AddressComponent { + public: + TestNonProperFirstNameAddressComponent() + : TestNonProperFirstNameAddressComponent(nullptr) {} + explicit TestNonProperFirstNameAddressComponent(AddressComponent* parent) + : AddressComponent(NAME_FIRST, parent, {&second_name_first_node_}) {} + + private: + TestAtomicFirstNameAddressComponent second_name_first_node_; +}; + +// Tests that the destructor does not crash +TEST(AutofillStructuredAddressAddressComponent, ConstructAndDestruct) { + AddressComponent* component = new AddressComponent(NAME_FULL, nullptr); + delete component; + EXPECT_TRUE(true); +} + +// Tests that a non-proper AddressComponent tree fails a DCHECK for +// |GetSupportedTypes()|. +TEST(AutofillStructuredAddressAddressComponent, + TestNonProperTreeDcheckFailure) { + TestNonProperFirstNameAddressComponent non_proper_compound; + ServerFieldTypeSet supported_tpyes; + EXPECT_DCHECK_DEATH(non_proper_compound.GetSupportedTypes(&supported_tpyes)); +} + +// Tests getting the root node. +TEST(AutofillStructuredAddressAddressComponent, TestGetRootNode) { + TestCompoundNameAddressComponent compound_component; + + // The root node should return the root node. + EXPECT_EQ(&compound_component, &(compound_component.GetRootNodeForTesting())); + + // Get a pointer to a subcomponent, verify that it is not the root node and + // check that it successfully retrieves the root node. + AddressComponent* first_name_subcomponent_ptr = + compound_component.GetFirstNameSubComponentForTesting(); + EXPECT_NE(&compound_component, first_name_subcomponent_ptr); + EXPECT_EQ(&compound_component, + &(first_name_subcomponent_ptr->GetRootNodeForTesting())); +} + +// Tests that additional field types are correctly retrieved. +TEST(AutofillStructuredAddressAddressComponent, TestGetSupportedFieldType) { + ServerFieldTypeSet field_type_set; + + TestAtomicFirstNameAddressComponent first_name_component; + TestAtomicMiddleNameAddressComponent middle_name_component; + + // The first name does not have an additional supported field type. + first_name_component.GetAdditionalSupportedFieldTypes(&field_type_set); + EXPECT_EQ(field_type_set, ServerFieldTypeSet({})); + + // The middle name supports an iniital. + middle_name_component.GetAdditionalSupportedFieldTypes(&field_type_set); + EXPECT_EQ(field_type_set, ServerFieldTypeSet({NAME_MIDDLE_INITIAL})); +} + +// Tests setting an additional field type. +TEST(AutofillStructuredAddressAddressComponent, TestSetFieldTypeValue) { + TestCompoundNameAddressComponent compound_name; + EXPECT_TRUE(compound_name.SetValueForTypeIfPossible( + NAME_MIDDLE_INITIAL, base::UTF8ToUTF16("M"), + VerificationStatus::kObserved)); + + EXPECT_EQ(compound_name.GetValueForType(NAME_MIDDLE), base::UTF8ToUTF16("M")); +} + +// Tests retrieving an additional field type. +TEST(AutofillStructuredAddressAddressComponent, TestGetFieldTypeValue) { + TestCompoundNameAddressComponent compound_name; + EXPECT_TRUE(compound_name.SetValueForTypeIfPossible( + NAME_MIDDLE, base::UTF8ToUTF16("Middle"), VerificationStatus::kObserved)); + + EXPECT_EQ(compound_name.GetValueForType(NAME_MIDDLE_INITIAL), + base::UTF8ToUTF16("M")); + EXPECT_EQ(compound_name.GetVerificationStatusForType(NAME_MIDDLE_INITIAL), + VerificationStatus::kObserved); +} + +// Tests adding all supported types to the set. +TEST(AutofillStructuredAddressAddressComponent, TestGetSupportedTypes) { + ServerFieldTypeSet field_type_set; + + TestAtomicFirstNameAddressComponent first_name_component; + TestAtomicMiddleNameAddressComponent middle_name_component; + TestCompoundNameAddressComponent compound_name; + + // The first name only supports NAME_FIRST. + first_name_component.GetSupportedTypes(&field_type_set); + EXPECT_EQ(field_type_set, ServerFieldTypeSet({NAME_FIRST})); + + // The middle name supports an initial. + field_type_set.clear(); + middle_name_component.GetSupportedTypes(&field_type_set); + EXPECT_EQ(field_type_set, + ServerFieldTypeSet({NAME_MIDDLE, NAME_MIDDLE_INITIAL})); + + // Verify that all types are added correctly in a compound structure. + field_type_set.clear(); + compound_name.GetSupportedTypes(&field_type_set); + EXPECT_EQ(field_type_set, + ServerFieldTypeSet({NAME_MIDDLE, NAME_MIDDLE_INITIAL, NAME_FIRST, + NAME_LAST, NAME_FULL})); +} + +// Tests the comparison of thw atoms of the same type. +TEST(AutofillStructuredAddressAddressComponent, TestComparisonOperator_Atom) { + AddressComponent left(NAME_FIRST); + AddressComponent right(NAME_FIRST); + + left.SetValue(base::UTF8ToUTF16("some value"), VerificationStatus::kParsed); + right.SetValue(base::UTF8ToUTF16("some other value"), + VerificationStatus::kFormatted); + EXPECT_NE(left.GetValue(), right.GetValue()); + EXPECT_NE(left.GetVerificationStatus(), right.GetVerificationStatus()); + + EXPECT_FALSE(left == right); + EXPECT_TRUE(left != right); + + right.SetValue(base::UTF8ToUTF16("some value"), VerificationStatus::kParsed); + + EXPECT_TRUE(left == right); + EXPECT_FALSE(left != right); +} + +// Tests comparison of two different types. +TEST(AutofillStructuredAddressAddressComponent, + TestComparisonOperator_DifferentTypes) { + AddressComponent type_a1(NAME_FIRST); + AddressComponent type_a2(NAME_FIRST); + AddressComponent type_b(NAME_LAST); + + EXPECT_TRUE(type_a1 == type_a2); + EXPECT_FALSE(type_a1 == type_b); +} + +// Tests the comparison with itself. +TEST(AutofillStructuredAddressAddressComponent, + TestComparisonOperator_SelfComparison) { + AddressComponent type_a(NAME_FIRST); + + EXPECT_TRUE(type_a == type_a); +} + +// Tests the comparison operator. +TEST(AutofillStructuredAddressAddressComponent, + TestComparisonOperator_Compound) { + TestCompoundNameAddressComponent left; + TestCompoundNameAddressComponent right; + + // Set left to a value and verify its state. + left.SetValueForTypeIfPossible(NAME_FULL, + base::UTF8ToUTF16("First Middle Last"), + VerificationStatus::kObserved); + EXPECT_TRUE(left.CompleteFullTree()); + EXPECT_EQ(left.GetValueForType(NAME_FULL), + base::UTF8ToUTF16("First Middle Last")); + EXPECT_EQ(left.GetValueForType(NAME_FIRST), base::UTF8ToUTF16("First")); + EXPECT_EQ(left.GetValueForType(NAME_MIDDLE), base::UTF8ToUTF16("Middle")); + EXPECT_EQ(left.GetValueForType(NAME_LAST), base::UTF8ToUTF16("Last")); + EXPECT_EQ(left.GetVerificationStatusForType(NAME_FULL), + VerificationStatus::kObserved); + EXPECT_EQ(left.GetVerificationStatusForType(NAME_FIRST), + VerificationStatus::kParsed); + EXPECT_EQ(left.GetVerificationStatusForType(NAME_LAST), + VerificationStatus::kParsed); + EXPECT_EQ(left.GetVerificationStatusForType(NAME_MIDDLE), + VerificationStatus::kParsed); + + // Set right to another value and verify its state. + right.SetValueForTypeIfPossible(NAME_FULL, + base::UTF8ToUTF16("The Dark Knight"), + VerificationStatus::kUserVerified); + EXPECT_TRUE(right.CompleteFullTree()); + EXPECT_EQ(right.GetValueForType(NAME_FULL), + base::UTF8ToUTF16("The Dark Knight")); + EXPECT_EQ(right.GetValueForType(NAME_FIRST), base::UTF8ToUTF16("The")); + EXPECT_EQ(right.GetValueForType(NAME_MIDDLE), base::UTF8ToUTF16("Dark")); + EXPECT_EQ(right.GetValueForType(NAME_LAST), base::UTF8ToUTF16("Knight")); + EXPECT_EQ(right.GetVerificationStatusForType(NAME_FULL), + VerificationStatus::kUserVerified); + EXPECT_EQ(right.GetVerificationStatusForType(NAME_FIRST), + VerificationStatus::kParsed); + EXPECT_EQ(right.GetVerificationStatusForType(NAME_LAST), + VerificationStatus::kParsed); + EXPECT_EQ(right.GetVerificationStatusForType(NAME_MIDDLE), + VerificationStatus::kParsed); + + EXPECT_FALSE(left == right); + EXPECT_TRUE(left != right); + + // Set left to the same values as right and verify that it is now equal. + TestCompoundNameAddressComponent same_right; + same_right.SetValueForTypeIfPossible(NAME_FULL, + base::UTF8ToUTF16("The Dark Knight"), + VerificationStatus::kUserVerified); + EXPECT_TRUE(same_right.CompleteFullTree()); + + EXPECT_TRUE(right == same_right); + EXPECT_FALSE(right != same_right); + + // Change one subcomponent and verify that it is not equal anymore. + same_right.SetValueForTypeIfPossible(NAME_LAST, base::UTF8ToUTF16("Joker"), + VerificationStatus::kParsed); + EXPECT_TRUE(right != same_right); + EXPECT_FALSE(right == same_right); +} + +// Tests the assignment operator. +TEST(AutofillStructuredAddressAddressComponent, TestAssignmentOperator_Atom) { + AddressComponent left(NAME_FIRST); + AddressComponent right(NAME_FIRST); + + left.SetValue(base::UTF8ToUTF16("some value"), VerificationStatus::kParsed); + right.SetValue(base::UTF8ToUTF16("some other value"), + VerificationStatus::kFormatted); + EXPECT_FALSE(left == right); + + left.SetValue(base::UTF8ToUTF16("some other value"), + VerificationStatus::kFormatted); + EXPECT_TRUE(left == right); +} + +// Tests the assignment operator on a compound node. +TEST(AutofillStructuredAddressAddressComponent, + TestAssignmentOperator_Compound) { + TestCompoundNameAddressComponent left; + TestCompoundNameAddressComponent right; + + left.SetValueForTypeIfPossible(NAME_FULL, + base::UTF8ToUTF16("First Middle Last"), + VerificationStatus::kObserved); + left.RecursivelyCompleteTree(); + + right.SetValueForTypeIfPossible(NAME_FULL, + base::UTF8ToUTF16("The Dark Knight"), + VerificationStatus::kParsed); + right.RecursivelyCompleteTree(); + + EXPECT_FALSE(left == right); + + left = right; + EXPECT_TRUE(left == right); +} + +// Tests that self-assignment does not break things. +TEST(AutofillStructuredAddressAddressComponent, SelfAssignment) { + TestCompoundNameAddressComponent left; + + left.SetValueForTypeIfPossible(NAME_FULL, + base::UTF8ToUTF16("First Middle Last"), + VerificationStatus::kObserved); + left = *(&left); + + EXPECT_EQ(left.GetValueForType(NAME_FULL), + base::UTF8ToUTF16("First Middle Last")); +} + +// Tests that the correct storage types are returned. +TEST(AutofillStructuredAddressAddressComponent, GetStorageType) { + EXPECT_EQ(TestAtomicFirstNameAddressComponent().GetStorageType(), NAME_FIRST); + EXPECT_EQ(TestAtomicMiddleNameAddressComponent().GetStorageType(), + NAME_MIDDLE); + EXPECT_EQ(TestAtomicLastNameAddressComponent().GetStorageType(), NAME_LAST); + EXPECT_EQ(TestCompoundNameAddressComponent().GetStorageType(), NAME_FULL); +} + +// Tests that the correct storage type names are returned. +TEST(AutofillStructuredAddressAddressComponent, GetStorageTypeName) { + EXPECT_EQ(TestAtomicFirstNameAddressComponent().GetStorageTypeName(), + "NAME_FIRST"); + EXPECT_EQ(TestAtomicMiddleNameAddressComponent().GetStorageTypeName(), + "NAME_MIDDLE"); + EXPECT_EQ(TestAtomicLastNameAddressComponent().GetStorageTypeName(), + "NAME_LAST"); + EXPECT_EQ(TestCompoundNameAddressComponent().GetStorageTypeName(), + "NAME_FULL"); +} + +// Tests that the correct atomicity is returned. +TEST(AutofillStructuredAddressAddressComponent, GetAtomicity) { + EXPECT_TRUE(TestAtomicFirstNameAddressComponent().IsAtomic()); + EXPECT_TRUE(TestAtomicMiddleNameAddressComponent().IsAtomic()); + EXPECT_TRUE(TestAtomicLastNameAddressComponent().IsAtomic()); + EXPECT_FALSE(TestCompoundNameAddressComponent().IsAtomic()); +} + +// Tests directly setting and retrieving values. +TEST(AutofillStructuredAddressAddressComponent, DirectlyGetSetAndUnsetValue) { + base::string16 test_value = base::ASCIIToUTF16("test_value"); + + // Create an atomic structured component and verify its initial unset state + TestAtomicFirstNameAddressComponent first_name_component; + EXPECT_EQ(first_name_component.GetValue(), base::string16()); + EXPECT_FALSE(first_name_component.IsValueAssigned()); + EXPECT_EQ(first_name_component.GetVerificationStatus(), + VerificationStatus::kNoStatus); + + // Set the value and the verification status and verify the set state. + first_name_component.SetValue(test_value, VerificationStatus::kObserved); + EXPECT_EQ(first_name_component.GetValue(), test_value); + EXPECT_TRUE(first_name_component.IsValueAssigned()); + EXPECT_EQ(first_name_component.GetVerificationStatus(), + VerificationStatus::kObserved); + + // Unset the value and verify the unset state again. + first_name_component.UnsetValue(); + EXPECT_EQ(first_name_component.GetValue(), base::string16()); + EXPECT_FALSE(first_name_component.IsValueAssigned()); + EXPECT_EQ(first_name_component.GetVerificationStatus(), + VerificationStatus::kNoStatus); +} + +// Tests recursively setting and retrieving values. +TEST(AutofillStructuredAddressAddressComponent, + RecursivelySettingAndGettingValues) { + base::string16 test_value = base::ASCIIToUTF16("test_value"); + + // Create a compound component that has a child of type NAME_FIRST. + TestCompoundNameAddressComponent compound_component; + + // Set the value and verification status of a type not present in the tree and + // verify the failure. + bool success = compound_component.SetValueForTypeIfPossible( + ADDRESS_HOME_COUNTRY, test_value, VerificationStatus::kObserved); + EXPECT_FALSE(success); + + // Set the value and verification status of a type that is a subcomponent of + // the compound and verify the success. + EXPECT_TRUE(compound_component.SetValueForTypeIfPossible( + NAME_FIRST, test_value, VerificationStatus::kObserved)); + + // Retrieve the value and verification status, verify the success and + // retrieved values. + base::string16 retrieved_value; + VerificationStatus retrieved_status; + EXPECT_TRUE(compound_component.GetValueAndStatusForTypeIfPossible( + NAME_FIRST, &retrieved_value, &retrieved_status)); + EXPECT_EQ(retrieved_value, test_value); + EXPECT_EQ(retrieved_status, VerificationStatus::kObserved); + + // Retrieve the value of a non-existing type and verify the failure. + EXPECT_FALSE(compound_component.GetValueAndStatusForTypeIfPossible( + ADDRESS_HOME_COUNTRY, &retrieved_value, &retrieved_status)); +} + +// Tests retrieving the subcomponents types. +TEST(AutofillStructuredAddressAddressComponent, GetSubcomponentTypes) { + // Create a compound component that has the subcomponents + // NAME_FIRST, NAME_MIDDLE, NAME_LAST. + TestCompoundNameAddressComponent compound_component; + + // Get the subcomponent types and verify the expectation. + auto sub_component_types = + compound_component.GetSubcomponentTypesForTesting(); + std::vector<ServerFieldType> expected_types{NAME_FIRST, NAME_MIDDLE, + NAME_LAST}; + EXPECT_EQ(sub_component_types, expected_types); +} + +// Tests getting the best format string for an atom. +TEST(AutofillStructuredAddressAddressComponent, GetBestFormatString_ForAtom) { + TestAtomicFirstNameAddressComponent first_name_component; + EXPECT_EQ(first_name_component.GetBestFormatStringForTesting(), + base::UTF8ToUTF16("${NAME_FIRST}")); +} + +// Tests getting the best format string using the fallback mechanism. +TEST(AutofillStructuredAddressAddressComponent, + GetBestFormatString_WithFallback) { + // Create a compound component. + TestCompoundNameAddressComponent compound_component; + + // Verify the retrieved default format string against the expectation. + base::string16 expected_result = + ASCIIToUTF16("${NAME_FIRST} ${NAME_MIDDLE} ${NAME_LAST}"); + base::string16 actual_result = + compound_component.GetBestFormatStringForTesting(); + EXPECT_EQ(expected_result, actual_result); +} + +// Tests getting the best format string using the fallback mechanism. +TEST(AutofillStructuredAddressAddressComponent, + GetBestFormatString_WithCustomMethod) { + // Create a compound component. + TestCompoundNameCustomFormatAddressComponent compound_component; + + // Verify the retrieved custom format string against the expectation. + base::string16 expected_result = ASCIIToUTF16("${NAME_LAST}, ${NAME_FIRST}"); + base::string16 actual_result = + compound_component.GetBestFormatStringForTesting(); + EXPECT_EQ(expected_result, actual_result); +} + +// Tests formatting the unstructured value from the subcomponents with an +// unsupported token. +TEST(AutofillStructuredAddressAddressComponent, + FormatValueFromSubcomponents_UnsupportedToken) { + base::string16 first_name = ASCIIToUTF16("Winston"); + base::string16 middle_name = ASCIIToUTF16("O'Brien"); + base::string16 last_name = ASCIIToUTF16("Smith"); + + // Create a compound component and set the values. + TestCompoundNameCustomFormatWithUnsupportedTokenAddressComponent + compound_component; + compound_component.SetValueForTypeIfPossible( + NAME_FIRST, first_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_MIDDLE, middle_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_LAST, last_name, VerificationStatus::kUserVerified); + + compound_component.FormatValueFromSubcomponentsForTesting(); + + base::string16 expected_value = + ASCIIToUTF16("Smith, Winston ${NOT_SUPPORTED}"); + base::string16 actual_value = compound_component.GetValue(); + + EXPECT_EQ(expected_value, actual_value); +} + +// Tests formatting the unstructured value from the subcomponents. +TEST(AutofillStructuredAddressAddressComponent, FormatValueFromSubcomponents) { + base::string16 first_name = ASCIIToUTF16("Winston"); + base::string16 middle_name = ASCIIToUTF16("O'Brien"); + base::string16 last_name = ASCIIToUTF16("Smith"); + + // Create a compound component and set the values. + TestCompoundNameAddressComponent compound_component; + compound_component.SetValueForTypeIfPossible( + NAME_FIRST, first_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_MIDDLE, middle_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_LAST, last_name, VerificationStatus::kUserVerified); + + compound_component.FormatValueFromSubcomponentsForTesting(); + + base::string16 expected_value = ASCIIToUTF16("Winston O'Brien Smith"); + base::string16 actual_value = compound_component.GetValue(); + + EXPECT_EQ(expected_value, actual_value); +} + +// Tests that formatted values are correctly trimmed. +TEST(AutofillStructuredAddressAddressComponent, + FormatAndTrimmValueFromSubcomponents) { + base::string16 first_name = ASCIIToUTF16(""); + base::string16 middle_name = ASCIIToUTF16("O'Brien "); + base::string16 last_name = ASCIIToUTF16("Smith"); + // Create a compound component. + TestCompoundNameAddressComponent compound_component; + + // Set the values of the components. + compound_component.SetValueForTypeIfPossible( + NAME_FIRST, first_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_MIDDLE, middle_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_LAST, last_name, VerificationStatus::kUserVerified); + + compound_component.FormatValueFromSubcomponentsForTesting(); + + // Expect that the leading whitespace due to the missing first name and the + // double white spaces after the middle name are correctly trimmed. + base::string16 expected_value = ASCIIToUTF16("O'Brien Smith"); + base::string16 actual_value = compound_component.GetValue(); + + EXPECT_EQ(expected_value, actual_value); +} + +TEST(AutofillStructuredAddressAddressComponent, + TestEquivalenceOfReplacePlaceholderImplementations) { + base::string16 first_name = ASCIIToUTF16("Winston"); + base::string16 middle_name = ASCIIToUTF16("O'Brien"); + base::string16 last_name = ASCIIToUTF16("Smith"); + // Create a compound component. + TestCompoundNameCustomFormatAddressComponent compound_component; + + // Set the values of the subcomponents. + compound_component.SetValueForTypeIfPossible( + NAME_FIRST, first_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_MIDDLE, middle_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_LAST, last_name, VerificationStatus::kUserVerified); +} + +// Tests the formatting of the unstructured value from the components with a +// type-specific format string. +TEST(AutofillStructuredAddressAddressComponent, + FormatValueFromSubcomponentsWithTypeSpecificFormat) { + base::string16 first_name = ASCIIToUTF16("Winston"); + base::string16 middle_name = ASCIIToUTF16("O'Brien"); + base::string16 last_name = ASCIIToUTF16("Smith"); + // Create a compound component. + TestCompoundNameCustomFormatAddressComponent compound_component; + + // Set the values of the subcomponents. + compound_component.SetValueForTypeIfPossible( + NAME_FIRST, first_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_MIDDLE, middle_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_LAST, last_name, VerificationStatus::kUserVerified); + + // Format the compound and verify the expectation. + compound_component.FormatValueFromSubcomponentsForTesting(); + base::string16 expected_value = ASCIIToUTF16("Smith, Winston"); + base::string16 actual_value = compound_component.GetValue(); + + EXPECT_EQ(expected_value, actual_value); +} + +// Tests parsing of an empty value. Because, that's why. +TEST(AutofillStructuredAddressAddressComponent, + TestParseValueAndAssignSubcomponentsByFallbackMethod_EmptyString) { + TestCompoundNameAddressComponent compound_component; + compound_component.SetValue(base::string16(), VerificationStatus::kObserved); + compound_component.ParseValueAndAssignSubcomponents(); + + EXPECT_EQ(compound_component.GetValue(), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), base::string16()); +} + +// Tests parsing using a defined method. +TEST(AutofillStructuredAddressAddressComponent, + TestParseValueAndAssignSubcomponentsByMethod) { + TestCompoundNameMethodParsedAddressComponent compound_component; + compound_component.SetValue(ASCIIToUTF16("Dr. Strangelove"), + VerificationStatus::kObserved); + compound_component.ParseValueAndAssignSubcomponents(); + + EXPECT_EQ(compound_component.GetValue(), ASCIIToUTF16("Dr. Strangelove")); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), + ASCIIToUTF16("Dr. Strangelove")); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), base::string16()); +} + +// Tests parsing using a defined method. +TEST(AutofillStructuredAddressAddressComponent, + TestParseValueAndAssignSubcomponentsByExpression) { + TestCompoundNameExpressionParsedAddressComponent compound_component; + compound_component.SetValue(ASCIIToUTF16("Dr. Strangelove"), + VerificationStatus::kObserved); + compound_component.ParseValueAndAssignSubcomponents(); + + EXPECT_EQ(compound_component.GetValue(), ASCIIToUTF16("Dr. Strangelove")); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), + ASCIIToUTF16("Dr. Strangelove")); +} + +// Go nuclear and parse the value of an atomic component. +TEST(AutofillStructuredAddressAddressComponent, + TestParseValueAndAssignSubcomponentsByFallbackMethod_Atom) { + TestAtomicFirstNameAddressComponent atomic_component; + atomic_component.SetValue(base::UTF8ToUTF16("Dangerzone"), + VerificationStatus::kObserved); + atomic_component.ParseValueAndAssignSubcomponents(); + + // The parsing should not crash the browser and keep the initial value intact. + EXPECT_EQ(base::UTF8ToUTF16("Dangerzone"), atomic_component.GetValue()); +} + +// Tests the fallback method to parse a value into its components if there are +// more space-separated tokens than components. +TEST(AutofillStructuredAddressAddressComponent, + TestParseValueAndAssignSubcomponentsByFallbackMethod) { + base::string16 full_name = ASCIIToUTF16("Winston O'Brien Hammer Smith"); + + // Create a compound component, set the value and parse the value of the + // subcomponents. + TestCompoundNameAddressComponent compound_component; + compound_component.SetValueForTypeIfPossible( + NAME_FULL, full_name, VerificationStatus::kUserVerified); + compound_component.ParseValueAndAssignSubcomponents(); + + // Define the expectations, and verify the expectation. + base::string16 first_name = ASCIIToUTF16("Winston"); + base::string16 middle_name = ASCIIToUTF16("O'Brien"); + base::string16 last_name = ASCIIToUTF16("Hammer Smith"); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), first_name); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), middle_name); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), last_name); +} + +// Tests the fallback method to parse a value into its components if there are +// less space-separated tokens than components. +TEST(AutofillStructuredAddressAddressComponent, + ParseValueAndAssignSubcomponentsByFallbackMethod_WithFewTokens) { + base::string16 full_name = ASCIIToUTF16("Winston"); + + // Create a compound component and assign a value. + TestCompoundNameAddressComponent compound_component; + compound_component.SetValueForTypeIfPossible( + NAME_FULL, full_name, VerificationStatus::kUserVerified); + + // Parse the full name into its components by using the fallback method + compound_component.ParseValueAndAssignSubcomponents(); + + // Verify the expectation. + base::string16 first_name = ASCIIToUTF16("Winston"); + base::string16 middle_name = ASCIIToUTF16(""); + base::string16 last_name = ASCIIToUTF16(""); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), first_name); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), middle_name); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), last_name); +} + +// Tests that a tree is regarded completable if and only if there if the +// maximum number of assigned nodes on a path from the root node to a leaf is +// exactly one. +TEST(AutofillStructuredAddressAddressComponent, IsTreeCompletable) { + // Some values. + base::string16 first_name = ASCIIToUTF16("Winston"); + base::string16 middle_name = ASCIIToUTF16("O'Brien"); + base::string16 full_name = ASCIIToUTF16("Winston O'Brien Smith"); + + // Create a compound component. + TestCompoundNameAddressComponent compound_component; + + // This tree is not completable because it has not a single assigned node. + EXPECT_FALSE(compound_component.IsTreeCompletable()); + + // Set the first name node of the tree. + compound_component.SetValueForTypeIfPossible( + NAME_FIRST, first_name, VerificationStatus::kUserVerified); + + // The tree should be completable because there is exactly one assigned node. + EXPECT_TRUE(compound_component.IsTreeCompletable()); + + // Set the middle-name node of the tree. + compound_component.SetValueForTypeIfPossible( + NAME_MIDDLE, middle_name, VerificationStatus::kUserVerified); + + // The tree should still be completable because the first and middle name are + // siblings and not in a direct line. + EXPECT_TRUE(compound_component.IsTreeCompletable()); + + // Set the full name node of the tree. + compound_component.SetValueForTypeIfPossible( + NAME_FULL, full_name, VerificationStatus::kUserVerified); + + // Now, the tree is not completable anymore because there are multiple + // assigned values on a path from the root to a leaf. + EXPECT_FALSE(compound_component.IsTreeCompletable()); + EXPECT_FALSE(compound_component.CompleteFullTree()); +} + +// Tests that the tree is completed successfully from the root node down to the +// leafs. +TEST(AutofillStructuredAddressAddressComponent, TreeCompletion_TopToBottom) { + // Some values. + base::string16 first_name = ASCIIToUTF16("Winston"); + base::string16 middle_name = ASCIIToUTF16("O'Brien"); + base::string16 last_name = ASCIIToUTF16("Smith"); + base::string16 full_name = ASCIIToUTF16("Winston O'Brien Smith"); + + // Create a compound component and set the value of the root node. + TestCompoundNameAddressComponent compound_component; + compound_component.SetValueForTypeIfPossible( + NAME_FULL, full_name, VerificationStatus::kUserVerified); + + // Verify that the are subcomponents empty. + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), base::string16()); + + // Complete the tree. + EXPECT_TRUE(compound_component.CompleteFullTree()); + + // Verify that the values for the subcomponents have been successfully parsed. + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), first_name); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), middle_name); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), last_name); +} + +// Tests that the tree is completed successfully from leaf nodes to the root. +TEST(AutofillStructuredAddressAddressComponent, TreeCompletion_BottomToTop) { + // Some values. + base::string16 first_name = ASCIIToUTF16("Winston"); + base::string16 middle_name = ASCIIToUTF16("O'Brien"); + base::string16 last_name = ASCIIToUTF16("Smith"); + base::string16 full_name = ASCIIToUTF16("Winston O'Brien Smith"); + + // Create a compound component and set the value of the first, middle and last + // name. + TestCompoundNameAddressComponent compound_component; + compound_component.SetValueForTypeIfPossible( + NAME_FIRST, first_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_MIDDLE, middle_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_LAST, last_name, VerificationStatus::kUserVerified); + + // Verify that the root node is empty. + EXPECT_EQ(compound_component.GetValueForType(NAME_FULL), base::string16()); + + // Complete the tree. + compound_component.CompleteFullTree(); + + // Verify that the value for the root node was successfully formatted. + EXPECT_EQ(compound_component.GetValueForType(NAME_FULL), full_name); +} + +// Tests that the tree is completed successfully both upwards and downwards when +// a node with both subcomponents and a parent is set. +TEST(AutofillStructuredAddressAddressComponent, TreeCompletion_ToTopAndBottom) { + // Define Some values. + base::string16 title = ASCIIToUTF16("Dr."); + base::string16 first_name = ASCIIToUTF16("Winston"); + base::string16 middle_name = ASCIIToUTF16("O'Brien"); + base::string16 last_name = ASCIIToUTF16("Smith"); + base::string16 full_name = ASCIIToUTF16("Winston O'Brien Smith"); + base::string16 full_name_with_title = + ASCIIToUTF16("Dr. Winston O'Brien Smith"); + + // Create a compound component. + TestCompoundNameWithTitleAddressComponent compound_component; + + // Set the value of the root node. + compound_component.SetValueForTypeIfPossible( + NAME_FULL, full_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_HONORIFIC_PREFIX, title, VerificationStatus::kUserVerified); + + // Verify that the are subcomponents empty. + // CREDIT_CARD_NAME_FULL is a fictive type containing a title and a full name. + EXPECT_EQ(compound_component.GetValueForType(CREDIT_CARD_NAME_FULL), + base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), base::string16()); + + // Complete the tree. + compound_component.CompleteFullTree(); + + // Verify that the values for the subcomponents have been successfully parsed + // and the parent node was probably formatted. + EXPECT_EQ(compound_component.GetValueForType(CREDIT_CARD_NAME_FULL), + full_name_with_title); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), first_name); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), middle_name); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), last_name); +} + +// Test that values are invalidated correctly. +TEST(AutofillStructuredAddressAddressComponent, + TestSettingsValuesWithInvalidation) { + // Define Some values. + base::string16 title = ASCIIToUTF16("Dr."); + base::string16 first_name = ASCIIToUTF16("Winston"); + base::string16 middle_name = ASCIIToUTF16("O'Brien"); + base::string16 last_name = ASCIIToUTF16("Smith"); + base::string16 full_name = ASCIIToUTF16("Winston O'Brien Smith"); + base::string16 full_name_with_title = + ASCIIToUTF16("Dr. Winston O'Brien Smith"); + + // Create a compound component. + TestCompoundNameWithTitleAddressComponent compound_component; + + // Set the value of the root node. + compound_component.SetValueForTypeIfPossible( + NAME_FULL, full_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_HONORIFIC_PREFIX, title, VerificationStatus::kUserVerified); + + // Verify that the are subcomponents empty. + // CREDIT_CARD_NAME_FULL is a fictive type containing a title and a full name. + EXPECT_EQ(compound_component.GetValueForType(CREDIT_CARD_NAME_FULL), + base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), base::string16()); + + // Complete the tree. + compound_component.CompleteFullTree(); + + // Verify that the values for the subcomponents have been successfully parsed + // and the parent node was probably formatted. + EXPECT_EQ(compound_component.GetValueForType(CREDIT_CARD_NAME_FULL), + full_name_with_title); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), first_name); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), middle_name); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), last_name); + + // Change the value of FULL_NAME and invalidate all child and ancestor nodes. + compound_component.SetValueForTypeIfPossible( + NAME_FULL, base::UTF8ToUTF16("Oh' Brian"), VerificationStatus::kObserved, + true, true); + EXPECT_EQ(compound_component.GetValueForType(CREDIT_CARD_NAME_FULL), + base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), base::string16()); +} + +// Test unsetting a value and its subcomponents. +TEST(AutofillStructuredAddressAddressComponent, + TestUnsettingAValueAndItsSubcomponents) { + // Define Some values. + base::string16 title = ASCIIToUTF16("Dr."); + base::string16 first_name = ASCIIToUTF16("Winston"); + base::string16 middle_name = ASCIIToUTF16("O'Brien"); + base::string16 last_name = ASCIIToUTF16("Smith"); + base::string16 full_name = ASCIIToUTF16("Winston O'Brien Smith"); + base::string16 full_name_with_title = + ASCIIToUTF16("Dr. Winston O'Brien Smith"); + + // Create a compound component. + TestCompoundNameWithTitleAddressComponent compound_component; + + // Set the value of the root node. + compound_component.SetValueForTypeIfPossible( + NAME_FULL, full_name, VerificationStatus::kUserVerified); + compound_component.SetValueForTypeIfPossible( + NAME_HONORIFIC_PREFIX, title, VerificationStatus::kUserVerified); + + // Verify that the are subcomponents empty. + // CREDIT_CARD_NAME_FULL is a fictive type containing a title and a full name. + EXPECT_EQ(compound_component.GetValueForType(CREDIT_CARD_NAME_FULL), + base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), base::string16()); + + // Complete the tree. + compound_component.CompleteFullTree(); + + // Verify that the values for the subcomponents have been successfully parsed + // and the parent node was probably formatted. + EXPECT_EQ(compound_component.GetValueForType(CREDIT_CARD_NAME_FULL), + full_name_with_title); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), first_name); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), middle_name); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), last_name); + + // Change the value of FULL_NAME and invalidate all child and ancestor nodes. + compound_component.UnsetValueForTypeIfSupported(NAME_FULL); + EXPECT_EQ(compound_component.GetValueForType(CREDIT_CARD_NAME_FULL), + full_name_with_title); + EXPECT_EQ(compound_component.GetValueForType(NAME_FIRST), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_MIDDLE), base::string16()); + EXPECT_EQ(compound_component.GetValueForType(NAME_LAST), base::string16()); +} + +// Tests that the tree is completed successfully both upwards and downwards when +// a node with both subcomponents and a parent is set. +TEST(AutofillStructuredAddressAddressComponent, + TestUnsettingParsedAndFormatedValues) { + // Define Some values. + + TestCompoundNameWithTitleAddressComponent compound_component; + + // Set a value somewhere in the tree, complete and verify that another node is + // assigned. + compound_component.SetValueForTypeIfPossible( + NAME_FULL, base::UTF8ToUTF16("Winston Brian Smith"), + VerificationStatus::kObserved); + EXPECT_EQ(VerificationStatus::kObserved, + compound_component.GetVerificationStatusForType(NAME_FULL)); + compound_component.CompleteFullTree(); + EXPECT_EQ(VerificationStatus::kParsed, + compound_component.GetVerificationStatusForType(NAME_MIDDLE)); + EXPECT_EQ( + VerificationStatus::kFormatted, + compound_component.GetVerificationStatusForType(CREDIT_CARD_NAME_FULL)); + + // Clear parsed and formatted values and verify the expectation. + compound_component.UnsetParsedAndFormattedValuesInEntireTree(); + EXPECT_EQ(VerificationStatus::kObserved, + compound_component.GetVerificationStatusForType(NAME_FULL)); + EXPECT_EQ(VerificationStatus::kNoStatus, + compound_component.GetVerificationStatusForType(NAME_MIDDLE)); + EXPECT_EQ( + VerificationStatus::kNoStatus, + compound_component.GetVerificationStatusForType(CREDIT_CARD_NAME_FULL)); +} + +} // namespace structured_address +} // namespace autofill
diff --git a/components/autofill_assistant/browser/actions/show_generic_ui_action.cc b/components/autofill_assistant/browser/actions/show_generic_ui_action.cc index 6f66a26..28f2b505 100644 --- a/components/autofill_assistant/browser/actions/show_generic_ui_action.cc +++ b/components/autofill_assistant/browser/actions/show_generic_ui_action.cc
@@ -118,8 +118,15 @@ } } + base::OnceCallback<void()> end_on_navigation_callback; + if (proto_.show_generic_ui().end_on_navigation()) { + end_on_navigation_callback = + base::BindOnce(&ShowGenericUiAction::OnNavigationEnded, + weak_ptr_factory_.GetWeakPtr()); + } delegate_->Prompt(/* user_actions = */ nullptr, - /* disable_force_expand_sheet = */ false); + /* disable_force_expand_sheet = */ false, + std::move(end_on_navigation_callback)); delegate_->SetGenericUi( std::make_unique<GenericUserInterfaceProto>( proto_.show_generic_ui().generic_user_interface()), @@ -166,12 +173,13 @@ preconditions_.emplace_back(std::make_unique<ElementPrecondition>( element_check.element_condition())); } - if (std::any_of( + if (proto_.show_generic_ui().allow_interrupt() || + std::any_of( preconditions_.begin(), preconditions_.end(), [&](const auto& precondition) { return !precondition->empty(); })) { has_pending_wait_for_dom_ = true; delegate_->WaitForDom( - base::TimeDelta::Max(), false, + base::TimeDelta::Max(), proto_.show_generic_ui().allow_interrupt(), base::BindRepeating(&ShowGenericUiAction::RegisterChecks, weak_ptr_factory_.GetWeakPtr()), base::BindOnce(&ShowGenericUiAction::OnDoneWaitForDom, @@ -179,6 +187,12 @@ } } +void ShowGenericUiAction::OnNavigationEnded() { + processed_action_proto_->mutable_show_generic_ui_result() + ->set_navigation_ended(true); + OnEndActionInteraction(ClientStatus(ACTION_APPLIED)); +} + void ShowGenericUiAction::RegisterChecks( BatchElementChecker* checker, base::OnceCallback<void(const ClientStatus&)> wait_for_dom_callback) { @@ -203,6 +217,9 @@ size_t precondition_index, const ClientStatus& status, const std::vector<std::string>& ignored_payloads) { + if (should_end_action_) { + return; + } delegate_->GetUserModel()->SetValue(proto_.show_generic_ui() .periodic_element_checks() .element_checks(precondition_index) @@ -243,6 +260,12 @@ } void ShowGenericUiAction::EndAction(const ClientStatus& status) { + if (!callback_) { + // Avoid race condition: it is possible that a breaking navigation event + // occurs immediately before or after the action would end naturally. + return; + } + delegate_->ClearGenericUi(); delegate_->CleanUpAfterPrompt(); UpdateProcessedAction(status);
diff --git a/components/autofill_assistant/browser/actions/show_generic_ui_action.h b/components/autofill_assistant/browser/actions/show_generic_ui_action.h index 5cdca28..f57505a 100644 --- a/components/autofill_assistant/browser/actions/show_generic_ui_action.h +++ b/components/autofill_assistant/browser/actions/show_generic_ui_action.h
@@ -46,6 +46,7 @@ void EndAction(const ClientStatus& status); void OnViewInflationFinished(const ClientStatus& status); + void OnNavigationEnded(); // From autofill::PersonalDataManagerObserver. void OnPersonalDataChanged() override;
diff --git a/components/autofill_assistant/browser/actions/show_generic_ui_action_unittest.cc b/components/autofill_assistant/browser/actions/show_generic_ui_action_unittest.cc index d0405c8..38f33b6 100644 --- a/components/autofill_assistant/browser/actions/show_generic_ui_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/show_generic_ui_action_unittest.cc
@@ -455,5 +455,72 @@ Run(); } +TEST_F(ShowGenericUiActionTest, EndActionOnNavigation) { + ON_CALL(mock_action_delegate_, OnSetGenericUi(_, _, _)) + .WillByDefault( + Invoke([&](std::unique_ptr<GenericUserInterfaceProto> generic_ui, + base::OnceCallback<void(const ClientStatus&)>& + end_action_callback, + base::OnceCallback<void(const ClientStatus&)>& + view_inflation_finished_callback) { + std::move(view_inflation_finished_callback) + .Run(ClientStatus(ACTION_APPLIED)); + })); + EXPECT_CALL(mock_action_delegate_, Prompt(_, _, _, _)) + .WillOnce(Invoke( + [](std::unique_ptr<std::vector<UserAction>> user_actions, + bool disable_force_expand_sheet, + base::OnceCallback<void()> end_navigation_callback, + bool browse_mode) { std::move(end_navigation_callback).Run(); })); + EXPECT_CALL(mock_action_delegate_, CleanUpAfterPrompt()).Times(1); + EXPECT_CALL( + callback_, + Run(Pointee( + AllOf(Property(&ProcessedActionProto::status, ACTION_APPLIED), + Property(&ProcessedActionProto::show_generic_ui_result, + Property(&ShowGenericUiProto::Result::navigation_ended, + true)))))); + + proto_.set_end_on_navigation(true); + Run(); +} + +TEST_F(ShowGenericUiActionTest, BreakingNavigationBeforeUiIsSet) { + // End action immediately with ACTION_APPLIED after it goes into prompt. + EXPECT_CALL(mock_action_delegate_, Prompt(_, _, _, _)) + .WillOnce(Invoke( + [](std::unique_ptr<std::vector<UserAction>> user_actions, + bool disable_force_expand_sheet, + base::OnceCallback<void()> end_navigation_callback, + bool browse_mode) { std::move(end_navigation_callback).Run(); })); + ON_CALL(mock_action_delegate_, OnSetGenericUi(_, _, _)) + .WillByDefault( + Invoke([&](std::unique_ptr<GenericUserInterfaceProto> generic_ui, + base::OnceCallback<void(const ClientStatus&)>& + end_action_callback, + base::OnceCallback<void(const ClientStatus&)>& + view_inflation_finished_callback) { + std::move(view_inflation_finished_callback) + .Run(ClientStatus(ACTION_APPLIED)); + // Also end action when UI is set. At this point, the action should + // have terminated already. + std::move(end_action_callback) + .Run(ClientStatus(OTHER_ACTION_STATUS)); + })); + EXPECT_CALL(mock_action_delegate_, CleanUpAfterPrompt()).Times(1); + EXPECT_CALL( + callback_, + Run(Pointee( + AllOf(Property(&ProcessedActionProto::status, ACTION_APPLIED), + Property(&ProcessedActionProto::show_generic_ui_result, + Property(&ShowGenericUiProto::Result::navigation_ended, + true)))))); + + proto_.set_end_on_navigation(true); + Run(); +} + +// TODO(b/161652848): Add test coverage for element checks and interrupts. + } // namespace } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/basic_interactions.cc b/components/autofill_assistant/browser/basic_interactions.cc index e118082..b9e9ce2 100644 --- a/components/autofill_assistant/browser/basic_interactions.cc +++ b/components/autofill_assistant/browser/basic_interactions.cc
@@ -245,6 +245,13 @@ ContainsClientOnlyValue({*value_a, *value_b}))); return true; } + if (proto.mode() == ValueComparisonProto::NOT_EQUAL) { + user_model->SetValue( + result_model_identifier, + SimpleValue(*value_a != *value_b, + ContainsClientOnlyValue({*value_a, *value_b}))); + return true; + } // All modes except EQUAL require a size of 1 and a common value type and // are only supported for a subset of value types. @@ -286,6 +293,7 @@ result = *value_a > *value_b; break; case ValueComparisonProto::EQUAL: + case ValueComparisonProto::NOT_EQUAL: case ValueComparisonProto::UNDEFINED: NOTREACHED(); return false;
diff --git a/components/autofill_assistant/browser/basic_interactions_unittest.cc b/components/autofill_assistant/browser/basic_interactions_unittest.cc index 1eb98bdb..9d9e678 100644 --- a/components/autofill_assistant/browser/basic_interactions_unittest.cc +++ b/components/autofill_assistant/browser/basic_interactions_unittest.cc
@@ -436,28 +436,32 @@ proto.set_result_model_identifier("result"); EXPECT_FALSE(basic_interactions_.ComputeValue(proto)); - // EQUAL supported for all value types. - proto.mutable_comparison()->set_mode(ValueComparisonProto::EQUAL); - EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); - user_model_.SetValue("value_a", SimpleValue(std::string("string_a"))); - user_model_.SetValue("value_b", SimpleValue(std::string("string_b"))); - EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); - user_model_.SetValue("value_a", SimpleValue(true)); - user_model_.SetValue("value_b", SimpleValue(false)); - EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); - user_model_.SetValue("value_a", SimpleValue(1)); - user_model_.SetValue("value_b", SimpleValue(2)); - EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); - user_model_.SetValue("value_a", SimpleValue(CreateDateProto(2020, 8, 7))); - user_model_.SetValue("value_b", SimpleValue(CreateDateProto(2020, 11, 5))); - EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); - ValueProto user_actions_value; - user_actions_value.mutable_user_actions(); - user_model_.SetValue("value_a", user_actions_value); - user_model_.SetValue("value_b", user_actions_value); - EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); + // EQUAL and NOT_EQUAL supported for all value types. + ValueComparisonProto::Mode support_all_types_modes[] = { + ValueComparisonProto::EQUAL, ValueComparisonProto::NOT_EQUAL}; + for (const auto mode : support_all_types_modes) { + proto.mutable_comparison()->set_mode(mode); + EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); + user_model_.SetValue("value_a", SimpleValue(std::string("string_a"))); + user_model_.SetValue("value_b", SimpleValue(std::string("string_b"))); + EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); + user_model_.SetValue("value_a", SimpleValue(true)); + user_model_.SetValue("value_b", SimpleValue(false)); + EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); + user_model_.SetValue("value_a", SimpleValue(1)); + user_model_.SetValue("value_b", SimpleValue(2)); + EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); + user_model_.SetValue("value_a", SimpleValue(CreateDateProto(2020, 8, 7))); + user_model_.SetValue("value_b", SimpleValue(CreateDateProto(2020, 11, 5))); + EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); + ValueProto user_actions_value; + user_actions_value.mutable_user_actions(); + user_model_.SetValue("value_a", user_actions_value); + user_model_.SetValue("value_b", user_actions_value); + EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); + } - // Some types are not supported for comparison mode != EQUAL. + // Some types are not supported for modes other than EQUAL and NOT_EQUAL. proto.mutable_comparison()->set_mode(ValueComparisonProto::LESS); user_model_.SetValue("value_a", ValueProto()); user_model_.SetValue("value_b", ValueProto()); @@ -465,6 +469,8 @@ user_model_.SetValue("value_a", SimpleValue(true)); user_model_.SetValue("value_b", SimpleValue(false)); EXPECT_FALSE(basic_interactions_.ComputeValue(proto)); + ValueProto user_actions_value; + user_actions_value.mutable_user_actions(); user_model_.SetValue("value_a", user_actions_value); user_model_.SetValue("value_b", user_actions_value); EXPECT_FALSE(basic_interactions_.ComputeValue(proto)); @@ -482,6 +488,12 @@ user_model_.SetValue("value_b", multi_value); EXPECT_FALSE(basic_interactions_.ComputeValue(proto)); + // Different types succeed for mode == NOT_EQUAL. + proto.mutable_comparison()->set_mode(ValueComparisonProto::NOT_EQUAL); + user_model_.SetValue("value_a", SimpleValue(1)); + user_model_.SetValue("value_b", SimpleValue(std::string("a"))); + EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); + // Check comparison results. proto.mutable_comparison()->set_mode(ValueComparisonProto::LESS); user_model_.SetValue("value_a", SimpleValue(1)); @@ -524,6 +536,21 @@ SimpleValue(1, /* is_client_side_only = */ true)); EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); EXPECT_EQ(*user_model_.GetValue("result"), SimpleValue(true, true)); + + proto.mutable_comparison()->set_mode(ValueComparisonProto::NOT_EQUAL); + user_model_.SetValue("value_a", SimpleValue(1)); + user_model_.SetValue("value_b", SimpleValue(std::string("a"))); + EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); + EXPECT_EQ(user_model_.GetValue("result"), SimpleValue(true)); + + user_model_.SetValue("value_a", SimpleValue(1)); + user_model_.SetValue("value_b", SimpleValue(2)); + EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); + EXPECT_EQ(user_model_.GetValue("result"), SimpleValue(true)); + + user_model_.SetValue("value_b", SimpleValue(1)); + EXPECT_TRUE(basic_interactions_.ComputeValue(proto)); + EXPECT_EQ(user_model_.GetValue("result"), SimpleValue(false)); } TEST_F(BasicInteractionsTest, ComputeValueCreateCreditCardResponse) {
diff --git a/components/autofill_assistant/browser/element_area.cc b/components/autofill_assistant/browser/element_area.cc index 6136a6e..0b513492 100644 --- a/components/autofill_assistant/browser/element_area.cc +++ b/components/autofill_assistant/browser/element_area.cc
@@ -50,6 +50,9 @@ void ElementArea::SetFromProto(const ElementAreaProto& proto) { rectangles_.clear(); + last_visual_viewport_ = RectF(); + last_rectangles_.clear(); + AddRectangles(proto.touchable(), /* restricted= */ false); AddRectangles(proto.restricted(), /* restricted= */ true);
diff --git a/components/autofill_assistant/browser/element_area_unittest.cc b/components/autofill_assistant/browser/element_area_unittest.cc index 17b6f48..3ccde28 100644 --- a/components/autofill_assistant/browser/element_area_unittest.cc +++ b/components/autofill_assistant/browser/element_area_unittest.cc
@@ -164,6 +164,17 @@ EXPECT_THAT(reported_area_, ElementsAre(MatchingRectF(25, 25, 75, 75))); } +TEST_F(ElementAreaTest, CallOnUpdateAfterSetFromProto) { + EXPECT_CALL(mock_web_controller_, + OnGetElementPosition(Eq(Selector({"#found"}).MustBeVisible()), _)) + .WillRepeatedly(RunOnceCallback<1>(true, RectF(25, 25, 75, 75))); + + SetElement("#found"); + EXPECT_EQ(on_update_call_count_, 1); + SetElement("#found"); + EXPECT_EQ(on_update_call_count_, 2); +} + TEST_F(ElementAreaTest, DontCallOnUpdateWhenViewportMissing) { // Swallowing calls to OnGetVisualViewport guarantees that the viewport // position will never be known.
diff --git a/components/autofill_assistant/browser/generic_ui.proto b/components/autofill_assistant/browser/generic_ui.proto index e4031ba9..f27361b 100644 --- a/components/autofill_assistant/browser/generic_ui.proto +++ b/components/autofill_assistant/browser/generic_ui.proto
@@ -208,9 +208,9 @@ optional string locale = 2; } -// A comparison of two values in the form |value_a| <mode> |value_b|. EQUAL is -// supported for all values. All other comparison modes are only supported for -// single integers, strings, and dates. +// A comparison of two values in the form |value_a| <mode> |value_b|. EQUAL and +// NOT_EQUAL are supported for all values. All other comparison modes are only +// supported for single integers, strings, and dates. message ValueComparisonProto { enum Mode { UNDEFINED = 0; @@ -219,6 +219,7 @@ EQUAL = 3; GREATER_OR_EQUAL = 4; GREATER = 5; + NOT_EQUAL = 6; } // The first value to compare.
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 9f6c5cf..a94716e 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -1325,6 +1325,8 @@ // The model containing the values for all keys specified in // |output_model_identifiers|. optional ModelProto model = 1; + // Set to true if the action was interrupted by a navigation event. + optional bool navigation_ended = 2; } // The generic user interface to show. @@ -1357,6 +1359,12 @@ repeated ElementCheck element_checks = 1; } optional PeriodicElementChecks periodic_element_checks = 6; + // When set to true, end this action on navigation events. The result will + // have |navigation_ended| set to true. + optional bool end_on_navigation = 7; + // If true, run scripts flagged with |interrupt=true| as soon as their + // preconditions match, then go back to the parent action. + optional bool allow_interrupt = 8; } // Allow choosing one or more possibility. If FocusElement was called just
diff --git a/components/blocklist/opt_out_blocklist/opt_out_blocklist.cc b/components/blocklist/opt_out_blocklist/opt_out_blocklist.cc index 8a451845..0aa180d 100644 --- a/components/blocklist/opt_out_blocklist/opt_out_blocklist.cc +++ b/components/blocklist/opt_out_blocklist/opt_out_blocklist.cc
@@ -168,6 +168,9 @@ blocklist_data_->ClearData(); loaded_ = false; + // Notify |blocklist_delegate_| on blocklist load status + blocklist_delegate_->OnLoadingStateChanged(loaded_); + // Notify |blocklist_delegate_| that the blocklist is cleared. blocklist_delegate_->OnBlocklistCleared(clock_->Now()); @@ -216,6 +219,9 @@ std::move(pending_callbacks_.front()).Run(); pending_callbacks_.pop(); } + + // Notify |blocklist_delegate_| on blocklist load status + blocklist_delegate_->OnLoadingStateChanged(loaded_); } } // namespace blocklist
diff --git a/components/blocklist/opt_out_blocklist/opt_out_blocklist_delegate.h b/components/blocklist/opt_out_blocklist/opt_out_blocklist_delegate.h index 14b767a..ed899cad 100644 --- a/components/blocklist/opt_out_blocklist/opt_out_blocklist_delegate.h +++ b/components/blocklist/opt_out_blocklist/opt_out_blocklist_delegate.h
@@ -27,11 +27,11 @@ // Notifies |this| that the user blocklisted has changed, and it is // guaranteed to be called when the user blocklisted status is changed. - // - // TODO(crbug/1099030): Update the comment and interface to support providing - // a signal that the blocklist is loaded and available. virtual void OnUserBlocklistedStatusChange(bool blocklisted) {} + // Notifies |this| the blocklist loaded state changed to |is_loaded|. + virtual void OnLoadingStateChanged(bool is_load) {} + // Notifies |this| that the blocklist is cleared at |time|. virtual void OnBlocklistCleared(base::Time time) {} };
diff --git a/components/blocklist/opt_out_blocklist/opt_out_blocklist_unittest.cc b/components/blocklist/opt_out_blocklist/opt_out_blocklist_unittest.cc index a5d5cee..b2e1624 100644 --- a/components/blocklist/opt_out_blocklist/opt_out_blocklist_unittest.cc +++ b/components/blocklist/opt_out_blocklist/opt_out_blocklist_unittest.cc
@@ -49,6 +49,9 @@ void OnUserBlocklistedStatusChange(bool blocklisted) override { user_blocklisted_ = blocklisted; } + void OnLoadingStateChanged(bool is_loaded) override { + blocklist_loaded_ = is_loaded; + } void OnBlocklistCleared(base::Time time) override { blocklist_cleared_ = true; blocklist_cleared_time_ = time; @@ -62,6 +65,9 @@ // Gets the state of user blocklisted status. bool user_blocklisted() const { return user_blocklisted_; } + // Gets the load state of blocklist. + bool blocklist_loaded() const { return blocklist_loaded_; } + // Gets the state of blocklisted cleared status of |this| for testing. bool blocklist_cleared() const { return blocklist_cleared_; } @@ -72,6 +78,9 @@ // The user blocklisted status of |this| blocklist_delegate. bool user_blocklisted_ = false; + // The blocklist load status of |this| blocklist_delegate. + bool blocklist_loaded_ = false; + // Check if the blocklist is notified as cleared on |this| blocklist_delegate. bool blocklist_cleared_ = false; @@ -952,6 +961,7 @@ opt_out_store->SetBlocklistData(std::move(data)); EXPECT_FALSE(blocklist_delegate_.user_blocklisted()); + EXPECT_FALSE(blocklist_delegate_.blocklist_loaded()); allowed_types.clear(); allowed_types[1] = 0; auto block_list = std::make_unique<TestOptOutBlocklist>( @@ -966,6 +976,7 @@ block_list->Init(); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(blocklist_delegate_.user_blocklisted()); + EXPECT_TRUE(blocklist_delegate_.blocklist_loaded()); } TEST_F(OptOutBlocklistTest, ObserverIsNotifiedOfHistoricalBlocklistedHosts) {
diff --git a/components/client_hints/OWNERS b/components/client_hints/OWNERS index 9f8f91b..8869c6b 100644 --- a/components/client_hints/OWNERS +++ b/components/client_hints/OWNERS
@@ -1,5 +1,6 @@ yoavweiss@chromium.org tbansal@chromium.org ryansturm@chromium.org +aarontag@chromium.org # COMPONENT: Blink>Loader
diff --git a/components/management_strings.grdp b/components/management_strings.grdp index 3d1fc30..021b1f6 100644 --- a/components/management_strings.grdp +++ b/components/management_strings.grdp
@@ -126,7 +126,7 @@ Websites you visit and the contents of not secure pages </message> <message name="IDS_MANAGEMENT_REPORT_PLUGIN_VM" desc="Message telling users that Plugin VM can collect data."> - <ph name="APP_NAME">$1<ex>Plugin VM</ex></ph> collects diagnostics data to improve the product experience. See <ph name="BEGIN_LINK"><a target="_blank" href="https://www.parallels.com/pcep"></ph>https://www.parallels.com/pcep<ph name="END_LINK"></a></ph> for more information. + Your administrator has allowed <ph name="APP_NAME">$1<ex>Plugin VM</ex></ph> to collect diagnostics data to improve the product experience. See <ph name="BEGIN_LINK"><a target="_blank" href="https://www.parallels.com/pcep"></ph>https://www.parallels.com/pcep<ph name="END_LINK"></a></ph> for more information. </message> <!-- Chrome OS update required end-of-life reached section -->
diff --git a/components/management_strings_grdp/IDS_MANAGEMENT_REPORT_PLUGIN_VM.png.sha1 b/components/management_strings_grdp/IDS_MANAGEMENT_REPORT_PLUGIN_VM.png.sha1 index ab12155c..a1504fe 100644 --- a/components/management_strings_grdp/IDS_MANAGEMENT_REPORT_PLUGIN_VM.png.sha1 +++ b/components/management_strings_grdp/IDS_MANAGEMENT_REPORT_PLUGIN_VM.png.sha1
@@ -1 +1 @@ -516d0e7dac1ff3fdf9bb21437fa124fb807cb147 \ No newline at end of file +d2003f243a5af1b041f136b9d1bef898f1f14927 \ No newline at end of file
diff --git a/components/password_manager/core/browser/multi_store_form_fetcher.cc b/components/password_manager/core/browser/multi_store_form_fetcher.cc index 1cb500b..960313b 100644 --- a/components/password_manager/core/browser/multi_store_form_fetcher.cc +++ b/components/password_manager/core/browser/multi_store_form_fetcher.cc
@@ -116,7 +116,7 @@ if (store.get() == client_->GetProfilePasswordStore() && should_migrate_http_passwords_ && results.empty() && form_digest_.url.SchemeIs(url::kHttpsScheme)) { - // TODO(crbug.com/1095556): Consider also supporting HTTP->HTTPS migration + // TODO(crbug.com/1107741): Consider also supporting HTTP->HTTPS migration // for the account store. http_migrator_ = std::make_unique<HttpPasswordStoreMigrator>( url::Origin::Create(form_digest_.url), client_, this);
diff --git a/components/password_manager/core/browser/password_manager_client_helper.cc b/components/password_manager/core/browser/password_manager_client_helper.cc index 067d653..c6ff2da2 100644 --- a/components/password_manager/core/browser/password_manager_client_helper.cc +++ b/components/password_manager/core/browser/password_manager_client_helper.cc
@@ -87,6 +87,8 @@ const PasswordFormManagerForUI& submitted_manager) const { return delegate_->GetPasswordFeatureManager() ->ShouldShowAccountStorageBubbleUi() && + delegate_->GetPasswordFeatureManager()->GetDefaultPasswordStore() == + autofill::PasswordForm::Store::kAccountStore && submitted_manager.IsMovableToAccountStore() && !delegate_->IsIncognito(); }
diff --git a/components/password_manager/core/browser/password_manager_client_helper_unittest.cc b/components/password_manager/core/browser/password_manager_client_helper_unittest.cc index 79c7926d..affef187 100644 --- a/components/password_manager/core/browser/password_manager_client_helper_unittest.cc +++ b/components/password_manager/core/browser/password_manager_client_helper_unittest.cc
@@ -121,14 +121,33 @@ CreateFormManager(&form, /*is_movable=*/true)); } -TEST_F(PasswordManagerClientHelperTest, PromptMoveForMovableForm) { +TEST_F(PasswordManagerClientHelperTest, PromptMoveForMovableFormInAccountMode) { EXPECT_CALL(*client()->GetPasswordFeatureManager(), ShouldShowAccountStorageBubbleUi) .WillOnce(Return(true)); + EXPECT_CALL(*client()->GetPasswordFeatureManager(), GetDefaultPasswordStore) + .WillOnce(Return(autofill::PasswordForm::Store::kAccountStore)); EXPECT_CALL(*client(), PromptUserToMovePasswordToAccount); EXPECT_CALL(*client(), PromptUserToEnableAutosignin).Times(0); - // Indicate successful login without matching form. + // Indicate successful login. + const PasswordForm form = + CreateForm(kTestUsername, kTestPassword, GURL(kTestOrigin)); + helper()->NotifySuccessfulLoginWithExistingPassword( + CreateFormManager(&form, /*is_movable=*/true)); +} + +TEST_F(PasswordManagerClientHelperTest, + NoPromptToMoveForMovableFormInProfileMode) { + EXPECT_CALL(*client()->GetPasswordFeatureManager(), + ShouldShowAccountStorageBubbleUi) + .WillOnce(Return(true)); + EXPECT_CALL(*client()->GetPasswordFeatureManager(), GetDefaultPasswordStore) + .WillOnce(Return(autofill::PasswordForm::Store::kProfileStore)); + EXPECT_CALL(*client(), PromptUserToMovePasswordToAccount).Times(0); + EXPECT_CALL(*client(), PromptUserToEnableAutosignin).Times(0); + + // Indicate successful login. const PasswordForm form = CreateForm(kTestUsername, kTestPassword, GURL(kTestOrigin)); helper()->NotifySuccessfulLoginWithExistingPassword(
diff --git a/components/password_manager/ios/password_form_helper.mm b/components/password_manager/ios/password_form_helper.mm index 27781e0..c806e85 100644 --- a/components/password_manager/ios/password_form_helper.mm +++ b/components/password_manager/ios/password_form_helper.mm
@@ -14,12 +14,10 @@ #include "components/autofill/core/common/form_data.h" #include "components/autofill/core/common/password_form_fill_data.h" #include "components/autofill/ios/browser/autofill_util.h" -#include "components/password_manager/core/browser/password_form_filling.h" #include "components/password_manager/ios/account_select_fill_data.h" #include "components/password_manager/ios/js_password_manager.h" #import "ios/web/public/js_messaging/web_frame.h" #import "ios/web/public/js_messaging/web_frame_util.h" -#import "ios/web/public/js_messaging/web_frames_manager.h" #import "ios/web/public/web_state.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -32,6 +30,7 @@ using autofill::FieldRendererId; using autofill::PasswordFormFillData; using base::SysNSStringToUTF16; +using base::SysUTF16ToNSString; using password_manager::FillData; using password_manager::GetPageURLAndCheckTrustLevel; using password_manager::SerializePasswordFormFillData; @@ -68,14 +67,6 @@ pageURL:(const GURL&)pageURL forms:(std::vector<FormData>*)forms; -// Autofills |username| and |password| into the form specified by |formData|, -// invoking |completionHandler| when finished with YES if successful and -// NO otherwise. |completionHandler| may be nil. -- (void)fillPasswordForm:(const autofill::PasswordFormFillData&)formData - withUsername:(const base::string16&)username - password:(const base::string16&)password - completionHandler:(nullable void (^)(BOOL))completionHandler; - @end // Category for test only. @@ -247,47 +238,6 @@ *forms = std::move(formsData); } -// TODO(kazinova): remove unnecessary arguments. -- (void)fillPasswordForm:(const autofill::PasswordFormFillData&)formData - withUsername:(const base::string16&)username - password:(const base::string16&)password - completionHandler:(nullable void (^)(BOOL))completionHandler { - if (formData.url.GetOrigin() != self.lastCommittedURL.GetOrigin()) { - if (completionHandler) { - completionHandler(NO); - } - return; - } - - // Necessary copy so the values can be used inside a block. - FieldRendererId usernameID = formData.username_field.unique_renderer_id; - FieldRendererId passwordID = formData.password_field.unique_renderer_id; - base::string16 usernameValue = username; - base::string16 passwordValue = password; - - // Send JSON over to the web view. - __weak PasswordFormHelper* weakSelf = self; - [self.jsPasswordManager - fillPasswordForm:SerializePasswordFormFillData(formData) - inFrame:GetMainFrame(_webState) - withUsername:base::SysUTF16ToNSString(username) - password:base::SysUTF16ToNSString(password) - completionHandler:^(NSString* result) { - BOOL success = [result isEqual:@"true"]; - if (success) { - weakSelf.fieldDataManager->UpdateFieldDataWithAutofilledValue( - usernameID, usernameValue, - FieldPropertiesFlags::kAutofilledOnPageLoad); - weakSelf.fieldDataManager->UpdateFieldDataWithAutofilledValue( - passwordID, passwordValue, - FieldPropertiesFlags::kAutofilledOnPageLoad); - } - if (completionHandler) { - completionHandler(success); - } - }]; -} - // Extracts known field data. - (void)extractKnownFieldData:(FormData&)form { for (auto& field : form.fields) { @@ -343,29 +293,47 @@ - (void)fillPasswordForm:(const autofill::PasswordFormFillData&)formData completionHandler:(nullable void (^)(BOOL))completionHandler { - // Don't fill immediately if waiting for the user to type a username. - if (formData.wait_for_username) { + // Necessary copy so the values can be used inside a block. + FieldRendererId usernameID = formData.username_field.unique_renderer_id; + FieldRendererId passwordID = formData.password_field.unique_renderer_id; + base::string16 usernameValue = formData.username_field.value; + base::string16 passwordValue = formData.password_field.value; + + // Don't fill if: + // 1. Waiting for the user to type a username. + // 2. |formData|'s origin is not matching the origin of the last commited URL. + // 3. If a field has user typed input or input filled on user trigger. + if (formData.wait_for_username || + formData.url.GetOrigin() != self.lastCommittedURL.GetOrigin() || + self.fieldDataManager->WasAutofilledOnUserTrigger(passwordID) || + self.fieldDataManager->DidUserType(passwordID)) { if (completionHandler) { completionHandler(NO); } return; } - // Do not refill the form if a field has user typed input or input filled - // on user trigger. - FieldRendererId passwordId = formData.password_field.unique_renderer_id; - if (self.fieldDataManager->WasAutofilledOnUserTrigger(passwordId) || - self.fieldDataManager->DidUserType(passwordId)) { - if (completionHandler) { - completionHandler(NO); - } - return; - } - - [self fillPasswordForm:formData - withUsername:formData.username_field.value - password:formData.password_field.value - completionHandler:completionHandler]; + // Send JSON over to the web view. + __weak PasswordFormHelper* weakSelf = self; + [self.jsPasswordManager + fillPasswordForm:SerializePasswordFormFillData(formData) + inFrame:GetMainFrame(_webState) + withUsername:SysUTF16ToNSString(formData.username_field.value) + password:SysUTF16ToNSString(formData.password_field.value) + completionHandler:^(NSString* result) { + BOOL success = [result isEqual:@"true"]; + if (success) { + weakSelf.fieldDataManager->UpdateFieldDataWithAutofilledValue( + usernameID, usernameValue, + FieldPropertiesFlags::kAutofilledOnPageLoad); + weakSelf.fieldDataManager->UpdateFieldDataWithAutofilledValue( + passwordID, passwordValue, + FieldPropertiesFlags::kAutofilledOnPageLoad); + } + if (completionHandler) { + completionHandler(success); + } + }]; } - (void)fillPasswordForm:(FormRendererId)formIdentifier @@ -412,8 +380,8 @@ [self.jsPasswordManager fillPasswordForm:SerializeFillData(fillData) inFrame:GetMainFrame(_webState) - withUsername:base::SysUTF16ToNSString(usernameValue) - password:base::SysUTF16ToNSString(passwordValue) + withUsername:SysUTF16ToNSString(usernameValue) + password:SysUTF16ToNSString(passwordValue) completionHandler:^(NSString* result) { BOOL success = [result isEqual:@"true"]; if (success) {
diff --git a/components/prefs/android/BUILD.gn b/components/prefs/android/BUILD.gn index fccae3c..2aa2728d 100644 --- a/components/prefs/android/BUILD.gn +++ b/components/prefs/android/BUILD.gn
@@ -17,20 +17,3 @@ ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] } - -java_library("junit") { - # Skip platform checks since Robolectric depends on requires_android targets. - bypass_platform_checks = true - testonly = true - sources = [ "java/src/org/chromium/components/prefs/PrefServiceTest.java" ] - deps = [ - ":java", - "//base:base_java", - "//base:base_java_test_support", - "//base:base_junit_test_support", - "//base/test:test_support_java", - "//third_party/android_deps:robolectric_all_java", - "//third_party/junit", - "//third_party/mockito:mockito_java", - ] -}
diff --git a/components/prefs/android/OWNERS b/components/prefs/android/OWNERS deleted file mode 100644 index 3d0f7a5..0000000 --- a/components/prefs/android/OWNERS +++ /dev/null
@@ -1,5 +0,0 @@ -twellington@chromium.org -chouinard@chromium.org - -# COMPONENT: Internals>Preferences -# OS: Android
diff --git a/components/prefs/android/java/src/org/chromium/components/prefs/PrefService.java b/components/prefs/android/java/src/org/chromium/components/prefs/PrefService.java index 3ee3f8b..64f1d05b 100644 --- a/components/prefs/android/java/src/org/chromium/components/prefs/PrefService.java +++ b/components/prefs/android/java/src/org/chromium/components/prefs/PrefService.java
@@ -5,7 +5,6 @@ package org.chromium.components.prefs; import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; @@ -24,8 +23,7 @@ mNativePrefServiceAndroid = 0; } - @VisibleForTesting - PrefService(long nativePrefServiceAndroid) { + private PrefService(long nativePrefServiceAndroid) { mNativePrefServiceAndroid = nativePrefServiceAndroid; }
diff --git a/components/prefs/android/java/src/org/chromium/components/prefs/PrefServiceTest.java b/components/prefs/android/java/src/org/chromium/components/prefs/PrefServiceTest.java deleted file mode 100644 index e1de428a..0000000 --- a/components/prefs/android/java/src/org/chromium/components/prefs/PrefServiceTest.java +++ /dev/null
@@ -1,108 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// generate_java_test.py - -package org.chromium.components.prefs; - -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.verify; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; - -import org.chromium.base.test.BaseRobolectricTestRunner; -import org.chromium.base.test.util.JniMocker; - -/** Unit tests for {@link PrefService}. */ -@RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE) -public class PrefServiceTest { - private static final String PREF = "42"; - private static final long NATIVE_HANDLE = 117; - - @Rule - public JniMocker mocker = new JniMocker(); - @Mock - private PrefService.Natives mNativeMock; - - PrefService mPrefService; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mocker.mock(PrefServiceJni.TEST_HOOKS, mNativeMock); - mPrefService = new PrefService(NATIVE_HANDLE); - } - - @Test - public void testGetBoolean() { - boolean expected = false; - - doReturn(expected).when(mNativeMock).getBoolean(NATIVE_HANDLE, PREF); - - assertEquals(expected, mPrefService.getBoolean(PREF)); - } - - @Test - public void testSetBoolean() { - boolean value = true; - - mPrefService.setBoolean(PREF, value); - - verify(mNativeMock).setBoolean(eq(NATIVE_HANDLE), eq(PREF), eq(value)); - } - - @Test - public void testGetInteger() { - int expected = 26; - - doReturn(expected).when(mNativeMock).getInteger(NATIVE_HANDLE, PREF); - - assertEquals(expected, mPrefService.getInteger(PREF)); - } - - @Test - public void testSetInteger() { - int value = 62; - - mPrefService.setInteger(PREF, value); - - verify(mNativeMock).setInteger(eq(NATIVE_HANDLE), eq(PREF), eq(value)); - } - - @Test - public void testGetString() { - String expected = "foo"; - - doReturn(expected).when(mNativeMock).getString(NATIVE_HANDLE, PREF); - - assertEquals(expected, mPrefService.getString(PREF)); - } - - @Test - public void testSetString() { - String value = "bar"; - - mPrefService.setString(PREF, value); - - verify(mNativeMock).setString(eq(NATIVE_HANDLE), eq(PREF), eq(value)); - } - - @Test - public void testIsManaged() { - boolean expected = true; - - doReturn(expected).when(mNativeMock).isManagedPreference(NATIVE_HANDLE, PREF); - - assertEquals(expected, mPrefService.isManagedPreference(PREF)); - } -}
diff --git a/components/prerender/common/BUILD.gn b/components/prerender/common/BUILD.gn index b5cd57e..8434b65 100644 --- a/components/prerender/common/BUILD.gn +++ b/components/prerender/common/BUILD.gn
@@ -10,11 +10,14 @@ "prerender_final_status.h", "prerender_origin.cc", "prerender_origin.h", + "prerender_url_loader_throttle.cc", + "prerender_url_loader_throttle.h", "prerender_util.cc", "prerender_util.h", ] deps = [ ":mojo_bindings", + "//content/public/common:common", "//extensions/common:common_constants", "//ipc", "//ipc:message_support",
diff --git a/chrome/common/prerender_url_loader_throttle.cc b/components/prerender/common/prerender_url_loader_throttle.cc similarity index 98% rename from chrome/common/prerender_url_loader_throttle.cc rename to components/prerender/common/prerender_url_loader_throttle.cc index c3ecc81..d3bf2e04 100644 --- a/chrome/common/prerender_url_loader_throttle.cc +++ b/components/prerender/common/prerender_url_loader_throttle.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/common/prerender_url_loader_throttle.h" +#include "components/prerender/common/prerender_url_loader_throttle.h" #include "base/bind.h" #include "build/build_config.h"
diff --git a/chrome/common/prerender_url_loader_throttle.h b/components/prerender/common/prerender_url_loader_throttle.h similarity index 92% rename from chrome/common/prerender_url_loader_throttle.h rename to components/prerender/common/prerender_url_loader_throttle.h index f7b35f5..ad5ef19 100644 --- a/chrome/common/prerender_url_loader_throttle.h +++ b/components/prerender/common/prerender_url_loader_throttle.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_COMMON_PRERENDER_URL_LOADER_THROTTLE_H_ -#define CHROME_COMMON_PRERENDER_URL_LOADER_THROTTLE_H_ +#ifndef COMPONENTS_PRERENDER_COMMON_PRERENDER_URL_LOADER_THROTTLE_H_ +#define COMPONENTS_PRERENDER_COMMON_PRERENDER_URL_LOADER_THROTTLE_H_ #include "base/callback.h" #include "base/memory/weak_ptr.h" @@ -75,4 +75,4 @@ } // namespace prerender -#endif // CHROME_COMMON_PRERENDER_URL_LOADER_THROTTLE_H_ +#endif // COMPONENTS_PRERENDER_COMMON_PRERENDER_URL_LOADER_THROTTLE_H_
diff --git a/components/prerender/renderer/BUILD.gn b/components/prerender/renderer/BUILD.gn new file mode 100644 index 0000000..4a20615b --- /dev/null +++ b/components/prerender/renderer/BUILD.gn
@@ -0,0 +1,17 @@ +# 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. + +static_library("renderer") { + sources = [ + "prerender_helper.cc", + "prerender_helper.h", + ] + + deps = [ + "//components/prerender/common", + "//components/prerender/common:mojo_bindings", + "//content/public/renderer", + "//third_party/blink/public:blink_headers", + ] +}
diff --git a/components/prerender/renderer/DEPS b/components/prerender/renderer/DEPS new file mode 100644 index 0000000..dec58a9b --- /dev/null +++ b/components/prerender/renderer/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+content/public/renderer", + "+third_party/blink/public", +]
diff --git a/chrome/renderer/prerender/prerender_helper.cc b/components/prerender/renderer/prerender_helper.cc similarity index 97% rename from chrome/renderer/prerender/prerender_helper.cc rename to components/prerender/renderer/prerender_helper.cc index e1e6912..820b305 100644 --- a/chrome/renderer/prerender/prerender_helper.cc +++ b/components/prerender/renderer/prerender_helper.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/renderer/prerender/prerender_helper.h" +#include "components/prerender/renderer/prerender_helper.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram_macros.h" -#include "chrome/common/prerender_url_loader_throttle.h" +#include "components/prerender//common/prerender_url_loader_throttle.h" #include "content/public/renderer/document_state.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_thread.h"
diff --git a/chrome/renderer/prerender/prerender_helper.h b/components/prerender/renderer/prerender_helper.h similarity index 93% rename from chrome/renderer/prerender/prerender_helper.h rename to components/prerender/renderer/prerender_helper.h index 492bf98..7187e74 100644 --- a/chrome/renderer/prerender/prerender_helper.h +++ b/components/prerender/renderer/prerender_helper.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_RENDERER_PRERENDER_PRERENDER_HELPER_H_ -#define CHROME_RENDERER_PRERENDER_PRERENDER_HELPER_H_ +#ifndef COMPONENTS_PRERENDER_RENDERER_PRERENDER_HELPER_H_ +#define COMPONENTS_PRERENDER_RENDERER_PRERENDER_HELPER_H_ #include "base/compiler_specific.h" #include "base/macros.h" @@ -78,4 +78,4 @@ } // namespace prerender -#endif // CHROME_RENDERER_PRERENDER_PRERENDER_HELPER_H_ +#endif // COMPONENTS_PRERENDER_RENDERER_PRERENDER_HELPER_H_
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 634cbe9e..446950f 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -853,12 +853,17 @@ SkiaOutputSurfaceImplOnGpu::~SkiaOutputSurfaceImplOnGpu() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // |context_provider_| and clients want either the context to be lost or made - // current on destruction. - if (context_state_ && MakeCurrent(false /* need_fbo0 */)) { - // This ensures any outstanding callbacks for promise images are performed. - gr_context()->flushAndSubmit(); - release_current_last_.emplace(gl_surface_, context_state_); + if (context_state_) { + context_state_->RemoveContextLostObserver(this); + + // |context_provider_| and clients want either the context to be lost or + // made current on destruction. + if (MakeCurrent(false /* need_fbo0 */)) { + // This ensures any outstanding callbacks for promise images are + // performed. + gr_context()->flushAndSubmit(); + release_current_last_.emplace(gl_surface_, context_state_); + } } if (copier_) { @@ -1478,6 +1483,9 @@ !features::IsUsingSkiaForGLReadback(); max_resource_cache_bytes_ = context_state_->gr_context()->getResourceCacheLimit(); + if (context_state_) + context_state_->AddContextLostObserver(this); + return true; } @@ -1827,6 +1835,10 @@ &SkiaOutputSurfaceImplOnGpu::DidSwapBuffersCompleteInternal, weak_ptr_); } +void SkiaOutputSurfaceImplOnGpu::OnContextLost() { + MarkContextLost(ContextLostReason::CONTEXT_LOST_UNKNOWN); +} + void SkiaOutputSurfaceImplOnGpu::MarkContextLost(ContextLostReason reason) { // This function potentially can be re-entered during from // SharedContextState::MarkContextLost(). This guards against it.
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index 554539b..9140522 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -70,7 +70,9 @@ // The SkiaOutputSurface implementation running on the GPU thread. This class // should be created, used and destroyed on the GPU thread. -class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate { +class SkiaOutputSurfaceImplOnGpu + : public gpu::ImageTransportSurfaceDelegate, + public gpu::SharedContextState::ContextLostObserver { public: class ScopedUseContextProvider; @@ -186,6 +188,9 @@ bool IsDisplayedAsOverlay(); + // gpu::SharedContextState::ContextLostObserver implementation: + void OnContextLost() override; + // gpu::ImageTransportSurfaceDelegate implementation: #if defined(OS_WIN) void DidCreateAcceleratedSurfaceChildWindow(
diff --git a/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/content/browser/accessibility/accessibility_tree_formatter_blink.cc index ce2b041..bec5d29 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_blink.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -96,7 +96,7 @@ case ax::mojom::IntAttribute::kTextUnderlineStyle: return ui::ToString(static_cast<ax::mojom::TextDecorationStyle>(value)); case ax::mojom::IntAttribute::kTextDirection: - return ui::ToString(static_cast<ax::mojom::TextDirection>(value)); + return ui::ToString(static_cast<ax::mojom::WritingDirection>(value)); case ax::mojom::IntAttribute::kTextPosition: return ui::ToString(static_cast<ax::mojom::TextPosition>(value)); case ax::mojom::IntAttribute::kImageAnnotationStatus:
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 64f0b04..764dff8 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -660,25 +660,25 @@ } // Step 2: correct for the thickness of the caret. - auto text_direction = static_cast<ax::mojom::TextDirection>( + auto text_direction = static_cast<ax::mojom::WritingDirection>( GetIntAttribute(ax::mojom::IntAttribute::kTextDirection)); constexpr int kCaretThickness = 1; switch (text_direction) { - case ax::mojom::TextDirection::kNone: - case ax::mojom::TextDirection::kLtr: { + case ax::mojom::WritingDirection::kNone: + case ax::mojom::WritingDirection::kLtr: { bounds.set_width(kCaretThickness); break; } - case ax::mojom::TextDirection::kRtl: { + case ax::mojom::WritingDirection::kRtl: { bounds.set_x(bounds.right() - kCaretThickness); bounds.set_width(kCaretThickness); break; } - case ax::mojom::TextDirection::kTtb: { + case ax::mojom::WritingDirection::kTtb: { bounds.set_height(kCaretThickness); break; } - case ax::mojom::TextDirection::kBtt: { + case ax::mojom::WritingDirection::kBtt: { bounds.set_y(bounds.bottom() - kCaretThickness); bounds.set_height(kCaretThickness); break; @@ -787,25 +787,25 @@ const int location_height = location.height(); gfx::RectF bounds; - switch (static_cast<ax::mojom::TextDirection>( + switch (static_cast<ax::mojom::WritingDirection>( GetIntAttribute(ax::mojom::IntAttribute::kTextDirection))) { - case ax::mojom::TextDirection::kNone: - case ax::mojom::TextDirection::kLtr: + case ax::mojom::WritingDirection::kNone: + case ax::mojom::WritingDirection::kLtr: bounds = gfx::RectF(start_pixel_offset, 0, end_pixel_offset - start_pixel_offset, location_height); break; - case ax::mojom::TextDirection::kRtl: { + case ax::mojom::WritingDirection::kRtl: { const int left = max_pixel_offset - end_pixel_offset; const int right = max_pixel_offset - start_pixel_offset; bounds = gfx::RectF(left, 0, right - left, location_height); break; } - case ax::mojom::TextDirection::kTtb: + case ax::mojom::WritingDirection::kTtb: bounds = gfx::RectF(0, start_pixel_offset, location_width, end_pixel_offset - start_pixel_offset); break; - case ax::mojom::TextDirection::kBtt: { + case ax::mojom::WritingDirection::kBtt: { const int top = max_pixel_offset - end_pixel_offset; const int bottom = max_pixel_offset - start_pixel_offset; bounds = gfx::RectF(0, top, location_width, bottom - top);
diff --git a/content/browser/accessibility/browser_accessibility_manager_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_unittest.cc index 971f451..de5fb71 100644 --- a/content/browser/accessibility/browser_accessibility_manager_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_manager_unittest.cc
@@ -136,7 +136,7 @@ inline_text1.role = ax::mojom::Role::kInlineTextBox; inline_text1.SetName("Hello, "); inline_text1.relative_bounds.bounds = gfx::RectF(100, 100, 29, 9); - inline_text1.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text1.SetTextDirection(ax::mojom::WritingDirection::kLtr); std::vector<int32_t> character_offsets1; character_offsets1.push_back(6); // 0 character_offsets1.push_back(11); // 1 @@ -154,7 +154,7 @@ inline_text2.role = ax::mojom::Role::kInlineTextBox; inline_text2.SetName("world."); inline_text2.relative_bounds.bounds = gfx::RectF(100, 109, 28, 9); - inline_text2.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text2.SetTextDirection(ax::mojom::WritingDirection::kLtr); std::vector<int32_t> character_offsets2; character_offsets2.push_back(5); character_offsets2.push_back(10); @@ -242,7 +242,7 @@ inline_text1.role = ax::mojom::Role::kInlineTextBox; inline_text1.SetName("ABC"); inline_text1.relative_bounds.bounds = gfx::RectF(0, 20, 33, 9); - inline_text1.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text1.SetTextDirection(ax::mojom::WritingDirection::kLtr); std::vector<int32_t> character_offsets{10, 21, 33}; inline_text1.AddIntListAttribute( ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets); @@ -260,7 +260,7 @@ inline_text2.role = ax::mojom::Role::kInlineTextBox; inline_text2.SetName("ABC"); inline_text2.relative_bounds.bounds = gfx::RectF(10, 40, 33, 9); - inline_text2.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text2.SetTextDirection(ax::mojom::WritingDirection::kLtr); inline_text2.AddIntListAttribute( ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets); static_text2.child_ids.push_back(5); @@ -360,7 +360,7 @@ inline_text1.role = ax::mojom::Role::kInlineTextBox; inline_text1.SetName("123"); inline_text1.relative_bounds.bounds = gfx::RectF(100, 100, 30, 20); - inline_text1.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text1.SetTextDirection(ax::mojom::WritingDirection::kLtr); std::vector<int32_t> character_offsets1; character_offsets1.push_back(10); // 0 character_offsets1.push_back(20); // 1 @@ -374,7 +374,7 @@ inline_text2.role = ax::mojom::Role::kInlineTextBox; inline_text2.SetName("abc"); inline_text2.relative_bounds.bounds = gfx::RectF(130, 100, 30, 20); - inline_text2.SetTextDirection(ax::mojom::TextDirection::kRtl); + inline_text2.SetTextDirection(ax::mojom::WritingDirection::kRtl); std::vector<int32_t> character_offsets2; character_offsets2.push_back(10); character_offsets2.push_back(20); @@ -457,7 +457,7 @@ inline_text.role = ax::mojom::Role::kInlineTextBox; inline_text.SetName("ABC"); inline_text.relative_bounds.bounds = gfx::RectF(100, 100, 16, 9); - inline_text.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text.SetTextDirection(ax::mojom::WritingDirection::kLtr); std::vector<int32_t> character_offsets1; character_offsets1.push_back(6); // 0 character_offsets1.push_back(11); // 1 @@ -536,7 +536,7 @@ inline_text1.role = ax::mojom::Role::kInlineTextBox; inline_text1.SetName("AB"); inline_text1.relative_bounds.bounds = gfx::RectF(100, 100, 40, 20); - inline_text1.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text1.SetTextDirection(ax::mojom::WritingDirection::kLtr); std::vector<int32_t> character_offsets1; character_offsets1.push_back(20); // 0 character_offsets1.push_back(40); // 1 @@ -548,7 +548,7 @@ inline_text2.role = ax::mojom::Role::kInlineTextBox; inline_text2.SetName("CD"); inline_text2.relative_bounds.bounds = gfx::RectF(160, 100, 40, 20); - inline_text2.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text2.SetTextDirection(ax::mojom::WritingDirection::kLtr); std::vector<int32_t> character_offsets2; character_offsets2.push_back(20); // 0 character_offsets2.push_back(40); // 1
diff --git a/content/browser/accessibility/browser_accessibility_unittest.cc b/content/browser/accessibility/browser_accessibility_unittest.cc index ed559c391..c4800985 100644 --- a/content/browser/accessibility/browser_accessibility_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_unittest.cc
@@ -289,7 +289,7 @@ inline_text1.role = ax::mojom::Role::kInlineTextBox; inline_text1.SetName("Hello, "); inline_text1.relative_bounds.bounds = gfx::RectF(100, 100, 29, 9); - inline_text1.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text1.SetTextDirection(ax::mojom::WritingDirection::kLtr); std::vector<int32_t> character_offsets1; character_offsets1.push_back(6); character_offsets1.push_back(11); @@ -307,7 +307,7 @@ inline_text2.role = ax::mojom::Role::kInlineTextBox; inline_text2.SetName("world."); inline_text2.relative_bounds.bounds = gfx::RectF(100, 109, 28, 9); - inline_text2.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text2.SetTextDirection(ax::mojom::WritingDirection::kLtr); std::vector<int32_t> character_offsets2; character_offsets2.push_back(5); character_offsets2.push_back(10); @@ -410,7 +410,7 @@ inline_text1.role = ax::mojom::Role::kInlineTextBox; inline_text1.SetName("ABC"); inline_text1.relative_bounds.bounds = gfx::RectF(0, 20, 33, 9); - inline_text1.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text1.SetTextDirection(ax::mojom::WritingDirection::kLtr); std::vector<int32_t> character_offsets{10, 21, 33}; inline_text1.AddIntListAttribute( ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets); @@ -428,7 +428,7 @@ inline_text2.role = ax::mojom::Role::kInlineTextBox; inline_text2.SetName("ABC"); inline_text2.relative_bounds.bounds = gfx::RectF(10, 40, 33, 9); - inline_text2.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text2.SetTextDirection(ax::mojom::WritingDirection::kLtr); inline_text2.AddIntListAttribute( ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets); static_text2.child_ids.push_back(5); @@ -537,7 +537,7 @@ inline_text1.role = ax::mojom::Role::kInlineTextBox; inline_text1.SetName("123"); inline_text1.relative_bounds.bounds = gfx::RectF(100, 100, 30, 20); - inline_text1.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text1.SetTextDirection(ax::mojom::WritingDirection::kLtr); std::vector<int32_t> character_offsets1; character_offsets1.push_back(10); // 0 character_offsets1.push_back(20); // 1 @@ -551,7 +551,7 @@ inline_text2.role = ax::mojom::Role::kInlineTextBox; inline_text2.SetName("abc"); inline_text2.relative_bounds.bounds = gfx::RectF(130, 100, 30, 20); - inline_text2.SetTextDirection(ax::mojom::TextDirection::kRtl); + inline_text2.SetTextDirection(ax::mojom::WritingDirection::kRtl); std::vector<int32_t> character_offsets2; character_offsets2.push_back(10); character_offsets2.push_back(20); @@ -637,7 +637,7 @@ inline_text.role = ax::mojom::Role::kInlineTextBox; inline_text.SetName("ABC"); inline_text.relative_bounds.bounds = gfx::RectF(100, 100, 16, 9); - inline_text.SetTextDirection(ax::mojom::TextDirection::kLtr); + inline_text.SetTextDirection(ax::mojom::WritingDirection::kLtr); std::vector<int32_t> character_offsets1; character_offsets1.push_back(6); // 0 character_offsets1.push_back(11); // 1
diff --git a/content/browser/appcache/appcache_backfillers.cc b/content/browser/appcache/appcache_backfillers.cc index c6a6b9d9..f3509a30e 100644 --- a/content/browser/appcache/appcache_backfillers.cc +++ b/content/browser/appcache/appcache_backfillers.cc
@@ -5,6 +5,7 @@ #include "content/browser/appcache/appcache_backfillers.h" #include "content/browser/appcache/appcache_update_job.h" +#include "net/http/http_request_headers.h" #include "sql/statement.h" #include "storage/browser/quota/padding_key.h" #include "url/gurl.h" @@ -19,7 +20,7 @@ return 0; return storage::ComputeResponsePadding( response_url, storage::GetDefaultPaddingKey(), /*has_metadata=*/false, - /*loaded_with_credentials=*/false); + /*loaded_with_credentials=*/false, net::HttpRequestHeaders::kGetMethod); } // Iterates over each Cache record; execute |callable| on each iteration.
diff --git a/content/browser/appcache/appcache_update_job.cc b/content/browser/appcache/appcache_update_job.cc index 0680e53..a021817 100644 --- a/content/browser/appcache/appcache_update_job.cc +++ b/content/browser/appcache/appcache_update_job.cc
@@ -26,6 +26,7 @@ #include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/base/request_priority.h" +#include "net/http/http_request_headers.h" #include "storage/browser/quota/padding_key.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/appcache/appcache.mojom.h" @@ -196,10 +197,10 @@ if (response_url.GetOrigin() == manifest_url.GetOrigin()) return 0; - return storage::ComputeResponsePadding(response_url.spec(), - storage::GetDefaultPaddingKey(), - /*has_metadata=*/false, - /*loaded_with_credentials=*/false); + return storage::ComputeResponsePadding( + response_url.spec(), storage::GetDefaultPaddingKey(), + /*has_metadata=*/false, /*loaded_with_credentials=*/false, + net::HttpRequestHeaders::kGetMethod); } } // namespace
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index a8ed8a5..a8913e6 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -43,8 +43,6 @@ #include "content/browser/worker_host/shared_worker_host.h" #include "content/browser/xr/service/vr_service_impl.h" #include "content/common/input/input_injector.mojom.h" -#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" -#include "content/common/media/renderer_audio_output_stream_factory.mojom.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/device_service.h" @@ -92,6 +90,8 @@ #include "third_party/blink/public/mojom/loader/content_security_notifier.mojom.h" #include "third_party/blink/public/mojom/loader/navigation_predictor.mojom.h" #include "third_party/blink/public/mojom/locks/lock_manager.mojom.h" +#include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" +#include "third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom.h" #include "third_party/blink/public/mojom/mediasession/media_session.mojom.h" #include "third_party/blink/public/mojom/mediastream/media_devices.mojom.h" #include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h" @@ -635,11 +635,11 @@ GetIOThreadTaskRunner({})); } - map->Add<mojom::RendererAudioInputStreamFactory>( + map->Add<blink::mojom::RendererAudioInputStreamFactory>( base::BindRepeating(&RenderFrameHostImpl::CreateAudioInputStreamFactory, base::Unretained(host))); - map->Add<mojom::RendererAudioOutputStreamFactory>( + map->Add<blink::mojom::RendererAudioOutputStreamFactory>( base::BindRepeating(&RenderFrameHostImpl::CreateAudioOutputStreamFactory, base::Unretained(host)));
diff --git a/content/browser/cache_storage/cache_storage.proto b/content/browser/cache_storage/cache_storage.proto index 3fcaef2..14ad0f0 100644 --- a/content/browser/cache_storage/cache_storage.proto +++ b/content/browser/cache_storage/cache_storage.proto
@@ -55,6 +55,7 @@ optional string alpn_negotiated_protocol = 11; optional bool was_fetched_via_spdy = 12; optional string mime_type = 13; + optional string request_method = 14; } message CacheMetadata {
diff --git a/content/browser/cache_storage/cache_storage_cache_unittest.cc b/content/browser/cache_storage/cache_storage_cache_unittest.cc index 9395f795..8abdcef6 100644 --- a/content/browser/cache_storage/cache_storage_cache_unittest.cc +++ b/content/browser/cache_storage/cache_storage_cache_unittest.cc
@@ -663,9 +663,9 @@ network::mojom::FetchResponseSource::kUnspecified, base::flat_map<std::string, std::string>(kHeaders.cbegin(), kHeaders.cend()), - base::nullopt /* mime_type */, nullptr /* blob */, - blink::mojom::ServiceWorkerResponseError::kUnknown, response_time_, - std::string() /* cache_storage_cache_name */, + base::nullopt /* mime_type */, net::HttpRequestHeaders::kGetMethod, + nullptr /* blob */, blink::mojom::ServiceWorkerResponseError::kUnknown, + response_time_, std::string() /* cache_storage_cache_name */, std::vector<std::string>() /* cors_exposed_header_names */, nullptr /* side_data_blob */, nullptr /* side_data_blob_for_cache_put */,
diff --git a/content/browser/cache_storage/cache_storage_manager_unittest.cc b/content/browser/cache_storage/cache_storage_manager_unittest.cc index 6bcf361..c25a0406 100644 --- a/content/browser/cache_storage/cache_storage_manager_unittest.cc +++ b/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -662,9 +662,9 @@ auto response = blink::mojom::FetchAPIResponse::New( std::vector<GURL>({request->url}), status_code, "OK", response_type, network::mojom::FetchResponseSource::kUnspecified, response_headers, - base::nullopt /* mime_type */, std::move(blob), - blink::mojom::ServiceWorkerResponseError::kUnknown, base::Time(), - std::string() /* cache_storage_cache_name */, + base::nullopt /* mime_type */, net::HttpRequestHeaders::kGetMethod, + std::move(blob), blink::mojom::ServiceWorkerResponseError::kUnknown, + base::Time(), std::string() /* cache_storage_cache_name */, std::vector<std::string>() /* cors_exposed_header_names */, nullptr /* side_data_blob */, nullptr /* side_data_blob_for_cache_put */,
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc index 61d2bc78..e356357 100644 --- a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc +++ b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc
@@ -48,6 +48,7 @@ #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/disk_cache/disk_cache.h" +#include "net/http/http_request_headers.h" #include "services/network/public/mojom/fetch_api.mojom.h" #include "storage/browser/blob/blob_storage_context.h" #include "storage/browser/quota/padding_key.h" @@ -420,12 +421,17 @@ if (metadata.response().has_mime_type()) mime_type = metadata.response().mime_type(); + base::Optional<std::string> request_method; + if (metadata.response().has_request_method()) + request_method = metadata.response().request_method(); + return blink::mojom::FetchAPIResponse::New( url_list, metadata.response().status_code(), metadata.response().status_text(), ProtoResponseTypeToFetchResponseType(metadata.response().response_type()), network::mojom::FetchResponseSource::kCacheStorage, headers, mime_type, - nullptr /* blob */, blink::mojom::ServiceWorkerResponseError::kUnknown, + request_method, nullptr /* blob */, + blink::mojom::ServiceWorkerResponseError::kUnknown, base::Time::FromInternalValue(metadata.response().response_time()), cache_name, std::vector<std::string>( @@ -478,8 +484,12 @@ const std::string& url = response->url_list(response->url_list_size() - 1); bool loaded_with_credentials = response->has_loaded_with_credentials() && response->loaded_with_credentials(); + const std::string& request_method = response->has_request_method() + ? response->request_method() + : net::HttpRequestHeaders::kGetMethod; return storage::ComputeResponsePadding(url, padding_key, side_data_size > 0, - loaded_with_credentials); + loaded_with_credentials, + request_method); } net::RequestPriority GetDiskCachePriority( @@ -1065,7 +1075,8 @@ if (owner_ != CacheStorageOwner::kBackgroundFetch && (!options || !options->ignore_method) && request && - !request->method.empty() && request->method != "GET") { + !request->method.empty() && + request->method != net::HttpRequestHeaders::kGetMethod) { std::move(callback).Run(CacheStorageError::kSuccess, std::make_unique<QueryCacheResults>()); return; @@ -1335,9 +1346,16 @@ DCHECK_GE(side_data_size, 0); if (!ShouldPadResourceSize(response)) return 0; - return storage::ComputeResponsePadding(response.url_list.back().spec(), - padding_key, side_data_size > 0, - response.loaded_with_credentials); + // Going forward we should always have a request method here since its + // impossible to create a no-cors Response via the constructor. We must + // handle a missing method, however, since we may get a Response loaded + // from an old cache_storage instance without the data. + std::string request_method = response.request_method.has_value() + ? response.request_method.value() + : net::HttpRequestHeaders::kGetMethod; + return storage::ComputeResponsePadding( + response.url_list.back().spec(), padding_key, side_data_size > 0, + response.loaded_with_credentials, request_method); } // static @@ -1794,6 +1812,10 @@ put_context->response->was_fetched_via_spdy); if (put_context->response->mime_type.has_value()) response_metadata->set_mime_type(put_context->response->mime_type.value()); + if (put_context->response->request_method.has_value()) { + response_metadata->set_request_method( + put_context->response->request_method.value()); + } response_metadata->set_response_time( put_context->response->response_time.ToInternalValue()); for (ResponseHeaderMap::const_iterator it =
diff --git a/content/browser/form_controls_browsertest.cc b/content/browser/form_controls_browsertest.cc index ac8107e..8f848be 100644 --- a/content/browser/form_controls_browsertest.cc +++ b/content/browser/form_controls_browsertest.cc
@@ -134,14 +134,13 @@ std::unique_ptr<base::test::ScopedFeatureList> feature_list_; }; +// Flaky: https://crbug.com/1091661. #if defined(OS_ANDROID) -#define DISABLED_ON_ANDROID(name) DISABLED##name +#define MAYBE_Checkbox DISABLED_CheckBox #else -#define DISABLED_ON_ANDROID(name) name +#define MAYBE_Checkbox CheckBox #endif - -// Flaky: https://crbug.com/1091661 -IN_PROC_BROWSER_TEST_F(FormControlsBrowserTest, DISABLED_ON_ANDROID(Checkbox)) { +IN_PROC_BROWSER_TEST_F(FormControlsBrowserTest, MAYBE_Checkbox) { RunFormControlsTest( "form_controls_browsertest_checkbox", "<input type=checkbox>" @@ -156,8 +155,13 @@ /* screenshot_height */ 40); } -// Flaky: https://crbug.com/1091661 -IN_PROC_BROWSER_TEST_F(FormControlsBrowserTest, DISABLED_ON_ANDROID(Radio)) { +// Flaky: https://crbug.com/1091661. +#if defined(OS_ANDROID) +#define MAYBE_Radio DISABLED_Radio +#else +#define MAYBE_Radio Radio +#endif +IN_PROC_BROWSER_TEST_F(FormControlsBrowserTest, MAYBE_Radio) { RunFormControlsTest( "form_controls_browsertest_radio", "<input type=radio>"
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc index 2df43b5f..1abf033 100644 --- a/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -1092,7 +1092,7 @@ // First make an existing committed entry. const GURL kExistingURL("http://foo/eh"); NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kExistingURL); - main_test_rfh()->OnMessageReceived(FrameHostMsg_DidStopLoading(0)); + main_test_rfh()->DidStopLoading(); EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0;
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 2cf0ea5..11cd02d 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -1648,7 +1648,7 @@ } void NavigationRequest::RegisterSubresourceOverride( - mojom::TransferrableURLLoaderPtr transferrable_loader) { + blink::mojom::TransferrableURLLoaderPtr transferrable_loader) { if (!transferrable_loader) return; if (!subresource_overrides_)
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index ccaa4324..3b72cc2 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -326,7 +326,7 @@ bool IsSameProcess() override; int GetNavigationEntryOffset() override; void RegisterSubresourceOverride( - mojom::TransferrableURLLoaderPtr transferrable_loader) override; + blink::mojom::TransferrableURLLoaderPtr transferrable_loader) override; GlobalFrameRoutingId GetPreviousRenderFrameHostId() override; bool IsServedFromBackForwardCache() override; void SetIsOverridingUserAgent(bool override_ua) override; @@ -1177,7 +1177,7 @@ // See comment on accessor. const base::UnguessableToken devtools_navigation_token_; - base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides_; // The NavigationClient interface for that requested this navigation in the
diff --git a/content/browser/frame_host/navigator_unittest.cc b/content/browser/frame_host/navigator_unittest.cc index 093a8b8..f21aa07 100644 --- a/content/browser/frame_host/navigator_unittest.cc +++ b/content/browser/frame_host/navigator_unittest.cc
@@ -127,8 +127,7 @@ contents()->NavigateAndCommit(kUrl1); EXPECT_TRUE(main_test_rfh()->IsRenderFrameLive()); - main_test_rfh()->OnMessageReceived( - FrameHostMsg_DidStopLoading(main_test_rfh()->GetRoutingID())); + main_test_rfh()->DidStopLoading(); // Start a renderer-initiated non-user-initiated navigation. EXPECT_FALSE(main_test_rfh()->navigation_request());
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index f07d96e..f41263c2 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1617,7 +1617,6 @@ IPC_MESSAGE_HANDLER(FrameHostMsg_Unload_ACK, OnUnloadACK) IPC_MESSAGE_HANDLER(FrameHostMsg_ContextMenu, OnContextMenu) IPC_MESSAGE_HANDLER(FrameHostMsg_VisualStateResponse, OnVisualStateResponse) - IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading) IPC_MESSAGE_HANDLER(FrameHostMsg_SelectionChanged, OnSelectionChanged) IPC_END_MESSAGE_MAP() @@ -2651,7 +2650,7 @@ // The page is already loaded since it came from the cache, so fire the stop // loading event. - OnDidStopLoading(); + DidStopLoading(); } void RenderFrameHostImpl::DidCommitPerNavigationMojoInterfaceNavigation( @@ -4264,33 +4263,6 @@ delegate_->DOMContentLoaded(this); } -void RenderFrameHostImpl::OnDidStopLoading() { - TRACE_EVENT1("navigation", "RenderFrameHostImpl::OnDidStopLoading", - "frame_tree_node", frame_tree_node_->frame_tree_node_id()); - - // This method should never be called when the frame is not loading. - // Unfortunately, it can happen if a history navigation happens during a - // BeforeUnload or Unload event. - // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been - // refactored in Blink. See crbug.com/466089 - if (!is_loading_) - return; - - was_discarded_ = false; - is_loading_ = false; - - // If we have a PeakGpuMemoryTrack, close it as loading as stopped. It will - // asynchronously receive the statistics from the GPU process, and update - // UMA stats. - if (loading_mem_tracker_) - loading_mem_tracker_.reset(); - - // Only inform the FrameTreeNode of a change in load state if the load state - // of this RenderFrameHost is being tracked. - if (!IsPendingDeletion()) - frame_tree_node_->DidStopLoading(); -} - void RenderFrameHostImpl::OnSelectionChanged(const base::string16& text, uint32_t offset, const gfx::Range& range) { @@ -4575,6 +4547,33 @@ std::move(blob_url_loader_factory), params->impression); } +void RenderFrameHostImpl::DidStopLoading() { + TRACE_EVENT1("navigation", "RenderFrameHostImpl::DidStopLoading", + "frame_tree_node", frame_tree_node_->frame_tree_node_id()); + + // This method should never be called when the frame is not loading. + // Unfortunately, it can happen if a history navigation happens during a + // BeforeUnload or Unload event. + // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been + // refactored in Blink. See crbug.com/466089 + if (!is_loading_) + return; + + was_discarded_ = false; + is_loading_ = false; + + // If we have a PeakGpuMemoryTrack, close it as loading as stopped. It will + // asynchronously receive the statistics from the GPU process, and update + // UMA stats. + if (loading_mem_tracker_) + loading_mem_tracker_.reset(); + + // Only inform the FrameTreeNode of a change in load state if the load state + // of this RenderFrameHost is being tracked. + if (!IsPendingDeletion()) + frame_tree_node_->DidStopLoading(); +} + void RenderFrameHostImpl::GetSavableResourceLinksCallback( blink::mojom::GetSavableResourceLinksReplyPtr reply) { if (!reply) { @@ -5640,7 +5639,7 @@ network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, bool is_view_source, base::Optional<SubresourceLoaderParams> subresource_loader_params, - base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info, const base::UnguessableToken& devtools_navigation_token, @@ -6474,12 +6473,12 @@ void RenderFrameHostImpl::ResetLoadingState() { if (is_loading()) { // When pending deletion, just set the loading state to not loading. - // Otherwise, OnDidStopLoading will take care of that, as well as sending + // Otherwise, DidStopLoading will take care of that, as well as sending // notification to the FrameTreeNode about the change in loading state. if (IsPendingDeletion() || IsInBackForwardCache()) is_loading_ = false; else - OnDidStopLoading(); + DidStopLoading(); } } @@ -7045,7 +7044,8 @@ } void RenderFrameHostImpl::CreateAudioInputStreamFactory( - mojo::PendingReceiver<mojom::RendererAudioInputStreamFactory> receiver) { + mojo::PendingReceiver<blink::mojom::RendererAudioInputStreamFactory> + receiver) { BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance(); DCHECK(browser_main_loop); MediaStreamManager* msm = browser_main_loop->media_stream_manager(); @@ -7054,7 +7054,8 @@ } void RenderFrameHostImpl::CreateAudioOutputStreamFactory( - mojo::PendingReceiver<mojom::RendererAudioOutputStreamFactory> receiver) { + mojo::PendingReceiver<blink::mojom::RendererAudioOutputStreamFactory> + receiver) { media::AudioSystem* audio_system = BrowserMainLoop::GetInstance()->audio_system(); MediaStreamManager* media_stream_manager = @@ -7923,8 +7924,8 @@ // Set is loading to true now if it has not been set yet. This happens for // renderer-initiated same-document navigations. It can also happen when a - // racy DidStopLoading IPC resets the loading state that was set to true in - // CommitNavigation. + // racy DidStopLoading Mojo method resets the loading state that was set to + // true in CommitNavigation. if (!is_loading()) { bool was_loading = frame_tree()->IsLoading(); is_loading_ = true; @@ -8025,7 +8026,7 @@ if (loading_mem_tracker_) loading_mem_tracker_->Cancel(); // Main Frames will create the tracker, which will be triggered after we - // receive OnDidStopLoading. + // receive DidStopLoading. loading_mem_tracker_ = navigation_request->TakePeakGpuMemoryTracker(); network::mojom::ClientSecurityStatePtr client_security_state = @@ -8216,7 +8217,7 @@ network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loader_factories, - base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ControllerServiceWorkerInfoPtr controller, blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info,
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index f339978..74f6470 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -62,7 +62,6 @@ #include "content/public/browser/render_process_host_observer.h" #include "content/public/common/javascript_dialog_type.h" #include "content/public/common/previews_state.h" -#include "content/public/common/transferrable_url_loader.mojom.h" #include "media/mojo/mojom/interface_factory.mojom-forward.h" #include "media/mojo/mojom/media_metrics_provider.mojom-forward.h" #include "media/mojo/services/media_metrics_provider.h" @@ -114,6 +113,7 @@ #include "third_party/blink/public/mojom/input/input_handler.mojom.h" #include "third_party/blink/public/mojom/installedapp/installed_app_provider.mojom.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-forward.h" +#include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_manager.mojom-forward.h" #include "third_party/blink/public/mojom/notifications/notification_service.mojom-forward.h" #include "third_party/blink/public/mojom/payments/payment_app.mojom.h" @@ -892,7 +892,7 @@ network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, bool is_view_source, base::Optional<SubresourceLoaderParams> subresource_loader_params, - base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info, const base::UnguessableToken& devtools_navigation_token, @@ -1380,10 +1380,12 @@ #endif void CreateAudioInputStreamFactory( - mojo::PendingReceiver<mojom::RendererAudioInputStreamFactory> receiver); + mojo::PendingReceiver<blink::mojom::RendererAudioInputStreamFactory> + receiver); void CreateAudioOutputStreamFactory( - mojo::PendingReceiver<mojom::RendererAudioOutputStreamFactory> receiver); + mojo::PendingReceiver<blink::mojom::RendererAudioOutputStreamFactory> + receiver); void GetFeatureObserver( mojo::PendingReceiver<blink::mojom::FeatureObserver> receiver); @@ -1682,6 +1684,7 @@ // mojom::FrameHost: void OpenURL(mojom::OpenURLParamsPtr params) override; + void DidStopLoading() override; void GetSavableResourceLinksFromRenderer(); @@ -1731,7 +1734,7 @@ network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loader_factories, - base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info, @@ -1867,7 +1870,6 @@ void OnForwardResourceTimingToParent( const ResourceTimingInfo& resource_timing); - void OnDidStopLoading(); void OnSelectionChanged(const base::string16& text, uint32_t offset, const gfx::Range& range);
diff --git a/content/browser/hid/hid_service.cc b/content/browser/hid/hid_service.cc index e182c460..efccfa37 100644 --- a/content/browser/hid/hid_service.cc +++ b/content/browser/hid/hid_service.cc
@@ -66,7 +66,7 @@ } void HidService::RegisterClient( - device::mojom::HidManagerClientAssociatedPtrInfo client) { + mojo::PendingAssociatedRemote<device::mojom::HidManagerClient> client) { clients_.Add(std::move(client)); }
diff --git a/content/browser/hid/hid_service.h b/content/browser/hid/hid_service.h index 07abd499..ead8fe0 100644 --- a/content/browser/hid/hid_service.h +++ b/content/browser/hid/hid_service.h
@@ -39,7 +39,8 @@ // blink::mojom::HidService: void RegisterClient( - device::mojom::HidManagerClientAssociatedPtrInfo client) override; + mojo::PendingAssociatedRemote<device::mojom::HidManagerClient> client) + override; void GetDevices(GetDevicesCallback callback) override; void RequestDevice(std::vector<blink::mojom::HidDeviceFilterPtr> filters, RequestDeviceCallback callback) override;
diff --git a/content/browser/media/audio_input_stream_broker.cc b/content/browser/media/audio_input_stream_broker.cc index 32bdf7e4..5e50a03 100644 --- a/content/browser/media/audio_input_stream_broker.cc +++ b/content/browser/media/audio_input_stream_broker.cc
@@ -66,7 +66,7 @@ media::UserInputMonitorBase* user_input_monitor, bool enable_agc, AudioStreamBroker::DeleterCallback deleter, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client) : AudioStreamBroker(render_process_id, render_frame_id), device_id_(device_id),
diff --git a/content/browser/media/audio_input_stream_broker.h b/content/browser/media/audio_input_stream_broker.h index c77b7ed..51abc29 100644 --- a/content/browser/media/audio_input_stream_broker.h +++ b/content/browser/media/audio_input_stream_broker.h
@@ -11,7 +11,6 @@ #include "base/memory/weak_ptr.h" #include "content/browser/media/audio_stream_broker.h" #include "content/common/content_export.h" -#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "media/base/audio_parameters.h" #include "media/mojo/mojom/audio_data_pipe.mojom.h" #include "media/mojo/mojom/audio_input_stream.mojom.h" @@ -20,6 +19,7 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/audio/public/mojom/stream_factory.mojom.h" +#include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" namespace media { class UserInputMonitorBase; @@ -42,7 +42,7 @@ media::UserInputMonitorBase* user_input_monitor, bool enable_agc, AudioStreamBroker::DeleterCallback deleter, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client); ~AudioInputStreamBroker() final; @@ -74,7 +74,7 @@ DeleterCallback deleter_; - mojo::Remote<mojom::RendererAudioInputStreamFactoryClient> + mojo::Remote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client_; mojo::Receiver<AudioInputStreamObserver> observer_receiver_{this}; mojo::PendingReceiver<media::mojom::AudioInputStreamClient>
diff --git a/content/browser/media/audio_input_stream_broker_unittest.cc b/content/browser/media/audio_input_stream_broker_unittest.cc index 6c028e0a..0f0c668 100644 --- a/content/browser/media/audio_input_stream_broker_unittest.cc +++ b/content/browser/media/audio_input_stream_broker_unittest.cc
@@ -43,12 +43,12 @@ base::MockCallback<base::OnceCallback<void(AudioStreamBroker*)>>>; class MockRendererAudioInputStreamFactoryClient - : public mojom::RendererAudioInputStreamFactoryClient { + : public blink::mojom::RendererAudioInputStreamFactoryClient { public: MockRendererAudioInputStreamFactoryClient() = default; ~MockRendererAudioInputStreamFactoryClient() override = default; - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> MakeRemote() { return receiver_.BindNewPipeAndPassRemote(); } @@ -71,7 +71,8 @@ void CloseReceiver() { receiver_.reset(); } private: - mojo::Receiver<mojom::RendererAudioInputStreamFactoryClient> receiver_{this}; + mojo::Receiver<blink::mojom::RendererAudioInputStreamFactoryClient> receiver_{ + this}; mojo::Remote<media::mojom::AudioInputStream> input_stream_; mojo::PendingReceiver<media::mojom::AudioInputStreamClient> client_receiver_; DISALLOW_COPY_AND_ASSIGN(MockRendererAudioInputStreamFactoryClient);
diff --git a/content/browser/media/audio_loopback_stream_broker.cc b/content/browser/media/audio_loopback_stream_broker.cc index 034c0e5..d5826e4 100644 --- a/content/browser/media/audio_loopback_stream_broker.cc +++ b/content/browser/media/audio_loopback_stream_broker.cc
@@ -25,7 +25,7 @@ uint32_t shared_memory_count, bool mute_source, AudioStreamBroker::DeleterCallback deleter, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client) : AudioStreamBroker(render_process_id, render_frame_id), source_(source),
diff --git a/content/browser/media/audio_loopback_stream_broker.h b/content/browser/media/audio_loopback_stream_broker.h index 36bbf04..6cdc94eb 100644 --- a/content/browser/media/audio_loopback_stream_broker.h +++ b/content/browser/media/audio_loopback_stream_broker.h
@@ -45,7 +45,7 @@ uint32_t shared_memory_count, bool mute_source, AudioStreamBroker::DeleterCallback deleter, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client); ~AudioLoopbackStreamBroker() final; @@ -76,7 +76,7 @@ // loopback stream is running. base::Optional<AudioMutingSession> muter_; - mojo::Remote<mojom::RendererAudioInputStreamFactoryClient> + mojo::Remote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client_; mojo::Receiver<AudioInputStreamObserver> observer_receiver_{this}; mojo::PendingReceiver<media::mojom::AudioInputStreamClient> client_receiver_;
diff --git a/content/browser/media/audio_loopback_stream_broker_unittest.cc b/content/browser/media/audio_loopback_stream_broker_unittest.cc index 6e5edf9..8f558e7 100644 --- a/content/browser/media/audio_loopback_stream_broker_unittest.cc +++ b/content/browser/media/audio_loopback_stream_broker_unittest.cc
@@ -59,12 +59,12 @@ base::MockCallback<base::OnceCallback<void(AudioStreamBroker*)>>>; class MockRendererAudioInputStreamFactoryClient - : public mojom::RendererAudioInputStreamFactoryClient { + : public blink::mojom::RendererAudioInputStreamFactoryClient { public: MockRendererAudioInputStreamFactoryClient() = default; ~MockRendererAudioInputStreamFactoryClient() override {} - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> MakeRemote() { return receiver_.BindNewPipeAndPassRemote(); } @@ -88,7 +88,8 @@ void CloseReceiver() { receiver_.reset(); } private: - mojo::Receiver<mojom::RendererAudioInputStreamFactoryClient> receiver_{this}; + mojo::Receiver<blink::mojom::RendererAudioInputStreamFactoryClient> receiver_{ + this}; mojo::Remote<media::mojom::AudioInputStream> input_stream_; mojo::PendingReceiver<media::mojom::AudioInputStreamClient> client_receiver_; };
diff --git a/content/browser/media/audio_stream_broker.cc b/content/browser/media/audio_stream_broker.cc index e4d9ad9..744855a7 100644 --- a/content/browser/media/audio_stream_broker.cc +++ b/content/browser/media/audio_stream_broker.cc
@@ -33,7 +33,7 @@ media::UserInputMonitorBase* user_input_monitor, bool enable_agc, AudioStreamBroker::DeleterCallback deleter, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client) final { return std::make_unique<AudioInputStreamBroker>( render_process_id, render_frame_id, device_id, params, @@ -49,7 +49,7 @@ uint32_t shared_memory_count, bool mute_source, AudioStreamBroker::DeleterCallback deleter, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client) final { return std::make_unique<AudioLoopbackStreamBroker>( render_process_id, render_frame_id, source, params, shared_memory_count,
diff --git a/content/browser/media/audio_stream_broker.h b/content/browser/media/audio_stream_broker.h index fd80dd5..105dc77 100644 --- a/content/browser/media/audio_stream_broker.h +++ b/content/browser/media/audio_stream_broker.h
@@ -13,10 +13,10 @@ #include "base/macros.h" #include "base/optional.h" #include "content/common/content_export.h" -#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "media/mojo/mojom/audio_input_stream.mojom.h" #include "media/mojo/mojom/audio_output_stream.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h" +#include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" namespace audio { namespace mojom { @@ -106,7 +106,7 @@ media::UserInputMonitorBase* user_input_monitor, bool enable_agc, AudioStreamBroker::DeleterCallback deleter, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client) = 0; virtual std::unique_ptr<AudioStreamBroker> CreateAudioLoopbackStreamBroker( @@ -117,7 +117,7 @@ uint32_t shared_memory_count, bool mute_source, AudioStreamBroker::DeleterCallback deleter, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client) = 0; virtual std::unique_ptr<AudioStreamBroker> CreateAudioOutputStreamBroker(
diff --git a/content/browser/media/forwarding_audio_stream_factory.cc b/content/browser/media/forwarding_audio_stream_factory.cc index 2e33951..fba4ac53 100644 --- a/content/browser/media/forwarding_audio_stream_factory.cc +++ b/content/browser/media/forwarding_audio_stream_factory.cc
@@ -79,7 +79,7 @@ const media::AudioParameters& params, uint32_t shared_memory_count, bool enable_agc, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -134,7 +134,7 @@ const media::AudioParameters& params, uint32_t shared_memory_count, bool mute_source, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client) { DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(loopback_source);
diff --git a/content/browser/media/forwarding_audio_stream_factory.h b/content/browser/media/forwarding_audio_stream_factory.h index 7ba03b9c..8fb6fd8 100644 --- a/content/browser/media/forwarding_audio_stream_factory.h +++ b/content/browser/media/forwarding_audio_stream_factory.h
@@ -18,12 +18,12 @@ #include "content/browser/media/audio_muting_session.h" #include "content/browser/media/audio_stream_broker.h" #include "content/common/content_export.h" -#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "content/public/browser/web_contents_observer.h" #include "media/mojo/mojom/audio_output_stream.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/audio/public/mojom/stream_factory.mojom.h" +#include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" namespace media { class AudioParameters; @@ -73,7 +73,7 @@ const media::AudioParameters& params, uint32_t shared_memory_count, bool enable_agc, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client); void AssociateInputAndOutputForAec( @@ -95,7 +95,7 @@ const media::AudioParameters& params, uint32_t shared_memory_count, bool mute_source, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client); // Sets the muting state for all output streams created through this
diff --git a/content/browser/media/forwarding_audio_stream_factory_unittest.cc b/content/browser/media/forwarding_audio_stream_factory_unittest.cc index fa9ae1c9..67081cc 100644 --- a/content/browser/media/forwarding_audio_stream_factory_unittest.cc +++ b/content/browser/media/forwarding_audio_stream_factory_unittest.cc
@@ -13,7 +13,6 @@ #include "base/run_loop.h" #include "base/test/mock_callback.h" #include "base/unguessable_token.h" -#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "content/public/test/test_renderer_host.h" @@ -26,6 +25,7 @@ #include "services/audio/public/mojom/stream_factory.mojom.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" using ::testing::Test; using ::testing::Mock; @@ -110,7 +110,7 @@ media::UserInputMonitorBase* user_input_monitor, bool enable_agc, AudioStreamBroker::DeleterCallback deleter, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client) final { std::unique_ptr<MockBroker> prepared_broker = std::move(prepared_input_stream_brokers_.front()); @@ -150,7 +150,7 @@ uint32_t shared_memory_count, bool mute_source, AudioStreamBroker::DeleterCallback deleter, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> renderer_factory_client) final { std::unique_ptr<MockBroker> prepared_broker = std::move(prepared_loopback_stream_brokers_.front()); @@ -258,7 +258,8 @@ } // namespace TEST_F(ForwardingAudioStreamFactoryTest, CreateInputStream_CreatesInputStream) { - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client; + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client; base::WeakPtr<MockBroker> broker = ExpectInputBrokerConstruction(main_rfh()); ForwardingAudioStreamFactory factory(web_contents(), @@ -276,7 +277,8 @@ TEST_F(ForwardingAudioStreamFactoryTest, CreateLoopbackStream_CreatesLoopbackStream) { std::unique_ptr<WebContents> source_contents = CreateTestWebContents(); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client; + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client; base::WeakPtr<MockBroker> broker = ExpectLoopbackBrokerConstruction(main_rfh()); @@ -325,7 +327,8 @@ { EXPECT_CALL(*main_rfh_broker, CreateStream(NotNull())); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client; + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client; ignore_result(client.InitWithNewPipeAndPassReceiver()); factory.core()->CreateInputStream( main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(), @@ -335,7 +338,8 @@ } { EXPECT_CALL(*other_rfh_broker, CreateStream(NotNull())); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client; + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client; ignore_result(client.InitWithNewPipeAndPassReceiver()); factory.core()->CreateInputStream( other_rfh()->GetProcess()->GetID(), other_rfh()->GetRoutingID(), @@ -368,7 +372,8 @@ { EXPECT_CALL(*main_rfh_broker, CreateStream(NotNull())); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client; + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client; ignore_result(client.InitWithNewPipeAndPassReceiver()); factory.core()->CreateLoopbackStream( main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(), @@ -378,7 +383,8 @@ } { EXPECT_CALL(*other_rfh_broker, CreateStream(NotNull())); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client; + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client; ignore_result(client.InitWithNewPipeAndPassReceiver()); factory.core()->CreateLoopbackStream( other_rfh()->GetProcess()->GetID(), other_rfh()->GetRoutingID(), @@ -457,7 +463,7 @@ { EXPECT_CALL(*main_rfh_input_broker, CreateStream(NotNull())); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> input_client; ignore_result(input_client.InitWithNewPipeAndPassReceiver()); factory.core()->CreateInputStream( @@ -468,7 +474,7 @@ } { EXPECT_CALL(*other_rfh_input_broker, CreateStream(NotNull())); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> input_client; ignore_result(input_client.InitWithNewPipeAndPassReceiver()); factory.core()->CreateInputStream( @@ -480,7 +486,7 @@ { EXPECT_CALL(*main_rfh_loopback_broker, CreateStream(NotNull())); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> input_client; ignore_result(input_client.InitWithNewPipeAndPassReceiver()); factory.core()->CreateLoopbackStream( @@ -491,7 +497,7 @@ } { EXPECT_CALL(*other_rfh_loopback_broker, CreateStream(NotNull())); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> input_client; ignore_result(input_client.InitWithNewPipeAndPassReceiver()); factory.core()->CreateLoopbackStream( @@ -537,7 +543,7 @@ } TEST_F(ForwardingAudioStreamFactoryTest, DestroyWebContents_DestroysStreams) { - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> input_client; base::WeakPtr<MockBroker> input_broker = ExpectInputBrokerConstruction(main_rfh()); @@ -590,7 +596,7 @@ { EXPECT_CALL(*main_rfh_input_broker, CreateStream(NotNull())); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> input_client; ignore_result(input_client.InitWithNewPipeAndPassReceiver()); factory.core()->CreateInputStream( @@ -601,7 +607,7 @@ } { EXPECT_CALL(*other_rfh_input_broker, CreateStream(NotNull())); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> input_client; ignore_result(input_client.InitWithNewPipeAndPassReceiver()); factory.core()->CreateInputStream(
diff --git a/content/browser/media/in_process_audio_loopback_stream_creator.cc b/content/browser/media/in_process_audio_loopback_stream_creator.cc index 2257a7c..9b99b38 100644 --- a/content/browser/media/in_process_audio_loopback_stream_creator.cc +++ b/content/browser/media/in_process_audio_loopback_stream_creator.cc
@@ -12,7 +12,6 @@ #include "base/location.h" #include "content/browser/browser_main_loop.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" @@ -20,16 +19,17 @@ #include "media/base/user_input_monitor.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" +#include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" namespace content { namespace { -// A mojom::RendererAudioInputStreamFactoryClient that holds a +// A blink::mojom::RendererAudioInputStreamFactoryClient that holds a // AudioLoopbackStreamCreator::StreamCreatedCallback. The callback runs when the // requested audio stream is created. class StreamCreatedCallbackAdapter final - : public mojom::RendererAudioInputStreamFactoryClient { + : public blink::mojom::RendererAudioInputStreamFactoryClient { public: explicit StreamCreatedCallbackAdapter( const AudioLoopbackStreamCreator::StreamCreatedCallback& callback) @@ -39,7 +39,7 @@ ~StreamCreatedCallbackAdapter() override {} - // mojom::RendererAudioInputStreamFactoryClient implementation. + // blink::mojom::RendererAudioInputStreamFactoryClient implementation. void StreamCreated( mojo::PendingRemote<media::mojom::AudioInputStream> stream, mojo::PendingReceiver<media::mojom::AudioInputStreamClient> @@ -63,7 +63,7 @@ AudioStreamBroker::LoopbackSource* loopback_source, const media::AudioParameters& params, uint32_t total_segments, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> client_remote) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -76,7 +76,7 @@ ForwardingAudioStreamFactory::Core* factory, const media::AudioParameters& params, uint32_t total_segments, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> client_remote) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -108,7 +108,8 @@ uint32_t total_segments, const StreamCreatedCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client; + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client; mojo::MakeSelfOwnedReceiver( std::make_unique<StreamCreatedCallbackAdapter>(callback), client.InitWithNewPipeAndPassReceiver());
diff --git a/content/browser/net/cross_origin_opener_policy_reporter.cc b/content/browser/net/cross_origin_opener_policy_reporter.cc index 71e99b2..ff079b3 100644 --- a/content/browser/net/cross_origin_opener_policy_reporter.cc +++ b/content/browser/net/cross_origin_opener_policy_reporter.cc
@@ -19,20 +19,20 @@ namespace { -constexpr char kUnsafeNone[] = "unsafe-none"; -constexpr char kSameOrigin[] = "same-origin"; -constexpr char kSameOriginPlusCoep[] = "same-origin-plus-coep"; -constexpr char kSameOriginAllowPopups[] = "same-origin-allow-popups"; - -constexpr char kDisposition[] = "disposition"; constexpr char kDispositionEnforce[] = "enforce"; constexpr char kDispositionReporting[] = "reporting"; +constexpr char kDisposition[] = "disposition"; constexpr char kDocumentURI[] = "document-uri"; +constexpr char kEffectivePolicy[] = "effective-policy"; constexpr char kNavigationURI[] = "navigation-uri"; -constexpr char kViolationType[] = "violation-type"; +constexpr char kProperty[] = "property"; +constexpr char kSameOriginAllowPopups[] = "same-origin-allow-popups"; +constexpr char kSameOriginPlusCoep[] = "same-origin-plus-coep"; +constexpr char kSameOrigin[] = "same-origin"; +constexpr char kUnsafeNone[] = "unsafe-none"; constexpr char kViolationTypeFromDocument[] = "navigation-from-document"; constexpr char kViolationTypeToDocument[] = "navigation-to-document"; -constexpr char kEffectivePolicy[] = "effective-policy"; +constexpr char kViolationType[] = "violation-type"; std::string CoopValueToString( network::mojom::CrossOriginOpenerPolicyValue coop_value) { @@ -169,7 +169,28 @@ void CrossOriginOpenerPolicyReporter::QueueAccessReport( const std::string& property) { - // TODO(arthursonzogni) Implement this. + // Cross-Origin-Opener-Policy-Report-Only is not required to provide + // endpoints. + if (!coop_.report_only_reporting_endpoint) + return; + + const std::string& endpoint = coop_.report_only_reporting_endpoint.value(); + + DCHECK(base::FeatureList::IsEnabled( + network::features::kCrossOriginOpenerPolicyAccessReporting)); + + base::DictionaryValue body; + body.SetStringPath(kDisposition, kDispositionReporting); + body.SetStringPath(kEffectivePolicy, + CoopValueToString(coop_.report_only_value)); + body.SetStringPath(kProperty, property); + // TODO(arthursonzogni): Fill "blocked-window-url". + // TODO(arthursonzogni): Fill "source-file". + // TODO(arthursonzogni): Fill "line-no". + // TODO(arthursonzogni): Fill "col-no". + // TODO(arthursonzogni): Fill "violation-type". + storage_partition_->GetNetworkContext()->QueueReport( + "coop", endpoint, context_url_, base::nullopt, std::move(body)); } void CrossOriginOpenerPolicyReporter::Clone(
diff --git a/content/browser/renderer_host/media/audio_input_stream_handle.cc b/content/browser/renderer_host/media/audio_input_stream_handle.cc index 9401577..2010053 100644 --- a/content/browser/renderer_host/media/audio_input_stream_handle.cc +++ b/content/browser/renderer_host/media/audio_input_stream_handle.cc
@@ -24,7 +24,7 @@ } // namespace AudioInputStreamHandle::AudioInputStreamHandle( - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> client_pending_remote, media::MojoAudioInputStream::CreateDelegateCallback create_delegate_callback,
diff --git a/content/browser/renderer_host/media/audio_input_stream_handle.h b/content/browser/renderer_host/media/audio_input_stream_handle.h index 799519a..b8dd45b2 100644 --- a/content/browser/renderer_host/media/audio_input_stream_handle.h +++ b/content/browser/renderer_host/media/audio_input_stream_handle.h
@@ -9,7 +9,6 @@ #include "base/macros.h" #include "base/sequence_checker.h" #include "content/common/content_export.h" -#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "media/mojo/mojom/audio_data_pipe.mojom.h" #include "media/mojo/mojom/audio_input_stream.mojom.h" #include "media/mojo/services/mojo_audio_input_stream.h" @@ -18,6 +17,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/system/buffer.h" #include "mojo/public/cpp/system/handle.h" +#include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" namespace content { @@ -30,7 +30,7 @@ // |deleter_callback| will be called when encountering an error, in which // case |this| should be synchronously destructed by its owner. AudioInputStreamHandle( - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> client_pending_remote, media::MojoAudioInputStream::CreateDelegateCallback create_delegate_callback, @@ -49,7 +49,8 @@ SEQUENCE_CHECKER(sequence_checker_); const base::UnguessableToken stream_id_; DeleterCallback deleter_callback_; - mojo::Remote<mojom::RendererAudioInputStreamFactoryClient> client_remote_; + mojo::Remote<blink::mojom::RendererAudioInputStreamFactoryClient> + client_remote_; mojo::PendingRemote<media::mojom::AudioInputStream> pending_stream_; mojo::PendingReceiver<media::mojom::AudioInputStreamClient> pending_stream_client_;
diff --git a/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc b/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc index f066c1d..278f7a8 100644 --- a/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc +++ b/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc
@@ -44,7 +44,7 @@ }; class MockRendererAudioInputStreamFactoryClient - : public mojom::RendererAudioInputStreamFactoryClient { + : public blink::mojom::RendererAudioInputStreamFactoryClient { public: MOCK_METHOD0(Created, void()); @@ -129,9 +129,10 @@ private: base::test::SingleThreadTaskEnvironment task_environment_; StrictMock<MockRendererAudioInputStreamFactoryClient> client_; - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> client_pending_remote_; - mojo::Receiver<mojom::RendererAudioInputStreamFactoryClient> client_receiver_; + mojo::Receiver<blink::mojom::RendererAudioInputStreamFactoryClient> + client_receiver_; StrictMock<MockDeleter> deleter_; media::AudioInputDelegate::EventHandler* event_handler_ = nullptr; std::unique_ptr<AudioInputStreamHandle> handle_;
diff --git a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc index acc14c6..27cdbf3 100644 --- a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc +++ b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc
@@ -98,20 +98,22 @@ } // namespace class RenderFrameAudioInputStreamFactory::Core final - : public mojom::RendererAudioInputStreamFactory { + : public blink::mojom::RendererAudioInputStreamFactory { public: - Core(mojo::PendingReceiver<mojom::RendererAudioInputStreamFactory> receiver, + Core(mojo::PendingReceiver<blink::mojom::RendererAudioInputStreamFactory> + receiver, MediaStreamManager* media_stream_manager, RenderFrameHost* render_frame_host); ~Core() final; - void Init( - mojo::PendingReceiver<mojom::RendererAudioInputStreamFactory> receiver); + void Init(mojo::PendingReceiver<blink::mojom::RendererAudioInputStreamFactory> + receiver); // mojom::RendererAudioInputStreamFactory implementation. void CreateStream( - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client, + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client, const base::UnguessableToken& session_id, const media::AudioParameters& audio_params, bool automatic_gain_control, @@ -122,7 +124,8 @@ const std::string& output_device_id) final; void CreateLoopbackStream( - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client, + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client, const media::AudioParameters& audio_params, uint32_t shared_memory_count, bool disable_local_echo, @@ -153,7 +156,8 @@ }; RenderFrameAudioInputStreamFactory::RenderFrameAudioInputStreamFactory( - mojo::PendingReceiver<mojom::RendererAudioInputStreamFactory> receiver, + mojo::PendingReceiver<blink::mojom::RendererAudioInputStreamFactory> + receiver, MediaStreamManager* media_stream_manager, RenderFrameHost* render_frame_host) : core_(new Core(std::move(receiver), @@ -174,7 +178,8 @@ } RenderFrameAudioInputStreamFactory::Core::Core( - mojo::PendingReceiver<mojom::RendererAudioInputStreamFactory> receiver, + mojo::PendingReceiver<blink::mojom::RendererAudioInputStreamFactory> + receiver, MediaStreamManager* media_stream_manager, RenderFrameHost* render_frame_host) : media_stream_manager_(media_stream_manager), @@ -207,13 +212,15 @@ } void RenderFrameAudioInputStreamFactory::Core::Init( - mojo::PendingReceiver<mojom::RendererAudioInputStreamFactory> receiver) { + mojo::PendingReceiver<blink::mojom::RendererAudioInputStreamFactory> + receiver) { DCHECK_CURRENTLY_ON(BrowserThread::IO); receiver_.Bind(std::move(receiver)); } void RenderFrameAudioInputStreamFactory::Core::CreateStream( - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client, + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client, const base::UnguessableToken& session_id, const media::AudioParameters& audio_params, bool automatic_gain_control, @@ -273,7 +280,8 @@ } void RenderFrameAudioInputStreamFactory::Core::CreateLoopbackStream( - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client, + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client, const media::AudioParameters& audio_params, uint32_t shared_memory_count, bool disable_local_echo,
diff --git a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h index 1fe77c4..3ae9d0db 100644 --- a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h +++ b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h
@@ -9,8 +9,8 @@ #include "base/macros.h" #include "content/common/content_export.h" -#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" namespace content { @@ -26,7 +26,8 @@ class CONTENT_EXPORT RenderFrameAudioInputStreamFactory final { public: RenderFrameAudioInputStreamFactory( - mojo::PendingReceiver<mojom::RendererAudioInputStreamFactory> receiver, + mojo::PendingReceiver<blink::mojom::RendererAudioInputStreamFactory> + receiver, MediaStreamManager* media_stream_manager, RenderFrameHost* render_frame_host);
diff --git a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc index d0837a3b..0ef2ddd 100644 --- a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc +++ b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc
@@ -127,7 +127,7 @@ }; class FakeRendererAudioInputStreamFactoryClient - : public mojom::RendererAudioInputStreamFactoryClient { + : public blink::mojom::RendererAudioInputStreamFactoryClient { public: void StreamCreated( mojo::PendingRemote<media::mojom::AudioInputStream> stream, @@ -187,7 +187,7 @@ }; TEST_F(MAYBE_RenderFrameAudioInputStreamFactoryTest, ConstructDestruct) { - mojo::Remote<mojom::RendererAudioInputStreamFactory> factory_remote; + mojo::Remote<blink::mojom::RendererAudioInputStreamFactory> factory_remote; RenderFrameAudioInputStreamFactory factory( factory_remote.BindNewPipeAndPassReceiver(), media_stream_manager_.get(), main_rfh()); @@ -195,7 +195,7 @@ TEST_F(MAYBE_RenderFrameAudioInputStreamFactoryTest, CreateOpenedStream_ForwardsCall) { - mojo::Remote<mojom::RendererAudioInputStreamFactory> factory_remote; + mojo::Remote<blink::mojom::RendererAudioInputStreamFactory> factory_remote; RenderFrameAudioInputStreamFactory factory( factory_remote.BindNewPipeAndPassReceiver(), media_stream_manager_.get(), main_rfh()); @@ -206,7 +206,8 @@ kDeviceName)); base::RunLoop().RunUntilIdle(); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client; + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client; ignore_result(client.InitWithNewPipeAndPassReceiver()); factory_remote->CreateStream(std::move(client), session_id, kParams, kAGC, kSharedMemoryCount); @@ -219,7 +220,7 @@ TEST_F(MAYBE_RenderFrameAudioInputStreamFactoryTest, CreateWebContentsCapture_ForwardsCall) { std::unique_ptr<WebContents> source_contents = CreateTestWebContents(); - mojo::Remote<mojom::RendererAudioInputStreamFactory> factory_remote; + mojo::Remote<blink::mojom::RendererAudioInputStreamFactory> factory_remote; RenderFrameAudioInputStreamFactory factory( factory_remote.BindNewPipeAndPassReceiver(), media_stream_manager_.get(), main_rfh()); @@ -233,7 +234,8 @@ capture_id.ToString(), kDeviceName)); base::RunLoop().RunUntilIdle(); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client; + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client; ignore_result(client.InitWithNewPipeAndPassReceiver()); factory_remote->CreateStream(std::move(client), session_id, kParams, kAGC, kSharedMemoryCount); @@ -246,7 +248,7 @@ TEST_F(MAYBE_RenderFrameAudioInputStreamFactoryTest, CreateWebContentsCaptureAfterCaptureSourceDestructed_Fails) { std::unique_ptr<WebContents> source_contents = CreateTestWebContents(); - mojo::Remote<mojom::RendererAudioInputStreamFactory> factory_remote; + mojo::Remote<blink::mojom::RendererAudioInputStreamFactory> factory_remote; RenderFrameAudioInputStreamFactory factory( factory_remote.BindNewPipeAndPassReceiver(), media_stream_manager_.get(), main_rfh()); @@ -261,7 +263,8 @@ base::RunLoop().RunUntilIdle(); source_contents.reset(); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client; + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client; ignore_result(client.InitWithNewPipeAndPassReceiver()); factory_remote->CreateStream(std::move(client), session_id, kParams, kAGC, kSharedMemoryCount); @@ -273,13 +276,14 @@ TEST_F(MAYBE_RenderFrameAudioInputStreamFactoryTest, CreateStreamWithoutValidSessionId_Fails) { - mojo::Remote<mojom::RendererAudioInputStreamFactory> factory_remote; + mojo::Remote<blink::mojom::RendererAudioInputStreamFactory> factory_remote; RenderFrameAudioInputStreamFactory factory( factory_remote.BindNewPipeAndPassReceiver(), media_stream_manager_.get(), main_rfh()); base::UnguessableToken session_id = base::UnguessableToken::Create(); - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client; + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client; ignore_result(client.InitWithNewPipeAndPassReceiver()); factory_remote->CreateStream(std::move(client), session_id, kParams, kAGC, kSharedMemoryCount);
diff --git a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc index 5f2a7fc6..4099192 100644 --- a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc +++ b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc
@@ -34,17 +34,19 @@ namespace content { class RenderFrameAudioOutputStreamFactory::Core final - : public mojom::RendererAudioOutputStreamFactory { + : public blink::mojom::RendererAudioOutputStreamFactory { public: Core(RenderFrameHost* frame, media::AudioSystem* audio_system, MediaStreamManager* media_stream_manager, - mojo::PendingReceiver<mojom::RendererAudioOutputStreamFactory> receiver); + mojo::PendingReceiver<blink::mojom::RendererAudioOutputStreamFactory> + receiver); ~Core() final = default; void Init( - mojo::PendingReceiver<mojom::RendererAudioOutputStreamFactory> receiver); + mojo::PendingReceiver<blink::mojom::RendererAudioOutputStreamFactory> + receiver); size_t current_number_of_providers_for_testing() { return stream_providers_.size(); @@ -107,7 +109,7 @@ base::flat_set<std::unique_ptr<media::mojom::AudioOutputStreamProvider>, base::UniquePtrComparator>; - // mojom::RendererAudioOutputStreamFactory implementation. + // blink::mojom::RendererAudioOutputStreamFactory implementation. void RequestDeviceAuthorization( mojo::PendingReceiver<media::mojom::AudioOutputStreamProvider> provider_receiver, @@ -134,7 +136,8 @@ const int frame_id_; AudioOutputAuthorizationHandler authorization_handler_; - mojo::Receiver<mojom::RendererAudioOutputStreamFactory> receiver_{this}; + mojo::Receiver<blink::mojom::RendererAudioOutputStreamFactory> receiver_{ + this}; // Always null-check this weak pointer before dereferencing it. base::WeakPtr<ForwardingAudioStreamFactory::Core> forwarding_factory_; @@ -154,7 +157,8 @@ RenderFrameHost* frame, media::AudioSystem* audio_system, MediaStreamManager* media_stream_manager, - mojo::PendingReceiver<mojom::RendererAudioOutputStreamFactory> receiver) + mojo::PendingReceiver<blink::mojom::RendererAudioOutputStreamFactory> + receiver) : core_(new Core(frame, audio_system, media_stream_manager, @@ -183,7 +187,8 @@ RenderFrameHost* frame, media::AudioSystem* audio_system, MediaStreamManager* media_stream_manager, - mojo::PendingReceiver<mojom::RendererAudioOutputStreamFactory> receiver) + mojo::PendingReceiver<blink::mojom::RendererAudioOutputStreamFactory> + receiver) : process_id_(frame->GetProcess()->GetID()), frame_id_(frame->GetRoutingID()), authorization_handler_(audio_system, media_stream_manager, process_id_) { @@ -209,7 +214,8 @@ } void RenderFrameAudioOutputStreamFactory::Core::Init( - mojo::PendingReceiver<mojom::RendererAudioOutputStreamFactory> receiver) { + mojo::PendingReceiver<blink::mojom::RendererAudioOutputStreamFactory> + receiver) { DCHECK_CURRENTLY_ON(BrowserThread::IO); receiver_.Bind(std::move(receiver));
diff --git a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h index 34bd3afa..bc30cad 100644 --- a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h +++ b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h
@@ -10,8 +10,8 @@ #include "base/macros.h" #include "content/common/content_export.h" -#include "content/common/media/renderer_audio_output_stream_factory.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom.h" namespace media { class AudioSystem; @@ -46,7 +46,8 @@ RenderFrameHost* frame, media::AudioSystem* audio_system, MediaStreamManager* media_stream_manager, - mojo::PendingReceiver<mojom::RendererAudioOutputStreamFactory> receiver); + mojo::PendingReceiver<blink::mojom::RendererAudioOutputStreamFactory> + receiver); ~RenderFrameAudioOutputStreamFactory();
diff --git a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc index dbe40d2..1533544e 100644 --- a/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc +++ b/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc
@@ -121,7 +121,7 @@ }; TEST_F(RenderFrameAudioOutputStreamFactoryTest, ConstructDestruct) { - mojo::Remote<mojom::RendererAudioOutputStreamFactory> factory_remote; + mojo::Remote<blink::mojom::RendererAudioOutputStreamFactory> factory_remote; RenderFrameAudioOutputStreamFactory factory( main_rfh(), audio_system_.get(), media_stream_manager_.get(), factory_remote.BindNewPipeAndPassReceiver()); @@ -129,7 +129,7 @@ TEST_F(RenderFrameAudioOutputStreamFactoryTest, RequestDeviceAuthorizationForDefaultDevice_StatusOk) { - mojo::Remote<mojom::RendererAudioOutputStreamFactory> factory_remote; + mojo::Remote<blink::mojom::RendererAudioOutputStreamFactory> factory_remote; RenderFrameAudioOutputStreamFactory factory( main_rfh(), audio_system_.get(), media_stream_manager_.get(), factory_remote.BindNewPipeAndPassReceiver()); @@ -151,7 +151,7 @@ TEST_F( RenderFrameAudioOutputStreamFactoryTest, RequestDeviceAuthorizationForDefaultDeviceAndDestroyProviderPtr_CleansUp) { - mojo::Remote<mojom::RendererAudioOutputStreamFactory> factory_remote; + mojo::Remote<blink::mojom::RendererAudioOutputStreamFactory> factory_remote; RenderFrameAudioOutputStreamFactory factory( main_rfh(), audio_system_.get(), media_stream_manager_.get(), factory_remote.BindNewPipeAndPassReceiver()); @@ -174,7 +174,7 @@ TEST_F( RenderFrameAudioOutputStreamFactoryTest, RequestDeviceAuthorizationForNondefaultDeviceWithoutAuthorization_Fails) { - mojo::Remote<mojom::RendererAudioOutputStreamFactory> factory_remote; + mojo::Remote<blink::mojom::RendererAudioOutputStreamFactory> factory_remote; RenderFrameAudioOutputStreamFactory factory( main_rfh(), audio_system_.get(), media_stream_manager_.get(), factory_remote.BindNewPipeAndPassReceiver()); @@ -195,7 +195,7 @@ TEST_F(RenderFrameAudioOutputStreamFactoryTest, CreateStream_CreatesStreamAndFreesProvider) { - mojo::Remote<mojom::RendererAudioOutputStreamFactory> factory_remote; + mojo::Remote<blink::mojom::RendererAudioOutputStreamFactory> factory_remote; RenderFrameAudioOutputStreamFactory factory( main_rfh(), audio_system_.get(), media_stream_manager_.get(), factory_remote.BindNewPipeAndPassReceiver()); @@ -227,7 +227,7 @@ MockAuthorizationCallback mock_callback; { - mojo::Remote<mojom::RendererAudioOutputStreamFactory> factory_remote; + mojo::Remote<blink::mojom::RendererAudioOutputStreamFactory> factory_remote; RenderFrameAudioOutputStreamFactory factory( main_rfh(), audio_system_.get(), media_stream_manager_.get(), factory_remote.BindNewPipeAndPassReceiver());
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 5f792f5..2f74aa8 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -41,7 +41,6 @@ #include "content/common/associated_interfaces.mojom.h" #include "content/common/child_process.mojom.h" #include "content/common/content_export.h" -#include "content/common/media/renderer_audio_output_stream_factory.mojom.h" #include "content/common/renderer.mojom.h" #include "content/common/renderer_host.mojom.h" #include "content/public/browser/browser_task_traits.h" @@ -82,6 +81,7 @@ #include "third_party/blink/public/mojom/filesystem/file_system.mojom.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-shared.h" #include "third_party/blink/public/mojom/loader/code_cache.mojom.h" +#include "third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom.h" #include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h" #include "third_party/blink/public/mojom/native_io/native_io.mojom-forward.h" #include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom.h"
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc index c88e3eb3..2daf04a1e 100644 --- a/content/browser/service_worker/service_worker_browsertest.cc +++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -1037,6 +1037,84 @@ EXPECT_EQ(301, fetch_response->status_code); } +// Check if a fetch event can be failed without crashing if starting a service +// worker fails. This is a regression test for https://crbug.com/1106977. +IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, + DispatchFetchEventToBrokenWorker) { + // Setup the server so that the test doesn't crash when tearing down. + StartServerAndNavigateToSetup(); + // This test is meaningful only when ServiceWorkerOnUI is enabled. + if (!ServiceWorkerContext::IsServiceWorkerOnUIEnabled()) + return; + + WorkerRunningStatusObserver observer(public_context()); + EXPECT_TRUE(NavigateToURL(shell(), + embedded_test_server()->GetURL( + "/service_worker/create_service_worker.html"))); + EXPECT_EQ("DONE", EvalJs(shell(), "register('fetch_event.js');")); + observer.WaitUntilRunning(); + + ASSERT_TRUE( + BrowserThread::CurrentlyOn(ServiceWorkerContext::GetCoreThreadId())); + scoped_refptr<ServiceWorkerVersion> version = + wrapper()->GetLiveVersion(observer.version_id()); + EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version->running_status()); + + { + base::RunLoop loop; + version->StopWorker(loop.QuitClosure()); + loop.Run(); + EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version->running_status()); + } + + // Set a non-existent resource to the version. + std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> resources; + resources.push_back(storage::mojom::ServiceWorkerResourceRecord::New( + 123456789, version->script_url(), 100)); + version->script_cache_map()->resource_map_.clear(); + version->script_cache_map()->SetResources(resources); + + bool is_prepare_callback_called = false; + base::RunLoop fetch_loop; + blink::ServiceWorkerStatusCode fetch_status; + ServiceWorkerFetchDispatcher::FetchEventResult fetch_result; + + auto request = blink::mojom::FetchAPIRequest::New(); + request->url = embedded_test_server()->GetURL("/service_worker/in-scope"); + request->method = "GET"; + request->is_main_resource_load = true; + auto dispatcher = std::make_unique<ServiceWorkerFetchDispatcher>( + std::move(request), blink::mojom::ResourceType::kMainFrame, + /*client_id=*/base::GenerateGUID(), version, + base::BindLambdaForTesting([&]() { is_prepare_callback_called = true; }), + base::BindLambdaForTesting( + [&](blink::ServiceWorkerStatusCode status, + ServiceWorkerFetchDispatcher::FetchEventResult result, + blink::mojom::FetchAPIResponsePtr response, + blink::mojom::ServiceWorkerStreamHandlePtr, + blink::mojom::ServiceWorkerFetchEventTimingPtr, + scoped_refptr<ServiceWorkerVersion>) { + fetch_status = status; + fetch_result = result; + fetch_loop.Quit(); + }), + /*is_offline_capability_check=*/false); + + // DispatchFetchEvent is called synchronously with dispatcher->Run() even if + // the worker is stopped. + dispatcher->Run(); + EXPECT_TRUE(is_prepare_callback_called); + + // Check if the fetch event fails due to error of reading the resource. + fetch_loop.Run(); + EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorDiskCache, fetch_status); + EXPECT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kShouldFallback, + fetch_result); + + // Make sure that no crash happens in the remaining tasks. + base::RunLoop().RunUntilIdle(); +} + class ServiceWorkerEagerCacheStorageSetupTest : public ServiceWorkerBrowserTest { public:
diff --git a/content/browser/service_worker/service_worker_disk_cache.cc b/content/browser/service_worker/service_worker_disk_cache.cc index 7507333..723b197 100644 --- a/content/browser/service_worker/service_worker_disk_cache.cc +++ b/content/browser/service_worker/service_worker_disk_cache.cc
@@ -6,7 +6,6 @@ #include <utility> -#include "content/common/service_worker/service_worker_utils.h" #include "net/base/io_buffer.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" @@ -25,16 +24,29 @@ return; } - DCHECK(io_buffer->http_info); - auto response_and_metadata = - ServiceWorkerUtils::CreateResourceResponseHeadAndMetadata( - io_buffer->http_info.get(), - /*options=*/network::mojom::kURLLoadOptionSendSSLInfoWithResponse, - /*request_start_time=*/base::TimeTicks(), - /*response_start_time=*/base::TimeTicks::Now(), - io_buffer->response_data_size); - std::move(callback).Run(result, std::move(response_and_metadata.head), - std::move(response_and_metadata.metadata)); + const net::HttpResponseInfo* http_info = io_buffer->http_info.get(); + DCHECK(http_info); + DCHECK(http_info->headers); + + auto head = network::mojom::URLResponseHead::New(); + head->request_start = base::TimeTicks(); + head->response_start = base::TimeTicks::Now(); + head->request_time = http_info->request_time; + head->response_time = http_info->response_time; + head->headers = http_info->headers; + head->headers->GetMimeType(&head->mime_type); + head->headers->GetCharset(&head->charset); + head->content_length = io_buffer->response_data_size; + head->was_fetched_via_spdy = http_info->was_fetched_via_spdy; + head->was_alpn_negotiated = http_info->was_alpn_negotiated; + head->connection_info = http_info->connection_info; + head->alpn_negotiated_protocol = http_info->alpn_negotiated_protocol; + head->remote_endpoint = http_info->remote_endpoint; + head->cert_status = http_info->ssl_info.cert_status; + head->ssl_info = http_info->ssl_info; + + std::move(callback).Run(result, std::move(head), + std::move(http_info->metadata)); } } // namespace @@ -63,11 +75,6 @@ const network::mojom::URLResponseHead& response_head, int response_data_size, net::CompletionOnceCallback callback) { - // This is copied from CreateHttpResponseInfoAndCheckHeaders(). - // TODO(bashi): Use CreateHttpResponseInfoAndCheckHeaders() - // once we remove URLResponseHead -> HttpResponseInfo -> URLResponseHead - // conversion, which drops some information needed for validation - // (e.g. mime type). auto response_info = std::make_unique<net::HttpResponseInfo>(); response_info->headers = response_head.headers; if (response_head.ssl_info.has_value())
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc index c797a8e5..3b29f0d 100644 --- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -625,6 +625,10 @@ void ServiceWorkerFetchDispatcher::DidFailToDispatch( std::unique_ptr<ResponseCallback> response_callback, blink::ServiceWorkerStatusCode status) { + // Fetch dispatcher can be completed at this point due to a failure of + // starting up a worker. In that case, let's simply ignore it. + if (IsCompleted()) + return; DidFail(status); } @@ -772,6 +776,10 @@ return request_.is_null(); } +bool ServiceWorkerFetchDispatcher::IsCompleted() const { + return fetch_callback_.is_null(); +} + // static void ServiceWorkerFetchDispatcher::OnFetchEventFinished( ServiceWorkerVersion* version,
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.h b/content/browser/service_worker/service_worker_fetch_dispatcher.h index 87ffce31..dfc319b 100644 --- a/content/browser/service_worker/service_worker_fetch_dispatcher.h +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -110,6 +110,7 @@ ServiceWorkerMetrics::EventType GetEventType() const; bool IsEventDispatched() const; + bool IsCompleted() const; blink::mojom::FetchAPIRequestPtr request_; std::string client_id_;
diff --git a/content/browser/service_worker/service_worker_script_cache_map.h b/content/browser/service_worker/service_worker_script_cache_map.h index 18a44c4..ad0d143f 100644 --- a/content/browser/service_worker/service_worker_script_cache_map.h +++ b/content/browser/service_worker/service_worker_script_cache_map.h
@@ -74,6 +74,8 @@ friend class ServiceWorkerVersion; friend class ServiceWorkerVersionBrowserTest; FRIEND_TEST_ALL_PREFIXES(ServiceWorkerReadFromCacheJobTest, ResourceNotFound); + FRIEND_TEST_ALL_PREFIXES(ServiceWorkerBrowserTest, + DispatchFetchEventToBrokenWorker); ServiceWorkerScriptCacheMap( ServiceWorkerVersion* owner,
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc index d1e05bd..b5b5ea2 100644 --- a/content/browser/service_worker/service_worker_test_utils.cc +++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -27,7 +27,6 @@ #include "content/common/frame_messages.h" #include "content/common/frame_messages.mojom.h" #include "content/public/common/child_process_host.h" -#include "content/public/common/transferrable_url_loader.mojom.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -39,6 +38,7 @@ #include "net/base/test_completion_callback.h" #include "net/http/http_response_info.h" #include "third_party/blink/public/common/loader/throttling_url_loader.h" +#include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h" namespace content { @@ -121,7 +121,7 @@ network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loader_factories, - base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index f8940750..a13ebeb 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -29,10 +29,12 @@ #include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/frame_host/navigation_request.h" +#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/web_contents/web_contents_view.h" +#include "content/common/frame.mojom-test-utils.h" #include "content/common/frame_messages.h" #include "content/common/page_messages.h" #include "content/common/unfreezable_frame_messages.h" @@ -4247,4 +4249,53 @@ EXPECT_FALSE(web_contents->ShouldIgnoreUnresponsiveRenderer()); } +// Intercept calls to RenderFramHostImpl's DidStopLoading mojo method. +class DidStopLoadingInterceptor : public mojom::FrameHostInterceptorForTesting { + public: + explicit DidStopLoadingInterceptor(RenderFrameHostImpl* render_frame_host) + : render_frame_host_(render_frame_host) { + render_frame_host_->frame_host_receiver_for_testing().SwapImplForTesting( + this); + } + + ~DidStopLoadingInterceptor() override = default; + + mojom::FrameHost* GetForwardingInterface() override { + return render_frame_host_; + } + + void DidStopLoading() override { + static_cast<RenderProcessHostImpl*>(render_frame_host_->GetProcess()) + ->mark_child_process_activity_time(); + render_frame_host_->DidStopLoading(); + } + + private: + RenderFrameHostImpl* render_frame_host_; + + DISALLOW_COPY_AND_ASSIGN(DidStopLoadingInterceptor); +}; + +// Test that get_process_idle_time() returns reasonable values when compared +// with time deltas measured locally. +IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, RenderIdleTime) { + EXPECT_TRUE(embedded_test_server()->Start()); + + base::TimeTicks start = base::TimeTicks::Now(); + DidStopLoadingInterceptor interceptor( + static_cast<content::RenderFrameHostImpl*>( + shell()->web_contents()->GetMainFrame())); + + GURL test_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), test_url)); + + base::TimeDelta renderer_td = shell() + ->web_contents() + ->GetMainFrame() + ->GetProcess() + ->GetChildProcessIdleTime(); + base::TimeDelta browser_td = base::TimeTicks::Now() - start; + EXPECT_TRUE(browser_td >= renderer_td); +} + } // namespace content
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index 05dd899..23f89d20 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -2122,8 +2122,7 @@ ui::PAGE_TRANSITION_AUTO_SUBFRAME); EXPECT_TRUE(contents()->IsLoading()); EXPECT_FALSE(contents()->IsLoadingToDifferentDocument()); - subframe->OnMessageReceived( - FrameHostMsg_DidStopLoading(subframe->GetRoutingID())); + subframe->DidStopLoading(); EXPECT_FALSE(contents()->IsLoading()); } @@ -2162,8 +2161,7 @@ // navigation in the current RenderFrameHost. There should still be a pending // RenderFrameHost and the WebContents should still be loading. same_process_navigation->Commit(); - current_rfh->OnMessageReceived( - FrameHostMsg_DidStopLoading(current_rfh->GetRoutingID())); + current_rfh->DidStopLoading(); EXPECT_EQ(contents()->GetPendingMainFrame(), pending_rfh); EXPECT_TRUE(contents()->IsLoading()); @@ -2183,8 +2181,7 @@ // Simulate the new current RenderFrameHost DidStopLoading. The WebContents // should now have stopped loading. - new_current_rfh->OnMessageReceived( - FrameHostMsg_DidStopLoading(new_current_rfh->GetRoutingID())); + new_current_rfh->DidStopLoading(); EXPECT_EQ(main_test_rfh(), new_current_rfh); EXPECT_FALSE(contents()->IsLoading()); }
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 54959ca..69b886d 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -440,8 +440,6 @@ "histogram_fetcher.mojom", "input/input_injector.mojom", "media/media_log_records.mojom", - "media/renderer_audio_input_stream_factory.mojom", - "media/renderer_audio_output_stream_factory.mojom", "native_types.mojom", "navigation_client.mojom", "navigation_params.mojom",
diff --git a/content/common/background_fetch/background_fetch_types.cc b/content/common/background_fetch/background_fetch_types.cc index b692336..eb94075 100644 --- a/content/common/background_fetch/background_fetch_types.cc +++ b/content/common/background_fetch/background_fetch_types.cc
@@ -32,7 +32,8 @@ return blink::mojom::FetchAPIResponse::New( response->url_list, response->status_code, response->status_text, response->response_type, response->response_source, response->headers, - response->mime_type, CloneSerializedBlob(response->blob), response->error, + response->mime_type, response->request_method, + CloneSerializedBlob(response->blob), response->error, response->response_time, response->cache_storage_cache_name, response->cors_exposed_header_names, CloneSerializedBlob(response->side_data_blob),
diff --git a/content/common/frame.mojom b/content/common/frame.mojom index eff5643a..bba4089 100644 --- a/content/common/frame.mojom +++ b/content/common/frame.mojom
@@ -11,7 +11,6 @@ import "content/common/navigation_params.mojom"; import "content/common/web_ui.mojom"; import "content/public/common/browser_controls_state.mojom"; -import "content/public/common/transferrable_url_loader.mojom"; import "content/public/common/window_container_type.mojom"; import "mojo/public/mojom/base/file_path.mojom"; import "mojo/public/mojom/base/string16.mojom"; @@ -546,4 +545,7 @@ // Requests that the given URL be opened in the specified manner. OpenURL(OpenURLParams params); + + // Called when the renderer is done loading a frame. + DidStopLoading(); };
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index e5632a9..baec093 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -466,9 +466,6 @@ // detached from the DOM. IPC_MESSAGE_ROUTED0(FrameHostMsg_Detach) -// Sent when the renderer is done loading a page. -IPC_MESSAGE_ROUTED0(FrameHostMsg_DidStopLoading) - #if BUILDFLAG(ENABLE_PLUGINS) // Notification sent from a renderer to the browser that a Pepper plugin // instance is created in the DOM.
diff --git a/content/common/navigation_client.mojom b/content/common/navigation_client.mojom index fe78527..596de59 100644 --- a/content/common/navigation_client.mojom +++ b/content/common/navigation_client.mojom
@@ -10,9 +10,9 @@ import "services/network/public/mojom/url_loader_factory.mojom"; import "content/common/frame_messages.mojom"; import "content/common/navigation_params.mojom"; -import "content/public/common/transferrable_url_loader.mojom"; import "mojo/public/mojom/base/unguessable_token.mojom"; import "url/mojom/url.mojom"; +import "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom"; import "third_party/blink/public/mojom/loader/url_loader_factory_bundle.mojom"; import "third_party/blink/public/mojom/service_worker/controller_service_worker.mojom"; import "third_party/blink/public/mojom/service_worker/service_worker_container.mojom"; @@ -61,7 +61,7 @@ handle<data_pipe_consumer>? response_body, network.mojom.URLLoaderClientEndpoints? url_loader_client_endpoints, blink.mojom.URLLoaderFactoryBundle? subresource_loader_factories, - array<TransferrableURLLoader>? subresource_overrides, + array<blink.mojom.TransferrableURLLoader>? subresource_overrides, blink.mojom.ControllerServiceWorkerInfo? controller_service_worker_info, blink.mojom.ServiceWorkerContainerInfoForClient? container_info, pending_remote<network.mojom.URLLoaderFactory>? prefetch_loader_factory,
diff --git a/content/common/service_worker/service_worker_utils.cc b/content/common/service_worker/service_worker_utils.cc index 11d45678..0de8e1b 100644 --- a/content/common/service_worker/service_worker_utils.cc +++ b/content/common/service_worker/service_worker_utils.cc
@@ -13,11 +13,8 @@ #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/origin_util.h" -#include "net/base/io_buffer.h" #include "net/base/load_flags.h" #include "net/http/http_byte_range.h" -#include "net/http/http_util.h" -#include "net/url_request/url_request.h" #include "services/network/public/cpp/features.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "third_party/blink/public/common/features.h" @@ -248,51 +245,6 @@ return ".Unknown"; } -ServiceWorkerUtils::ResourceResponseHeadAndMetadata:: - ResourceResponseHeadAndMetadata( - network::mojom::URLResponseHeadPtr head, - scoped_refptr<net::IOBufferWithSize> metadata) - : head(std::move(head)), metadata(std::move(metadata)) {} - -ServiceWorkerUtils::ResourceResponseHeadAndMetadata:: - ResourceResponseHeadAndMetadata(ResourceResponseHeadAndMetadata&& other) = - default; - -ServiceWorkerUtils::ResourceResponseHeadAndMetadata:: - ~ResourceResponseHeadAndMetadata() = default; - -ServiceWorkerUtils::ResourceResponseHeadAndMetadata -ServiceWorkerUtils::CreateResourceResponseHeadAndMetadata( - const net::HttpResponseInfo* http_info, - uint32_t options, - base::TimeTicks request_start_time, - base::TimeTicks response_start_time, - int response_data_size) { - DCHECK(http_info); - DCHECK(http_info->headers); - - auto head = network::mojom::URLResponseHead::New(); - head->request_start = request_start_time; - head->response_start = response_start_time; - head->request_time = http_info->request_time; - head->response_time = http_info->response_time; - head->headers = http_info->headers; - head->headers->GetMimeType(&head->mime_type); - head->headers->GetCharset(&head->charset); - head->content_length = response_data_size; - head->was_fetched_via_spdy = http_info->was_fetched_via_spdy; - head->was_alpn_negotiated = http_info->was_alpn_negotiated; - head->connection_info = http_info->connection_info; - head->alpn_negotiated_protocol = http_info->alpn_negotiated_protocol; - head->remote_endpoint = http_info->remote_endpoint; - head->cert_status = http_info->ssl_info.cert_status; - - if (options & network::mojom::kURLLoadOptionSendSSLInfoWithResponse) - head->ssl_info = http_info->ssl_info; - - return {std::move(head), std::move(http_info->metadata)}; -} - bool LongestScopeMatcher::MatchLongest(const GURL& scope) { if (!ServiceWorkerUtils::ScopeMatches(scope, url_)) return false;
diff --git a/content/common/service_worker/service_worker_utils.h b/content/common/service_worker/service_worker_utils.h index 1ea5f93..33462720 100644 --- a/content/common/service_worker/service_worker_utils.h +++ b/content/common/service_worker/service_worker_utils.h
@@ -14,8 +14,6 @@ #include "base/macros.h" #include "content/common/content_export.h" #include "content/public/common/content_switches.h" -#include "net/http/http_request_headers.h" -#include "services/network/public/mojom/url_response_head.mojom.h" #include "third_party/blink/public/common/fetch/fetch_api_request_headers_map.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" @@ -77,26 +75,6 @@ CONTENT_EXPORT static const char* FetchResponseSourceToSuffix( network::mojom::FetchResponseSource source); - struct CONTENT_EXPORT ResourceResponseHeadAndMetadata { - ResourceResponseHeadAndMetadata( - network::mojom::URLResponseHeadPtr head, - scoped_refptr<net::IOBufferWithSize> metadata); - ResourceResponseHeadAndMetadata(ResourceResponseHeadAndMetadata&& other); - ResourceResponseHeadAndMetadata( - const ResourceResponseHeadAndMetadata& other) = delete; - ~ResourceResponseHeadAndMetadata(); - - network::mojom::URLResponseHeadPtr head; - scoped_refptr<net::IOBufferWithSize> metadata; - }; - - CONTENT_EXPORT static ResourceResponseHeadAndMetadata - CreateResourceResponseHeadAndMetadata(const net::HttpResponseInfo* http_info, - uint32_t options, - base::TimeTicks request_start_time, - base::TimeTicks response_start_time, - int response_data_size); - private: static bool IsPathRestrictionSatisfiedInternal( const GURL& scope,
diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h index ec1ab7f4c..c679ff6 100644 --- a/content/public/browser/navigation_handle.h +++ b/content/public/browser/navigation_handle.h
@@ -15,7 +15,6 @@ #include "content/public/browser/restore_type.h" #include "content/public/common/impression.h" #include "content/public/common/referrer.h" -#include "content/public/common/transferrable_url_loader.mojom.h" #include "net/base/auth.h" #include "net/base/ip_endpoint.h" #include "net/base/isolation_info.h" @@ -23,6 +22,7 @@ #include "net/dns/public/resolve_error_info.h" #include "net/http/http_response_info.h" #include "services/network/public/cpp/resource_request_body.h" +#include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h" #include "ui/base/page_transition_types.h" class GURL; @@ -382,7 +382,7 @@ virtual int GetNavigationEntryOffset() = 0; virtual void RegisterSubresourceOverride( - mojom::TransferrableURLLoaderPtr transferrable_loader) = 0; + blink::mojom::TransferrableURLLoaderPtr transferrable_loader) = 0; // Force enables the given origin trials for this navigation. This needs to // be called from WebContents::ReadyToCommitNavigation or earlier to have an
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn index 22651bb1..f1446d90 100644 --- a/content/public/common/BUILD.gn +++ b/content/public/common/BUILD.gn
@@ -313,7 +313,6 @@ "fullscreen_video_element.mojom", "performance_manager/v8_per_frame_memory.mojom", "resource_usage_reporter.mojom", - "transferrable_url_loader.mojom", "was_activated_option.mojom", "webplugininfo.mojom", "window_container_type.mojom",
diff --git a/content/public/test/mock_navigation_handle.h b/content/public/test/mock_navigation_handle.h index c132ce6..7149f13 100644 --- a/content/public/test/mock_navigation_handle.h +++ b/content/public/test/mock_navigation_handle.h
@@ -122,7 +122,7 @@ void(std::unique_ptr<NavigationThrottle>)); MOCK_METHOD0(IsDeferredForTesting, bool()); MOCK_METHOD1(RegisterSubresourceOverride, - void(mojom::TransferrableURLLoaderPtr)); + void(blink::mojom::TransferrableURLLoaderPtr)); MOCK_METHOD0(FromDownloadCrossOriginRedirect, bool()); MOCK_METHOD0(IsSameProcess, bool()); MOCK_METHOD0(GetNavigationEntryOffset, int());
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc index 1c5ae04..c5703be 100644 --- a/content/renderer/accessibility/blink_ax_tree_source.cc +++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -810,7 +810,7 @@ dst->SetListStyle(src.GetListStyle()); } - if (src.GetTextDirection() != ax::mojom::TextDirection::kNone) { + if (src.GetTextDirection() != ax::mojom::WritingDirection::kNone) { dst->SetTextDirection(src.GetTextDirection()); }
diff --git a/content/renderer/loader/child_url_loader_factory_bundle.cc b/content/renderer/loader/child_url_loader_factory_bundle.cc index ed1ce72..c3ecec1 100644 --- a/content/renderer/loader/child_url_loader_factory_bundle.cc +++ b/content/renderer/loader/child_url_loader_factory_bundle.cc
@@ -262,7 +262,7 @@ const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { auto override_iter = subresource_overrides_.find(request.url); if (override_iter != subresource_overrides_.end()) { - mojom::TransferrableURLLoaderPtr transferrable_loader = + blink::mojom::TransferrableURLLoaderPtr transferrable_loader = std::move(override_iter->second); subresource_overrides_.erase(override_iter); @@ -325,7 +325,8 @@ } void ChildURLLoaderFactoryBundle::UpdateSubresourceOverrides( - std::vector<mojom::TransferrableURLLoaderPtr>* subresource_overrides) { + std::vector<blink::mojom::TransferrableURLLoaderPtr>* + subresource_overrides) { for (auto& element : *subresource_overrides) subresource_overrides_[element->url] = std::move(element); }
diff --git a/content/renderer/loader/child_url_loader_factory_bundle.h b/content/renderer/loader/child_url_loader_factory_bundle.h index 91b35704..880c826 100644 --- a/content/renderer/loader/child_url_loader_factory_bundle.h +++ b/content/renderer/loader/child_url_loader_factory_bundle.h
@@ -12,12 +12,12 @@ #include "base/callback.h" #include "base/optional.h" #include "content/common/content_export.h" -#include "content/public/common/transferrable_url_loader.mojom.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 "services/network/public/mojom/url_loader_factory.mojom-forward.h" #include "third_party/blink/public/common/loader/url_loader_factory_bundle.h" +#include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h" namespace content { @@ -121,7 +121,8 @@ void Update( std::unique_ptr<ChildPendingURLLoaderFactoryBundle> pending_factories); void UpdateSubresourceOverrides( - std::vector<mojom::TransferrableURLLoaderPtr>* subresource_overrides); + std::vector<blink::mojom::TransferrableURLLoaderPtr>* + subresource_overrides); void SetPrefetchLoaderFactory( mojo::PendingRemote<network::mojom::URLLoaderFactory> prefetch_loader_factory); @@ -150,7 +151,8 @@ bool is_deprecated_process_wide_factory_ = false; - std::map<GURL, mojom::TransferrableURLLoaderPtr> subresource_overrides_; + std::map<GURL, blink::mojom::TransferrableURLLoaderPtr> + subresource_overrides_; }; } // namespace content
diff --git a/content/renderer/media/audio/audio_device_factory.cc b/content/renderer/media/audio/audio_device_factory.cc index 8b210159..848ac33 100644 --- a/content/renderer/media/audio/audio_device_factory.cc +++ b/content/renderer/media/audio/audio_device_factory.cc
@@ -16,7 +16,6 @@ #include "base/threading/platform_thread.h" #include "build/build_config.h" #include "content/common/content_constants_internal.h" -#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "content/renderer/media/audio/audio_input_ipc_factory.h" #include "content/renderer/media/audio/audio_output_ipc_factory.h" #include "content/renderer/media/audio/audio_renderer_mixer_manager.h" @@ -28,6 +27,7 @@ #include "media/audio/audio_output_device.h" #include "media/base/audio_renderer_mixer_input.h" #include "media/base/media_switches.h" +#include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" namespace content {
diff --git a/content/renderer/media/audio/audio_input_ipc_factory.cc b/content/renderer/media/audio/audio_input_ipc_factory.cc index 3886a0cc..bc833be0 100644 --- a/content/renderer/media/audio/audio_input_ipc_factory.cc +++ b/content/renderer/media/audio/audio_input_ipc_factory.cc
@@ -11,12 +11,12 @@ #include "base/check_op.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" -#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "content/renderer/media/audio/mojo_audio_input_ipc.h" #include "content/renderer/render_frame_impl.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" namespace content { @@ -25,7 +25,8 @@ void CreateMojoAudioInputStreamOnMainThread( const base::UnguessableToken& frame_token, const media::AudioSourceParameters& source_params, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client, + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client, const media::AudioParameters& params, bool automatic_gain_control, uint32_t total_segments) { @@ -42,7 +43,8 @@ scoped_refptr<base::SequencedTaskRunner> main_task_runner, const base::UnguessableToken& frame_token, const media::AudioSourceParameters& source_params, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client, + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client, const media::AudioParameters& params, bool automatic_gain_control, uint32_t total_segments) {
diff --git a/content/renderer/media/audio/audio_output_ipc_factory.cc b/content/renderer/media/audio/audio_output_ipc_factory.cc index 92dd24e..6651543 100644 --- a/content/renderer/media/audio/audio_output_ipc_factory.cc +++ b/content/renderer/media/audio/audio_output_ipc_factory.cc
@@ -43,7 +43,8 @@ void AudioOutputIPCFactory::RegisterRemoteFactory( const base::UnguessableToken& frame_token, blink::BrowserInterfaceBrokerProxy* interface_broker) { - mojo::PendingRemote<mojom::RendererAudioOutputStreamFactory> factory_remote; + mojo::PendingRemote<blink::mojom::RendererAudioOutputStreamFactory> + factory_remote; interface_broker->GetInterface( factory_remote.InitWithNewPipeAndPassReceiver()); // Unretained is safe due to the contract at the top of the header file. @@ -64,7 +65,7 @@ base::Unretained(this), frame_token)); } -mojom::RendererAudioOutputStreamFactory* +blink::mojom::RendererAudioOutputStreamFactory* AudioOutputIPCFactory::GetRemoteFactory( const base::UnguessableToken& frame_token) const { DCHECK(io_task_runner_->BelongsToCurrentThread()); @@ -74,7 +75,7 @@ void AudioOutputIPCFactory::RegisterRemoteFactoryOnIOThread( const base::UnguessableToken& frame_token, - mojo::PendingRemote<mojom::RendererAudioOutputStreamFactory> + mojo::PendingRemote<blink::mojom::RendererAudioOutputStreamFactory> factory_pending_remote) { DCHECK(io_task_runner_->BelongsToCurrentThread()); std::pair<StreamFactoryMap::iterator, bool> emplace_result =
diff --git a/content/renderer/media/audio/audio_output_ipc_factory.h b/content/renderer/media/audio/audio_output_ipc_factory.h index b8a5171..d950e66e 100644 --- a/content/renderer/media/audio/audio_output_ipc_factory.h +++ b/content/renderer/media/audio/audio_output_ipc_factory.h
@@ -10,9 +10,9 @@ #include "base/containers/flat_map.h" #include "base/memory/ref_counted.h" #include "content/common/content_export.h" -#include "content/common/media/renderer_audio_output_stream_factory.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom.h" namespace base { class SingleThreadTaskRunner; @@ -64,16 +64,16 @@ const base::UnguessableToken& frame_token) const; private: - using StreamFactoryMap = - base::flat_map<base::UnguessableToken, - mojo::Remote<mojom::RendererAudioOutputStreamFactory>>; + using StreamFactoryMap = base::flat_map< + base::UnguessableToken, + mojo::Remote<blink::mojom::RendererAudioOutputStreamFactory>>; - mojom::RendererAudioOutputStreamFactory* GetRemoteFactory( + blink::mojom::RendererAudioOutputStreamFactory* GetRemoteFactory( const base::UnguessableToken& frame_token) const; void RegisterRemoteFactoryOnIOThread( const base::UnguessableToken& frame_token, - mojo::PendingRemote<mojom::RendererAudioOutputStreamFactory> + mojo::PendingRemote<blink::mojom::RendererAudioOutputStreamFactory> factory_pending_remote); void MaybeDeregisterRemoteFactoryOnIOThread(
diff --git a/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc b/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc index 03a2e92b..24514c3c 100644 --- a/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc +++ b/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc
@@ -44,7 +44,8 @@ return io_thread; } -class FakeRemoteFactory : public mojom::RendererAudioOutputStreamFactory { +class FakeRemoteFactory + : public blink::mojom::RendererAudioOutputStreamFactory { public: FakeRemoteFactory() = default; ~FakeRemoteFactory() override {} @@ -69,12 +70,13 @@ void Bind(mojo::ScopedMessagePipeHandle handle) { EXPECT_FALSE(receiver_.is_bound()); receiver_.Bind( - mojo::PendingReceiver<mojom::RendererAudioOutputStreamFactory>( + mojo::PendingReceiver<blink::mojom::RendererAudioOutputStreamFactory>( std::move(handle))); } private: - mojo::Receiver<mojom::RendererAudioOutputStreamFactory> receiver_{this}; + mojo::Receiver<blink::mojom::RendererAudioOutputStreamFactory> receiver_{ + this}; base::OnceClosure on_called_; }; @@ -120,7 +122,7 @@ auto& interface_broker = blink::GetEmptyBrowserInterfaceBroker(); interface_broker.SetBinderForTesting( - mojom::RendererAudioOutputStreamFactory::Name_, + blink::mojom::RendererAudioOutputStreamFactory::Name_, base::BindRepeating(&FakeRemoteFactory::Bind, base::Unretained(&remote_factory))); @@ -146,7 +148,7 @@ ipc_factory.MaybeDeregisterRemoteFactory(TokenFromInt(0)); interface_broker.SetBinderForTesting( - mojom::RendererAudioOutputStreamFactory::Name_, {}); + blink::mojom::RendererAudioOutputStreamFactory::Name_, {}); io_thread.reset(); base::RunLoop().RunUntilIdle(); @@ -163,7 +165,7 @@ auto& interface_broker = blink::GetEmptyBrowserInterfaceBroker(); interface_broker.SetBinderForTesting( - mojom::RendererAudioOutputStreamFactory::Name_, + blink::mojom::RendererAudioOutputStreamFactory::Name_, base::BindLambdaForTesting([&](mojo::ScopedMessagePipeHandle handle) { static int factory_index = 0; DCHECK_LT(factory_index, n_factories); @@ -209,7 +211,7 @@ } interface_broker.SetBinderForTesting( - mojom::RendererAudioOutputStreamFactory::Name_, {}); + blink::mojom::RendererAudioOutputStreamFactory::Name_, {}); io_thread.reset(); base::RunLoop().RunUntilIdle(); @@ -225,7 +227,7 @@ auto& interface_broker = blink::GetEmptyBrowserInterfaceBroker(); interface_broker.SetBinderForTesting( - mojom::RendererAudioOutputStreamFactory::Name_, + blink::mojom::RendererAudioOutputStreamFactory::Name_, base::BindRepeating(&FakeRemoteFactory::Bind, base::Unretained(&remote_factory))); @@ -240,7 +242,7 @@ base::RunLoop().RunUntilIdle(); interface_broker.SetBinderForTesting( - mojom::RendererAudioOutputStreamFactory::Name_, {}); + blink::mojom::RendererAudioOutputStreamFactory::Name_, {}); io_thread.reset(); base::RunLoop().RunUntilIdle(); }
diff --git a/content/renderer/media/audio/mojo_audio_input_ipc.cc b/content/renderer/media/audio/mojo_audio_input_ipc.cc index 450acb41..519a6099 100644 --- a/content/renderer/media/audio/mojo_audio_input_ipc.cc +++ b/content/renderer/media/audio/mojo_audio_input_ipc.cc
@@ -39,7 +39,8 @@ delegate_ = delegate; - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client; + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client; factory_client_receiver_.Bind(client.InitWithNewPipeAndPassReceiver()); factory_client_receiver_.set_disconnect_handler(base::BindOnce( &media::AudioInputIPCDelegate::OnError, base::Unretained(delegate_)));
diff --git a/content/renderer/media/audio/mojo_audio_input_ipc.h b/content/renderer/media/audio/mojo_audio_input_ipc.h index 58efe08..032cc06f 100644 --- a/content/renderer/media/audio/mojo_audio_input_ipc.h +++ b/content/renderer/media/audio/mojo_audio_input_ipc.h
@@ -13,7 +13,6 @@ #include "base/sequence_checker.h" #include "base/time/time.h" #include "content/common/content_export.h" -#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "media/audio/audio_input_ipc.h" #include "media/audio/audio_source_parameters.h" #include "media/mojo/mojom/audio_input_stream.mojom.h" @@ -22,6 +21,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" namespace content { @@ -30,7 +30,7 @@ // thread. class CONTENT_EXPORT MojoAudioInputIPC : public media::AudioInputIPC, - public mojom::RendererAudioInputStreamFactoryClient, + public blink::mojom::RendererAudioInputStreamFactoryClient, public media::mojom::AudioInputStreamClient { public: // This callback is used by MojoAudioInputIPC to create streams. @@ -38,7 +38,8 @@ // called or |client| is destructed. using StreamCreatorCB = base::RepeatingCallback<void( const media::AudioSourceParameters& source_params, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> client, + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + client, const media::AudioParameters& params, bool automatic_gain_control, uint32_t total_segments)>; @@ -85,7 +86,7 @@ // Initialized on StreamCreated. base::Optional<base::UnguessableToken> stream_id_; mojo::Receiver<AudioInputStreamClient> stream_client_receiver_{this}; - mojo::Receiver<RendererAudioInputStreamFactoryClient> + mojo::Receiver<blink::mojom::RendererAudioInputStreamFactoryClient> factory_client_receiver_{this}; media::AudioInputIPCDelegate* delegate_ = nullptr;
diff --git a/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc b/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc index 22681946..6dc7264 100644 --- a/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc +++ b/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc
@@ -82,12 +82,13 @@ receiver_(stream_), initially_muted_(initially_muted) {} - void Create(const media::AudioSourceParameters& source_params, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> - factory_client, - const media::AudioParameters& params, - bool automatic_gain_control, - uint32_t total_segments) { + void Create( + const media::AudioSourceParameters& source_params, + mojo::PendingRemote<blink::mojom::RendererAudioInputStreamFactoryClient> + factory_client, + const media::AudioParameters& params, + bool automatic_gain_control, + uint32_t total_segments) { EXPECT_FALSE(receiver_.is_bound()); EXPECT_NE(stream_, nullptr); EXPECT_EQ(source_params.session_id, SourceParams().session_id); @@ -124,7 +125,8 @@ private: media::mojom::AudioInputStream* stream_; mojo::Remote<media::mojom::AudioInputStreamClient> stream_client_; - mojo::Remote<mojom::RendererAudioInputStreamFactoryClient> factory_client_; + mojo::Remote<blink::mojom::RendererAudioInputStreamFactoryClient> + factory_client_; mojo::Receiver<media::mojom::AudioInputStream> receiver_; bool initially_muted_; base::CancelableSyncSocket socket_; @@ -164,16 +166,17 @@ base::test::SingleThreadTaskEnvironment::MainThreadType::IO); StrictMock<MockDelegate> delegate; - const std::unique_ptr<media::AudioInputIPC> ipc = std::make_unique< - MojoAudioInputIPC>( - SourceParams(), - base::BindRepeating( - [](const media::AudioSourceParameters&, - mojo::PendingRemote<mojom::RendererAudioInputStreamFactoryClient> - factory_client, - const media::AudioParameters& params, bool automatic_gain_control, - uint32_t total_segments) {}), - base::BindRepeating(&AssociateOutputForAec)); + const std::unique_ptr<media::AudioInputIPC> ipc = + std::make_unique<MojoAudioInputIPC>( + SourceParams(), + base::BindRepeating( + [](const media::AudioSourceParameters&, + mojo::PendingRemote< + blink::mojom::RendererAudioInputStreamFactoryClient> + factory_client, + const media::AudioParameters& params, + bool automatic_gain_control, uint32_t total_segments) {}), + base::BindRepeating(&AssociateOutputForAec)); EXPECT_CALL(delegate, OnError());
diff --git a/content/renderer/media/audio/mojo_audio_output_ipc.h b/content/renderer/media/audio/mojo_audio_output_ipc.h index 52fb420b..e4295b74 100644 --- a/content/renderer/media/audio/mojo_audio_output_ipc.h +++ b/content/renderer/media/audio/mojo_audio_output_ipc.h
@@ -14,7 +14,6 @@ #include "base/single_thread_task_runner.h" #include "base/time/time.h" #include "content/common/content_export.h" -#include "content/common/media/renderer_audio_output_stream_factory.mojom.h" #include "media/audio/audio_output_ipc.h" #include "media/mojo/mojom/audio_data_pipe.mojom.h" #include "media/mojo/mojom/audio_output_stream.mojom.h" @@ -22,6 +21,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom.h" namespace content { @@ -32,8 +32,8 @@ : public media::AudioOutputIPC, public media::mojom::AudioOutputStreamProviderClient { public: - using FactoryAccessorCB = - base::RepeatingCallback<mojom::RendererAudioOutputStreamFactory*()>; + using FactoryAccessorCB = base::RepeatingCallback< + blink::mojom::RendererAudioOutputStreamFactory*()>; // |factory_accessor| is required to provide a // RendererAudioOutputStreamFactory* if IPC is possible. @@ -64,7 +64,7 @@ private: static constexpr double kDefaultVolume = 1.0; - using AuthorizationCB = mojom::RendererAudioOutputStreamFactory:: + using AuthorizationCB = blink::mojom::RendererAudioOutputStreamFactory:: RequestDeviceAuthorizationCallback; bool AuthorizationRequested() const;
diff --git a/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc b/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc index 4c0824789..2aee416 100644 --- a/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc +++ b/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc
@@ -46,7 +46,9 @@ MojoAudioOutputIPC::FactoryAccessorCB NullAccessor() { return base::BindRepeating( - []() -> mojom::RendererAudioOutputStreamFactory* { return nullptr; }); + []() -> blink::mojom::RendererAudioOutputStreamFactory* { + return nullptr; + }); } class TestStreamProvider : public media::mojom::AudioOutputStreamProvider { @@ -94,7 +96,8 @@ base::CancelableSyncSocket socket_; }; -class TestRemoteFactory : public mojom::RendererAudioOutputStreamFactory { +class TestRemoteFactory + : public blink::mojom::RendererAudioOutputStreamFactory { public: TestRemoteFactory() : expect_request_(false), @@ -165,14 +168,17 @@ } private: - mojom::RendererAudioOutputStreamFactory* get() { return this_remote_.get(); } + blink::mojom::RendererAudioOutputStreamFactory* get() { + return this_remote_.get(); + } bool expect_request_; base::Optional<base::UnguessableToken> expected_session_id_; std::string expected_device_id_; - mojo::Remote<mojom::RendererAudioOutputStreamFactory> this_remote_; - mojo::Receiver<mojom::RendererAudioOutputStreamFactory> receiver_{this}; + mojo::Remote<blink::mojom::RendererAudioOutputStreamFactory> this_remote_; + mojo::Receiver<blink::mojom::RendererAudioOutputStreamFactory> receiver_{ + this}; std::unique_ptr<TestStreamProvider> provider_; base::Optional<mojo::Receiver<media::mojom::AudioOutputStreamProvider>> provider_receiver_;
diff --git a/content/renderer/navigation_client.cc b/content/renderer/navigation_client.cc index 0d9b602a..8252b91 100644 --- a/content/renderer/navigation_client.cc +++ b/content/renderer/navigation_client.cc
@@ -22,7 +22,7 @@ mojo::ScopedDataPipeConsumerHandle response_body, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loaders, - base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info, blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info,
diff --git a/content/renderer/navigation_client.h b/content/renderer/navigation_client.h index 404d863b..7284e18 100644 --- a/content/renderer/navigation_client.h +++ b/content/renderer/navigation_client.h
@@ -26,7 +26,7 @@ mojo::ScopedDataPipeConsumerHandle response_body, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loaders, - base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 4b25d73..c571b07 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -3071,7 +3071,7 @@ network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loader_factories, - base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info, blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info, @@ -3206,7 +3206,7 @@ mojom::CommitNavigationParamsPtr commit_params, std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loader_factories, - base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info, blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info, @@ -3291,7 +3291,7 @@ // The browser expects the frame to be loading this navigation. Inform it // that the load stopped if needed. if (frame_ && !frame_->IsLoading()) - Send(new FrameHostMsg_DidStopLoading(routing_id_)); + GetFrameHost()->DidStopLoading(); return; } @@ -3379,7 +3379,7 @@ // The browser expects this frame to be loading an error page. Inform it // that the load stopped. AbortCommitNavigation(); - Send(new FrameHostMsg_DidStopLoading(routing_id_)); + GetFrameHost()->DidStopLoading(); browser_side_navigation_pending_ = false; browser_side_navigation_pending_url_ = GURL(); return; @@ -3412,7 +3412,7 @@ // either, as the frame has already been populated with something // unrelated to this navigation failure. In that case, just send a stop // IPC to the browser to unwind its state, and leave the frame as-is. - Send(new FrameHostMsg_DidStopLoading(routing_id_)); + GetFrameHost()->DidStopLoading(); } browser_side_navigation_pending_ = false; browser_side_navigation_pending_url_ = GURL(); @@ -3572,7 +3572,7 @@ // that the load stopped if needed. if (frame_ && !frame_->IsLoading() && commit_status != blink::mojom::CommitResult::Ok) { - Send(new FrameHostMsg_DidStopLoading(routing_id_)); + GetFrameHost()->DidStopLoading(); } } @@ -3591,7 +3591,7 @@ // that the load stopped if needed, while leaving the debug URL visible in the // address bar. if (weak_this && frame_ && !frame_->IsLoading()) - Send(new FrameHostMsg_DidStopLoading(routing_id_)); + GetFrameHost()->DidStopLoading(); } void RenderFrameImpl::UpdateSubresourceLoaderFactories( @@ -4862,7 +4862,7 @@ return WebString(); } -mojom::RendererAudioInputStreamFactory* +blink::mojom::RendererAudioInputStreamFactory* RenderFrameImpl::GetAudioInputStreamFactory() { if (!audio_input_stream_factory_) GetBrowserInterfaceBroker()->GetInterface( @@ -5400,7 +5400,7 @@ // this state anymore. history_subframe_unique_names_.clear(); - Send(new FrameHostMsg_DidStopLoading(routing_id_)); + GetFrameHost()->DidStopLoading(); } void RenderFrameImpl::NotifyAccessibilityModeChange(ui::AXMode new_mode) { @@ -5809,7 +5809,7 @@ scoped_refptr<ChildURLLoaderFactoryBundle> RenderFrameImpl::CreateLoaderFactoryBundle( std::unique_ptr<blink::PendingURLLoaderFactoryBundle> info, - base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, mojo::PendingRemote<network::mojom::URLLoaderFactory> prefetch_loader_factory) {
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index c5b50c3..e3b965a 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -34,7 +34,6 @@ #include "content/common/download/mhtml_file_writer.mojom.h" #include "content/common/frame.mojom.h" #include "content/common/frame_delete_intention.h" -#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "content/common/navigation_params.mojom.h" #include "content/common/render_accessibility.mojom.h" #include "content/common/renderer.mojom.h" @@ -92,6 +91,7 @@ #include "third_party/blink/public/mojom/input/focus_type.mojom-forward.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h" #include "third_party/blink/public/mojom/loader/resource_load_info_notifier.mojom.h" +#include "third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom.h" #include "third_party/blink/public/mojom/renderer_preferences.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h" #include "third_party/blink/public/mojom/use_counter/css_property_id.mojom.h" @@ -553,7 +553,7 @@ network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loader_factories, - base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info, @@ -745,7 +745,7 @@ blink::WebString UserAgentOverride() override; base::Optional<blink::UserAgentMetadata> UserAgentMetadataOverride() override; blink::WebString DoNotTrackValue() override; - mojom::RendererAudioInputStreamFactory* GetAudioInputStreamFactory(); + blink::mojom::RendererAudioInputStreamFactory* GetAudioInputStreamFactory(); bool AllowContentInitiatedDataUrlNavigations( const blink::WebURL& url) override; void PostAccessibilityEvent(const ui::AXEvent& event) override; @@ -1039,7 +1039,7 @@ scoped_refptr<ChildURLLoaderFactoryBundle> CreateLoaderFactoryBundle( std::unique_ptr<blink::PendingURLLoaderFactoryBundle> info, - base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, mojo::PendingRemote<network::mojom::URLLoaderFactory> prefetch_loader_factory); @@ -1086,7 +1086,7 @@ mojom::CommitNavigationParamsPtr commit_params, std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loader_factories, - base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info, @@ -1364,7 +1364,7 @@ std::unique_ptr<blink::WebMediaStreamDeviceObserver> web_media_stream_device_observer_; - mojo::Remote<mojom::RendererAudioInputStreamFactory> + mojo::Remote<blink::mojom::RendererAudioInputStreamFactory> audio_input_stream_factory_; // The media permission dispatcher attached to this frame.
diff --git a/content/shell/renderer/web_test/web_ax_object_proxy.cc b/content/shell/renderer/web_test/web_ax_object_proxy.cc index 8aeecdc..1cc6896 100644 --- a/content/shell/renderer/web_test/web_ax_object_proxy.cc +++ b/content/shell/renderer/web_test/web_ax_object_proxy.cc
@@ -470,7 +470,7 @@ return blink::WebRect(); switch (inline_text_box.GetTextDirection()) { - case ax::mojom::TextDirection::kLtr: { + case ax::mojom::WritingDirection::kLtr: { if (local_index) { int left = inline_text_box_rect.x + character_offsets[local_index - 1]; @@ -483,7 +483,7 @@ character_offsets[0], inline_text_box_rect.height); } - case ax::mojom::TextDirection::kRtl: { + case ax::mojom::WritingDirection::kRtl: { int right = inline_text_box_rect.x + inline_text_box_rect.width; if (local_index) { @@ -498,7 +498,7 @@ character_offsets[0], inline_text_box_rect.height); } - case ax::mojom::TextDirection::kTtb: { + case ax::mojom::WritingDirection::kTtb: { if (local_index) { int top = inline_text_box_rect.y + character_offsets[local_index - 1]; int height = character_offsets[local_index] - @@ -509,7 +509,7 @@ return blink::WebRect(inline_text_box_rect.x, inline_text_box_rect.y, inline_text_box_rect.width, character_offsets[0]); } - case ax::mojom::TextDirection::kBtt: { + case ax::mojom::WritingDirection::kBtt: { int bottom = inline_text_box_rect.y + inline_text_box_rect.height; if (local_index) {
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc index 695d8c8..f09faaf 100644 --- a/content/test/test_render_frame.cc +++ b/content/test/test_render_frame.cc
@@ -217,6 +217,8 @@ is_url_opened_ = true; } + void DidStopLoading() override {} + void DidAddMessageToConsole(blink::mojom::ConsoleMessageLevel log_level, const base::string16& msg, int32_t line_number,
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index 19706d6..7cd67ba 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -548,7 +548,7 @@ network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loader_factories, - base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ControllerServiceWorkerInfoPtr controller, blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info, @@ -695,7 +695,7 @@ DidFinishLoad(GetLastCommittedURL()); } - OnDidStopLoading(); + DidStopLoading(); } } // namespace content
diff --git a/content/test/test_render_frame_host.h b/content/test/test_render_frame_host.h index d23cdeec..57d6178 100644 --- a/content/test/test_render_frame_host.h +++ b/content/test/test_render_frame_host.h
@@ -224,7 +224,7 @@ network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, std::unique_ptr<blink::PendingURLLoaderFactoryBundle> subresource_loader_factories, - base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>> + base::Optional<std::vector<blink::mojom::TransferrableURLLoaderPtr>> subresource_overrides, blink::mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
diff --git a/docs/android_build_instructions.md b/docs/android_build_instructions.md index 8cad7fc6..cc36d85 100644 --- a/docs/android_build_instructions.md +++ b/docs/android_build_instructions.md
@@ -355,6 +355,17 @@ * What it does: Uses multiple `.so` files instead of just one (faster links) * `is_java_debug = true` *(default=`is_debug`)* * What it does: Disables ProGuard (slow build step) + * `treat_warnings_as_errors = false` *(default=`true`)* + * Causes any compiler warnings or lint checks to not fail the build. + * Allows you to iterate without needing to satisfy static analysis checks. + * `use_errorprone_java_compiler = false` *(default=`true`) + * Don't run Errorprone checks when compiling Java files. + * Speeds up Java compiles by ~30% at the cost of not seeing ErrorProne + warnings. + * `disable_android_lint = true` *(default=`false`)* + * Don't run Android Lint when building APK / App Bundle targets. + * Lint usually takes > 60 seconds to run, so disabling it dramatically + reduces incremental build times. #### Incremental Install [Incremental Install](/build/android/incremental_install/README.md) uses
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 0d6fb4b0..72dd41b 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -268,6 +268,7 @@ "info_map.cc", "info_map.h", "install_flag.h", + "install_stage.h", "json_file_sanitizer.cc", "json_file_sanitizer.h", "lazy_background_task_queue.cc",
diff --git a/extensions/browser/guest_view/extensions_guest_view_message_filter.cc b/extensions/browser/guest_view/extensions_guest_view_message_filter.cc index 7c442c9b..9478fd08 100644 --- a/extensions/browser/guest_view/extensions_guest_view_message_filter.cc +++ b/extensions/browser/guest_view/extensions_guest_view_message_filter.cc
@@ -202,7 +202,7 @@ const GURL& original_url, int32_t element_instance_id, const gfx::Size& element_size, - content::mojom::TransferrableURLLoaderPtr transferrable_url_loader) { + blink::mojom::TransferrableURLLoaderPtr transferrable_url_loader) { if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&ExtensionsGuestViewMessageFilter::
diff --git a/extensions/browser/guest_view/extensions_guest_view_message_filter.h b/extensions/browser/guest_view/extensions_guest_view_message_filter.h index fc9ce56..69ef8643 100644 --- a/extensions/browser/guest_view/extensions_guest_view_message_filter.h +++ b/extensions/browser/guest_view/extensions_guest_view_message_filter.h
@@ -75,7 +75,7 @@ const GURL& original_url, int32_t element_instance_id, const gfx::Size& element_size, - content::mojom::TransferrableURLLoaderPtr transferrable_url_loader) + blink::mojom::TransferrableURLLoaderPtr transferrable_url_loader) override; void CreateMimeHandlerViewGuest( int32_t render_frame_id,
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc index 390b07fc..d5ccc45 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
@@ -46,7 +46,7 @@ bool embedded, const GURL& handler_url, const std::string& extension_id, - content::mojom::TransferrableURLLoaderPtr transferrable_loader, + blink::mojom::TransferrableURLLoaderPtr transferrable_loader, const GURL& original_url) : embedded_(embedded), tab_id_(tab_id), @@ -65,7 +65,7 @@ return weak_factory_.GetWeakPtr(); } -content::mojom::TransferrableURLLoaderPtr +blink::mojom::TransferrableURLLoaderPtr StreamContainer::TakeTransferrableURLLoader() { return std::move(transferrable_loader_); }
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h index 56babf6..3e287fd 100644 --- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h +++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
@@ -11,10 +11,10 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "components/guest_view/browser/guest_view.h" -#include "content/public/common/transferrable_url_loader.mojom.h" #include "extensions/common/api/mime_handler.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" +#include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h" namespace content { class WebContents; @@ -28,18 +28,17 @@ // resource stream. class StreamContainer { public: - StreamContainer( - int tab_id, - bool embedded, - const GURL& handler_url, - const std::string& extension_id, - content::mojom::TransferrableURLLoaderPtr transferrable_loader, - const GURL& original_url); + StreamContainer(int tab_id, + bool embedded, + const GURL& handler_url, + const std::string& extension_id, + blink::mojom::TransferrableURLLoaderPtr transferrable_loader, + const GURL& original_url); ~StreamContainer(); base::WeakPtr<StreamContainer> GetWeakPtr(); - content::mojom::TransferrableURLLoaderPtr TakeTransferrableURLLoader(); + blink::mojom::TransferrableURLLoaderPtr TakeTransferrableURLLoader(); bool embedded() const { return embedded_; } int tab_id() const { return tab_id_; } @@ -58,7 +57,7 @@ const int tab_id_; const GURL handler_url_; const std::string extension_id_; - content::mojom::TransferrableURLLoaderPtr transferrable_loader_; + blink::mojom::TransferrableURLLoaderPtr transferrable_loader_; std::string mime_type_; GURL original_url_;
diff --git a/extensions/browser/install_stage.h b/extensions/browser/install_stage.h new file mode 100644 index 0000000..b4d0a375 --- /dev/null +++ b/extensions/browser/install_stage.h
@@ -0,0 +1,25 @@ +// 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_INSTALL_STAGE_H_ +#define EXTENSIONS_BROWSER_INSTALL_STAGE_H_ + +namespace extensions { + +// The different stages of the extension installation process. +enum class InstallationStage { + // The validation of signature of the extensions is about to be started. + kVerification = 0, + // Extension archive is about to be copied into the working directory. + kCopying = 1, + // Extension archive is about to be unpacked. + kUnpacking = 2, + // Final checks before the installation is finished. + kFinalizing = 3, + kComplete = 4, +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_INSTALL_STAGE_H_
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc index 783d7b87..2c25b11 100644 --- a/extensions/browser/sandboxed_unpacker.cc +++ b/extensions/browser/sandboxed_unpacker.cc
@@ -34,6 +34,7 @@ #include "extensions/browser/extension_file_task_runner.h" #include "extensions/browser/install/crx_install_error.h" #include "extensions/browser/install/sandboxed_unpacker_failure_reason.h" +#include "extensions/browser/install_stage.h" #include "extensions/browser/zipfile_installer.h" #include "extensions/common/api/declarative_net_request/dnr_manifest_data.h" #include "extensions/common/constants.h" @@ -222,7 +223,7 @@ // We assume that we are started on the thread that the client wants us // to do file IO on. DCHECK(unpacker_io_task_runner_->RunsTasksInCurrentSequence()); - + client_->OnStageChanged(InstallationStage::kVerification); std::string expected_hash; if (!crx_info.expected_hash.empty() && base::CommandLine::ForCurrentProcess()->HasSwitch( @@ -242,6 +243,7 @@ crx_info.required_format))) return; // ValidateSignature() already reported the error. + client_->OnStageChanged(InstallationStage::kCopying); // Copy the crx file into our working directory. base::FilePath temp_crx_path = temp_dir_.GetPath().Append(crx_info.path.BaseName()); @@ -271,7 +273,7 @@ l10n_util::GetStringUTF16(IDS_EXTENSION_UNPACK_FAILED)); return; } - + client_->OnStageChanged(InstallationStage::kUnpacking); // Make sure to create the directory where the extension will be unzipped, as // the unzipper service requires it. base::FilePath unzipped_dir =
diff --git a/extensions/browser/sandboxed_unpacker.h b/extensions/browser/sandboxed_unpacker.h index f9b702c..cf83572 100644 --- a/extensions/browser/sandboxed_unpacker.h +++ b/extensions/browser/sandboxed_unpacker.h
@@ -41,6 +41,7 @@ namespace extensions { class Extension; enum class SandboxedUnpackerFailureReason; +enum class InstallationStage; namespace declarative_net_request { struct IndexAndPersistJSONRulesetResult; @@ -88,6 +89,9 @@ declarative_net_request::RulesetChecksums ruleset_checksums) = 0; virtual void OnUnpackFailure(const CrxInstallError& error) = 0; + // Called after stage of installation is changed. + virtual void OnStageChanged(InstallationStage stage) {} + protected: friend class base::RefCountedDeleteOnSequence<SandboxedUnpackerClient>; friend class base::DeleteHelper<SandboxedUnpackerClient>;
diff --git a/extensions/common/mojom/guest_view.mojom b/extensions/common/mojom/guest_view.mojom index 52a1aafb..7b637367 100644 --- a/extensions/common/mojom/guest_view.mojom +++ b/extensions/common/mojom/guest_view.mojom
@@ -4,8 +4,8 @@ module extensions.mojom; -import "content/public/common/transferrable_url_loader.mojom"; import "extensions/common/api/mime_handler.mojom"; +import "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom"; import "url/mojom/url.mojom"; @@ -19,7 +19,7 @@ url.mojom.Url original_url, int32 element_instance_id, gfx.mojom.Size element_size, - content.mojom.TransferrableURLLoader transferrable_url_loader); + blink.mojom.TransferrableURLLoader transferrable_url_loader); // Tells the browser to create a mime handler guest view for a plugin. // This method is called for full-frame plugins or for all plugins when the
diff --git a/extensions/renderer/DEPS b/extensions/renderer/DEPS index b4650051..53951d1 100644 --- a/extensions/renderer/DEPS +++ b/extensions/renderer/DEPS
@@ -9,6 +9,7 @@ "+third_party/cld_3", "+third_party/blink/public/mojom/devtools/console_message.mojom.h", + "+third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h", "+third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h", "+third_party/blink/public/platform", "+third_party/blink/public/strings/grit/blink_strings.h",
diff --git a/extensions/renderer/api/automation/automation_internal_custom_bindings.cc b/extensions/renderer/api/automation/automation_internal_custom_bindings.cc index 0fbbff6..e6453dc2 100644 --- a/extensions/renderer/api/automation/automation_internal_custom_bindings.cc +++ b/extensions/renderer/api/automation/automation_internal_custom_bindings.cc
@@ -948,21 +948,21 @@ int end_offset = end > 0 ? character_offsets[end - 1] : 0; switch (node->data().GetTextDirection()) { - case ax::mojom::TextDirection::kLtr: + case ax::mojom::WritingDirection::kLtr: default: local_bounds.set_x(local_bounds.x() + start_offset); local_bounds.set_width(end_offset - start_offset); break; - case ax::mojom::TextDirection::kRtl: + case ax::mojom::WritingDirection::kRtl: local_bounds.set_x(local_bounds.x() + local_bounds.width() - end_offset); local_bounds.set_width(end_offset - start_offset); break; - case ax::mojom::TextDirection::kTtb: + case ax::mojom::WritingDirection::kTtb: local_bounds.set_y(local_bounds.y() + start_offset); local_bounds.set_height(end_offset - start_offset); break; - case ax::mojom::TextDirection::kBtt: + case ax::mojom::WritingDirection::kBtt: local_bounds.set_y(local_bounds.y() + local_bounds.height() - end_offset); local_bounds.set_height(end_offset - start_offset);
diff --git a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc index e9005fbb..88f3393b 100644 --- a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc +++ b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc
@@ -101,7 +101,7 @@ new_client.InitWithNewPipeAndPassReceiver(), &original_loader, &original_client); - auto transferrable_loader = content::mojom::TransferrableURLLoader::New(); + auto transferrable_loader = blink::mojom::TransferrableURLLoader::New(); transferrable_loader->url_loader = std::move(original_loader); transferrable_loader->url_loader_client = std::move(original_client); @@ -379,7 +379,7 @@ } void MimeHandlerViewContainer::SetEmbeddedLoader( - content::mojom::TransferrableURLLoaderPtr transferrable_url_loader) { + blink::mojom::TransferrableURLLoaderPtr transferrable_url_loader) { transferrable_url_loader_ = std::move(transferrable_url_loader); transferrable_url_loader_->url = GURL(plugin_path_ + base::GenerateGUID()); // Warning: It is possible that |this| gets destroyed after this line (when
diff --git a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h index 29bbe8fc..bf219605 100644 --- a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h +++ b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h
@@ -14,7 +14,6 @@ #include "base/macros.h" #include "base/optional.h" #include "components/guest_view/renderer/guest_view_container.h" -#include "content/public/common/transferrable_url_loader.mojom.h" #include "extensions/common/api/mime_handler.mojom.h" #include "extensions/common/guest_view/mime_handler_view_uma_types.h" #include "extensions/common/mojom/guest_view.mojom.h" @@ -22,6 +21,7 @@ #include "ipc/ipc_message.h" #include "mojo/public/cpp/bindings/receiver.h" #include "services/network/public/mojom/url_loader.mojom.h" +#include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h" #include "third_party/blink/public/web/web_associated_url_loader_client.h" #include "ui/gfx/geometry/size.h" #include "url/gurl.h" @@ -123,7 +123,7 @@ // by the URLLoaderThrottle which intercepts the resource load, which is then // sent to the browser to be handed off to the plugin. void SetEmbeddedLoader( - content::mojom::TransferrableURLLoaderPtr transferrable_url_loader); + blink::mojom::TransferrableURLLoaderPtr transferrable_url_loader); void CreateMimeHandlerViewGuestIfNecessary(); int32_t GetInstanceId() const; @@ -157,7 +157,7 @@ const std::string mime_type_; // Used when network service is enabled: - content::mojom::TransferrableURLLoaderPtr transferrable_url_loader_; + blink::mojom::TransferrableURLLoaderPtr transferrable_url_loader_; // Used when network service is disabled: // A URL loader to load the |original_url_| when the plugin is embedded. In
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index c6aa402..ba1dacdd 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn
@@ -324,7 +324,10 @@ ] if (use_ozone) { - deps += [ "//ui/ozone" ] + deps += [ + "//ui/base:features", + "//ui/ozone", + ] } if (enable_vulkan) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index ccba700..693e293 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -118,6 +118,10 @@ #include <OpenGL/CGLIOSurface.h> #endif // OS_MACOSX +#if defined(USE_OZONE) +#include "ui/base/ui_base_features.h" // nogncheck +#endif + // Note: this undefs far and near so include this after other Windows headers. #include "third_party/angle/src/image_util/loadimage.h" @@ -3216,14 +3220,14 @@ bool is_cleared = false; gfx::BufferFormat buffer_format = gfx::BufferFormat::RGBA_8888; if (format == GL_RGB) { + buffer_format = gfx::BufferFormat::RGBX_8888; #if defined(USE_OZONE) // BGRX format is preferred for Ozone as it matches the format used by the // buffer queue and is as a result guaranteed to work on all devices. // TODO(reveman): Define this format in one place instead of having to // duplicate BGRX_8888. - buffer_format = gfx::BufferFormat::BGRX_8888; -#else - buffer_format = gfx::BufferFormat::RGBX_8888; + if (features::IsUsingOzonePlatform()) + buffer_format = gfx::BufferFormat::BGRX_8888; #endif } scoped_refptr<gl::GLImage> image =
diff --git a/gpu/command_buffer/service/shared_context_state.cc b/gpu/command_buffer/service/shared_context_state.cc index 479619f..f791025 100644 --- a/gpu/command_buffer/service/shared_context_state.cc +++ b/gpu/command_buffer/service/shared_context_state.cc
@@ -104,7 +104,7 @@ scoped_refptr<gl::GLSurface> surface, scoped_refptr<gl::GLContext> context, bool use_virtualized_gl_contexts, - base::OnceClosure context_lost_callback, + ContextLostCallback context_lost_callback, GrContextType gr_context_type, viz::VulkanContextProvider* vulkan_context_provider, viz::MetalContextProvider* metal_context_provider, @@ -490,7 +490,8 @@ gr_context_ = nullptr; } UpdateSkiaOwnedMemorySize(); - std::move(context_lost_callback_).Run(); + std::move(context_lost_callback_) + .Run(!context_lost_by_robustness_extension); for (auto& observer : context_lost_observers_) observer.OnContextLost(); } @@ -738,6 +739,7 @@ LOG(ERROR) << "SharedContextState context lost via ARB/EXT_robustness. Reset " "status = " << gles2::GLES2Util::GetStringEnum(driver_status); + context_lost_by_robustness_extension = true; switch (driver_status) { case GL_GUILTY_CONTEXT_RESET_ARB:
diff --git a/gpu/command_buffer/service/shared_context_state.h b/gpu/command_buffer/service/shared_context_state.h index ec476f3..a835dc1 100644 --- a/gpu/command_buffer/service/shared_context_state.h +++ b/gpu/command_buffer/service/shared_context_state.h
@@ -61,6 +61,8 @@ public base::RefCounted<SharedContextState>, public GrContextOptions::ShaderErrorHandler { public: + using ContextLostCallback = base::OnceCallback<void(bool)>; + // TODO: Refactor code to have seperate constructor for GL and Vulkan and not // initialize/use GL related info for vulkan and vice-versa. SharedContextState( @@ -68,7 +70,7 @@ scoped_refptr<gl::GLSurface> surface, scoped_refptr<gl::GLContext> context, bool use_virtualized_gl_contexts, - base::OnceClosure context_lost_callback, + ContextLostCallback context_lost_callback, GrContextType gr_context_type = GrContextType::kGL, viz::VulkanContextProvider* vulkan_context_provider = nullptr, viz::MetalContextProvider* metal_context_provider = nullptr, @@ -250,7 +252,7 @@ bool use_virtualized_gl_contexts_ = false; bool support_vulkan_external_object_ = false; - base::OnceClosure context_lost_callback_; + ContextLostCallback context_lost_callback_; GrContextType gr_context_type_ = GrContextType::kGL; MemoryTracker memory_tracker_; viz::VulkanContextProvider* const vk_context_provider_; @@ -289,6 +291,7 @@ base::MRUCache<void*, sk_sp<SkSurface>> sk_surface_cache_; bool device_needs_reset_ = false; + bool context_lost_by_robustness_extension = false; base::Time last_gl_check_graphics_reset_status_; bool disable_check_reset_status_throttling_for_test_ = false;
diff --git a/gpu/command_buffer/service/skia_utils.cc b/gpu/command_buffer/service/skia_utils.cc index 6c6a8e28..cfa3d91 100644 --- a/gpu/command_buffer/service/skia_utils.cc +++ b/gpu/command_buffer/service/skia_utils.cc
@@ -170,6 +170,7 @@ DCHECK(!context_state->gr_context()->abandoned()); if (!context_state->GrContextIsVulkan()) { + DCHECK(context_state->gr_context()); context_state->gr_context()->deleteBackendTexture( std::move(*backend_texture)); return;
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc index 41b15653..76f4ead 100644 --- a/gpu/command_buffer/service/wrapped_sk_image.cc +++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -446,6 +446,9 @@ SharedImageManager* manager, MemoryTypeTracker* tracker, scoped_refptr<SharedContextState> context_state) { + if (context_state_->context_lost()) + return nullptr; + DCHECK_EQ(context_state_, context_state.get()); return std::make_unique<WrappedSkImageRepresentation>(manager, this, tracker); }
diff --git a/gpu/ipc/common/gpu_memory_buffer_support.cc b/gpu/ipc/common/gpu_memory_buffer_support.cc index 5d05df1..9bc45768 100644 --- a/gpu/ipc/common/gpu_memory_buffer_support.cc +++ b/gpu/ipc/common/gpu_memory_buffer_support.cc
@@ -8,6 +8,7 @@ #include "base/notreached.h" #include "build/build_config.h" #include "gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.h" +#include "ui/base/ui_base_features.h" #include "ui/gfx/buffer_format_util.h" #include "ui/gfx/buffer_usage_util.h" @@ -46,8 +47,12 @@ GpuMemoryBufferSupport::GpuMemoryBufferSupport() { #if defined(USE_OZONE) - client_native_pixmap_factory_ = ui::CreateClientNativePixmapFactoryOzone(); -#elif defined(OS_LINUX) + if (features::IsUsingOzonePlatform()) { + client_native_pixmap_factory_ = ui::CreateClientNativePixmapFactoryOzone(); + return; + } +#endif +#if defined(OS_LINUX) client_native_pixmap_factory_.reset( gfx::CreateClientNativePixmapFactoryDmabuf()); #endif @@ -116,10 +121,13 @@ } NOTREACHED(); return false; -#elif defined(USE_OZONE) - return ui::OzonePlatform::GetInstance()->IsNativePixmapConfigSupported(format, - usage); -#elif defined(USE_X11) +#elif defined(USE_OZONE) || defined(USE_X11) +#if defined(USE_OZONE) + if (features::IsUsingOzonePlatform()) { + return ui::OzonePlatform::GetInstance()->IsNativePixmapConfigSupported( + format, usage); + } +#endif // On X11, GPU memory buffer support can only be determined after GPU // initialization. // viz::HostGpuMemoryBufferManager::IsNativeGpuMemoryBufferConfiguration()
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc index 98f44c24..231bea9 100644 --- a/gpu/ipc/service/gpu_channel_manager.cc +++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -740,8 +740,7 @@ auto shared_context_state = base::MakeRefCounted<SharedContextState>( std::move(share_group), std::move(surface), std::move(context), use_virtualized_gl_contexts, - base::BindOnce(&GpuChannelManager::OnContextLost, base::Unretained(this), - /*synthetic_loss=*/false), + base::BindOnce(&GpuChannelManager::OnContextLost, base::Unretained(this)), gpu_preferences_.gr_context_type, vulkan_context_provider_, metal_context_provider_, dawn_context_provider_, peak_memory_monitor_.GetWeakPtr());
diff --git a/gpu/vulkan/BUILD.gn b/gpu/vulkan/BUILD.gn index a6f86a9e..4af8209f 100644 --- a/gpu/vulkan/BUILD.gn +++ b/gpu/vulkan/BUILD.gn
@@ -165,6 +165,7 @@ sources = [ "tests/native_window.h" ] deps = [ + "//ui/base:features", "//ui/gfx", "//ui/gfx:native_widget_types", ]
diff --git a/gpu/vulkan/tests/native_window.cc b/gpu/vulkan/tests/native_window.cc index f8dce865..a2f7d15 100644 --- a/gpu/vulkan/tests/native_window.cc +++ b/gpu/vulkan/tests/native_window.cc
@@ -5,6 +5,7 @@ #include "gpu/vulkan/tests/native_window.h" #include "base/containers/flat_map.h" +#include "ui/base/ui_base_features.h" #include "ui/platform_window/platform_window_delegate.h" #include "ui/platform_window/platform_window_init_properties.h" @@ -26,15 +27,23 @@ void Initialize(const gfx::Rect& bounds) { DCHECK(!platform_window_); + +#if defined(USE_OZONE) || defined(USE_X11) + ui::PlatformWindowInitProperties props(bounds); #if defined(USE_OZONE) - ui::PlatformWindowInitProperties props(bounds); - platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow( - this, std::move(props)); -#elif defined(USE_X11) - ui::PlatformWindowInitProperties props(bounds); - auto x11_window = std::make_unique<ui::X11Window>(this); - x11_window->Initialize(std::move(props)); - platform_window_ = std::move(x11_window); + if (features::IsUsingOzonePlatform()) { + platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow( + this, std::move(props)); + } +#endif +#if defined(USE_X11) + if (!platform_window_) { + DCHECK(!features::IsUsingOzonePlatform()); + auto x11_window = std::make_unique<ui::X11Window>(this); + x11_window->Initialize(std::move(props)); + platform_window_ = std::move(x11_window); + } +#endif #else NOTIMPLEMENTED(); return;
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn index e022b85..eac25f7 100644 --- a/ios/chrome/app/BUILD.gn +++ b/ios/chrome/app/BUILD.gn
@@ -140,7 +140,6 @@ ":app", ":blocking_scene_commands", ":mode", - ":scoped_ui_blocker", ":tests_hook", "//base", "//build:branding_buildflags", @@ -223,6 +222,7 @@ "//ios/chrome/browser/ui/main", "//ios/chrome/browser/ui/main:scene", "//ios/chrome/browser/ui/main:scene_guts", + "//ios/chrome/browser/ui/scoped_ui_blocker", "//ios/chrome/browser/ui/tab_grid", "//ios/chrome/browser/ui/tab_grid:tab_grid_ui", "//ios/chrome/browser/ui/table_view", @@ -278,25 +278,6 @@ deps = [ "//base" ] } -source_set("scoped_ui_blocker") { - configs += [ "//build/config/compiler:enable_arc" ] - sources = [ - "scoped_ui_blocker.h", - "scoped_ui_blocker.mm", - ] - - deps = [ - "//base", - "//ios/chrome/app/application_delegate:application_delegate_internal", - "//ios/chrome/browser/ui/main:scene", - ] - - allow_circular_includes_from = [ - "//ios/chrome/app/application_delegate:application_delegate_internal", - "//ios/chrome/browser/ui/main:scene", - ] -} - source_set("mode") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ "application_mode.h" ]
diff --git a/ios/chrome/app/application_delegate/BUILD.gn b/ios/chrome/app/application_delegate/BUILD.gn index e5a53448..07b6c38 100644 --- a/ios/chrome/app/application_delegate/BUILD.gn +++ b/ios/chrome/app/application_delegate/BUILD.gn
@@ -211,6 +211,8 @@ "//ui/base", "//url", ] + public_deps = [ "//ios/chrome/browser/ui/scoped_ui_blocker" ] + if (ios_enable_metrickit) { deps += [ ":metric_kit_subscriber" ] }
diff --git a/ios/chrome/app/application_delegate/app_state.h b/ios/chrome/app/application_delegate/app_state.h index a3a20c5..02e498c 100644 --- a/ios/chrome/app/application_delegate/app_state.h +++ b/ios/chrome/app/application_delegate/app_state.h
@@ -7,6 +7,8 @@ #import <UIKit/UIKit.h> +#import "ios/chrome/browser/ui/scoped_ui_blocker/ui_blocker_manager.h" + @class AppState; @protocol BrowserLauncher; @class CommandDispatcher; @@ -34,7 +36,7 @@ // Represents the application state and responds to application state changes // and system events. -@interface AppState : NSObject +@interface AppState : NSObject <UIBlockerManager> - (instancetype)init NS_UNAVAILABLE; @@ -61,13 +63,6 @@ // is shown. When there is no blocking UI shown in any scene, this is nil. @property(nonatomic, weak, readonly) SceneState* sceneShowingBlockingUI; -// Call this when showing a new blocking UI in |scene|. -// It is an error to call this for scene A when scene B is already showing one -// or more blocking UI. -- (void)incrementBlockingUICounterForScene:(SceneState*)scene; -// Call this after dismissing a blocking UI. -- (void)decrementBlockingUICounter; - // Saves the launchOptions to be used from -newTabFromLaunchOptions. If the // application is in background, initialize the browser to basic. If not, launch // the browser.
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm index bdc925b..dfb1c13 100644 --- a/ios/chrome/app/application_delegate/app_state.mm +++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -26,7 +26,6 @@ #import "ios/chrome/app/application_delegate/user_activity_handler.h" #import "ios/chrome/app/deferred_initialization_runner.h" #import "ios/chrome/app/main_application_delegate.h" -#import "ios/chrome/app/scoped_ui_blocker.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_constants.h" @@ -53,6 +52,7 @@ #import "ios/chrome/browser/ui/main/scene_delegate.h" #import "ios/chrome/browser/ui/main/scene_state.h" #import "ios/chrome/browser/ui/safe_mode/safe_mode_coordinator.h" +#import "ios/chrome/browser/ui/scoped_ui_blocker/scoped_ui_blocker.h" #import "ios/chrome/browser/ui/util/multi_window_support.h" #include "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/web_state_list/web_state_list_metrics_browser_agent.h" @@ -143,8 +143,8 @@ // never reset. @property(nonatomic, assign) BOOL firstSceneHasActivated; -// Redefined as readwrite. -@property(nonatomic, weak, readwrite) SceneState* sceneShowingBlockingUI; +// The current blocker target if any. +@property(nonatomic, weak, readwrite) id<UIBlockerTarget> uiBlockerTarget; // The counter of currently shown blocking UIs. Do not use this directly, // instead use incrementBlockingUICounterForScene: and @@ -196,14 +196,15 @@ _safeModeCoordinator = safeModeCoordinator; } -- (void)setSceneShowingBlockingUI:(SceneState*)newScene { - _sceneShowingBlockingUI = newScene; - for (SceneState* scene in self.connectedScenes) { - // When there's a scene with blocking UI, all other scenes should show the - // overlay. - BOOL shouldPresentOverlay = (newScene != nil) && (scene != newScene); - scene.presentingModalOverlay = shouldPresentOverlay; - } +- (void)setUiBlockerTarget:(id<UIBlockerTarget>)uiBlockerTarget { + _uiBlockerTarget = uiBlockerTarget; + for (SceneState* scene in self.connectedScenes) { + // When there's a scene with blocking UI, all other scenes should show the + // overlay. + BOOL shouldPresentOverlay = + (uiBlockerTarget != nil) && (scene != uiBlockerTarget); + scene.presentingModalOverlay = shouldPresentOverlay; + } } #pragma mark - Public methods. @@ -531,24 +532,6 @@ #pragma mark - Multiwindow-related -- (void)decrementBlockingUICounter { - DCHECK(self.blockingUICounter > 0 && self.sceneShowingBlockingUI != nil); - self.blockingUICounter--; - if (self.blockingUICounter == 0) { - self.sceneShowingBlockingUI = nil; - } -} - -- (void)incrementBlockingUICounterForScene:(SceneState*)scene { - DCHECK(self.sceneShowingBlockingUI == nil || - scene == self.sceneShowingBlockingUI) - << "Another scene is already showing a blocking UI!"; - self.blockingUICounter++; - if (!self.sceneShowingBlockingUI) { - self.sceneShowingBlockingUI = scene; - } -} - - (SceneState*)foregroundActiveScene { for (SceneState* sceneState in self.connectedScenes) { if (sceneState.activationLevel == SceneActivationLevelForegroundActive) { @@ -616,8 +599,10 @@ [self.safeModeCoordinator start]; - _safeModeBlocker = - std::make_unique<ScopedUIBlocker>(self.foregroundActiveScene); + if (IsMultiwindowSupported()) { + _safeModeBlocker = + std::make_unique<ScopedUIBlocker>(self.foregroundActiveScene); + } } - (void)initializeUI { @@ -656,6 +641,25 @@ [[PreviousSessionInfo sharedInstance] beginRecordingCurrentSession]; } +#pragma mark - UIBlockerManager + +- (void)incrementBlockingUICounterForTarget:(id<UIBlockerTarget>)target { + DCHECK(self.uiBlockerTarget == nil || target == self.uiBlockerTarget) + << "Another scene is already showing a blocking UI!"; + self.blockingUICounter++; + if (!self.uiBlockerTarget) { + self.uiBlockerTarget = target; + } +} + +- (void)decrementBlockingUICounterForTarget:(id<UIBlockerTarget>)target { + DCHECK(self.blockingUICounter > 0 && self.uiBlockerTarget == target); + self.blockingUICounter--; + if (self.blockingUICounter == 0) { + self.uiBlockerTarget = nil; + } +} + #pragma mark - Scene notifications // Handler for UISceneDidActivateNotification. @@ -680,8 +684,8 @@ } } sceneDelegate.sceneState.presentingModalOverlay = - self.sceneShowingBlockingUI && - (self.sceneShowingBlockingUI != sceneDelegate.sceneState); + (self.uiBlockerTarget != nil) && + (self.uiBlockerTarget != sceneDelegate.sceneState); } }
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index d49aa0c..4baebba 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -28,7 +28,6 @@ #import "ios/chrome/app/blocking_scene_commands.h" #import "ios/chrome/app/deferred_initialization_runner.h" #import "ios/chrome/app/memory_monitor.h" -#import "ios/chrome/app/scoped_ui_blocker.h" #import "ios/chrome/app/spotlight/spotlight_manager.h" #include "ios/chrome/app/startup/chrome_main_starter.h" #include "ios/chrome/app/startup/client_registration.h" @@ -90,6 +89,7 @@ #import "ios/chrome/browser/ui/main/browser_view_wrangler.h" #import "ios/chrome/browser/ui/main/scene_controller_guts.h" #import "ios/chrome/browser/ui/main/scene_delegate.h" +#import "ios/chrome/browser/ui/scoped_ui_blocker/scoped_ui_blocker.h" #import "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/browser/ui/util/multi_window_support.h" #import "ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.h" @@ -262,9 +262,6 @@ // Hander for the startup tasks, deferred or not. StartupTasks* _startupTasks; - - // UI blocker used during first run in multiwindow. - std::unique_ptr<ScopedUIBlocker> _firstRunUIBlocker; } // The ChromeBrowserState associated with the main (non-OTR) browsing mode. @@ -607,10 +604,6 @@ object:nil]; [self markEulaAsAccepted]; - - if (IsMultiwindowSupported()) { - _firstRunUIBlocker.reset(); - } } - (void)handleFirstRunUIDidFinish { @@ -1085,11 +1078,6 @@ selector:@selector(handleFirstRunUIDidFinish) name:kChromeFirstRunUIDidFinishNotification object:nil]; - - if (IsMultiwindowSupported()) { - // Update the AppState. - _firstRunUIBlocker = std::make_unique<ScopedUIBlocker>(presentingScene); - } } - (void)crashIfRequested {
diff --git a/ios/chrome/app/scoped_ui_blocker.h b/ios/chrome/app/scoped_ui_blocker.h deleted file mode 100644 index 86bbec3c..0000000 --- a/ios/chrome/app/scoped_ui_blocker.h +++ /dev/null
@@ -1,28 +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 IOS_CHROME_APP_SCOPED_UI_BLOCKER_H_ -#define IOS_CHROME_APP_SCOPED_UI_BLOCKER_H_ - -#include "base/logging.h" -#include "base/macros.h" -#import "ios/chrome/app/application_delegate/app_state.h" -#import "ios/chrome/browser/ui/main/scene_state.h" - -// A helper object that increments AppState's blocking UI counter for -// its entire lifetime. -class ScopedUIBlocker { - public: - explicit ScopedUIBlocker(SceneState* scene); - ~ScopedUIBlocker(); - - private: - // The scene showing the blocking UI. - __weak SceneState* scene_; - - ScopedUIBlocker(const ScopedUIBlocker&) = delete; - ScopedUIBlocker& operator=(const ScopedUIBlocker&) = delete; -}; - -#endif // IOS_CHROME_APP_SCOPED_UI_BLOCKER_H_
diff --git a/ios/chrome/app/scoped_ui_blocker.mm b/ios/chrome/app/scoped_ui_blocker.mm deleted file mode 100644 index 9bcf36a8..0000000 --- a/ios/chrome/app/scoped_ui_blocker.mm +++ /dev/null
@@ -1,22 +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. - -#import "ios/chrome/app/scoped_ui_blocker.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -ScopedUIBlocker::ScopedUIBlocker(SceneState* scene) : scene_(scene) { - DCHECK(scene_); - AppState* appState = scene.appState; - DCHECK(appState.sceneShowingBlockingUI == nil || - appState.sceneShowingBlockingUI == scene_) - << "Another scene is already showing a blocking UI!"; - [appState incrementBlockingUICounterForScene:scene]; -} - -ScopedUIBlocker::~ScopedUIBlocker() { - [scene_.appState decrementBlockingUICounter]; -}
diff --git a/ios/chrome/browser/ui/commands/command_dispatcher.mm b/ios/chrome/browser/ui/commands/command_dispatcher.mm index 08d7d62..5e569fca 100644 --- a/ios/chrome/browser/ui/commands/command_dispatcher.mm +++ b/ios/chrome/browser/ui/commands/command_dispatcher.mm
@@ -110,7 +110,7 @@ - (CommandDispatcher*)strictCallableForProtocol:(Protocol*)protocol { CHECK([self dispatchingForProtocol:protocol]) - << "Dispatcher failed protocol confromance"; + << "Dispatcher failed protocol conformance"; return self; }
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm index f50db87..dd1a1db 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
@@ -56,10 +56,11 @@ } // namespace -@interface ContentSuggestionsMediator ()<ContentSuggestionsItemDelegate, - ContentSuggestionsServiceObserver, - MostVisitedSitesObserving, - ReadingListModelBridgeObserver> { +@interface ContentSuggestionsMediator () <BooleanObserver, + ContentSuggestionsItemDelegate, + ContentSuggestionsServiceObserver, + MostVisitedSitesObserving, + ReadingListModelBridgeObserver> { // Bridge for this class to become an observer of a ContentSuggestionsService. std::unique_ptr<ContentSuggestionsServiceBridge> _suggestionBridge; std::unique_ptr<ntp_tiles::MostVisitedSites> _mostVisitedSites; @@ -369,22 +370,13 @@ - (void)toggleArticlesVisibility { [self.contentArticlesExpanded setValue:![self.contentArticlesExpanded value]]; + [self reloadArticleSection]; +} - // Update the section information for new collapsed state. - ntp_snippets::Category category = ntp_snippets::Category::FromKnownCategory( - ntp_snippets::KnownCategories::ARTICLES); - ContentSuggestionsCategoryWrapper* wrapper = - [ContentSuggestionsCategoryWrapper wrapperWithCategory:category]; - ContentSuggestionsSectionInformation* sectionInfo = - self.sectionInformationByCategory[wrapper]; - sectionInfo.expanded = [self.contentArticlesExpanded value]; +#pragma mark - BooleanObserver - // Reloading the section with animations looks bad because the section - // border with the new collapsed height draws before the elements collapse. - BOOL animationsWereEnabled = [UIView areAnimationsEnabled]; - [UIView setAnimationsEnabled:NO]; - [self.dataSink reloadSection:sectionInfo]; - [UIView setAnimationsEnabled:animationsWereEnabled]; +- (void)booleanDidChange:(id<ObservableBoolean>)observableBoolean { + [self reloadArticleSection]; } #pragma mark - ContentSuggestionsServiceObserver @@ -563,6 +555,24 @@ #pragma mark - Private +- (void)reloadArticleSection { + // Update the section information for new collapsed state. + ntp_snippets::Category category = ntp_snippets::Category::FromKnownCategory( + ntp_snippets::KnownCategories::ARTICLES); + ContentSuggestionsCategoryWrapper* wrapper = + [ContentSuggestionsCategoryWrapper wrapperWithCategory:category]; + ContentSuggestionsSectionInformation* sectionInfo = + self.sectionInformationByCategory[wrapper]; + sectionInfo.expanded = [self.contentArticlesExpanded value]; + + // Reloading the section with animations looks bad because the section + // border with the new collapsed height draws before the elements collapse. + BOOL animationsWereEnabled = [UIView areAnimationsEnabled]; + [UIView setAnimationsEnabled:NO]; + [self.dataSink reloadSection:sectionInfo]; + [UIView setAnimationsEnabled:animationsWereEnabled]; +} + // Converts the |suggestions| from |category| to CSCollectionViewItem and adds // them to the |contentArray| if the category is available. - (void)addSuggestions: @@ -705,6 +715,13 @@ } } +- (void)setContentArticlesExpanded:(PrefBackedBoolean*)contentArticlesExpanded { + if (_contentArticlesExpanded == contentArticlesExpanded) + return; + _contentArticlesExpanded = contentArticlesExpanded; + [contentArticlesExpanded setObserver:self]; +} + #pragma mark - ReadingListModelBridgeObserver - (void)readingListModelLoaded:(const ReadingListModel*)model {
diff --git a/ios/chrome/browser/ui/favicon/BUILD.gn b/ios/chrome/browser/ui/favicon/BUILD.gn index 46d07c2..adb21cf 100644 --- a/ios/chrome/browser/ui/favicon/BUILD.gn +++ b/ios/chrome/browser/ui/favicon/BUILD.gn
@@ -11,7 +11,6 @@ ] deps = [ "resources:default_favicon", - "resources:default_world_favicon", "resources:default_world_favicon_incognito", "resources:default_world_favicon_regular", "//base", @@ -20,6 +19,7 @@ "//ios/chrome/browser/favicon", "//ios/chrome/browser/ui/util", "//ios/chrome/common/ui/favicon", + "//ios/chrome/common/ui/resources:default_world_favicon", "//url", ] configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/chrome/browser/ui/favicon/resources/BUILD.gn b/ios/chrome/browser/ui/favicon/resources/BUILD.gn index 3d7c12a..481b51e 100644 --- a/ios/chrome/browser/ui/favicon/resources/BUILD.gn +++ b/ios/chrome/browser/ui/favicon/resources/BUILD.gn
@@ -4,15 +4,6 @@ import("//build/config/ios/asset_catalog.gni") -imageset("default_world_favicon") { - sources = [ - "default_world_favicon.imageset/Contents.json", - "default_world_favicon.imageset/default_world_favicon.png", - "default_world_favicon.imageset/default_world_favicon@2x.png", - "default_world_favicon.imageset/default_world_favicon@3x.png", - ] -} - imageset("default_world_favicon_incognito") { sources = [ "default_world_favicon_incognito.imageset/Contents.json",
diff --git a/ios/chrome/browser/ui/main/BUILD.gn b/ios/chrome/browser/ui/main/BUILD.gn index e77d3b0f..414211a 100644 --- a/ios/chrome/browser/ui/main/BUILD.gn +++ b/ios/chrome/browser/ui/main/BUILD.gn
@@ -85,6 +85,7 @@ "//ios/public/provider/chrome/browser/signin", "//ios/public/provider/chrome/browser/user_feedback", ] + public_deps = [ "//ios/chrome/browser/ui/scoped_ui_blocker" ] allow_circular_includes_from = [ ":main" ]
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm index a5d5c0f5..563991f 100644 --- a/ios/chrome/browser/ui/main/scene_controller.mm +++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -22,7 +22,6 @@ #import "ios/chrome/app/chrome_overlay_window.h" #import "ios/chrome/app/deferred_initialization_runner.h" #import "ios/chrome/app/main_controller_guts.h" -#import "ios/chrome/app/scoped_ui_blocker.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/browsing_data/browsing_data_remove_mask.h" #include "ios/chrome/browser/browsing_data/browsing_data_remover.h" @@ -62,6 +61,7 @@ #include "ios/chrome/browser/ui/history/history_coordinator.h" #import "ios/chrome/browser/ui/main/browser_interface_provider.h" #import "ios/chrome/browser/ui/main/browser_view_wrangler.h" +#import "ios/chrome/browser/ui/scoped_ui_blocker/scoped_ui_blocker.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #include "ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.h" #import "ios/chrome/browser/ui/ui_feature_flags.h"
diff --git a/ios/chrome/browser/ui/main/scene_state.h b/ios/chrome/browser/ui/main/scene_state.h index 5b1d4dc..e627b94 100644 --- a/ios/chrome/browser/ui/main/scene_state.h +++ b/ios/chrome/browser/ui/main/scene_state.h
@@ -7,6 +7,7 @@ #import <UIKit/UIKit.h> +#import "ios/chrome/browser/ui/scoped_ui_blocker/ui_blocker_target.h" #import "ios/chrome/browser/window_activities/window_activity_helpers.h" @class AppState; @@ -55,7 +56,7 @@ // An object containing the state of a UIWindowScene. One state object // corresponds to one scene. -@interface SceneState : NSObject +@interface SceneState : NSObject <UIBlockerTarget> - (instancetype)initWithAppState:(AppState*)appState NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/main/scene_state.mm b/ios/chrome/browser/ui/main/scene_state.mm index e63656b8..0c7c61a9 100644 --- a/ios/chrome/browser/ui/main/scene_state.mm +++ b/ios/chrome/browser/ui/main/scene_state.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/ui/main/scene_state.h" #import "base/ios/crb_protocol_observers.h" +#import "ios/chrome/app/application_delegate/app_state.h" #import "ios/chrome/app/chrome_overlay_window.h" #import "ios/chrome/browser/ui/main/scene_controller.h" #import "ios/chrome/browser/ui/util/multi_window_support.h" @@ -117,6 +118,10 @@ [self.observers sceneState:self receivedUserActivity:pendingUserActivity]; } +- (id<UIBlockerManager>)uiBlockerManager { + return _appState; +} + #pragma mark - debug - (NSString*)description {
diff --git a/ios/chrome/browser/ui/scoped_ui_blocker/BUILD.gn b/ios/chrome/browser/ui/scoped_ui_blocker/BUILD.gn new file mode 100644 index 0000000..88a63b6d --- /dev/null +++ b/ios/chrome/browser/ui/scoped_ui_blocker/BUILD.gn
@@ -0,0 +1,16 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("scoped_ui_blocker") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "scoped_ui_blocker.h", + "scoped_ui_blocker.h", + "scoped_ui_blocker.mm", + "ui_blocker_manager.h", + "ui_blocker_target.h", + ] + + deps = [ "//base" ] +}
diff --git a/ios/chrome/browser/ui/scoped_ui_blocker/scoped_ui_blocker.h b/ios/chrome/browser/ui/scoped_ui_blocker/scoped_ui_blocker.h new file mode 100644 index 0000000..e0c97b39 --- /dev/null +++ b/ios/chrome/browser/ui/scoped_ui_blocker/scoped_ui_blocker.h
@@ -0,0 +1,31 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SCOPED_UI_BLOCKER_SCOPED_UI_BLOCKER_H_ +#define IOS_CHROME_BROWSER_UI_SCOPED_UI_BLOCKER_SCOPED_UI_BLOCKER_H_ + +#import <Foundation/Foundation.h> + +#include "base/logging.h" +#include "base/macros.h" + +@protocol UIBlockerManager; +@protocol UIBlockerTarget; + +// A helper object that increments AppState's blocking UI counter for +// its entire lifetime. +class ScopedUIBlocker { + public: + explicit ScopedUIBlocker(id<UIBlockerTarget> target); + ~ScopedUIBlocker(); + + private: + // The target showing the blocking UI. + __weak id<UIBlockerTarget> target_; + + ScopedUIBlocker(const ScopedUIBlocker&) = delete; + ScopedUIBlocker& operator=(const ScopedUIBlocker&) = delete; +}; + +#endif // IOS_CHROME_BROWSER_UI_SCOPED_UI_BLOCKER_SCOPED_UI_BLOCKER_H_
diff --git a/ios/chrome/browser/ui/scoped_ui_blocker/scoped_ui_blocker.mm b/ios/chrome/browser/ui/scoped_ui_blocker/scoped_ui_blocker.mm new file mode 100644 index 0000000..d069e6f0 --- /dev/null +++ b/ios/chrome/browser/ui/scoped_ui_blocker/scoped_ui_blocker.mm
@@ -0,0 +1,25 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/scoped_ui_blocker/scoped_ui_blocker.h" + +#import "base/check.h" +#import "ios/chrome/browser/ui/scoped_ui_blocker/ui_blocker_manager.h" +#import "ios/chrome/browser/ui/scoped_ui_blocker/ui_blocker_target.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +ScopedUIBlocker::ScopedUIBlocker(id<UIBlockerTarget> target) : target_(target) { + DCHECK(target_); + id<UIBlockerManager> uiBlockerManager = target.uiBlockerManager; + DCHECK(uiBlockerManager); + [uiBlockerManager incrementBlockingUICounterForTarget:target_]; +} + +ScopedUIBlocker::~ScopedUIBlocker() { + DCHECK(target_) << "Cannot unlock the blocking UI if scene is deallocated."; + [target_.uiBlockerManager decrementBlockingUICounterForTarget:target_]; +}
diff --git a/ios/chrome/browser/ui/scoped_ui_blocker/ui_blocker_manager.h b/ios/chrome/browser/ui/scoped_ui_blocker/ui_blocker_manager.h new file mode 100644 index 0000000..ba18fcf --- /dev/null +++ b/ios/chrome/browser/ui/scoped_ui_blocker/ui_blocker_manager.h
@@ -0,0 +1,28 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SCOPED_UI_BLOCKER_UI_BLOCKER_MANAGER_H_ +#define IOS_CHROME_BROWSER_UI_SCOPED_UI_BLOCKER_UI_BLOCKER_MANAGER_H_ + +#import <Foundation/Foundation.h> + +@protocol UIBlockerTarget; + +// Manager in charge to block and unblock all UI. +@protocol UIBlockerManager <NSObject> + +// Call this when showing a new blocking UI in |target|. +// It is an error to call this for target A when target B is already showing one +// or more blocking UI. +// This method can be called multiple time with the same target, before calling +// |decrementBlockingUICounterForTarget:|. +- (void)incrementBlockingUICounterForTarget:(id<UIBlockerTarget>)target; +// Call this after dismissing a blocking UI. +// |target| has to be the same value when |incrementBlockingUICounterForTarget:| +// was called. +- (void)decrementBlockingUICounterForTarget:(id<UIBlockerTarget>)target; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SCOPED_UI_BLOCKER_UI_BLOCKER_MANAGER_H_
diff --git a/ios/chrome/browser/ui/scoped_ui_blocker/ui_blocker_target.h b/ios/chrome/browser/ui/scoped_ui_blocker/ui_blocker_target.h new file mode 100644 index 0000000..cde00282 --- /dev/null +++ b/ios/chrome/browser/ui/scoped_ui_blocker/ui_blocker_target.h
@@ -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. + +#ifndef IOS_CHROME_BROWSER_UI_SCOPED_UI_BLOCKER_UI_BLOCKER_TARGET_H_ +#define IOS_CHROME_BROWSER_UI_SCOPED_UI_BLOCKER_UI_BLOCKER_TARGET_H_ + +#import <Foundation/Foundation.h> + +@protocol UIBlockerManager; + +// Target to block all UI. +@protocol UIBlockerTarget <NSObject> + +// Returns UI blocker manager. +@property(nonatomic, weak, readonly) id<UIBlockerManager> uiBlockerManager; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SCOPED_UI_BLOCKER_UI_BLOCKER_TARGET_H_
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm index 81d0347..8b6a855 100644 --- a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
@@ -143,6 +143,7 @@ - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; + [self.navigationController setToolbarHidden:YES animated:YES]; } - (void)setEditing:(BOOL)editing animated:(BOOL)animated {
diff --git a/ios/chrome/browser/ui/tabs/BUILD.gn b/ios/chrome/browser/ui/tabs/BUILD.gn index f3b4f35..80be000 100644 --- a/ios/chrome/browser/ui/tabs/BUILD.gn +++ b/ios/chrome/browser/ui/tabs/BUILD.gn
@@ -48,7 +48,6 @@ "//ios/chrome/browser/ui/colors", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/elements", - "//ios/chrome/browser/ui/favicon/resources:default_world_favicon", "//ios/chrome/browser/ui/fullscreen", "//ios/chrome/browser/ui/fullscreen:feature_flags", "//ios/chrome/browser/ui/image_util", @@ -64,6 +63,7 @@ "//ios/chrome/common", "//ios/chrome/common/ui/colors", "//ios/chrome/common/ui/elements", + "//ios/chrome/common/ui/resources:default_world_favicon", "//ios/chrome/common/ui/util", "//ios/third_party/material_components_ios", "//ios/web",
diff --git a/ios/chrome/browser/web/tab_order_egtest.mm b/ios/chrome/browser/web/tab_order_egtest.mm index 9b180c0..ebbb0184 100644 --- a/ios/chrome/browser/web/tab_order_egtest.mm +++ b/ios/chrome/browser/web/tab_order_egtest.mm
@@ -47,7 +47,8 @@ @implementation TabOrderTestCase // Tests that new tabs are always inserted after their parent tab. -- (void)testChildTabOrdering { +// TODO(crbug.com/1106739): reenable this test. +- (void)DISABLED_testChildTabOrdering { GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); const GURL URL1 = self.testServer->GetURL(kLinksTestURL1); @@ -61,8 +62,6 @@ [ElementSelector selectorWithElementID:kLinkSelectorID], true /* menu should appear */)]; [[EarlGrey selectElementWithMatcher:OpenLinkInNewTabButton()] - assertWithMatcher:grey_notNil()]; - [[EarlGrey selectElementWithMatcher:OpenLinkInNewTabButton()] performAction:grey_tap()]; [ChromeEarlGrey waitForMainTabCount:2U]; NSString* childTab1ID = [ChromeEarlGrey nextTabID];
diff --git a/ios/chrome/common/ui/resources/BUILD.gn b/ios/chrome/common/ui/resources/BUILD.gn new file mode 100644 index 0000000..ff6b3a9e --- /dev/null +++ b/ios/chrome/common/ui/resources/BUILD.gn
@@ -0,0 +1,14 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/ios/asset_catalog.gni") + +imageset("default_world_favicon") { + sources = [ + "default_world_favicon.imageset/Contents.json", + "default_world_favicon.imageset/default_world_favicon.png", + "default_world_favicon.imageset/default_world_favicon@2x.png", + "default_world_favicon.imageset/default_world_favicon@3x.png", + ] +}
diff --git a/ios/chrome/browser/ui/favicon/resources/default_world_favicon.imageset/Contents.json b/ios/chrome/common/ui/resources/default_world_favicon.imageset/Contents.json similarity index 100% rename from ios/chrome/browser/ui/favicon/resources/default_world_favicon.imageset/Contents.json rename to ios/chrome/common/ui/resources/default_world_favicon.imageset/Contents.json
diff --git a/ios/chrome/browser/ui/favicon/resources/default_world_favicon.imageset/default_world_favicon.png b/ios/chrome/common/ui/resources/default_world_favicon.imageset/default_world_favicon.png similarity index 100% rename from ios/chrome/browser/ui/favicon/resources/default_world_favicon.imageset/default_world_favicon.png rename to ios/chrome/common/ui/resources/default_world_favicon.imageset/default_world_favicon.png Binary files differ
diff --git a/ios/chrome/browser/ui/favicon/resources/default_world_favicon.imageset/default_world_favicon@2x.png b/ios/chrome/common/ui/resources/default_world_favicon.imageset/default_world_favicon@2x.png similarity index 100% rename from ios/chrome/browser/ui/favicon/resources/default_world_favicon.imageset/default_world_favicon@2x.png rename to ios/chrome/common/ui/resources/default_world_favicon.imageset/default_world_favicon@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/favicon/resources/default_world_favicon.imageset/default_world_favicon@3x.png b/ios/chrome/common/ui/resources/default_world_favicon.imageset/default_world_favicon@3x.png similarity index 100% rename from ios/chrome/browser/ui/favicon/resources/default_world_favicon.imageset/default_world_favicon@3x.png rename to ios/chrome/common/ui/resources/default_world_favicon.imageset/default_world_favicon@3x.png Binary files differ
diff --git a/ios/chrome/credential_provider_extension/ui/BUILD.gn b/ios/chrome/credential_provider_extension/ui/BUILD.gn index fed9800..19e3010 100644 --- a/ios/chrome/credential_provider_extension/ui/BUILD.gn +++ b/ios/chrome/credential_provider_extension/ui/BUILD.gn
@@ -34,6 +34,7 @@ "//ios/chrome/common/ui/colors", "//ios/chrome/common/ui/confirmation_alert", "//ios/chrome/common/ui/elements:popover_label_view_controller", + "//ios/chrome/common/ui/resources:default_world_favicon", "//ios/chrome/common/ui/util", "//ios/chrome/credential_provider_extension:metrics_util", "//ios/chrome/credential_provider_extension:password_util",
diff --git a/ios/chrome/credential_provider_extension/ui/resources/BUILD.gn b/ios/chrome/credential_provider_extension/ui/resources/BUILD.gn index cc216de..fcd7da9 100644 --- a/ios/chrome/credential_provider_extension/ui/resources/BUILD.gn +++ b/ios/chrome/credential_provider_extension/ui/resources/BUILD.gn
@@ -8,7 +8,6 @@ group("resources") { deps = [ ":consent_illustration", - ":default_world_favicon", ":empty_credentials_illustration", ":info_icon", ":password_hide_icon", @@ -52,15 +51,6 @@ ] } -imageset("default_world_favicon") { - sources = [ - "default_world_favicon.imageset/Contents.json", - "default_world_favicon.imageset/default_world_favicon.png", - "default_world_favicon.imageset/default_world_favicon@2x.png", - "default_world_favicon.imageset/default_world_favicon@3x.png", - ] -} - imageset("info_icon") { sources = [ "info_icon.imageset/Contents.json",
diff --git a/ios/chrome/credential_provider_extension/ui/resources/default_world_favicon.imageset/Contents.json b/ios/chrome/credential_provider_extension/ui/resources/default_world_favicon.imageset/Contents.json deleted file mode 100644 index 3614ccd..0000000 --- a/ios/chrome/credential_provider_extension/ui/resources/default_world_favicon.imageset/Contents.json +++ /dev/null
@@ -1,23 +0,0 @@ -{ - "images": [ - { - "idiom": "universal", - "scale": "1x", - "filename": "default_world_favicon.png" - }, - { - "idiom": "universal", - "scale": "2x", - "filename": "default_world_favicon@2x.png" - }, - { - "idiom": "universal", - "scale": "3x", - "filename": "default_world_favicon@3x.png" - } - ], - "info": { - "version": 1, - "author": "xcode" - } -}
diff --git a/ios/chrome/credential_provider_extension/ui/resources/default_world_favicon.imageset/default_world_favicon.png b/ios/chrome/credential_provider_extension/ui/resources/default_world_favicon.imageset/default_world_favicon.png deleted file mode 100644 index 3b6c9360..0000000 --- a/ios/chrome/credential_provider_extension/ui/resources/default_world_favicon.imageset/default_world_favicon.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/credential_provider_extension/ui/resources/default_world_favicon.imageset/default_world_favicon@2x.png b/ios/chrome/credential_provider_extension/ui/resources/default_world_favicon.imageset/default_world_favicon@2x.png deleted file mode 100644 index 72b0b7c..0000000 --- a/ios/chrome/credential_provider_extension/ui/resources/default_world_favicon.imageset/default_world_favicon@2x.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/credential_provider_extension/ui/resources/default_world_favicon.imageset/default_world_favicon@3x.png b/ios/chrome/credential_provider_extension/ui/resources/default_world_favicon.imageset/default_world_favicon@3x.png deleted file mode 100644 index 7d10a12..0000000 --- a/ios/chrome/credential_provider_extension/ui/resources/default_world_favicon.imageset/default_world_favicon@3x.png +++ /dev/null Binary files differ
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl index 7c41163..730e5fe 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -120,7 +120,7 @@ {{interface_macros.declare_sync_method_params("param_", method)}}) { #if BUILDFLAG(MOJO_TRACE_ENABLED) {%- set qualified_method_name = "%s::%s::%s" % (namespace_as_string, - class_name, method_name) %} + class_name, method.name) %} {{interface_macros.trace_event("param_", method.parameters, qualified_method_name)}} #endif @@ -163,7 +163,7 @@ {{interface_macros.declare_request_params("in_", method)}}) { #if BUILDFLAG(MOJO_TRACE_ENABLED) {%- set qualified_method_name = "%s::%s::%s" % (namespace_as_string, class_name, - method_name) %} + method.name) %} {{interface_macros.trace_event("in_", method.parameters, qualified_method_name)}} #endif
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl index 8e64300b..0b415c2 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl
@@ -24,8 +24,7 @@ {%- endif -%} {%- endmacro -%} -{%- macro trace_event(prefix, method_parameters, qualified_method_name, - value="input_params_for_tracing") -%} +{%- macro trace_event(prefix, method_parameters, qualified_method_name) -%} {#- This macro assumes that the argument names are the ones declared by -#} {#- |declare_request_params|. Namely the |prefix| should be the same here as -#} {#- in |declare_request_params|. -#} @@ -33,15 +32,17 @@ TRACE_EVENT1( "mojom", "{{qualified_method_name}}", "input_parameters", [&](){ - auto {{value}} = std::make_unique<base::trace_event::TracedValue>(); + auto value = std::make_unique<base::trace_event::TracedValue>(); + base::trace_event::TracedValue* raw_value = value.get(); {%- for param in method_parameters %} -{%- for line in param.kind|write_input_param_for_tracing(prefix, - param.name, - value) %} +{%- for line in param.kind|write_input_param_for_tracing( + parameter_name=param.name, + cpp_parameter_name=prefix+param.name, + value='raw_value') %} {{line}} {%- endfor -%} {%- endfor %} - return {{value}}; + return value; }()); {%- else -%} TRACE_EVENT0("mojom", "{{qualified_method_name}}");
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl index 0679323..0bb970e 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
@@ -128,6 +128,19 @@ {{type}} {{name}}; {%- endfor %} +#if BUILDFLAG(MOJO_TRACE_ENABLED) + // Write this structure into |value|. The members are represented as a + // dictionary |member name|: |member value|. + // + // |value| The TracedValue to be written into. + // |parameter_name| Name of the variable holding this structure, + // used as the name of the dictionary representing this structure. + // If nullptr, then the dictionary representing this structure has no name + // (used in arrays of structures). + void ToTracedValue(base::trace_event::TracedValue* value, + const char* parameter_name = nullptr); +#endif // BUILDFLAG(MOJO_TRACE_ENABLED) + private: static bool Validate(const void* data, mojo::internal::ValidationContext* validation_context);
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl index d65dd69..fe9aeada 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl
@@ -32,6 +32,26 @@ } {%- endif %} +#if BUILDFLAG(MOJO_TRACE_ENABLED) +void {{struct.name}}::ToTracedValue(base::trace_event::TracedValue* value, + const char* parameter_name) { + if (parameter_name) { + value->BeginDictionary(parameter_name); + } else { + value->BeginDictionary(); + } +{%- for field in struct.fields %} +{%- for line in field.kind|write_input_param_for_tracing( + parameter_name=field.name, + cpp_parameter_name='this->'+field.name, + value='value') %} + {{line}} +{%- endfor -%} +{%- endfor %} + value->EndDictionary(); +} +#endif // BUILDFLAG(MOJO_TRACE_ENABLED) + bool {{struct.name}}::Validate( const void* data, mojo::internal::ValidationContext* validation_context) {
diff --git a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.cc.tmpl b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.cc.tmpl index e946228..e64615ed 100644 --- a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.cc.tmpl +++ b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.cc.tmpl
@@ -70,23 +70,10 @@ {%- set mojom_type = interface|get_qualified_name_for_kind(flatten_nested_kind=True) %} {%- set proto_type = "::mojolpm" ~ (interface|get_qualified_name_for_kind(flatten_nested_kind=True)) %} class {{interface.name}}Impl : public {{mojom_type}} { - ::mojo::BindingSet<{{mojom_type}}> bindings_; - ::mojo::AssociatedBindingSet<{{mojom_type}}> associated_bindings_; - public: {{interface.name}}Impl() { } - void Bind({{mojom_type}}Request&& request) { - DCHECK(mojolpm::GetContext()->task_runner()->RunsTasksInCurrentSequence()); - bindings_.AddBinding(this, std::move(request)); - } - - void Bind({{mojom_type}}AssociatedRequest&& request) { - DCHECK(mojolpm::GetContext()->task_runner()->RunsTasksInCurrentSequence()); - associated_bindings_.AddBinding(this, std::move(request)); - } - {%- for method in interface.methods -%}{{"\n"}} void {{method.name}}({{ "\n" }} {%- for param in method.parameters -%} @@ -158,146 +145,6 @@ {%- endfor %} }; -bool FromProto(const {{proto_type}}::Ptr& input, - {{mojom_type}}PtrInfo& output) { - bool result = false; - std::unique_ptr<{{mojom_type}}Ptr> output_ptr = nullptr; - - if (input.id()) { - output_ptr = mojolpm::GetContext()->GetAndRemoveInstance<{{mojom_type}}Ptr>(input.id()); - } else { - output_ptr = NewInstance<{{mojom_type}}>(); - } - - if (output_ptr) { - // NB: PassInterface is allowed, since output_ptr is bound on this sequence - // (the fuzzer sequence) - output = output_ptr.release()->PassInterface(); - result = true; - } else { - // we otherwise create a local instance - ::mojo::InterfacePtr<{{mojom_type}}> ptr; - ::mojo::InterfaceRequest<{{mojom_type}}> request = ::mojo::MakeRequest(&ptr); - auto impl = std::make_unique<{{interface.name}}Impl>(); - impl->Bind(std::move(request)); - mojolpm::GetContext()->AddInstance(std::move(impl)); - output = ptr.PassInterface(); - result = true; - } - - return result; -} - -bool FromProto(const {{proto_type}}::AssociatedPtr& input, - {{mojom_type}}AssociatedPtrInfo& output) { - bool result = false; - std::unique_ptr<{{mojom_type}}AssociatedPtr> output_ptr; - - if (input.id()) { - output_ptr = mojolpm::GetContext()->GetAndRemoveInstance<{{mojom_type}}AssociatedPtr>(input.id()); - } else { - output_ptr = NewAssociatedInstance<{{mojom_type}}>(); - } - - if (output_ptr) { - // NB: PassInterface is allowed, since output_ptr is bound on this sequence - // (the fuzzer sequence) - output = output_ptr.release()->PassInterface(); - result = true; - } else { - // we otherwise create a local instance - ::mojo::AssociatedInterfacePtr<{{mojom_type}}> ptr; - ::mojo::AssociatedInterfaceRequest<{{mojom_type}}> request = ::mojo::MakeRequest(&ptr); - auto impl = std::make_unique<{{interface.name}}Impl>(); - impl->Bind(std::move(request)); - mojolpm::GetContext()->AddInstance(std::move(impl)); - output = ptr.PassInterface(); - result = true; - } - - return result; -} - -bool FromProto(const {{proto_type}}::Request& input, - {{mojom_type}}Request& output) { - {{mojom_type}}Ptr ptr; - - output = ::mojo::MakeRequest(&ptr); - mojolpm::GetContext()->AddInstance(input.id(), std::move(ptr)); - - return true; -} - -bool FromProto(const {{proto_type}}::AssociatedRequest& input, - {{mojom_type}}AssociatedRequest& output) { - {{mojom_type}}AssociatedPtr ptr; - - output = ::mojo::MakeRequest(&ptr); - mojolpm::GetContext()->AddInstance(input.id(), std::move(ptr)); - - return true; -} - -bool ToProto({{mojom_type}}PtrInfo&& input, - {{proto_type}}::Ptr& output) { - bool result = false; - - // NB: Not implementing this at present as it only has limited applicability, - // and the corresponding types are being deprecated. If your target needs this - // to fuzz effectively, consider porting to the new mojo types. - NOTREACHED(); - - return result; -} - -bool ToProto({{mojom_type}}Ptr&& input, - {{proto_type}}::Ptr& output) { - bool result = false; - - // NB: Not implementing this at present as it only has limited applicability, - // and the corresponding types are being deprecated. If your target needs this - // to fuzz effectively, consider porting to the new mojo types. - CHECK(false); - - return result; -} - -bool ToProto({{mojom_type}}AssociatedPtrInfo&& input, - {{proto_type}}::AssociatedPtr& output) { - bool result = false; - - // NB: Not implementing this at present as it only has limited applicability, - // and the corresponding types are being deprecated. If your target needs this - // to fuzz effectively, consider porting to the new mojo types. - CHECK(false); - - return result; -} - -bool ToProto({{mojom_type}}Request&& input, - {{proto_type}}::Request& output) { - bool result = false; - - // NB: Not implementing this at present as it only has limited applicability, - // and the corresponding types are being deprecated. If your target needs this - // to fuzz effectively, consider porting to the new mojo types. - CHECK(false); - - return result; -} - -bool ToProto({{mojom_type}}AssociatedRequest&& input, - {{proto_type}}::AssociatedRequest& output) { - bool result = false; - - // NB: Not implementing this at present as it only has limited applicability, - // and the corresponding types are being deprecated. If your target needs this - // to fuzz effectively, consider porting to the new mojo types. - CHECK(false); - - return result; -} - bool FromProto(const {{proto_type}}::PendingRemote& input, ::mojo::PendingRemote<{{mojom_type}}>& output) { bool result = false; @@ -477,69 +324,6 @@ {%- set mojom_type = interface|get_qualified_name_for_kind(flatten_nested_kind=True) %} {%- set proto_type = "::mojolpm" ~ (interface|get_qualified_name_for_kind(flatten_nested_kind=True)) %} {%- if interface.methods %} -bool HandleMethodCall(const {{proto_type}}::MethodCall& input) { - bool result = false; - - //mojolpmdbg("HandleMethodCall({{interface.name}})\n"); - - {{mojom_type}}Ptr* instance_ptr; - instance_ptr = mojolpm::GetContext()->GetInstance<{{mojom_type}}Ptr>(input.ptr().id()); - - if (instance_ptr && *instance_ptr) { - result = true; - } - - if (result) { - switch (input.method_case()) { -{%- for method in interface.methods %} - case {{proto_type}}::MethodCall::k{{("m_" ~ method.name)|under_to_camel(digits_split=True)}}: { - result = HandleMethodCall(*instance_ptr, input.{{("m" ~ method.name)|camel_to_under}}()); - } break; -{%- endfor %} -case {{proto_type}}::MethodCall::kReset: { - mojolpm::GetContext()->GetAndRemoveInstance<{{mojom_type}}Ptr>(input.ptr().id()); - } break; - default: { - result = false; - } - } - } - - return result; -} - -bool HandleMethodCallA(const {{proto_type}}::MethodCallA& input) { - bool result = false; - - //mojolpmdbg("HandleMethodCall({{interface.name}})\n"); - - {{mojom_type}}AssociatedPtr* instance_ptr; - instance_ptr = mojolpm::GetContext()->GetInstance<{{mojom_type}}AssociatedPtr>(input.ptr().id()); - - if (instance_ptr && instance_ptr->is_bound() && *instance_ptr) { - result = true; - } - - if (result) { - switch (input.method_case()) { -{%- for method in interface.methods %} - case {{proto_type}}::MethodCallA::k{{("m_" ~ method.name)|under_to_camel(digits_split=True)}}: { - result = HandleMethodCallA(*instance_ptr, input.{{("m" ~ method.name)|camel_to_under}}()); - } break; -{%- endfor %} - case {{proto_type}}::MethodCallA::kReset: { - mojolpm::GetContext()->GetAndRemoveInstance<{{mojom_type}}AssociatedPtr>(input.ptr().id()); - } break; - - default: { - result = false; - } - } - } - - return result; -} - bool HandleRemoteMethodCall(const {{proto_type}}::RemoteMethodCall& input) { bool result = false; @@ -639,102 +423,6 @@ mojolpm::GetContext()->NextAction(); }{{"\n"-}} {%- endif %} -bool HandleMethodCall({{mojom_type}}Ptr& instance, - const {{proto_type}}::{{interface.name}}_{{method.name}}& input) { - bool mojolpm_result = true; - mojolpmdbg("HandleMethodCall({{interface.name}}::{{method.name}})\n"); -{%- for param in method.parameters %} -{%- set name = param.name|camel_to_under %} -{%- set kind = param.kind %} -{%- set param_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set param_maybe_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=True) %} - {{param_mojom_type}} local_{{name}}; -{%- if kind|is_nullable_kind %} - {{param_maybe_mojom_type}} local_maybe_{{name}}; -{%- endif %} -{%- endfor %} - -{%- for param in method.parameters -%} -{%- set name = param.name|camel_to_under %} -{%- set kind = param.kind %} -{%- if not kind|is_nullable_kind %} - mojolpm_result &= FromProto(input.m_{{name}}(), local_{{name}}); - mojolpmdbg("{{name}} %i\n", mojolpm_result); -{%- else %} - if (FromProto(input.m_{{name}}(), local_maybe_{{name}})) { - local_{{name}} = std::move(local_maybe_{{name}}); - } -{%- endif %} -{%- endfor %} - if (mojolpm_result) { - instance->{{method.name}}( -{%- for param in method.parameters -%} -{%- set name = param.name|camel_to_under %} -{%- set kind = param.kind %} -{%- if kind|is_interface_kind or kind|is_associated_kind %} - {{kind|cpp_wrapper_param_type(add_same_module_namespaces=true)}}(std::move(local_{{name}})){{ ',' if not loop.last }} -{%- else %} - std::move(local_{{name}}){{ ',' if not loop.last }} -{%- endif %} -{%- endfor -%} -{%- if method.response_parameters != None -%} -{{ ',' if method.parameters }} - base::BindOnce(&{{interface.name}}_{{method.name}}Callback)); - } -{%- else -%} -); - } -{%- endif %} - return mojolpm_result; -} - -bool HandleMethodCallA({{mojom_type}}AssociatedPtr& instance, - const {{proto_type}}::{{interface.name}}_{{method.name}}& input) { - bool mojolpm_result = true; - mojolpmdbg("HandleMethodCallA({{interface.name}}::{{method.name}})\n"); -{%- for param in method.parameters %} -{%- set name = param.name|camel_to_under %} -{%- set kind = param.kind %} -{%- set param_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set param_maybe_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=True) %} - {{param_mojom_type}} local_{{name}}; -{%- if kind|is_nullable_kind %} - {{param_maybe_mojom_type}} local_maybe_{{name}}; -{%- endif %} -{%- endfor %} - -{%- for param in method.parameters -%} -{%- set name = param.name|camel_to_under %} -{%- set kind = param.kind %} -{%- if not kind|is_nullable_kind %} - mojolpm_result &= FromProto(input.m_{{name}}(), local_{{name}}); -{%- else %} - if (FromProto(input.m_{{name}}(), local_maybe_{{name}})) { - local_{{name}} = std::move(local_maybe_{{name}}); - } -{%- endif %} -{%- endfor %} - if (mojolpm_result) { - instance->{{method.name}}( -{%- for param in method.parameters -%} -{%- set name = param.name|camel_to_under %} -{%- set kind = param.kind %} -{%- if kind|is_interface_kind or kind|is_associated_kind %} - {{kind|cpp_wrapper_param_type(add_same_module_namespaces=true)}}(std::move(local_{{name}})){{ ',' if not loop.last }} -{%- else %} - std::move(local_{{name}}){{ ',' if not loop.last }} -{%- endif %} -{%- endfor -%} -{%- if method.response_parameters != None -%} -{{ ',' if method.parameters }} - base::BindOnce(&{{interface.name}}_{{method.name}}Callback)); - } -{%- else -%} -); - } -{%- endif %} - return mojolpm_result; -} bool HandleRemoteMethodCall(::mojo::Remote<{{mojom_type}}>& instance, const {{proto_type}}::{{interface.name}}_{{method.name}}& input) { bool mojolpm_result = true; @@ -766,11 +454,7 @@ {%- for param in method.parameters -%} {%- set name = param.name|camel_to_under %} {%- set kind = param.kind %} -{%- if kind|is_interface_kind or kind|is_associated_kind %} - {{kind|cpp_wrapper_param_type(add_same_module_namespaces=true)}}(std::move(local_{{name}})){{ ',' if not loop.last }} -{%- else %} std::move(local_{{name}}){{ ',' if not loop.last }} -{%- endif %} {%- endfor -%} {%- if method.response_parameters != None -%} {{ ',' if method.parameters }} @@ -817,11 +501,7 @@ {%- for param in method.parameters -%} {%- set name = param.name|camel_to_under %} {%- set kind = param.kind %} -{%- if kind|is_interface_kind or kind|is_associated_kind %} - {{kind|cpp_wrapper_param_type(add_same_module_namespaces=true)}}(std::move(local_{{name}})){{ ',' if not loop.last }} -{%- else %} std::move(local_{{name}}){{ ',' if not loop.last }} -{%- endif %} {%- endfor -%} {%- if method.response_parameters != None -%} {{ ',' if method.parameters }}
diff --git a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.h.tmpl b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.h.tmpl index 16af070..20ebd05 100644 --- a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.h.tmpl +++ b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.h.tmpl
@@ -117,42 +117,6 @@ {%- set proto_type = "::mojolpm" ~ (interface|get_qualified_name_for_kind(flatten_nested_kind=True)) %} // interface {{interface.name}} bool FromProto( - const {{proto_type}}::Ptr& input, - {{mojom_type}}PtrInfo& output); - -bool ToProto( - {{mojom_type}}Ptr&& input, - {{proto_type}}::Ptr& output); - -bool ToProto( - {{mojom_type}}PtrInfo&& input, - {{proto_type}}::Ptr& output); - -bool FromProto( - const {{proto_type}}::AssociatedPtr& input, - {{mojom_type}}AssociatedPtrInfo& output); - -bool ToProto( - {{mojom_type}}AssociatedPtrInfo&& input, - {{proto_type}}::AssociatedPtr& output); - -bool FromProto( - const {{proto_type}}::Request& input, - {{mojom_type}}Request& output); - -bool ToProto( - {{mojom_type}}Request&& input, - {{proto_type}}::Request& output); - -bool FromProto( - const {{proto_type}}::AssociatedRequest& input, - {{mojom_type}}AssociatedRequest& output); - -bool ToProto( - {{mojom_type}}AssociatedRequest&& input, - {{proto_type}}::AssociatedRequest& output); - -bool FromProto( const {{proto_type}}::PendingRemote& input, ::mojo::PendingRemote<{{mojom_type}}>& output); @@ -213,12 +177,6 @@ {%- set mojom_type = interface|get_qualified_name_for_kind(flatten_nested_kind=True) %} {%- set proto_type = "::mojolpm" ~ (interface|get_qualified_name_for_kind(flatten_nested_kind=True)) %} {%- if interface.methods %} -bool HandleMethodCall( - const {{proto_type}}::MethodCall& input); - -bool HandleMethodCallA( - const {{proto_type}}::MethodCallA& input); - bool HandleRemoteMethodCall( const {{proto_type}}::RemoteMethodCall& input); @@ -228,14 +186,6 @@ bool AddResponse( const {{proto_type}}::ReceiverResponse& response);{{"\n"-}} {%- for method in interface.methods %} -bool HandleMethodCall( - {{mojom_type}}Ptr& instance, - const {{proto_type}}::{{interface.name}}_{{method.name}}& input); - -bool HandleMethodCallA( - {{mojom_type}}AssociatedPtr& instance, - const {{proto_type}}::{{interface.name}}_{{method.name}}& input); - bool HandleRemoteMethodCall( ::mojo::Remote<{{mojom_type}}>& instance, const {{proto_type}}::{{interface.name}}_{{method.name}}& input);
diff --git a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.proto.tmpl b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.proto.tmpl index 521cdf4..0bd0c05 100644 --- a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.proto.tmpl +++ b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.proto.tmpl
@@ -229,23 +229,6 @@ {%- for interface in interfaces %} message {{interface.name}} { - // TODO(markbrand): remove the old types once crbug/955171 is landed. - message Ptr { - required uint32 id = 1; - } - - message AssociatedPtr { - required uint32 id = 1; - } - - message Request { - required uint32 id = 1; - } - - message AssociatedRequest { - required uint32 id = 1; - } - message PendingRemote { required uint32 id = 1; } @@ -349,28 +332,6 @@ {%- endfor%} {%- if interface.methods|length %} - message MethodCall { - required {{interface.name}}.Ptr ptr = 1; - - oneof method { - Reset reset = 2; -{%- for method in interface.methods %} - {{interface.name}}_{{method.name}} m_{{method.name|camel_to_under}} = {{loop.index + 2}}; -{%- endfor %} - } - } - - message MethodCallA { - required {{interface.name}}.AssociatedPtr ptr = 1; - - oneof method { - Reset reset = 2; -{%- for method in interface.methods %} - {{interface.name}}_{{method.name}} m_{{method.name|camel_to_under}} = {{loop.index + 2}}; -{%- endfor %} - } - } - message RemoteMethodCall { required {{interface.name}}.PendingRemote remote = 1;
diff --git a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_macros.tmpl b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_macros.tmpl index c34ddb3..82d677e 100644 --- a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_macros.tmpl +++ b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_macros.tmpl
@@ -30,18 +30,6 @@ {{ add_instance(kind.key_kind, name ~ "_key", True)|indent(2, True) }} {{ add_instance(kind.value_kind, name ~ "_value", True)|indent(2, True) }} } -{%- elif kind|is_interface_kind %} -{%- set mojom_type = kind|get_qualified_name_for_kind(flatten_nested_kind=True) %} - if ({{name}}) { - {{mojom_type}}Ptr tmp_{{name}}(std::move({{name}})); - mojolpm::GetContext()->AddInstance(std::move(tmp_{{name}})); - } -{%- elif kind|is_associated_interface_kind %} -{%- set mojom_type = kind.kind|get_qualified_name_for_kind(flatten_nested_kind=True) %} - if ({{name}}) { - {{mojom_type}}AssociatedPtr tmp_{{name}}(std::move({{name}})); - mojolpm::GetContext()->AddInstance(std::move(tmp_{{name}})); - } {%- elif kind|is_pending_remote_kind %} {%- set mojom_type = kind.kind|get_qualified_name_for_kind(flatten_nested_kind=True) %} if ({{name}}) {
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py index 5ec78a7..a756278 100644 --- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -670,22 +670,21 @@ GetCppPodType(constant.kind), constant.name, self._ConstantValue(constant)) - def _WriteInputParamForTracing(self, kind, mojo_prefix, parameter_name, + def _WriteInputParamForTracing(self, kind, parameter_name, cpp_parameter_name, value): """Generates lines of C++ to log parameter |parameter_name| into TracedValue |value|. Args: kind: {Kind} The kind of the parameter (corresponds to its C++ type). - mojo_prefix: {string} The prefix of the auto-generated parameter. - parameter_name: {string} The mojom parameter name to be logged - (auto-generated C++ parameter name is |mojo_prefix+parameter_name|). + parameter_name: {string} The name of the mojom parameter to be logged. + cpp_parameter_name: {string} The actual C++ variable name corresponding to + the mojom parameter |parameter_name|. value: {string} The C++ TracedValue* variable name to be logged into. Yields: {string} C++ lines of code that trace |parameter_name| into |value|. """ - cpp_parameter_name = mojo_prefix + parameter_name value_name_cppname = (value, parameter_name, cpp_parameter_name) # TODO(crbug.com/1103623): Support more involved types. if mojom.IsEnumKind(kind): @@ -729,6 +728,15 @@ if mojom.IsFloatKind(kind) or mojom.IsDoubleKind(kind): yield '%s->SetDouble("%s", %s);' % value_name_cppname return + if (mojom.IsStructKind(kind) and not self._IsTypemappedKind(kind) + and not IsNativeOnlyKind(kind)): + yield 'if (%s.is_null()) {' % cpp_parameter_name + yield ' %s->SetString("%s", "nullptr");' % (value, parameter_name) + yield '} else {' + yield ' %s->ToTracedValue(%s, "%s");' % (cpp_parameter_name, value, + parameter_name) + yield '}' + return yield '%s->SetString("%s", "<value of type %s>");' % ( value, parameter_name, self._GetCppWrapperParamType(kind))
diff --git a/mojo/public/tools/bindings/generators/mojom_mojolpm_generator.py b/mojo/public/tools/bindings/generators/mojom_mojolpm_generator.py index 557488fe..af2e1d02 100644 --- a/mojo/public/tools/bindings/generators/mojom_mojolpm_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_mojolpm_generator.py
@@ -346,18 +346,6 @@ or mojom.IsUnionKind(kind)): return self._GetCppProtoNameForKind( kind, add_same_module_namespaces=add_same_module_namespaces) - elif mojom.IsInterfaceKind(kind): - return '%s::Ptr' % self._GetCppProtoNameForKind( - kind, add_same_module_namespaces=add_same_module_namespaces) - elif mojom.IsInterfaceRequestKind(kind): - return '%s::Request' % self._GetCppProtoNameForKind( - kind.kind, add_same_module_namespaces=add_same_module_namespaces) - elif mojom.IsAssociatedInterfaceKind(kind): - return '%s::AssociatedPtr' % self._GetCppProtoNameForKind( - kind.kind, add_same_module_namespaces=add_same_module_namespaces) - elif mojom.IsAssociatedInterfaceRequestKind(kind): - return '%s::AssociatedRequest' % self._GetCppProtoNameForKind( - kind.kind, add_same_module_namespaces=add_same_module_namespaces) elif mojom.IsPendingRemoteKind(kind): return "%s::PendingRemote" % self._GetCppProtoNameForKind( kind.kind, add_same_module_namespaces=add_same_module_namespaces) @@ -403,15 +391,6 @@ return ("map<%sKey, %sValue>" % (self._GetProtoFieldType(kind.key_kind, quantified=False), self._GetProtoFieldType(kind.value_kind, quantified=False))) - elif mojom.IsInterfaceKind(kind): - unquantified = "%s.Ptr" % self._GetProtoNameForKind(kind) - elif mojom.IsInterfaceRequestKind(kind): - unquantified = "%s.Request" % self._GetProtoNameForKind(kind.kind) - elif mojom.IsAssociatedInterfaceKind(kind): - unquantified = "%s.AssociatedPtr" % self._GetProtoNameForKind(kind.kind) - elif mojom.IsAssociatedInterfaceRequestKind(kind): - unquantified = ("%s.AssociatedRequest" % - self._GetProtoNameForKind(kind.kind)) elif mojom.IsPendingRemoteKind(kind): unquantified = "%s.PendingRemote" % self._GetProtoNameForKind(kind.kind) elif mojom.IsPendingReceiverKind(kind):
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 7f03585..21f7e12 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -5,6 +5,7 @@ #include "services/network/network_context.h" #include <memory> +#include <string> #include <utility> #include "base/barrier_closure.h" @@ -1723,6 +1724,41 @@ std::move(callback).Run(base::nullopt); } +#if defined(OS_CHROMEOS) +void NetworkContext::LookupProxyAuthCredentials( + const net::ProxyServer& proxy_server, + const std::string& auth_scheme, + const std::string& realm, + LookupProxyAuthCredentialsCallback callback) { + net::HttpAuth::Scheme net_scheme = + net::HttpAuth::StringToScheme(base::ToLowerASCII(auth_scheme)); + if (net_scheme == net::HttpAuth::Scheme::AUTH_SCHEME_MAX) { + std::move(callback).Run(base::nullopt); + return; + } + net::HttpAuthCache* http_auth_cache = + url_request_context_->http_transaction_factory() + ->GetSession() + ->http_auth_cache(); + const char* scheme = proxy_server.is_https() ? "https://" : "http://"; + GURL proxy_url(scheme + proxy_server.host_port_pair().ToString()); + if (!proxy_url.is_valid()) { + std::move(callback).Run(base::nullopt); + return; + } + + // Unlike server credentials, proxy credentials are not keyed on + // NetworkIsolationKey. + net::HttpAuthCache::Entry* entry = + http_auth_cache->Lookup(proxy_url, net::HttpAuth::AUTH_PROXY, realm, + net_scheme, net::NetworkIsolationKey()); + if (entry) + std::move(callback).Run(entry->credentials()); + else + std::move(callback).Run(base::nullopt); +} +#endif + const net::HttpAuthPreferences* NetworkContext::GetHttpAuthPreferences() const { return &http_auth_merged_preferences_; }
diff --git a/services/network/network_context.h b/services/network/network_context.h index 325f447..411d99ea 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -407,6 +407,13 @@ const GURL& url, const net::NetworkIsolationKey& network_isolation_key, LookupServerBasicAuthCredentialsCallback callback) override; +#if defined(OS_CHROMEOS) + void LookupProxyAuthCredentials( + const net::ProxyServer& proxy_server, + const std::string& auth_scheme, + const std::string& realm, + LookupProxyAuthCredentialsCallback callback) override; +#endif void GetOriginPolicyManager( mojo::PendingReceiver<mojom::OriginPolicyManager> receiver) override;
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index ca1f1bd..782b059 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -1905,6 +1905,116 @@ EXPECT_FALSE(result.has_value()); } +#if defined(OS_CHROMEOS) +base::Optional<net::AuthCredentials> GetProxyAuthCredentials( + NetworkContext* network_context, + const net::ProxyServer& proxy_server, + const std::string& scheme, + const std::string& realm) { + base::RunLoop run_loop; + base::Optional<net::AuthCredentials> result; + network_context->LookupProxyAuthCredentials( + proxy_server, scheme, realm, + base::BindLambdaForTesting( + [&](const base::Optional<net::AuthCredentials>& credentials) { + result = credentials; + run_loop.Quit(); + })); + run_loop.Run(); + return result; +} + +TEST_F(NetworkContextTest, LookupProxyAuthCredentials) { + GURL http_proxy("http://bar.test:1080"); + GURL https_proxy("https://bar.test:443"); + GURL http_proxy2("http://bar.test:443"); + GURL foo_proxy("foo://bar.test:1080"); + GURL server_origin("http://foo.test:3128"); + + std::unique_ptr<NetworkContext> network_context = + CreateContextWithParams(CreateContextParams()); + network_context->SetSplitAuthCacheByNetworkIsolationKey(true); + net::HttpAuthCache* cache = network_context->url_request_context() + ->http_transaction_factory() + ->GetSession() + ->http_auth_cache(); + + base::string16 user = base::ASCIIToUTF16("user"); + base::string16 password = base::ASCIIToUTF16("pass"); + cache->Add(http_proxy, net::HttpAuth::AUTH_PROXY, "Realm", + net::HttpAuth::AUTH_SCHEME_BASIC, net::NetworkIsolationKey(), + "basic realm=Realm", net::AuthCredentials(user, password), + /* path = */ ""); + cache->Add(https_proxy, net::HttpAuth::AUTH_PROXY, "Realm", + net::HttpAuth::AUTH_SCHEME_BASIC, net::NetworkIsolationKey(), + "basic realm=Realm", net::AuthCredentials(user, password), + /* path = */ ""); + cache->Add(server_origin, net::HttpAuth::AUTH_SERVER, "Realm", + net::HttpAuth::AUTH_SCHEME_BASIC, net::NetworkIsolationKey(), + "basic realm=Realm", net::AuthCredentials(user, password), + /* path = */ "/"); + base::Optional<net::AuthCredentials> result = GetProxyAuthCredentials( + network_context.get(), + net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP, + net::HostPortPair::FromURL(http_proxy)), + "bAsIc", "Realm"); + ASSERT_TRUE(result.has_value()); + EXPECT_EQ(user, result->username()); + EXPECT_EQ(password, result->password()); + + result = GetProxyAuthCredentials( + network_context.get(), + net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTPS, + net::HostPortPair::FromURL(https_proxy)), + "bAsIc", "Realm"); + ASSERT_TRUE(result.has_value()); + EXPECT_EQ(user, result->username()); + EXPECT_EQ(password, result->password()); + + // Check that the proxy scheme is taken into account when looking for + // credentials + result = GetProxyAuthCredentials( + network_context.get(), + net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP, + net::HostPortPair::FromURL(http_proxy2)), + "basic", "Realm"); + EXPECT_FALSE(result.has_value()); + + // Check that the proxy authentication method is taken into account when + // looking for credentials + result = GetProxyAuthCredentials( + network_context.get(), + net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP, + net::HostPortPair::FromURL(http_proxy)), + "digest", "Realm"); + EXPECT_FALSE(result.has_value()); + + // Check that the realm is taken into account when looking for credentials + result = GetProxyAuthCredentials( + network_context.get(), + net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP, + net::HostPortPair::FromURL(http_proxy)), + "basic", "Realm 2"); + EXPECT_FALSE(result.has_value()); + + // All non-https proxies are cached as "http://" proxies + result = GetProxyAuthCredentials( + network_context.get(), + net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP, + net::HostPortPair::FromURL(foo_proxy)), + "basic", "Realm"); + EXPECT_FALSE(result.has_value()); + + // Server credentials should not be returned + result = GetProxyAuthCredentials( + network_context.get(), + net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP, + net::HostPortPair::FromURL(server_origin)), + "basic", "Realm"); + EXPECT_FALSE(result.has_value()); +} +#endif + #if BUILDFLAG(ENABLE_REPORTING) TEST_F(NetworkContextTest, ClearReportingCacheReports) { auto reporting_context = std::make_unique<net::TestReportingContext>(
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 2c696bb..e0aab3e 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -1376,6 +1376,16 @@ NetworkIsolationKey network_isolation_key) => (AuthCredentials? credentials); + // Looks up the proxy authentication credentials associated with + // |proxy_server|, |auth_scheme| and |realm| in the HttpAuthCache. + // |auth_scheme| is the authentication scheme of the challenge and it's + // specified as a case-insensitive string. Unlike server credentials, proxy + // credentials are not keyed on NetworkIsolationKey. + [EnableIf=is_chromeos] + LookupProxyAuthCredentials(proxy_resolver.mojom.ProxyServer proxy_server, + string auth_scheme, string realm) + => (AuthCredentials? credentials); + [Sync] // Enables the checking of static PKP records. EnableStaticKeyPinningForTesting() => ();
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h index ef97b4c..0dfed1a7 100644 --- a/services/network/test/test_network_context.h +++ b/services/network/test/test_network_context.h
@@ -264,6 +264,13 @@ const GURL& url, const net::NetworkIsolationKey& network_isolation_key, LookupServerBasicAuthCredentialsCallback callback) override {} +#if defined(OS_CHROMEOS) + void LookupProxyAuthCredentials( + const net::ProxyServer& proxy_server, + const std::string& auth_scheme, + const std::string& realm, + LookupProxyAuthCredentialsCallback callback) override {} +#endif void GetOriginPolicyManager( mojo::PendingReceiver<mojom::OriginPolicyManager> receiver) override {} };
diff --git a/storage/browser/quota/padding_key.cc b/storage/browser/quota/padding_key.cc index 60c3b60..788f6f4 100644 --- a/storage/browser/quota/padding_key.cc +++ b/storage/browser/quota/padding_key.cc
@@ -9,6 +9,7 @@ #include "base/no_destructor.h" #include "crypto/hmac.h" +#include "net/http/http_request_headers.h" using crypto::SymmetricKey; @@ -57,7 +58,8 @@ int64_t ComputeResponsePadding(const std::string& response_url, const crypto::SymmetricKey* padding_key, bool has_metadata, - bool loaded_with_credentials) { + bool loaded_with_credentials, + const std::string& request_method) { DCHECK(!response_url.empty()); crypto::HMAC hmac(crypto::HMAC::SHA256); @@ -68,6 +70,14 @@ key += "METADATA"; if (loaded_with_credentials) key += "CREDENTIALED"; + + // It should only be possible to have a CORS safelisted method here since + // the spec does not permit other methods for no-cors requests. + DCHECK(request_method == net::HttpRequestHeaders::kGetMethod || + request_method == net::HttpRequestHeaders::kHeadMethod || + request_method == net::HttpRequestHeaders::kPostMethod); + key += request_method; + uint64_t digest_start; CHECK(hmac.Sign(key, reinterpret_cast<uint8_t*>(&digest_start), sizeof(digest_start)));
diff --git a/storage/browser/quota/padding_key.h b/storage/browser/quota/padding_key.h index e582b4c9..4b5978a 100644 --- a/storage/browser/quota/padding_key.h +++ b/storage/browser/quota/padding_key.h
@@ -62,7 +62,8 @@ int64_t ComputeResponsePadding(const std::string& response_url, const crypto::SymmetricKey* padding_key, bool has_metadata, - bool loaded_with_credentials); + bool loaded_with_credentials, + const std::string& request_method); } // namespace storage
diff --git a/testing/buildbot/filters/bfcache.content_browsertests.filter b/testing/buildbot/filters/bfcache.content_browsertests.filter index 25c0268..74c7098 100644 --- a/testing/buildbot/filters/bfcache.content_browsertests.filter +++ b/testing/buildbot/filters/bfcache.content_browsertests.filter
@@ -53,3 +53,4 @@ -RenderFrameHostImplBeforeUnloadBrowserTest.SubframeShowsDialogWhenMainFrameNavigates -RenderFrameHostImplBrowserTest.CheckIsCurrentBeforeAndAfterUnload -RenderFrameHostImplBrowserTest.CheckLifecycleStateTransitionOnMainFrame +-SecurityExploitBrowserTest.DidCommitInvalidURL
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 1960b2e..18c6e2f 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -85,12 +85,15 @@ "loader/request_context_frame_type.mojom", "loader/resource_load_info.mojom", "loader/resource_load_info_notifier.mojom", + "loader/transferrable_url_loader.mojom", "loader/url_loader_factory_bundle.mojom", "locks/lock_manager.mojom", "manifest/display_mode.mojom", "manifest/manifest.mojom", "manifest/manifest_manager.mojom", "manifest/manifest_observer.mojom", + "media/renderer_audio_input_stream_factory.mojom", + "media/renderer_audio_output_stream_factory.mojom", "mediastream/aec_dump.mojom", "mediastream/media_devices.mojom", "mediastream/media_stream.mojom",
diff --git a/third_party/blink/public/mojom/fetch/fetch_api_response.mojom b/third_party/blink/public/mojom/fetch/fetch_api_response.mojom index ec7f275..b4e4b9a 100644 --- a/third_party/blink/public/mojom/fetch/fetch_api_response.mojom +++ b/third_party/blink/public/mojom/fetch/fetch_api_response.mojom
@@ -46,6 +46,10 @@ // The mime type of the response, if one has been set. string? mime_type; + // The http request method used to load the response. May be unset for + // synthetic Response objects created via the constructor. + string? request_method; + // Mojo interface to read the response payload. SerializedBlob? blob;
diff --git a/third_party/blink/public/mojom/hid/hid.mojom b/third_party/blink/public/mojom/hid/hid.mojom index 75272a0..bb68311d 100644 --- a/third_party/blink/public/mojom/hid/hid.mojom +++ b/third_party/blink/public/mojom/hid/hid.mojom
@@ -73,7 +73,7 @@ interface HidService { // Registers a HidManagerClient to be notified when HID devices are added or // removed. - RegisterClient(associated device.mojom.HidManagerClient client); + RegisterClient(pending_associated_remote<device.mojom.HidManagerClient> client); // Retrieves information about all devices that this client has permission to // access.
diff --git a/content/public/common/transferrable_url_loader.mojom b/third_party/blink/public/mojom/loader/transferrable_url_loader.mojom similarity index 96% rename from content/public/common/transferrable_url_loader.mojom rename to third_party/blink/public/mojom/loader/transferrable_url_loader.mojom index af3adc71..4c5c4d95 100644 --- a/content/public/common/transferrable_url_loader.mojom +++ b/third_party/blink/public/mojom/loader/transferrable_url_loader.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -module content.mojom; +module blink.mojom; import "services/network/public/mojom/url_response_head.mojom"; import "services/network/public/mojom/url_loader.mojom";
diff --git a/third_party/blink/public/mojom/media/OWNERS b/third_party/blink/public/mojom/media/OWNERS new file mode 100644 index 0000000..94ab98ba --- /dev/null +++ b/third_party/blink/public/mojom/media/OWNERS
@@ -0,0 +1,4 @@ +file://content/common/media/OWNERS + +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/content/common/media/renderer_audio_input_stream_factory.mojom b/third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom similarity index 98% rename from content/common/media/renderer_audio_input_stream_factory.mojom rename to third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom index 361de5d0..9713cd2f 100644 --- a/content/common/media/renderer_audio_input_stream_factory.mojom +++ b/third_party/blink/public/mojom/media/renderer_audio_input_stream_factory.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -module content.mojom; +module blink.mojom; import "media/mojo/mojom/audio_data_pipe.mojom"; import "media/mojo/mojom/audio_input_stream.mojom";
diff --git a/content/common/media/renderer_audio_output_stream_factory.mojom b/third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom similarity index 98% rename from content/common/media/renderer_audio_output_stream_factory.mojom rename to third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom index c151fec4..92cb788 100644 --- a/content/common/media/renderer_audio_output_stream_factory.mojom +++ b/third_party/blink/public/mojom/media/renderer_audio_output_stream_factory.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -module content.mojom; +module blink.mojom; import "media/mojo/mojom/audio_output_stream.mojom"; import "media/mojo/mojom/audio_parameters.mojom";
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 576af16c..f6fb128 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2546,7 +2546,6 @@ kLegacyLayoutByFlexBox = 3210, kLegacyLayoutByFrameSet = 3211, kLegacyLayoutByGrid = 3212, - kLegacyLayoutByMenuList = 3213, kLegacyLayoutByMultiCol = 3214, kLegacyLayoutByPrinting = 3215, kLegacyLayoutByRuby = 3216,
diff --git a/third_party/blink/public/web/web_ax_object.h b/third_party/blink/public/web/web_ax_object.h index b9bf20f29..72e328c1 100644 --- a/third_party/blink/public/web/web_ax_object.h +++ b/third_party/blink/public/web/web_ax_object.h
@@ -191,7 +191,7 @@ BLINK_EXPORT ax::mojom::Role Role() const; BLINK_EXPORT WebString StringValue() const; BLINK_EXPORT ax::mojom::ListStyle GetListStyle() const; - BLINK_EXPORT ax::mojom::TextDirection GetTextDirection() const; + BLINK_EXPORT ax::mojom::WritingDirection GetTextDirection() const; BLINK_EXPORT ax::mojom::TextPosition GetTextPosition() const; BLINK_EXPORT void GetTextStyleAndTextDecorationStyle( int32_t* text_style,
diff --git a/third_party/blink/renderer/core/css/css_variable_data.cc b/third_party/blink/renderer/core/css/css_variable_data.cc index 303a387c..03e2a89 100644 --- a/third_party/blink/renderer/core/css/css_variable_data.cc +++ b/third_party/blink/renderer/core/css/css_variable_data.cc
@@ -83,7 +83,6 @@ needs_variable_resolution_(needs_variable_resolution), has_font_units_(false), has_root_font_units_(false), - absolutized_(false), base_url_(base_url.IsValid() ? base_url.GetString() : String()), charset_(charset) { DCHECK(!range.AtEnd());
diff --git a/third_party/blink/renderer/core/css/css_variable_data.h b/third_party/blink/renderer/core/css/css_variable_data.h index 70df8fc..d225dff 100644 --- a/third_party/blink/renderer/core/css/css_variable_data.h +++ b/third_party/blink/renderer/core/css/css_variable_data.h
@@ -38,17 +38,17 @@ } static scoped_refptr<CSSVariableData> CreateResolved( - const Vector<CSSParserToken>& resolved_tokens, + Vector<CSSParserToken> resolved_tokens, Vector<String> backing_strings, bool is_animation_tainted, bool has_font_units, bool has_root_font_units, - bool absolutized, const String& base_url, const WTF::TextEncoding& charset) { return base::AdoptRef(new CSSVariableData( - resolved_tokens, std::move(backing_strings), is_animation_tainted, - has_font_units, has_root_font_units, absolutized, base_url, charset)); + std::move(resolved_tokens), std::move(backing_strings), + is_animation_tainted, has_font_units, has_root_font_units, base_url, + charset)); } CSSParserTokenRange TokenRange() const { return tokens_; } @@ -70,10 +70,6 @@ // font-size of the root element, e.g. 'rem'. bool HasRootFontUnits() const { return has_root_font_units_; } - // True if this CSSVariableData has undergone absolutization. Absolutization - // is required for e.g. registered properties with 'em' units. - bool IsAbsolutized() const { return absolutized_; } - const String& BaseURL() const { return base_url_; } const WTF::TextEncoding& Charset() const { return charset_; } @@ -86,8 +82,7 @@ : is_animation_tainted_(false), needs_variable_resolution_(false), has_font_units_(false), - has_root_font_units_(false), - absolutized_(false) {} + has_root_font_units_(false) {} CSSVariableData(const CSSParserTokenRange&, bool is_animation_tainted, @@ -95,21 +90,19 @@ const KURL& base_url, const WTF::TextEncoding& charset); - CSSVariableData(const Vector<CSSParserToken>& resolved_tokens, + CSSVariableData(Vector<CSSParserToken> resolved_tokens, Vector<String> backing_strings, bool is_animation_tainted, bool has_font_units, bool has_root_font_units, - bool absolutized, const String& base_url, const WTF::TextEncoding& charset) : backing_strings_(std::move(backing_strings)), - tokens_(resolved_tokens), + tokens_(std::move(resolved_tokens)), is_animation_tainted_(is_animation_tainted), needs_variable_resolution_(false), has_font_units_(has_font_units), has_root_font_units_(has_root_font_units), - absolutized_(absolutized), base_url_(base_url), charset_(charset) {} @@ -124,7 +117,6 @@ const bool needs_variable_resolution_; bool has_font_units_; bool has_root_font_units_; - bool absolutized_; String base_url_; WTF::TextEncoding charset_; DISALLOW_COPY_AND_ASSIGN(CSSVariableData);
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc index ca33486..82de618 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -1974,11 +1974,10 @@ const bool has_font_units = false; const bool has_root_font_units = false; - const bool absolutized = true; return CSSVariableData::CreateResolved( - tokens, std::move(backing_strings), is_animation_tainted, has_font_units, - has_root_font_units, absolutized, g_null_atom, WTF::TextEncoding()); + std::move(tokens), std::move(backing_strings), is_animation_tainted, + has_font_units, has_root_font_units, g_null_atom, WTF::TextEncoding()); } LengthSize StyleBuilderConverter::ConvertIntrinsicSize(
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.cc b/third_party/blink/renderer/core/css/resolver/style_cascade.cc index a17473e..fca76ca 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade.cc +++ b/third_party/blink/renderer/core/css/resolver/style_cascade.cc
@@ -32,6 +32,7 @@ #include "third_party/blink/renderer/core/css/style_engine.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/frame/web_feature.h" +#include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style_property_shorthand.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" @@ -227,6 +228,8 @@ map_.Add(property.GetCSSPropertyName(), e.Priority()); } } + + MaybeUseCountSummaryDisplayBlock(); } void StyleCascade::AnalyzeInterpolations() { @@ -530,11 +533,9 @@ scoped_refptr<CSSVariableData> StyleCascade::TokenSequence::BuildVariableData() { - // TODO(andruud): Why not also std::move tokens? - const bool absolutized = true; return CSSVariableData::CreateResolved( - tokens_, std::move(backing_strings_), is_animation_tainted_, - has_font_units_, has_root_font_units_, absolutized, base_url_, charset_); + std::move(tokens_), std::move(backing_strings_), is_animation_tainted_, + has_font_units_, has_root_font_units_, base_url_, charset_); } bool StyleCascade::ShouldRevert(const CSSProperty& property, @@ -700,11 +701,7 @@ const CSSValue& value, CascadeOrigin origin, CascadeResolver& resolver) { - // In forced colors mode, we can behave like 'revert' any value [1], but we - // should only use-count the true uses of 'revert'. - // [1] https://drafts.csswg.org/css-color-adjust-1/#forced-colors-properties - if (IsRevert(value)) - GetDocument().CountUse(WebFeature::kCSSKeywordRevert); + MaybeUseCountRevert(value); CascadeOrigin target_origin = TargetOriginForRevert(origin); @@ -931,4 +928,30 @@ return *original; } +void StyleCascade::CountUse(WebFeature feature) { + GetDocument().CountUse(feature); +} + +void StyleCascade::MaybeUseCountRevert(const CSSValue& value) { + // In forced colors mode, any value can behave like 'revert' [1], but we + // should only use-count the true uses of 'revert'. + // [1] https://drafts.csswg.org/css-color-adjust-1/#forced-colors-properties + if (IsRevert(value)) + CountUse(WebFeature::kCSSKeywordRevert); +} + +// TODO(crbug.com/590014): Remove this when display type of <summary> is fixed +void StyleCascade::MaybeUseCountSummaryDisplayBlock() { + if (!state_.GetElement().HasTagName(html_names::kSummaryTag)) + return; + CascadePriority priority = map_.At(CSSPropertyName(CSSPropertyID::kDisplay)); + if (priority.GetOrigin() == CascadeOrigin::kUserAgent) + return; + const CSSValue* value = ValueAt(match_result_, priority.GetPosition()); + if (auto* identifier = DynamicTo<CSSIdentifierValue>(value)) { + if (identifier->GetValueID() == CSSValueID::kBlock) + CountUse(WebFeature::kSummaryElementWithDisplayBlockAuthorRule); + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.h b/third_party/blink/renderer/core/css/resolver/style_cascade.h index e9be592..a8e6d7b 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade.h +++ b/third_party/blink/renderer/core/css/resolver/style_cascade.h
@@ -19,6 +19,7 @@ #include "third_party/blink/renderer/core/css/resolver/cascade_origin.h" #include "third_party/blink/renderer/core/css/resolver/cascade_priority.h" #include "third_party/blink/renderer/core/css/resolver/match_result.h" +#include "third_party/blink/renderer/core/frame/web_feature_forward.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/text/text_encoding.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -324,6 +325,10 @@ bool ShouldRevert(const CSSProperty&, const CSSValue&, CascadeOrigin); + void CountUse(WebFeature); + void MaybeUseCountRevert(const CSSValue&); + void MaybeUseCountSummaryDisplayBlock(); + StyleResolverState& state_; MatchResult match_result_; CascadeInterpolations interpolations_;
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index 6f7c1f3..11c32674 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -948,22 +948,6 @@ MatchAllRules(state, collector, matching_behavior != kMatchAllRulesExcludingSMIL); - // TODO(dominicc): Remove this counter when Issue 590014 is fixed. - if (element->HasTagName(html_names::kSummaryTag)) { - MatchedPropertiesRange matched_range = match_result.AuthorRules(); - for (const auto& matched : matched_range) { - const CSSValue* value = - matched.properties->GetPropertyCSSValue(CSSPropertyID::kDisplay); - auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); - if (identifier_value && - identifier_value->GetValueID() == CSSValueID::kBlock) { - UseCounter::Count( - element->GetDocument(), - WebFeature::kSummaryElementWithDisplayBlockAuthorRule); - } - } - } - if (tracker_) AddMatchedRulesToTracker(collector);
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index 1b13af30..f39b209 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -2698,6 +2698,29 @@ GetCSSPropertyColor())); } +TEST_F(StyleEngineTest, SummaryDisplayUseCount) { + // Should not be use-counted: wrong element type. + GetDocument().body()->setInnerHTML( + "<style>div { display: block; }</style><div></div>"); + UpdateAllLifecyclePhases(); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kSummaryElementWithDisplayBlockAuthorRule)); + + // Should not be use-counted: wrong display type: + GetDocument().body()->setInnerHTML( + "<style>summary { display: inline; }</style><summary></summary>"); + UpdateAllLifecyclePhases(); + EXPECT_FALSE(GetDocument().IsUseCounted( + WebFeature::kSummaryElementWithDisplayBlockAuthorRule)); + + // Should be use-counted: + GetDocument().body()->setInnerHTML( + "<style>summary { display: block; }</style><summary></summary>"); + UpdateAllLifecyclePhases(); + EXPECT_TRUE(GetDocument().IsUseCounted( + WebFeature::kSummaryElementWithDisplayBlockAuthorRule)); +} + TEST_F(StyleEngineTest, RevertUseCount) { ScopedCSSRevertForTest scoped_feature(true);
diff --git a/third_party/blink/renderer/core/css/style_environment_variables.cc b/third_party/blink/renderer/core/css/style_environment_variables.cc index d1e3e8e..1a7404f 100644 --- a/third_party/blink/renderer/core/css/style_environment_variables.cc +++ b/third_party/blink/renderer/core/css/style_environment_variables.cc
@@ -149,11 +149,12 @@ Vector<String> backing_strings; backing_strings.push_back(value); - SetVariable(name, - CSSVariableData::CreateResolved( - tokens, backing_strings, false /* is_animation_tainted */, - false /* has_font_units */, false /* has_root_font_units*/, - true /* absolutized */, g_null_atom, WTF::TextEncoding())); + SetVariable( + name, + CSSVariableData::CreateResolved( + std::move(tokens), std::move(backing_strings), + false /* is_animation_tainted */, false /* has_font_units */, + false /* has_root_font_units*/, g_null_atom, WTF::TextEncoding())); } void StyleEnvironmentVariables::SetVariable(const UADefinedVariable name,
diff --git a/third_party/blink/renderer/core/editing/BUILD.gn b/third_party/blink/renderer/core/editing/BUILD.gn index 829afcf..31fbacd 100644 --- a/third_party/blink/renderer/core/editing/BUILD.gn +++ b/third_party/blink/renderer/core/editing/BUILD.gn
@@ -336,7 +336,6 @@ "visible_units_paragraph.cc", "visible_units_sentence.cc", "visible_units_word.cc", - "writing_direction.h", ] if (is_mac) {
diff --git a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc index 151283c..f41b19e5 100644 --- a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc +++ b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
@@ -48,7 +48,6 @@ #include "third_party/blink/renderer/core/editing/visible_position.h" #include "third_party/blink/renderer/core/editing/visible_selection.h" #include "third_party/blink/renderer/core/editing/visible_units.h" -#include "third_party/blink/renderer/core/editing/writing_direction.h" #include "third_party/blink/renderer/core/html/html_font_element.h" #include "third_party/blink/renderer/core/html/html_span_element.h" #include "third_party/blink/renderer/core/html_names.h" @@ -566,7 +565,7 @@ HTMLElement* ApplyStyleCommand::SplitAncestorsWithUnicodeBidi( Node* node, bool before, - WritingDirection allowed_direction) { + mojo_base::mojom::blink::TextDirection allowed_direction) { // We are allowed to leave the highest ancestor with unicode-bidi unsplit if // it is unicode-bidi: embed and direction: allowedDirection. In that case, we // return the unsplit ancestor. Otherwise, we return 0. @@ -597,10 +596,11 @@ HTMLElement* unsplit_ancestor = nullptr; - WritingDirection highest_ancestor_direction; + mojo_base::mojom::blink::TextDirection highest_ancestor_direction; auto* highest_ancestor_html_element = DynamicTo<HTMLElement>(highest_ancestor_with_unicode_bidi); - if (allowed_direction != WritingDirection::kNatural && + if (allowed_direction != + mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION && highest_ancestor_unicode_bidi != CSSValueID::kBidiOverride && highest_ancestor_html_element && MakeGarbageCollected<EditingStyle>(highest_ancestor_with_unicode_bidi, @@ -750,7 +750,8 @@ // selection and prevent us from adding redundant ones, as described in: // <rdar://problem/3724344> Bolding and unbolding creates extraneous tags Position remove_start = MostBackwardCaretPosition(start); - WritingDirection text_direction = WritingDirection::kNatural; + mojo_base::mojom::blink::TextDirection text_direction = + mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION; bool has_text_direction = style->GetTextDirection(text_direction); EditingStyle* style_without_embedding = nullptr; EditingStyle* embedding_style = nullptr;
diff --git a/third_party/blink/renderer/core/editing/commands/apply_style_command.h b/third_party/blink/renderer/core/editing/commands/apply_style_command.h index daa86e763..d0170d6 100644 --- a/third_party/blink/renderer/core/editing/commands/apply_style_command.h +++ b/third_party/blink/renderer/core/editing/commands/apply_style_command.h
@@ -37,8 +37,6 @@ enum ShouldIncludeTypingStyle { kIncludeTypingStyle, kIgnoreTypingStyle }; -enum class WritingDirection; - class CORE_EXPORT ApplyStyleCommand final : public CompositeEditCommand { public: enum PropertyLevel { kPropertyDefault, kForceBlockProperties }; @@ -160,7 +158,7 @@ HTMLElement* SplitAncestorsWithUnicodeBidi( Node*, bool before, - WritingDirection allowed_direction); + mojo_base::mojom::blink::TextDirection allowed_direction); void RemoveEmbeddingUpToEnclosingBlock(Node*, HTMLElement* unsplit_ancestor, EditingState*);
diff --git a/third_party/blink/renderer/core/editing/commands/style_commands.cc b/third_party/blink/renderer/core/editing/commands/style_commands.cc index 84c26596..c0136e7 100644 --- a/third_party/blink/renderer/core/editing/commands/style_commands.cc +++ b/third_party/blink/renderer/core/editing/commands/style_commands.cc
@@ -44,7 +44,6 @@ #include "third_party/blink/renderer/core/editing/ephemeral_range.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/editing/visible_position.h" -#include "third_party/blink/renderer/core/editing/writing_direction.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html/html_font_element.h" @@ -417,20 +416,20 @@ value_id == CSSValueID::kPlaintext; } -WritingDirection StyleCommands::TextDirectionForSelection( +mojo_base::mojom::blink::TextDirection StyleCommands::TextDirectionForSelection( const VisibleSelection& selection, EditingStyle* typing_style, bool& has_nested_or_multiple_embeddings) { has_nested_or_multiple_embeddings = true; if (selection.IsNone()) - return WritingDirection::kNatural; + return mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION; const Position position = MostForwardCaretPosition(selection.Start()); const Node* anchor_node = position.AnchorNode(); if (!anchor_node) - return WritingDirection::kNatural; + return mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION; Position end; if (selection.IsRange()) { @@ -455,12 +454,12 @@ const CSSValueID unicode_bidi_value = unicode_bidi_identifier_value->GetValueID(); if (IsUnicodeBidiNestedOrMultipleEmbeddings(unicode_bidi_value)) - return WritingDirection::kNatural; + return mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION; } } if (selection.IsCaret()) { - WritingDirection direction; + mojo_base::mojom::blink::TextDirection direction; if (typing_style && typing_style->GetTextDirection(direction)) { has_nested_or_multiple_embeddings = false; return direction; @@ -472,7 +471,8 @@ // The selection is either a caret with no typing attributes or a range in // which no embedding is added, so just use the start position to decide. const Node* block = EnclosingBlock(anchor_node); - WritingDirection found_direction = WritingDirection::kNatural; + mojo_base::mojom::blink::TextDirection found_direction = + mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION; for (Node& runner : NodeTraversal::InclusiveAncestorsOf(*anchor_node)) { if (runner == block) @@ -496,7 +496,7 @@ continue; if (unicode_bidi_value == CSSValueID::kBidiOverride) - return WritingDirection::kNatural; + return mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION; DCHECK(EditingStyleUtilities::IsEmbedOrIsolate(unicode_bidi_value)) << static_cast<int>(unicode_bidi_value); @@ -511,17 +511,19 @@ direction_value != CSSValueID::kRtl) continue; - if (found_direction != WritingDirection::kNatural) - return WritingDirection::kNatural; + if (found_direction != + mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION) + return mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION; // In the range case, make sure that the embedding element persists until // the end of the range. if (selection.IsRange() && !end.AnchorNode()->IsDescendantOf(element)) - return WritingDirection::kNatural; + return mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION; - found_direction = direction_value == CSSValueID::kLtr - ? WritingDirection::kLeftToRight - : WritingDirection::kRightToLeft; + found_direction = + direction_value == CSSValueID::kLtr + ? mojo_base::mojom::blink::TextDirection::LEFT_TO_RIGHT + : mojo_base::mojom::blink::TextDirection::RIGHT_TO_LEFT; } has_nested_or_multiple_embeddings = false; return found_direction; @@ -529,13 +531,14 @@ EditingTriState StyleCommands::StateTextWritingDirection( LocalFrame& frame, - WritingDirection direction) { + mojo_base::mojom::blink::TextDirection direction) { frame.GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kEditing); bool has_nested_or_multiple_embeddings; - WritingDirection selection_direction = TextDirectionForSelection( - frame.Selection().ComputeVisibleSelectionInDOMTreeDeprecated(), - frame.GetEditor().TypingStyle(), has_nested_or_multiple_embeddings); + mojo_base::mojom::blink::TextDirection selection_direction = + TextDirectionForSelection( + frame.Selection().ComputeVisibleSelectionInDOMTreeDeprecated(), + frame.GetEditor().TypingStyle(), has_nested_or_multiple_embeddings); // TODO(editing-dev): We should be returning MixedTriState when // selectionDirection == direction && hasNestedOrMultipleEmbeddings return (selection_direction == direction && @@ -547,19 +550,22 @@ EditingTriState StyleCommands::StateTextWritingDirectionLeftToRight( LocalFrame& frame, Event*) { - return StateTextWritingDirection(frame, WritingDirection::kLeftToRight); + return StateTextWritingDirection( + frame, mojo_base::mojom::blink::TextDirection::LEFT_TO_RIGHT); } EditingTriState StyleCommands::StateTextWritingDirectionNatural( LocalFrame& frame, Event*) { - return StateTextWritingDirection(frame, WritingDirection::kNatural); + return StateTextWritingDirection( + frame, mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION); } EditingTriState StyleCommands::StateTextWritingDirectionRightToLeft( LocalFrame& frame, Event*) { - return StateTextWritingDirection(frame, WritingDirection::kRightToLeft); + return StateTextWritingDirection( + frame, mojo_base::mojom::blink::TextDirection::RIGHT_TO_LEFT); } EditingTriState StyleCommands::StateUnderline(LocalFrame& frame, Event*) {
diff --git a/third_party/blink/renderer/core/editing/commands/style_commands.h b/third_party/blink/renderer/core/editing/commands/style_commands.h index 0400ca2..4728106 100644 --- a/third_party/blink/renderer/core/editing/commands/style_commands.h +++ b/third_party/blink/renderer/core/editing/commands/style_commands.h
@@ -46,7 +46,6 @@ enum class EditingTriState; enum class EditorCommandSource; -enum class WritingDirection; // This class provides static functions about commands related to style. class StyleCommands { @@ -203,11 +202,11 @@ // TODO(editing-dev): We should make |textDirectionForSelection()| to take // |selectionInDOMTree|. - static WritingDirection TextDirectionForSelection(const VisibleSelection&, - EditingStyle*, - bool&); - static EditingTriState StateTextWritingDirection(LocalFrame&, - WritingDirection); + static mojo_base::mojom::blink::TextDirection + TextDirectionForSelection(const VisibleSelection&, EditingStyle*, bool&); + static EditingTriState StateTextWritingDirection( + LocalFrame&, + mojo_base::mojom::blink::TextDirection); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/editing_style.cc b/third_party/blink/renderer/core/editing/editing_style.cc index 6736935..0dde54d9 100644 --- a/third_party/blink/renderer/core/editing/editing_style.cc +++ b/third_party/blink/renderer/core/editing/editing_style.cc
@@ -57,7 +57,6 @@ #include "third_party/blink/renderer/core/editing/position.h" #include "third_party/blink/renderer/core/editing/serializers/html_interchange.h" #include "third_party/blink/renderer/core/editing/visible_selection.h" -#include "third_party/blink/renderer/core/editing/writing_direction.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html/html_font_element.h" @@ -636,7 +635,8 @@ font_size_delta_ == kNoFontDelta; } -bool EditingStyle::GetTextDirection(WritingDirection& writing_direction) const { +bool EditingStyle::GetTextDirection( + mojo_base::mojom::blink::TextDirection& writing_direction) const { if (!mutable_style_) return false; @@ -657,14 +657,15 @@ writing_direction = direction_identifier_value->GetValueID() == CSSValueID::kLtr - ? WritingDirection::kLeftToRight - : WritingDirection::kRightToLeft; + ? mojo_base::mojom::blink::TextDirection::LEFT_TO_RIGHT + : mojo_base::mojom::blink::TextDirection::RIGHT_TO_LEFT; return true; } if (unicode_bidi_value == CSSValueID::kNormal) { - writing_direction = WritingDirection::kNatural; + writing_direction = + mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION; return true; }
diff --git a/third_party/blink/renderer/core/editing/editing_style.h b/third_party/blink/renderer/core/editing/editing_style.h index 240cb4bd..08fbbec 100644 --- a/third_party/blink/renderer/core/editing/editing_style.h +++ b/third_party/blink/renderer/core/editing/editing_style.h
@@ -32,6 +32,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_EDITING_STYLE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_EDITING_STYLE_H_ +#include "mojo/public/mojom/base/text_direction.mojom-blink-forward.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css_value_keywords.h" @@ -58,7 +59,6 @@ class CSSPropertyValueSet; enum class EditingTriState; enum class SecureContextMode; -enum class WritingDirection; class CORE_EXPORT EditingStyle final : public GarbageCollected<EditingStyle> { public: @@ -86,7 +86,7 @@ EditingStyle(CSSPropertyID, const String& value, SecureContextMode); MutableCSSPropertyValueSet* Style() { return mutable_style_.Get(); } - bool GetTextDirection(WritingDirection&) const; + bool GetTextDirection(mojo_base::mojom::blink::TextDirection&) const; bool IsEmpty() const; void OverrideWithStyle(const CSSPropertyValueSet*); void Clear();
diff --git a/third_party/blink/renderer/core/editing/editor.cc b/third_party/blink/renderer/core/editing/editor.cc index 96dffd1..304e2f10 100644 --- a/third_party/blink/renderer/core/editing/editor.cc +++ b/third_party/blink/renderer/core/editing/editor.cc
@@ -65,7 +65,6 @@ #include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h" #include "third_party/blink/renderer/core/editing/visible_position.h" #include "third_party/blink/renderer/core/editing/visible_units.h" -#include "third_party/blink/renderer/core/editing/writing_direction.h" #include "third_party/blink/renderer/core/events/keyboard_event.h" #include "third_party/blink/renderer/core/events/text_event.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" @@ -633,14 +632,17 @@ undo_stack_->Redo(); } -void Editor::SetBaseWritingDirection(WritingDirection direction) { +void Editor::SetBaseWritingDirection( + mojo_base::mojom::blink::TextDirection direction) { Element* focused_element = GetFrame().GetDocument()->FocusedElement(); if (auto* text_control = ToTextControlOrNull(focused_element)) { - if (direction == WritingDirection::kNatural) + if (direction == mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION) return; text_control->setAttribute( html_names::kDirAttr, - direction == WritingDirection::kLeftToRight ? "ltr" : "rtl"); + direction == mojo_base::mojom::blink::TextDirection::LEFT_TO_RIGHT + ? "ltr" + : "rtl"); text_control->DispatchInputEvent(); return; } @@ -649,9 +651,11 @@ MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode); style->SetProperty( CSSPropertyID::kDirection, - direction == WritingDirection::kLeftToRight + direction == mojo_base::mojom::blink::TextDirection::LEFT_TO_RIGHT ? "ltr" - : direction == WritingDirection::kRightToLeft ? "rtl" : "inherit", + : direction == mojo_base::mojom::blink::TextDirection::RIGHT_TO_LEFT + ? "rtl" + : "inherit", /* important */ false, GetFrame().DomWindow()->GetSecureContextMode()); ApplyParagraphStyleToSelection( style, InputEvent::InputType::kFormatSetBlockTextDirection);
diff --git a/third_party/blink/renderer/core/editing/editor.h b/third_party/blink/renderer/core/editing/editor.h index 23acef1..49e938a4 100644 --- a/third_party/blink/renderer/core/editing/editor.h +++ b/third_party/blink/renderer/core/editing/editor.h
@@ -59,7 +59,6 @@ enum class DragSourceType { kHTMLSource, kPlainTextSource }; enum class EditorParagraphSeparator { kIsDiv, kIsP }; enum class EditorCommandSource { kMenuOrKeyBinding, kDOM }; -enum class WritingDirection; class CORE_EXPORT Editor final : public GarbageCollected<Editor> { public: @@ -133,7 +132,7 @@ // Supposed to be used as |const UndoStack&|. UndoStack& GetUndoStack() const { return *undo_stack_; } - void SetBaseWritingDirection(WritingDirection); + void SetBaseWritingDirection(mojo_base::mojom::blink::TextDirection); // smartInsertDeleteEnabled and selectTrailingWhitespaceEnabled are // mutually exclusive, meaning that enabling one will disable the other.
diff --git a/third_party/blink/renderer/core/editing/writing_direction.h b/third_party/blink/renderer/core/editing/writing_direction.h deleted file mode 100644 index af5e583cb9..0000000 --- a/third_party/blink/renderer/core/editing/writing_direction.h +++ /dev/null
@@ -1,35 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_WRITING_DIRECTION_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_WRITING_DIRECTION_H_ - -namespace blink { - -enum class WritingDirection { kNatural, kLeftToRight, kRightToLeft }; - -} // namespace blink - -#endif
diff --git a/third_party/blink/renderer/core/fetch/fetch_manager.cc b/third_party/blink/renderer/core/fetch/fetch_manager.cc index bd31c5e..d677de5 100644 --- a/third_party/blink/renderer/core/fetch/fetch_manager.cc +++ b/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -428,7 +428,8 @@ BodyStreamBuffer::Create(script_state, place_holder_body_, signal_)); response_data->InitFromResourceResponse( - url_list_, fetch_request_data_->Credentials(), tainting, response); + url_list_, fetch_request_data_->Method(), + fetch_request_data_->Credentials(), tainting, response); FetchResponseData* tainted_response = nullptr;
diff --git a/third_party/blink/renderer/core/fetch/fetch_response_data.cc b/third_party/blink/renderer/core/fetch/fetch_response_data.cc index c595b241..2605dadb 100644 --- a/third_party/blink/renderer/core/fetch/fetch_response_data.cc +++ b/third_party/blink/renderer/core/fetch/fetch_response_data.cc
@@ -191,6 +191,7 @@ new_response->status_message_ = status_message_; new_response->header_list_ = header_list_->Clone(); new_response->mime_type_ = mime_type_; + new_response->request_method_ = request_method_; new_response->response_time_ = response_time_; new_response->cache_storage_cache_name_ = cache_storage_cache_name_; new_response->cors_exposed_header_names_ = cors_exposed_header_names_; @@ -262,6 +263,7 @@ response->response_type = type_; response->response_source = response_source_; response->mime_type = mime_type_; + response->request_method = request_method_; response->response_time = response_time_; response->cache_storage_cache_name = cache_storage_cache_name_; response->cors_exposed_header_names = @@ -279,6 +281,7 @@ void FetchResponseData::InitFromResourceResponse( const Vector<KURL>& request_url_list, + const AtomicString& request_method, network::mojom::CredentialsMode request_credentials, FetchRequestData::Tainting tainting, const ResourceResponse& response) { @@ -308,6 +311,7 @@ } SetMimeType(response.MimeType()); + SetRequestMethod(request_method); SetResponseTime(response.ResponseTime()); if (response.WasCached()) {
diff --git a/third_party/blink/renderer/core/fetch/fetch_response_data.h b/third_party/blink/renderer/core/fetch/fetch_response_data.h index 0c4bfcb..e5c65cc 100644 --- a/third_party/blink/renderer/core/fetch/fetch_response_data.h +++ b/third_party/blink/renderer/core/fetch/fetch_response_data.h
@@ -95,6 +95,9 @@ status_message_ = status_message; } void SetMimeType(const String& type) { mime_type_ = type; } + void SetRequestMethod(const AtomicString& method) { + request_method_ = method; + } void SetResponseTime(base::Time response_time) { response_time_ = response_time; } @@ -131,6 +134,7 @@ // Initialize non-body data from the given |response|. void InitFromResourceResponse( const Vector<KURL>& request_url_list, + const AtomicString& request_method, network::mojom::CredentialsMode request_credentials, FetchRequestData::Tainting tainting, const ResourceResponse& response); @@ -148,6 +152,7 @@ Member<FetchResponseData> internal_response_; Member<BodyStreamBuffer> buffer_; String mime_type_; + AtomicString request_method_; base::Time response_time_; String cache_storage_cache_name_; HTTPHeaderSet cors_exposed_header_names_;
diff --git a/third_party/blink/renderer/core/fetch/response.cc b/third_party/blink/renderer/core/fetch/response.cc index 619232c2..a1f5932 100644 --- a/third_party/blink/renderer/core/fetch/response.cc +++ b/third_party/blink/renderer/core/fetch/response.cc
@@ -378,6 +378,8 @@ response->SetURLList(fetch_api_response.url_list); response->SetStatus(fetch_api_response.status_code); response->SetStatusMessage(WTF::AtomicString(fetch_api_response.status_text)); + response->SetRequestMethod( + WTF::AtomicString(fetch_api_response.request_method)); response->SetResponseTime(fetch_api_response.response_time); response->SetCacheStorageCacheName( fetch_api_response.cache_storage_cache_name);
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 814e0c05..25a7913 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -91,7 +91,6 @@ #include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h" #include "third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h" #include "third_party/blink/renderer/core/editing/surrounding_text.h" -#include "third_party/blink/renderer/core/editing/writing_direction.h" #include "third_party/blink/renderer/core/execution_context/window_agent.h" #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h" #include "third_party/blink/renderer/core/fileapi/public_url_manager.h" @@ -803,15 +802,18 @@ switch (direction) { case base::i18n::TextDirection::UNKNOWN_DIRECTION: - editor.SetBaseWritingDirection(WritingDirection::kNatural); + editor.SetBaseWritingDirection( + mojo_base::mojom::blink::TextDirection::UNKNOWN_DIRECTION); break; case base::i18n::TextDirection::LEFT_TO_RIGHT: - editor.SetBaseWritingDirection(WritingDirection::kLeftToRight); + editor.SetBaseWritingDirection( + mojo_base::mojom::blink::TextDirection::LEFT_TO_RIGHT); break; case base::i18n::TextDirection::RIGHT_TO_LEFT: - editor.SetBaseWritingDirection(WritingDirection::kRightToLeft); + editor.SetBaseWritingDirection( + mojo_base::mojom::blink::TextDirection::RIGHT_TO_LEFT); break; default:
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_base.cc b/third_party/blink/renderer/core/frame/web_frame_widget_base.cc index 2a2048e0..e76085af 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_base.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
@@ -1515,12 +1515,6 @@ } } -WebTextInputType WebFrameWidgetBase::TextInputType() { - WebLocalFrame* focused_frame = FocusedWebLocalFrameInWidget(); - if (!focused_frame) - return WebTextInputType::kWebTextInputTypeNone; - return focused_frame->GetInputMethodController()->TextInputType(); -} void WebFrameWidgetBase::AddImeTextSpansToExistingText( uint32_t start,
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_base.h b/third_party/blink/renderer/core/frame/web_frame_widget_base.h index acade8a..be7e3d7 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_base.h +++ b/third_party/blink/renderer/core/frame/web_frame_widget_base.h
@@ -142,7 +142,6 @@ void GetCompositionCharacterBoundsInWindow( Vector<gfx::Rect>* bounds) override; gfx::Range CompositionRange() override; - WebTextInputType TextInputType() override; WebTextInputInfo TextInputInfo() override; ui::mojom::VirtualKeyboardVisibilityRequest GetLastVirtualKeyboardVisibilityRequest() override;
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 eb55e9f..0863431 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
@@ -169,7 +169,6 @@ #include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h" #include "third_party/blink/renderer/core/editing/text_affinity.h" #include "third_party/blink/renderer/core/editing/visible_position.h" -#include "third_party/blink/renderer/core/editing/writing_direction.h" #include "third_party/blink/renderer/core/events/after_print_event.h" #include "third_party/blink/renderer/core/events/before_print_event.h" #include "third_party/blink/renderer/core/exported/local_frame_client_impl.h"
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index f34d6c126..e504a3810 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -44,7 +44,6 @@ #include "third_party/blink/renderer/core/dom/node_lists_node_data.h" #include "third_party/blink/renderer/core/dom/node_traversal.h" #include "third_party/blink/renderer/core/events/keyboard_event.h" -#include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/html/forms/form_controller.h" #include "third_party/blink/renderer/core/html/forms/form_data.h" #include "third_party/blink/renderer/core/html/forms/html_form_element.h" @@ -363,14 +362,6 @@ return !UsesMenuList(); } -bool HTMLSelectElement::TypeShouldForceLegacyLayout() const { - if (!RuntimeEnabledFeatures::LayoutNGForControlsEnabled() && UsesMenuList()) { - UseCounter::Count(GetDocument(), WebFeature::kLegacyLayoutByMenuList); - return true; - } - return false; -} - LayoutObject* HTMLSelectElement::CreateLayoutObject( const ComputedStyle& style, LegacyLayout legacy_layout) {
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.h b/third_party/blink/renderer/core/html/forms/html_select_element.h index 86570a1..8e5029a3 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.h +++ b/third_party/blink/renderer/core/html/forms/html_select_element.h
@@ -211,7 +211,6 @@ void ParseAttribute(const AttributeModificationParams&) override; bool IsPresentationAttribute(const QualifiedName&) const override; - bool TypeShouldForceLegacyLayout() const override; LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override; void DidRecalcStyle(const StyleRecalcChange) override; void AttachLayoutTree(AttachContext&) override;
diff --git a/third_party/blink/renderer/core/inspector/inspect_tools.cc b/third_party/blink/renderer/core/inspector/inspect_tools.cc index 181cb05..520f770 100644 --- a/third_party/blink/renderer/core/inspector/inspect_tools.cc +++ b/third_party/blink/renderer/core/inspector/inspect_tools.cc
@@ -227,6 +227,9 @@ } bool SearchingForNodeTool::HandlePointerEvent(const WebPointerEvent& event) { + // Trigger Inspect only when a pointer device is pressed down. + if (event.GetType() != WebInputEvent::Type::kPointerDown) + return false; Node* node = HoveredNodeForEvent(overlay_->GetFrame(), event, false); if (node) { overlay_->Inspect(node);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc index 465fe25..ea47434 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.cc
@@ -357,20 +357,23 @@ const auto* layout_box = ToLayoutBoxOrNull(GetLayoutObject()); if (UNLIKELY(!layout_box)) return nullptr; + const wtf_size_t fragment_count = layout_box->PhysicalFragmentCount(); + if (fragment_count == 0) { + // This should not happen, but DCHECK hits. crbug.com/1107204 + return nullptr; + } - DCHECK_GT(layout_box->PhysicalFragmentCount(), 0u); - if (layout_box->PhysicalFragmentCount() == 1) { + if (fragment_count == 1) { const NGPhysicalFragment* post_layout = layout_box->GetPhysicalFragment(0); DCHECK(post_layout); if (UNLIKELY(post_layout && post_layout != this)) { - // Relayout boundary is the only case this can happen. crbug.com/829028 + // This can happen at the relayout boundary crbug.com/829028 + // but DCHECKing |IsRelayoutBoundary| hits. crbug.com/1107204 DCHECK(layout_box->IsRelayoutBoundary()); return post_layout; } - } else { - // TODO(crbug.com/829028): Block fragmentation not supported yet. - DCHECK(!layout_box->IsRelayoutBoundary()); } + // TODO(crbug.com/829028): Block fragmentation not supported yet. DCHECK(std::any_of(layout_box->PhysicalFragments().begin(), layout_box->PhysicalFragments().end(), [this](const NGPhysicalFragment& fragment) {
diff --git a/third_party/blink/renderer/core/svg/svg_circle_element.cc b/third_party/blink/renderer/core/svg/svg_circle_element.cc index b322e86f..f6aaff7 100644 --- a/third_party/blink/renderer/core/svg/svg_circle_element.cc +++ b/third_party/blink/renderer/core/svg/svg_circle_element.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/renderer/core/svg/svg_circle_element.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.h" #include "third_party/blink/renderer/core/svg/svg_length.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -62,8 +63,8 @@ Path path; SVGLengthContext length_context(this); - DCHECK(GetLayoutObject()); - const ComputedStyle& style = GetLayoutObject()->StyleRef(); + const ComputedStyle& style = ComputedStyleRef(); + const SVGComputedStyle& svg_style = style.SvgStyle(); float r = length_context.ValueForLength(svg_style.R(), style,
diff --git a/third_party/blink/renderer/core/svg/svg_ellipse_element.cc b/third_party/blink/renderer/core/svg/svg_ellipse_element.cc index a5098d79..f5d6ed2 100644 --- a/third_party/blink/renderer/core/svg/svg_ellipse_element.cc +++ b/third_party/blink/renderer/core/svg/svg_ellipse_element.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/renderer/core/svg/svg_ellipse_element.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_ellipse.h" #include "third_party/blink/renderer/core/svg/svg_length.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -70,8 +71,8 @@ Path path; SVGLengthContext length_context(this); - DCHECK(GetLayoutObject()); - const ComputedStyle& style = GetLayoutObject()->StyleRef(); + const ComputedStyle& style = ComputedStyleRef(); + const SVGComputedStyle& svg_style = style.SvgStyle(); FloatSize radii(ToFloatSize(
diff --git a/third_party/blink/renderer/core/svg/svg_geometry_element.cc b/third_party/blink/renderer/core/svg/svg_geometry_element.cc index 4710421..c7f27292 100644 --- a/third_party/blink/renderer/core/svg/svg_geometry_element.cc +++ b/third_party/blink/renderer/core/svg/svg_geometry_element.cc
@@ -154,22 +154,36 @@ return AsPath().length(); } -SVGPointTearOff* SVGGeometryElement::getPointAtLength(float length) { +SVGPointTearOff* SVGGeometryElement::getPointAtLength( + float length, + ExceptionState& exception_state) { GetDocument().UpdateStyleAndLayoutForNode(this, DocumentUpdateReason::kJavaScript); - FloatPoint point; - if (GetLayoutObject()) { - const Path& path = AsPath(); - if (length < 0) { - length = 0; - } else { - float computed_length = path.length(); - if (length > computed_length) - length = computed_length; - } - point = path.PointAtLength(length); + if (!EnsureComputedStyle()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "The element is in an inactive document."); + return nullptr; } + + const Path& path = AsPath(); + + if (path.IsEmpty()) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "The element's path is empty."); + return nullptr; + } + + if (length < 0) { + length = 0; + } else { + float computed_length = path.length(); + if (length > computed_length) + length = computed_length; + } + FloatPoint point = path.PointAtLength(length); + return SVGPointTearOff::CreateDetached(point); }
diff --git a/third_party/blink/renderer/core/svg/svg_geometry_element.h b/third_party/blink/renderer/core/svg/svg_geometry_element.h index 8ec93d84..37607cb 100644 --- a/third_party/blink/renderer/core/svg/svg_geometry_element.h +++ b/third_party/blink/renderer/core/svg/svg_geometry_element.h
@@ -52,7 +52,7 @@ SVGAnimatedNumber* pathLength() const { return path_length_.Get(); } virtual float getTotalLength(ExceptionState&); - virtual SVGPointTearOff* getPointAtLength(float distance); + virtual SVGPointTearOff* getPointAtLength(float distance, ExceptionState&); float AuthorPathLength() const; float PathLengthScaleFactor() const;
diff --git a/third_party/blink/renderer/core/svg/svg_geometry_element.idl b/third_party/blink/renderer/core/svg/svg_geometry_element.idl index 4babc7f..02711605 100644 --- a/third_party/blink/renderer/core/svg/svg_geometry_element.idl +++ b/third_party/blink/renderer/core/svg/svg_geometry_element.idl
@@ -38,5 +38,5 @@ [HighEntropy, Measure] boolean isPointInFill(SVGPoint point); [HighEntropy, Measure] boolean isPointInStroke(SVGPoint point); [HighEntropy, Measure, RaisesException] float getTotalLength(); - [HighEntropy, Measure] SVGPoint getPointAtLength(float distance); + [HighEntropy, Measure, RaisesException] SVGPoint getPointAtLength(float distance); };
diff --git a/third_party/blink/renderer/core/svg/svg_line_element.cc b/third_party/blink/renderer/core/svg/svg_line_element.cc index b3013d2..d74a5aab 100644 --- a/third_party/blink/renderer/core/svg/svg_line_element.cc +++ b/third_party/blink/renderer/core/svg/svg_line_element.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/renderer/core/svg/svg_line_element.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/svg/svg_length.h" #include "third_party/blink/renderer/platform/graphics/path.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -66,6 +67,8 @@ Path path; SVGLengthContext length_context(this); + DCHECK(GetComputedStyle()); + path.MoveTo(FloatPoint(x1()->CurrentValue()->Value(length_context), y1()->CurrentValue()->Value(length_context))); path.AddLineTo(FloatPoint(x2()->CurrentValue()->Value(length_context),
diff --git a/third_party/blink/renderer/core/svg/svg_path_element.cc b/third_party/blink/renderer/core/svg/svg_path_element.cc index 0a3c9ca..748a3df 100644 --- a/third_party/blink/renderer/core/svg/svg_path_element.cc +++ b/third_party/blink/renderer/core/svg/svg_path_element.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/renderer/core/svg/svg_path_element.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/svg/svg_mpath_element.h" #include "third_party/blink/renderer/core/svg/svg_path_query.h" @@ -47,8 +48,8 @@ } const StylePath* SVGPathElement::GetStylePath() const { - if (LayoutObject* layout_object = GetLayoutObject()) { - const StylePath* style_path = layout_object->StyleRef().SvgStyle().D(); + if (const ComputedStyle* style = GetComputedStyle()) { + const StylePath* style_path = style->SvgStyle().D(); if (style_path) return style_path; return StylePath::EmptyPath(); @@ -70,10 +71,26 @@ return SVGPathQuery(PathByteStream()).GetTotalLength(); } -SVGPointTearOff* SVGPathElement::getPointAtLength(float length) { +SVGPointTearOff* SVGPathElement::getPointAtLength( + float length, + ExceptionState& exception_state) { GetDocument().UpdateStyleAndLayoutForNode(this, DocumentUpdateReason::kJavaScript); - SVGPathQuery path_query(PathByteStream()); + if (!EnsureComputedStyle()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "The element is in an inactive document."); + return nullptr; + } + + const SVGPathByteStream& byte_stream = PathByteStream(); + if (byte_stream.IsEmpty()) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "The element's path is empty."); + return nullptr; + } + + SVGPathQuery path_query(byte_stream); if (length < 0) { length = 0; } else {
diff --git a/third_party/blink/renderer/core/svg/svg_path_element.h b/third_party/blink/renderer/core/svg/svg_path_element.h index babb968..52e61e67 100644 --- a/third_party/blink/renderer/core/svg/svg_path_element.h +++ b/third_party/blink/renderer/core/svg/svg_path_element.h
@@ -39,7 +39,7 @@ Path AttributePath() const; float getTotalLength(ExceptionState&) override; - SVGPointTearOff* getPointAtLength(float distance) override; + SVGPointTearOff* getPointAtLength(float distance, ExceptionState&) override; SVGAnimatedPath* GetPath() const { return path_.Get(); } float ComputePathLength() const override;
diff --git a/third_party/blink/renderer/core/svg/svg_poly_element.cc b/third_party/blink/renderer/core/svg/svg_poly_element.cc index d612f35..2aaa9f1 100644 --- a/third_party/blink/renderer/core/svg/svg_poly_element.cc +++ b/third_party/blink/renderer/core/svg/svg_poly_element.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/renderer/core/svg/svg_poly_element.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/svg/svg_animated_point_list.h" #include "third_party/blink/renderer/platform/graphics/path.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -43,6 +44,7 @@ Path SVGPolyElement::AsPathFromPoints() const { Path path; + DCHECK(GetComputedStyle()); const SVGPointList* points_value = Points()->CurrentValue(); if (points_value->IsEmpty())
diff --git a/third_party/blink/renderer/core/svg/svg_rect_element.cc b/third_party/blink/renderer/core/svg/svg_rect_element.cc index a98dde36..bb60bab 100644 --- a/third_party/blink/renderer/core/svg/svg_rect_element.cc +++ b/third_party/blink/renderer/core/svg/svg_rect_element.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/renderer/core/svg/svg_rect_element.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_rect.h" #include "third_party/blink/renderer/core/svg/svg_length.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -86,8 +87,7 @@ Path path; SVGLengthContext length_context(this); - DCHECK(GetLayoutObject()); - const ComputedStyle& style = GetLayoutObject()->StyleRef(); + const ComputedStyle& style = ComputedStyleRef(); FloatSize size(ToFloatSize( length_context.ResolveLengthPair(style.Width(), style.Height(), style)));
diff --git a/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc b/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc index 961b69c..30a6442 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
@@ -160,19 +160,19 @@ // In addition to LTR and RTL direction, edit fields also support // top to bottom and bottom to top via the CSS writing-mode property. -ax::mojom::TextDirection AXInlineTextBox::GetTextDirection() const { +ax::mojom::blink::WritingDirection AXInlineTextBox::GetTextDirection() const { if (!inline_text_box_) return AXObject::GetTextDirection(); switch (inline_text_box_->GetDirection()) { case AbstractInlineTextBox::kLeftToRight: - return ax::mojom::TextDirection::kLtr; + return ax::mojom::blink::WritingDirection::kLtr; case AbstractInlineTextBox::kRightToLeft: - return ax::mojom::TextDirection::kRtl; + return ax::mojom::blink::WritingDirection::kRtl; case AbstractInlineTextBox::kTopToBottom: - return ax::mojom::TextDirection::kTtb; + return ax::mojom::blink::WritingDirection::kTtb; case AbstractInlineTextBox::kBottomToTop: - return ax::mojom::TextDirection::kBtt; + return ax::mojom::blink::WritingDirection::kBtt; } return AXObject::GetTextDirection();
diff --git a/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h b/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h index 76af7737..ba665de 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h +++ b/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.h
@@ -65,7 +65,7 @@ SkMatrix44& out_container_transform, bool* clips_children = nullptr) const override; AXObject* ComputeParent() const override; - ax::mojom::TextDirection GetTextDirection() const override; + ax::mojom::blink::WritingDirection GetTextDirection() const override; Node* GetNode() const override; AXObject* NextOnLine() const override; AXObject* PreviousOnLine() const override;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc index a7bb6633..aeac617 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -922,7 +922,7 @@ return AXNodeObject::GetText(); } -ax::mojom::blink::TextDirection AXLayoutObject::GetTextDirection() const { +ax::mojom::blink::WritingDirection AXLayoutObject::GetTextDirection() const { if (!GetLayoutObject()) return AXNodeObject::GetTextDirection(); @@ -933,16 +933,16 @@ if (style->IsHorizontalWritingMode()) { switch (style->Direction()) { case TextDirection::kLtr: - return ax::mojom::blink::TextDirection::kLtr; + return ax::mojom::blink::WritingDirection::kLtr; case TextDirection::kRtl: - return ax::mojom::blink::TextDirection::kRtl; + return ax::mojom::blink::WritingDirection::kRtl; } } else { switch (style->Direction()) { case TextDirection::kLtr: - return ax::mojom::blink::TextDirection::kTtb; + return ax::mojom::blink::WritingDirection::kTtb; case TextDirection::kRtl: - return ax::mojom::blink::TextDirection::kBtt; + return ax::mojom::blink::WritingDirection::kBtt; } }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.h b/third_party/blink/renderer/modules/accessibility/ax_layout_object.h index b383619..d339eb3f 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
@@ -105,7 +105,7 @@ // Properties of static elements. ax::mojom::blink::ListStyle GetListStyle() const final; String GetText() const override; - ax::mojom::blink::TextDirection GetTextDirection() const final; + ax::mojom::blink::WritingDirection GetTextDirection() const final; ax::mojom::blink::TextPosition GetTextPosition() const final; void GetTextStyleAndTextDecorationStyle( int32_t* text_style,
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h index 5b92ea74..d86307f 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -657,8 +657,8 @@ virtual ax::mojom::blink::TextAlign GetTextAlign() const { return ax::mojom::blink::TextAlign::kNone; } - virtual ax::mojom::blink::TextDirection GetTextDirection() const { - return ax::mojom::blink::TextDirection::kLtr; + virtual ax::mojom::blink::WritingDirection GetTextDirection() const { + return ax::mojom::blink::WritingDirection::kLtr; } virtual ax::mojom::blink::TextPosition GetTextPosition() const { return ax::mojom::blink::TextPosition::kNone;
diff --git a/third_party/blink/renderer/modules/exported/web_ax_object.cc b/third_party/blink/renderer/modules/exported/web_ax_object.cc index 2d1cb16..eddbc3b 100644 --- a/third_party/blink/renderer/modules/exported/web_ax_object.cc +++ b/third_party/blink/renderer/modules/exported/web_ax_object.cc
@@ -965,9 +965,9 @@ return private_->GetListStyle(); } -ax::mojom::TextDirection WebAXObject::GetTextDirection() const { +ax::mojom::blink::WritingDirection WebAXObject::GetTextDirection() const { if (IsDetached()) - return ax::mojom::TextDirection::kLtr; + return ax::mojom::blink::WritingDirection::kLtr; return private_->GetTextDirection(); }
diff --git a/third_party/blink/renderer/modules/service_worker/fetch_event.cc b/third_party/blink/renderer/modules/service_worker/fetch_event.cc index f115536..2db345f 100644 --- a/third_party/blink/renderer/modules/service_worker/fetch_event.cc +++ b/third_party/blink/renderer/modules/service_worker/fetch_event.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h" +#include "third_party/blink/renderer/platform/network/http_names.h" #include "third_party/blink/renderer/platform/network/network_utils.h" namespace blink { @@ -141,7 +142,7 @@ url_list[0] = preload_response_->CurrentRequestUrl(); response_data->InitFromResourceResponse( - url_list, network::mojom::CredentialsMode::kInclude, + url_list, http_names::kGET, network::mojom::CredentialsMode::kInclude, FetchRequestData::kBasicTainting, preload_response_->ToResourceResponse());
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc index ad53a97..e269afe 100644 --- a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc +++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
@@ -161,6 +161,11 @@ return scope_data[kMarkProcessWorklists]; } +base::TimeDelta ThreadHeapStatsCollector::Event::flushing_v8_references_time() + const { + return scope_data[kMarkFlushV8References]; +} + base::TimeDelta ThreadHeapStatsCollector::Event::atomic_marking_time() const { return scope_data[kAtomicPauseMarkPrologue] + scope_data[kAtomicPauseMarkRoots] + @@ -238,6 +243,10 @@ return current_.worklist_processing_time_foreground(); } +base::TimeDelta ThreadHeapStatsCollector::flushing_v8_references_time() const { + return current_.flushing_v8_references_time(); +} + size_t ThreadHeapStatsCollector::allocated_space_bytes() const { return allocated_space_bytes_; }
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.h b/third_party/blink/renderer/platform/heap/heap_stats_collector.h index ad6f20f..ef693eb 100644 --- a/third_party/blink/renderer/platform/heap/heap_stats_collector.h +++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.h
@@ -242,6 +242,9 @@ // Time spent processing worklist in the foreground thread. base::TimeDelta worklist_processing_time_foreground() const; + // Time spent flushing v8 references (this is done only in the foreground) + base::TimeDelta flushing_v8_references_time() const; + // Time spent in foreground tasks marking the heap. base::TimeDelta foreground_marking_time() const; @@ -330,6 +333,8 @@ base::TimeDelta worklist_processing_time_foreground() const; + base::TimeDelta flushing_v8_references_time() const; + int64_t allocated_bytes_since_prev_gc() const; size_t allocated_space_bytes() const;
diff --git a/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc b/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc index f17cea8d..2b5a7685 100644 --- a/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc +++ b/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc
@@ -18,9 +18,15 @@ void MarkingSchedulingOracle::UpdateIncrementalMarkingStats( size_t overall_marked_bytes, - base::TimeDelta overall_marking_time) { + base::TimeDelta overall_marking_time, + base::TimeDelta non_contributing_time) { incrementally_marked_bytes_ = overall_marked_bytes; - incremental_marking_time_so_far_ = overall_marking_time; + // |non_contributing_time| is time spent during |overall_marking_time| which + // does not contribute to |overall_marked_bytes| and is thus ignored so that + // it doesn't affect the marking speed. + DCHECK_LE(non_contributing_time, overall_marking_time); + incremental_marking_time_so_far_ = + overall_marking_time - non_contributing_time; } void MarkingSchedulingOracle::AddConcurrentlyMarkedBytes(size_t marked_bytes) {
diff --git a/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h b/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h index 642304c..188c79e 100644 --- a/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h +++ b/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h
@@ -32,7 +32,7 @@ explicit MarkingSchedulingOracle(); - void UpdateIncrementalMarkingStats(size_t, base::TimeDelta); + void UpdateIncrementalMarkingStats(size_t, base::TimeDelta, base::TimeDelta); void AddConcurrentlyMarkedBytes(size_t); size_t GetOverallMarkedBytes();
diff --git a/third_party/blink/renderer/platform/heap/test/marking_scheduling_oracle_test.cc b/third_party/blink/renderer/platform/heap/test/marking_scheduling_oracle_test.cc index 5350b96..65bfc55c 100644 --- a/third_party/blink/renderer/platform/heap/test/marking_scheduling_oracle_test.cc +++ b/third_party/blink/renderer/platform/heap/test/marking_scheduling_oracle_test.cc
@@ -31,7 +31,8 @@ // Add incrementally marked bytes to tell oracle this is not the first step. oracle.UpdateIncrementalMarkingStats( MarkingSchedulingOracle::kMinimumMarkedBytesInStep, - base::TimeDelta::FromMilliseconds(1)); + base::TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromMilliseconds(0)); oracle.SetElapsedTimeForTesting(0); // Given marking speed set above, Minimum duration should be 1ms. EXPECT_EQ(1, oracle.GetNextIncrementalStepDurationForTask(kObjectSize) @@ -42,8 +43,10 @@ MarkingSchedulingOracle oracle; // Add incrementally marked bytes to tell oracle this is not the first step. oracle.UpdateIncrementalMarkingStats( - 1, base::TimeDelta::FromMilliseconds( - MarkingSchedulingOracle::kEstimatedMarkingTimeMs)); + 1, + base::TimeDelta::FromMilliseconds( + MarkingSchedulingOracle::kEstimatedMarkingTimeMs), + base::TimeDelta::FromMilliseconds(0)); oracle.SetElapsedTimeForTesting( MarkingSchedulingOracle::kEstimatedMarkingTimeMs); EXPECT_EQ(MarkingSchedulingOracle::kMaximumIncrementalMarkingStepDuration, @@ -55,7 +58,8 @@ // Add incrementally marked bytes to tell oracle this is not the first step. oracle.UpdateIncrementalMarkingStats( MarkingSchedulingOracle::kMinimumMarkedBytesInStep, - base::TimeDelta::FromMilliseconds(1)); + base::TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromMilliseconds(0)); oracle.AddConcurrentlyMarkedBytes(0.6 * kObjectSize); oracle.SetElapsedTimeForTesting( 0.5 * MarkingSchedulingOracle::kEstimatedMarkingTimeMs); @@ -69,7 +73,8 @@ MarkingSchedulingOracle oracle; oracle.UpdateIncrementalMarkingStats( 0.1 * kObjectSize, - base::TimeDelta::FromMilliseconds(kForegoundMarkingTime)); + base::TimeDelta::FromMilliseconds(kForegoundMarkingTime), + base::TimeDelta::FromMilliseconds(0)); oracle.AddConcurrentlyMarkedBytes(0.25 * kObjectSize); oracle.SetElapsedTimeForTesting( 0.5 * MarkingSchedulingOracle::kEstimatedMarkingTimeMs);
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc index 45f064b..3e950f6 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -1611,7 +1611,8 @@ // the object graph, this is fine. marking_scheduling_->UpdateIncrementalMarkingStats( visitor->marked_bytes(), - Heap().stats_collector()->worklist_processing_time_foreground()); + Heap().stats_collector()->worklist_processing_time_foreground(), + Heap().stats_collector()->flushing_v8_references_time()); return finished; }
diff --git a/third_party/blink/renderer/platform/widget/frame_widget.h b/third_party/blink/renderer/platform/widget/frame_widget.h index e8fdf2b..c383722 100644 --- a/third_party/blink/renderer/platform/widget/frame_widget.h +++ b/third_party/blink/renderer/platform/widget/frame_widget.h
@@ -123,7 +123,6 @@ Vector<gfx::Rect>* bounds) = 0; virtual gfx::Range CompositionRange() = 0; - virtual WebTextInputType TextInputType() = 0; virtual WebTextInputInfo TextInputInfo() = 0; virtual ui::mojom::blink::VirtualKeyboardVisibilityRequest GetLastVirtualKeyboardVisibilityRequest() = 0;
diff --git a/third_party/blink/renderer/platform/widget/widget_base.cc b/third_party/blink/renderer/platform/widget/widget_base.cc index 25bb9fd9..2485322 100644 --- a/third_party/blink/renderer/platform/widget/widget_base.cc +++ b/third_party/blink/renderer/platform/widget/widget_base.cc
@@ -669,10 +669,7 @@ } ui::TextInputType WidgetBase::GetTextInputType() { - FrameWidget* frame_widget = client_->FrameWidget(); - if (!frame_widget) - return ui::TextInputType::TEXT_INPUT_TYPE_NONE; - return ConvertWebTextInputType(frame_widget->TextInputType()); + return ConvertWebTextInputType(client_->GetTextInputType()); } void WidgetBase::UpdateSelectionBounds() {
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 764df65..3304e881 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -6919,7 +6919,7 @@ crbug.com/1104381 fast/hidpi/image-srcset-change-resource-dpr.html [ Pass Failure ] # Temporarily disable tests to allow fixing of devtools path escaping -crbug.com/1094436 http/tests/devtools/overrides/project-added-with-existing-files-bind.js [ Pass Timeout ] +crbug.com/1094436 http/tests/devtools/overrides/project-added-with-existing-files-bind.js [ Pass Timeout Failure ] crbug.com/1094436 http/tests/devtools/persistence/automapping-urlencoded-paths.js [ Pass Failure ] crbug.com/1094436 http/tests/devtools/sources/debugger-ui/snippet-edit-breakpoint.js [ Pass Timeout ] crbug.com/1094436 http/tests/devtools/sources/debugger/navigator-view.js [ Pass Failure 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 363cf5a..5e65ea2 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
@@ -14734,7 +14734,7 @@ ] ], "floats-clear-multicol-balancing-000.html": [ - "a4f3379eca002adbe13b960198967425f7c13787", + "b034ceab493971d0bd37d4fc185c80677165019a", [ null, [ @@ -14747,7 +14747,7 @@ ] ], "floats-clear-multicol-balancing-001.html": [ - "9c8f8148d06727ebf1c166811ef4e2c373339a32", + "5944343c603363864d3509489903db530b1f3f9c", [ null, [ @@ -14760,7 +14760,7 @@ ] ], "floats-clear-multicol-balancing-002.html": [ - "e0343b0ce7a0f7030e2c3b1d9ae3d1056a9bebb3", + "99f86d1d455bb4527b390d7dbb2960198d27d098", [ null, [ @@ -14773,7 +14773,7 @@ ] ], "floats-clear-multicol-balancing-003.html": [ - "8b68f3ad4ebbf98a67875f4823e8c7a348a80421", + "4bc32d833da7c6e1c73e728490a2b4993b4dac95", [ null, [ @@ -73294,7 +73294,7 @@ ] ], "multicol-basic-001.html": [ - "e3da1a9fd7c1d46e23984cb6d704c79d899d3a7e", + "702cf549b1e572f4b6e17ba637603f5667d64b1c", [ null, [ @@ -73307,7 +73307,7 @@ ] ], "multicol-basic-002.html": [ - "f325b85ee1b33d86b7b1a1d2dac99c26b2b3cb05", + "50334e96d604092f43fa2583fac0cec7062cfda6", [ null, [ @@ -73320,7 +73320,7 @@ ] ], "multicol-basic-003.html": [ - "814d1e7cd82c54cbae47dbfcb13e105f40050f05", + "05cc1e0fe1f3259978c0eff8b55a349bab58e5ba", [ null, [ @@ -73333,7 +73333,7 @@ ] ], "multicol-basic-004.html": [ - "4d8082611936d5ebd70ce2692aff8cc1a9fafd10", + "a6699692612985852375d0201330f31b6c64e3b3", [ null, [ @@ -161982,7 +161982,7 @@ [] ], "floats-clear-multicol-balancing-000-ref.html": [ - "78b7ffaf2d1a6db9064d1968a47c65b1540e57b0", + "e3b700c5d783c1b7e3c0a21c84d681779058132b", [] ], "margin-collapse-024-ref.xht": [ @@ -179305,11 +179305,11 @@ [] ], "multicol-count-computed-003-ref.xht": [ - "60074ee46c61fc59247345639866f76185243fb0", + "a2182c59e9bed14940f6f6802400be9be311b892", [] ], "multicol-count-computed-004-ref.xht": [ - "def8e5083ab45f7223a287af52953789dad1413c", + "f9eaa671722aedd2898799db8a72358293967898", [] ], "multicol-dynamic-add-001-ref.html": [ @@ -179369,7 +179369,7 @@ [] ], "multicol-gap-large-001-ref.xht": [ - "162d875e76c5c17eaf60924b85ed9011246a6ca3", + "3802c3653b2dcfb9bc0d15f644d5eac0a0b247e6", [] ], "multicol-gap-large-002-ref.xht": [ @@ -179729,19 +179729,19 @@ [] ], "multicol-span-all-margin-001-ref.xht": [ - "6605ad8efb3ea3b3e5e6396dbbf31eb572613fef", + "30319f3554f7aae0b567f4676a47592eb65fc707", [] ], "multicol-span-all-margin-002-ref.xht": [ - "1538f14025a06e2434808d424e59e8004c0da443", + "48b80d12fbfd54208ccbf3f55402509b16982a0a", [] ], "multicol-span-all-margin-bottom-001-ref.xht": [ - "2152b5663724bd65393277d21f8f1caad3128c63", + "b3ec5201c139a26ab5d4db65d1e00313e202d12f", [] ], "multicol-span-all-margin-nested-001-ref.xht": [ - "dee66329f997bdf882bbb5ee40b5a76efd11877f", + "44f1198df8cdd467172975ba5cf6302313fe303c", [] ], "multicol-span-all-margin-nested-firstchild-ref.xht": [ @@ -179848,7 +179848,7 @@ [] ], "multicol-basic-ref.html": [ - "7d88977b059defbe00f1b7dbbb37b58f607cf28b", + "33b4469428a20d7e49bc3cfce803ad186af7097f", [] ], "multicol-clip-scrolled-content-001-ref.html": [ @@ -200554,19 +200554,19 @@ [] ], "request-init-stream.any-expected.txt": [ - "43ad8c18016b2d327428b0c344ea64496105fef0", + "099610119e527436264172c04d3462c0aa756a3b", [] ], "request-init-stream.any.serviceworker-expected.txt": [ - "43ad8c18016b2d327428b0c344ea64496105fef0", + "099610119e527436264172c04d3462c0aa756a3b", [] ], "request-init-stream.any.sharedworker-expected.txt": [ - "43ad8c18016b2d327428b0c344ea64496105fef0", + "099610119e527436264172c04d3462c0aa756a3b", [] ], "request-init-stream.any.worker-expected.txt": [ - "43ad8c18016b2d327428b0c344ea64496105fef0", + "099610119e527436264172c04d3462c0aa756a3b", [] ], "request-reset-attributes.https-expected.txt": [ @@ -200598,7 +200598,7 @@ [] ], "bad-chunk-encoding.py": [ - "23c7b3f47c4d11f51c5174b86541efc5988ba155", + "94a77adead858b48137e3988d0c674cd945a4270", [] ], "basic.html": [ @@ -200626,7 +200626,7 @@ [] ], "echo-content.py": [ - "9a038f329c87e4e9dab96caa8d6fda973880d732", + "5e137e15d7d3b0f684b7a1a2aa0b27a719730eb4", [] ], "empty.txt": [ @@ -200654,7 +200654,7 @@ [] ], "redirect-empty-location.py": [ - "2baabae03b0bf368bbcd9b26a01d22ecd8e86470", + "1a5f7feb2a4b329473d29d45c1b245c66258d8df", [] ], "redirect.py": [ @@ -200666,7 +200666,7 @@ [] ], "script-with-header.py": [ - "5337cc97bdd7737e40398cb066a98a5246ba4392", + "9a9c70ef5cf00d7f16963004e77ff135ed92afb4", [] ], "stash-put.py": [ @@ -200678,7 +200678,7 @@ [] ], "status.py": [ - "5d72e10b24bfd5a36d719940388bb55d44433546", + "05a59d5a637edde8fb049627fdce8a3a0e836716", [] ], "sw-intercept.js": [ @@ -200974,11 +200974,11 @@ [] ], "document-with-0x00-in-header.py": [ - "6e8db6195910ef4c85dced8b24541ecde83c5405", + "223b3c4027826f2bba1394db465c93ec7cbbe001", [] ], "script-with-0x00-in-header.py": [ - "f4a016a369831ee5dcdb3563468ccf8dd0b0982b", + "39f58d8270e7671bf74e40ac84e05a7558df4f68", [] ] } @@ -226681,6 +226681,14 @@ "fbc746a30b6dfa6d00fc2db747c78ec09a7beefc", [] ], + "idlharness.https.any-expected.txt": [ + "b19442ce9fefa877199b04b5ae0c03abc37358d1", + [] + ], + "idlharness.https.any.worker-expected.txt": [ + "c5b4984c269c0049c00b1b981b145ef3942a33c7", + [] + ], "persist-permission-manual.https-expected.txt": [ "3a7b64464fdcb74942be21a3c4b4264fd27dd9fa", [] @@ -242380,6 +242388,10 @@ "46523a905a9f70183d0a5e96cff2d76ad9e6d549", [] ], + "access-control-basic-cors-safelisted-response-headers.py": [ + "346b6b919656b23fb911587d447756711a59231e", + [] + ], "access-control-basic-denied.py": [ "0d3964cb1157f75bbc59d2fa75c16aa98951a591", [] @@ -242404,10 +242416,6 @@ "9b347bca4234e5dccbf5f71c3657b1a02d5c7ac6", [] ], - "access-control-basic-whitelist-response-headers.py": [ - "346b6b919656b23fb911587d447756711a59231e", - [] - ], "access-control-cookie.py": [ "8c26475c387a7de7458060f18adeab3b6429361a", [] @@ -242627,7 +242635,7 @@ [] ], "invalid-utf8-html.py": [ - "c15d17151a136974fa0838cc3b3311fde2a78fa4", + "1c0cd84f42ffb2261d70dbad034cd99eb9ba1b90", [] ], "last-modified.py": [ @@ -242689,7 +242697,7 @@ [] ], "shift-jis-html.py": [ - "47c67d8ae39e96bacd97d7cb14c59151060e2683", + "b3326c1ba7b3b2398fc1933ae4a49ad05a005b84", [] ], "status.py": [ @@ -242725,7 +242733,7 @@ [] ], "win-1252-xml.py": [ - "d88086e936ea17f75f30c18f4e9bd424ba609fff", + "50e9f04fb8dde0f20b07c5b0777caa005480be3a", [] ], "workerxhr-origin-referrer.js": [ @@ -321333,7 +321341,7 @@ ] ], "canvas-createImageBitmap-e_srgb.html": [ - "9cad95a87ba552bba2b055e97f048b3589f993a5", + "829e120df45fd43b7f34616ca1385d8dbee9ccf5", [ null, {} @@ -412148,7 +412156,7 @@ ] ], "access-control-basic-cors-safelisted-response-headers.htm": [ - "a5c470b74f51d6c577d335159427d3c804bce5ba", + "be9a10ef0163a928a5ad6144d9d979b270e2cf24", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-000-ref.html b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-000-ref.html index 78b7ffaf..e3b700c 100644 --- a/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-000-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-000-ref.html
@@ -20,7 +20,7 @@ height: 250px; } .clear { - border-bottom: solid orange; + border-bottom: 5px solid orange; background: red; } </style>
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-000.html b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-000.html index a4f3379e..b034cea 100644 --- a/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-000.html +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-000.html
@@ -32,7 +32,7 @@ } .clear { - border-bottom: solid orange; + border-bottom: 5px solid orange; } </style>
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-001.html b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-001.html index 9c8f814..5944343c 100644 --- a/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-001.html +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-001.html
@@ -31,7 +31,7 @@ } .clear { - border-bottom: solid orange; + border-bottom: 5px solid orange; background: red; } </style>
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-002.html b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-002.html index e0343b0..99f86d1 100644 --- a/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-002.html +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-002.html
@@ -33,7 +33,7 @@ .clear { clear: left; - border-bottom: solid orange; + border-bottom: 5px solid orange; background: red; } </style>
diff --git a/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-003.html b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-003.html index 8b68f3a..4bc32d83 100644 --- a/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-003.html +++ b/third_party/blink/web_tests/external/wpt/css/CSS2/floats-clear/floats-clear-multicol-balancing-003.html
@@ -42,7 +42,7 @@ background: red; } .bar { - border-bottom: orange solid; + border-bottom: 5px orange solid; } </style>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-001.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-001.html index e3da1a9f..702cf54 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-001.html
@@ -14,7 +14,7 @@ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> <style type="text/css"> .multicol-wrapper>*{ - font-family: Ahem; + font: 20px/1 Ahem; } div.multicol-wrapper{
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-002.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-002.html index f325b85..50334e9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-002.html
@@ -14,7 +14,7 @@ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> <style type="text/css"> .multicol-wrapper>*{ - font-family: Ahem; + font: 20px/1 Ahem; } div.multicol-wrapper{
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-003.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-003.html index 814d1e7..05cc1e0f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-003.html +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-003.html
@@ -14,7 +14,7 @@ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> <style type="text/css"> .multicol-wrapper>*{ - font-family: Ahem; + font: 20px/1 Ahem; } div.multicol-wrapper{
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-004.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-004.html index 4d808261..a669969 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-004.html +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-basic-004.html
@@ -14,7 +14,7 @@ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> <style type="text/css"> .multicol-wrapper>*{ - font-family: Ahem; + font: 20px/1 Ahem; } div.multicol-wrapper{
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-count-computed-003-ref.xht b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-count-computed-003-ref.xht index 60074ee4..a2182c5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-count-computed-003-ref.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-count-computed-003-ref.xht
@@ -4,9 +4,11 @@ <title>CSS Reftest Reference</title> <link rel="author" title="Opera Software ASA" href="http://www.opera.com/" /> <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!-- 2013-07-29 --> - <meta name="flags" content="image" /> + <meta name="flags" content="image ahem" /> + <link rel="stylesheet" href="/fonts/ahem.css" /> <style type="text/css"><![CDATA[ + body {font: 1.25em/1 Ahem;} img {vertical-align: top;} ]]></style> </head>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-count-computed-004-ref.xht b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-count-computed-004-ref.xht index def8e508..f9eaa67 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-count-computed-004-ref.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-count-computed-004-ref.xht
@@ -4,9 +4,11 @@ <title>CSS Reftest Reference</title> <link rel="author" title="Opera Software ASA" href="http://www.opera.com/" /> <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!-- 2013-07-29 --> - <meta name="flags" content="image" /> + <meta name="flags" content="image ahem" /> + <link rel="stylesheet" href="/fonts/ahem.css" /> <style type="text/css"><![CDATA[ + body {font: 1.25em/1 Ahem;} img {vertical-align: top;} ]]></style> </head> @@ -22,4 +24,4 @@ <div><img src="support/swatch-gray.png" width="280" height="20" alt="Image download support must be enabled" /></div> </body> -</html> \ No newline at end of file +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-gap-large-001-ref.xht b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-gap-large-001-ref.xht index 162d875..3802c365 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-gap-large-001-ref.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-gap-large-001-ref.xht
@@ -4,8 +4,10 @@ <title>CSS Reftest Reference</title> <link rel="author" title="Opera Software ASA" href="http://www.opera.com/" /> <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!-- 2013-08-06 --> - <meta name="flags" content="image" /> + <meta name="flags" content="image ahem" /> + <link rel="stylesheet" href="/fonts/ahem.css" /> <style type="text/css"><![CDATA[ + body {font: 1.25em/1 Ahem;} img {vertical-align: top;} ]]></style> </head> @@ -18,4 +20,4 @@ <div><img src="support/swatch-gray.png" width="260" height="20" alt="Image download support must be enabled" /></div> </body> -</html> \ No newline at end of file +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-001-ref.xht b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-001-ref.xht index 6605ad8..30319f3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-001-ref.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-001-ref.xht
@@ -4,11 +4,13 @@ <title>CSS Reftest Reference</title> <link rel="author" title="Opera Software ASA" href="http://www.opera.com/" /> <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!-- 2013-08-18 --> - <meta name="flags" content="image" /> + <meta name="flags" content="image ahem" /> + <link rel="stylesheet" href="/fonts/ahem.css" /> <style type="text/css"><![CDATA[ div { - border: gray solid 1.25em; + font: 1.25em/1 Ahem; + border: gray solid 1em; width: 160px; } @@ -20,4 +22,4 @@ <div><img src="support/swatch-blue.png" width="80" height="40" alt="Image download support must be enabled" /><img src="support/swatch-pink.png" width="80" height="40" alt="Image download support must be enabled" /> <img src="support/swatch-yellow.png" width="160" height="20" alt="Image download support must be enabled" /> <img src="support/black20x20.png" width="160" height="20" alt="Image download support must be enabled" /> <img src="support/swatch-yellow.png" width="160" height="20" alt="Image download support must be enabled" /> <img src="support/black20x20.png" width="160" height="20" alt="Image download support must be enabled" /> <img src="support/swatch-yellow.png" width="160" height="20" alt="Image download support must be enabled" /> <img src="support/swatch-navy.png" width="160" height="40" alt="Image download support must be enabled" /></div> </body> -</html> \ No newline at end of file +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-002-ref.xht b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-002-ref.xht index 1538f14..48b80d1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-002-ref.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-002-ref.xht
@@ -4,8 +4,11 @@ <title>CSS Reftest Reference</title> <link rel="author" title="Opera Software ASA" href="http://www.opera.com/" /> <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!-- 2013-08-19 --> - <meta name="flags" content="image" /> + <meta name="flags" content="image ahem" /> + <link rel="stylesheet" href="/fonts/ahem.css" /> <style type="text/css"><![CDATA[ + body {font: 1.25em/1 Ahem;} + div {width: 240px;} img {vertical-align: top;}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-bottom-001-ref.xht b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-bottom-001-ref.xht index 2152b56..b3ec520 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-bottom-001-ref.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-bottom-001-ref.xht
@@ -4,11 +4,13 @@ <title>CSS Reftest Reference</title> <link rel="author" title="Opera Software ASA" href="http://www.opera.com/" /> <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!-- 2013-08-19 --> - <meta name="flags" content="image" /> + <meta name="flags" content="image ahem" /> + <link rel="stylesheet" href="/fonts/ahem.css" /> <style type="text/css"><![CDATA[ div { - border: gray solid 1.25em; + font: 1.25em/1 Ahem; + border: gray solid 1em; width: 160px; }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-nested-001-ref.xht b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-nested-001-ref.xht index dee6632..44f1198 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-nested-001-ref.xht +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/multicol-span-all-margin-nested-001-ref.xht
@@ -4,11 +4,13 @@ <title>CSS Reftest Reference</title> <link rel="author" title="Opera Software ASA" href="http://www.opera.com/" /> <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!-- 2013-08-19 --> - <meta name="flags" content="image" /> + <meta name="flags" content="image ahem" /> + <link rel="stylesheet" href="/fonts/ahem.css" /> <style type="text/css"><![CDATA[ div { - border: gray solid 1.25em; + font: 1.25em/1 Ahem; + border: gray solid 1em; width: 160px; } @@ -28,4 +30,4 @@ </div> </body> -</html> \ No newline at end of file +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/reference/multicol-basic-ref.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/reference/multicol-basic-ref.html index 7d88977b0..33b4469 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-multicol/reference/multicol-basic-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/reference/multicol-basic-ref.html
@@ -10,7 +10,7 @@ <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> <style type="text/css"> .multicol-wrapper>*{ - font-family: Ahem; + font: 20px/1 Ahem; } div.multicol-wrapper{
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/resources/bad-chunk-encoding.py b/third_party/blink/web_tests/external/wpt/fetch/api/resources/bad-chunk-encoding.py index 23c7b3f..94a77ade 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/api/resources/bad-chunk-encoding.py +++ b/third_party/blink/web_tests/external/wpt/fetch/api/resources/bad-chunk-encoding.py
@@ -1,13 +1,13 @@ import time def main(request, response): - delay = float(request.GET.first("ms", 1000)) / 1E3 - count = int(request.GET.first("count", 50)) + delay = float(request.GET.first(b"ms", 1000)) / 1E3 + count = int(request.GET.first(b"count", 50)) time.sleep(delay) - response.headers.set("Transfer-Encoding", "chunked") + response.headers.set(b"Transfer-Encoding", b"chunked") response.write_status_headers() time.sleep(delay) - for i in xrange(count): - response.writer.write_content("a\r\nTEST_CHUNK\r\n") + for i in range(count): + response.writer.write_content(b"a\r\nTEST_CHUNK\r\n") time.sleep(delay) - response.writer.write_content("garbage") + response.writer.write_content(b"garbage")
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/resources/echo-content.py b/third_party/blink/web_tests/external/wpt/fetch/api/resources/echo-content.py index 9a038f3..5e137e1 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/api/resources/echo-content.py +++ b/third_party/blink/web_tests/external/wpt/fetch/api/resources/echo-content.py
@@ -1,10 +1,12 @@ +from wptserve.utils import isomorphic_encode + def main(request, response): - headers = [("X-Request-Method", request.method), - ("X-Request-Content-Length", request.headers.get("Content-Length", "NO")), - ("X-Request-Content-Type", request.headers.get("Content-Type", "NO")), + headers = [(b"X-Request-Method", isomorphic_encode(request.method)), + (b"X-Request-Content-Length", request.headers.get(b"Content-Length", b"NO")), + (b"X-Request-Content-Type", request.headers.get(b"Content-Type", b"NO")), # Avoid any kind of content sniffing on the response. - ("Content-Type", "text/plain")] + (b"Content-Type", b"text/plain")] content = request.body return headers, content
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/resources/redirect-empty-location.py b/third_party/blink/web_tests/external/wpt/fetch/api/resources/redirect-empty-location.py index 2baabae..1a5f7fe 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/api/resources/redirect-empty-location.py +++ b/third_party/blink/web_tests/external/wpt/fetch/api/resources/redirect-empty-location.py
@@ -1,3 +1,3 @@ def main(request, response): - headers = [("Location", "")] - return 302, headers, "" + headers = [(b"Location", b"")] + return 302, headers, b""
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/resources/script-with-header.py b/third_party/blink/web_tests/external/wpt/fetch/api/resources/script-with-header.py index 5337cc9..9a9c70ef 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/api/resources/script-with-header.py +++ b/third_party/blink/web_tests/external/wpt/fetch/api/resources/script-with-header.py
@@ -1,7 +1,7 @@ def main(request, response): - headers = [("Content-type", request.GET.first("mime"))] - if "content" in request.GET and request.GET.first("content") == "empty": - content = '' + headers = [(b"Content-type", request.GET.first(b"mime"))] + if b"content" in request.GET and request.GET.first(b"content") == b"empty": + content = b'' else: - content = "console.log('Script loaded')" + content = b"console.log('Script loaded')" return 200, headers, content
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/resources/status.py b/third_party/blink/web_tests/external/wpt/fetch/api/resources/status.py index 5d72e10..05a59d5 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/api/resources/status.py +++ b/third_party/blink/web_tests/external/wpt/fetch/api/resources/status.py
@@ -1,9 +1,11 @@ +from wptserve.utils import isomorphic_encode + def main(request, response): - code = int(request.GET.first("code", 200)) - text = request.GET.first("text", "OMG") - content = request.GET.first("content", "") - type = request.GET.first("type", "") + code = int(request.GET.first(b"code", 200)) + text = request.GET.first(b"text", b"OMG") + content = request.GET.first(b"content", b"") + type = request.GET.first(b"type", b"") status = (code, text) - headers = [("Content-Type", type), - ("X-Request-Method", request.method)] + headers = [(b"Content-Type", type), + (b"X-Request-Method", isomorphic_encode(request.method))] return status, headers, content
diff --git a/third_party/blink/web_tests/external/wpt/fetch/h1-parsing/resources/document-with-0x00-in-header.py b/third_party/blink/web_tests/external/wpt/fetch/h1-parsing/resources/document-with-0x00-in-header.py index 6e8db61..223b3c4 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/h1-parsing/resources/document-with-0x00-in-header.py +++ b/third_party/blink/web_tests/external/wpt/fetch/h1-parsing/resources/document-with-0x00-in-header.py
@@ -1,4 +1,4 @@ def main(request, response): - response.headers.set("Content-Type", "text/html") - response.headers.set("Custom", "\0") - return "<!doctype html><b>This is a document.</b>" + response.headers.set(b"Content-Type", b"text/html") + response.headers.set(b"Custom", b"\0") + return b"<!doctype html><b>This is a document.</b>"
diff --git a/third_party/blink/web_tests/external/wpt/fetch/h1-parsing/resources/script-with-0x00-in-header.py b/third_party/blink/web_tests/external/wpt/fetch/h1-parsing/resources/script-with-0x00-in-header.py index f4a016a3..39f58d8 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/h1-parsing/resources/script-with-0x00-in-header.py +++ b/third_party/blink/web_tests/external/wpt/fetch/h1-parsing/resources/script-with-0x00-in-header.py
@@ -1,4 +1,4 @@ def main(request, response): - response.headers.set("Content-Type", "text/javascript") - response.headers.set("Custom", "\0") - return "var thisIsJavaScript = 0" + response.headers.set(b"Content-Type", b"text/javascript") + response.headers.set(b"Custom", b"\0") + return b"var thisIsJavaScript = 0"
diff --git a/third_party/blink/web_tests/external/wpt/native-io/rename_async_failure_handling.tentative.https.any.js b/third_party/blink/web_tests/external/wpt/native-io/rename_async_failure_handling.tentative.https.any.js index 5e0f964..64ea24f 100644 --- a/third_party/blink/web_tests/external/wpt/native-io/rename_async_failure_handling.tentative.https.any.js +++ b/third_party/blink/web_tests/external/wpt/native-io/rename_async_failure_handling.tentative.https.any.js
@@ -93,8 +93,8 @@ closed_file.close(); const opened_file = await nativeIO.open('opened_file'); testCase.add_cleanup(async () => { - closed_file.close(); - opened_file.close(); + await closed_file.close(); + await opened_file.close(); await nativeIO.delete('closed_file'); await nativeIO.delete('opened_file'); });
diff --git a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-02.svg b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-02.svg index 4cf93da..9420503d 100644 --- a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-02.svg +++ b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-02.svg
@@ -1,13 +1,12 @@ <svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml"> <title>SVGGeometryElement.prototype.getPointAtLength() query with 'pathLength'</title> <h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getPointAtLength"/> + <path id='pathElement' d='M0,0L100,0L100,100' pathLength="1000"/> <h:script src="/resources/testharness.js"/> <h:script src="/resources/testharnessreport.js"/> <script> test(function() { - let path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - path.setAttribute('d', 'M0,0L100,0L100,100'); - path.setAttribute('pathLength', '1000'); + let path = document.getElementById('pathElement'); var point = path.getPointAtLength(50); assert_approx_equals(point.x, 50, 1e-5);
diff --git a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-03.svg b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-03.svg new file mode 100644 index 0000000..61737efb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-03.svg
@@ -0,0 +1,30 @@ +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:html="http://www.w3.org/1999/xhtml"> + <title>When SVGGeometryElement.getPointAtLength is called with an element that is not in the document, throw exception</title> + <html:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getPointAtLength"/> + <html:script src="/resources/testharness.js"/> + <html:script src="/resources/testharnessreport.js"/> + <script><![CDATA[ + test(function() { + var pathElement = document.createElementNS("http://www.w3.org/2000/svg", "path"); + pathElement.setAttribute("d", 'M0,20 L400,20 L640,20'); + assert_throws_dom("InvalidStateError", function() { pathElement.getPointAtLength(700) }); + }, document.title + " with SVGPathElement"); + + test(function() { + var rectElement = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + rectElement.setAttribute("rx", 0); + rectElement.setAttribute("ry", 0); + rectElement.setAttribute("width", 200); + rectElement.setAttribute("height", 300); + assert_throws_dom("InvalidStateError", function() { rectElement.getPointAtLength(300); }); + }, document.title + " with SVGRectElement"); + + test(function() { + var circleElement = document.createElementNS("http://www.w3.org/2000/svg", "circle"); + circleElement.setAttribute("r", 10); + assert_throws_dom("InvalidStateError", function() { circleElement.getPointAtLength(100); }); + }, document.title + " with SVGCircleElement"); + ]]></script> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-04.svg b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-04.svg new file mode 100644 index 0000000..f0a1363 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-04.svg
@@ -0,0 +1,79 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml"> + <title>SVGGeometryElement.getPointAtLength: 'display' and a valid path</title> + <h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getPointAtLength"/> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <path id='pathElement1' d='M0,0L100,0L100,100' description='path with display: defualt'/> + <path id='pathElement2' style='display:none' d='M0,0L100,0L100,100' description='path with display: none'/> + <rect id='rectElement1' x='0' y='0' width='50' height='50' description='rect with display: default'/> + <rect id='rectElement2' style='display:none' x='0' y='0' width='50' height='50' description='rect with display: none'/> + <circle id='circleElement1' cx='0' cy='0' r='50' description='circle with display: defualt'/> + <circle id='circleElement2' style='display:none' cx='0' cy='0' r='50' description='circle with display: none'/> + <polygon id='polygonElement1' points="0,0 50,0 50,50 0,50" description='polygon with display: default'/> + <polygon id='polygonElement2' style='display:none' points="0,0 50,0 50,50 0,50" description='polygon with display: none'/> + <polyline id='polylineElement1' points="0,0 50,0 50,50 0,50" description='polyline with display: default'/> + <polyline id='polylineElement2' style='display:none' points="0,0 50,0 50,50 0,50" description='polyline with display: none'/> + <ellipse id='ellipseElement1' cx='0' cy='0' rx='50' ry='50' description='ellipse with display: default'/> + <ellipse id='ellipseElement2' style='display:none' cx='0' cy='0' rx='50' ry='50' description='ellipse with display: none'/> + <script> +['pathElement1', 'pathElement2'].forEach(elementId => { + test(function() { + let element = document.getElementById(elementId); + var point = element.getPointAtLength(50); + assert_approx_equals(point.x, 50, 1e-5); + assert_approx_equals(point.y, 0, 1e-5); + }, document.title + ', ' + + document.getElementById(elementId).getAttribute('description')); +}); + +['rectElement1', 'rectElement2'].forEach(elementId => { + test(function() { + let element = document.getElementById(elementId); + var point = element.getPointAtLength(50); + assert_approx_equals(point.x, 50, 1e-5); + assert_approx_equals(point.y, 0, 1e-5); + }, document.title + ', ' + + document.getElementById(elementId).getAttribute('description')); +}); + +['circleElement1', 'circleElement2'].forEach(elementId => { + test(function() { + let element = document.getElementById(elementId); + var point = element.getPointAtLength(0); + assert_approx_equals(point.x, 50, 1e-5); + assert_approx_equals(point.y, 0, 1e-5); + }, document.title + ', ' + + document.getElementById(elementId).getAttribute('description')); +}); + +['polygonElement1', 'polygonElement2'].forEach(elementId => { + test(function() { + let element = document.getElementById(elementId); + var point = element.getPointAtLength(50); + assert_approx_equals(point.x, 50, 1e-5); + assert_approx_equals(point.y, 0, 1e-5); + }, document.title + ', ' + + document.getElementById(elementId).getAttribute('description')); +}); + +['polylineElement1', 'polylineElement2'].forEach(elementId => { + test(function() { + let element = document.getElementById(elementId); + var point = element.getPointAtLength(50); + assert_approx_equals(point.x, 50, 1e-5); + assert_approx_equals(point.y, 0, 1e-5); + }, document.title + ', ' + + document.getElementById(elementId).getAttribute('description')); +}); + +['ellipseElement1', 'ellipseElement2'].forEach(elementId => { + test(function() { + let element = document.getElementById(elementId); + var point = element.getPointAtLength(0); + assert_approx_equals(point.x, 50, 1e-5); + assert_approx_equals(point.y, 0, 1e-5); + }, document.title + ', ' + + document.getElementById(elementId).getAttribute('description')); +}); + </script> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-05.svg b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-05.svg new file mode 100644 index 0000000..50a7137 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.getPointAtLength-05.svg
@@ -0,0 +1,67 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml"> + <title>SVGGeometryElement.getPointAtLength: 'display' and empty path</title> + <h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#__svg__SVGGeometryElement__getPointAtLength"/> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <path id='pathElement1' description='path with display: defualt and an empty path'/> + <path id='pathElement2' style='display:none' description='path with display: none and an empty path'/> + <rect id='rectElement1' description='rect with display: defualt and an empty path'/> + <rect id='rectElement2' style='display:none' description='rect with display: none and an empty path'/> + <circle id='circleElement1' description='circle with display: default and an empty path'/> + <circle id='circleElement2' style='display:none' description='circle with display: none and an empty path'/> + <polygon id='polygonElement1' description='polygon with display: defualt and an empty path'/> + <polygon id='polygonElement2' style='display:none' description='polygon with display: none and an empty path'/> + <polyline id='polylineElement1' description='polyline with display: default and an empty path'/> + <polyline id='polylineElement2' style='display:none' description='polyline with display: none and an empty path'/> + <ellipse id='ellipseElement1' description='ellipse with display: default and an empty path'/> + <ellipse id='ellipseElement2' style='display:none' description='ellipse with display: none and an empty path'/> + <script> +['pathElement1', 'pathElement2'].forEach(elementId => { + test(function() { + let element = document.getElementById(elementId); + assert_throws_dom("InvalidStateError", function() { element.getPointAtLength(300); }); + }, document.title + ', ' + + document.getElementById(elementId).getAttribute('description')); +}); + +['rectElement1', 'rectElement2'].forEach(elementId => { + test(function() { + let element = document.getElementById(elementId); + assert_throws_dom("InvalidStateError", function() { element.getPointAtLength(300); }); + }, document.title + ', ' + + document.getElementById(elementId).getAttribute('description')); +}); + +['circleElement1', 'circleElement2'].forEach(elementId => { + test(function() { + let element = document.getElementById(elementId); + assert_throws_dom("InvalidStateError", function() { element.getPointAtLength(300); }); + }, document.title + ', ' + + document.getElementById(elementId).getAttribute('description')); +}); + +['polygonElement1', 'polygonElement2'].forEach(elementId => { + test(function() { + let element = document.getElementById(elementId); + assert_throws_dom("InvalidStateError", function() { element.getPointAtLength(300); }); + }, document.title + ', ' + + document.getElementById(elementId).getAttribute('description')); +}); + +['polylineElement1', 'polylineElement2'].forEach(elementId => { + test(function() { + let element = document.getElementById(elementId); + assert_throws_dom("InvalidStateError", function() { element.getPointAtLength(300); }); + }, document.title + ', ' + + document.getElementById(elementId).getAttribute('description')); +}); + +['ellipseElement1', 'ellipseElement2'].forEach(elementId => { + test(function() { + let element = document.getElementById(elementId); + assert_throws_dom("InvalidStateError", function() { element.getPointAtLength(300); }); + }, document.title + ', ' + + document.getElementById(elementId).getAttribute('description')); +}); + </script> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/xhr/access-control-basic-cors-safelisted-response-headers.htm b/third_party/blink/web_tests/external/wpt/xhr/access-control-basic-cors-safelisted-response-headers.htm index a5c470b..be9a10e 100644 --- a/third_party/blink/web_tests/external/wpt/xhr/access-control-basic-cors-safelisted-response-headers.htm +++ b/third_party/blink/web_tests/external/wpt/xhr/access-control-basic-cors-safelisted-response-headers.htm
@@ -12,7 +12,7 @@ const xhr = new XMLHttpRequest; xhr.open("GET", get_host_info().HTTP_REMOTE_ORIGIN + - "/xhr/resources/access-control-basic-whitelist-response-headers.py", false); + "/xhr/resources/access-control-basic-cors-safelisted-response-headers.py", false); xhr.send(); assert_not_equals(xhr.getResponseHeader("cache-control"), null);
diff --git a/third_party/blink/web_tests/external/wpt/xhr/resources/access-control-basic-whitelist-response-headers.py b/third_party/blink/web_tests/external/wpt/xhr/resources/access-control-basic-cors-safelisted-response-headers.py similarity index 100% rename from third_party/blink/web_tests/external/wpt/xhr/resources/access-control-basic-whitelist-response-headers.py rename to third_party/blink/web_tests/external/wpt/xhr/resources/access-control-basic-cors-safelisted-response-headers.py
diff --git a/third_party/blink/web_tests/external/wpt/xhr/resources/invalid-utf8-html.py b/third_party/blink/web_tests/external/wpt/xhr/resources/invalid-utf8-html.py index c15d171..1c0cd84 100644 --- a/third_party/blink/web_tests/external/wpt/xhr/resources/invalid-utf8-html.py +++ b/third_party/blink/web_tests/external/wpt/xhr/resources/invalid-utf8-html.py
@@ -1,5 +1,7 @@ +from six import int2byte + def main(request, response): headers = [(b"Content-type", b"text/html;charset=utf-8")] - content = chr(0xff) + content = int2byte(0xff) return headers, content
diff --git a/third_party/blink/web_tests/external/wpt/xhr/resources/shift-jis-html.py b/third_party/blink/web_tests/external/wpt/xhr/resources/shift-jis-html.py index 47c67d8..b3326c1 100644 --- a/third_party/blink/web_tests/external/wpt/xhr/resources/shift-jis-html.py +++ b/third_party/blink/web_tests/external/wpt/xhr/resources/shift-jis-html.py
@@ -1,6 +1,8 @@ +from six import int2byte + def main(request, response): headers = [(b"Content-type", b"text/html;charset=shift-jis")] # Shift-JIS bytes for katakana TE SU TO ('test') - content = chr(0x83) + chr(0x65) + chr(0x83) + chr(0x58) + chr(0x83) + chr(0x67) + content = int2byte(0x83) + int2byte(0x65) + int2byte(0x83) + int2byte(0x58) + int2byte(0x83) + int2byte(0x67) return headers, content
diff --git a/third_party/blink/web_tests/external/wpt/xhr/resources/win-1252-xml.py b/third_party/blink/web_tests/external/wpt/xhr/resources/win-1252-xml.py index d88086e..50e9f04f 100644 --- a/third_party/blink/web_tests/external/wpt/xhr/resources/win-1252-xml.py +++ b/third_party/blink/web_tests/external/wpt/xhr/resources/win-1252-xml.py
@@ -1,5 +1,7 @@ +from six import int2byte + def main(request, response): headers = [(b"Content-type", b"application/xml;charset=windows-1252")] - content = '<' + chr(0xff) + '/>' + content = b'<' + int2byte(0xff) + b'/>' return headers, content
diff --git a/third_party/blink/web_tests/http/tests/cachestorage/padding.html b/third_party/blink/web_tests/http/tests/cachestorage/padding.html index 49c9a08..1e50d195 100644 --- a/third_party/blink/web_tests/http/tests/cachestorage/padding.html +++ b/third_party/blink/web_tests/http/tests/cachestorage/padding.html
@@ -6,9 +6,20 @@ <script> 'use strict'; -async function usage_for_credentials(cache, url, mode) { - const r = await fetch(url, { mode: 'no-cors', credentials: mode }); +async function usage(cache, url, init, clone) { + const i = { mode: 'no-cors' }; + let r = await fetch(url, { + mode: 'no-cors', + credentials: init.credentials, + method: init.method, + }); assert_equals('opaque', r.type); + if (clone) + r = r.clone(); + // Note, this stores the response under a Request key that has different + // attributes than what we fetched above. This is purposeful to ensure + // that we are varying on how the Response was loaded and not on the Request + // key. await cache.put(url, r); return (await navigator.storage.estimate()).usage; } @@ -18,12 +29,12 @@ const url = 'http://localhost:8000/cachestorage/resources/simple.txt'; // Get the reported disk usage for an opaque response without credentials. - const usage1 = await usage_for_credentials(cache, url, 'omit'); - const usage2 = await usage_for_credentials(cache, url, 'same-origin'); + const usage1 = await usage(cache, url, { credentials: 'omit' }); + const usage2 = await usage(cache, url, { credentials: 'same-origin' }); // Get the reported disk usage for an opaque response with the same URL, // but also with credentials enabled. - const usage3 = await usage_for_credentials(cache, url, 'include'); + const usage3 = await usage(cache, url, { credentials: 'include' }); assert_equals(usage1, usage2, "Credentials mode 'omit' and 'same-origin' should have the " + @@ -33,4 +44,54 @@ "padding size."); }, 'Cache padding varies based on if Response was loaded with credentials.'); +promise_test(async t => { + const cache = await caches.open('padding'); + const url = 'http://localhost:8000/cachestorage/resources/simple.txt'; + + const usage1 = await usage(cache, url, { method: 'GET' }); + const usage1b = await usage(cache, url, { method: 'GET' }); + assert_equals(usage1, usage1b, + "Usage should be same if the request does not vary."); + + const usage2 = await usage(cache, url, { method: 'HEAD' }); + const usage2b = await usage(cache, url, { method: 'HEAD' }); + assert_equals(usage2, usage2b, + "Usage should be same if the request does not vary."); + + const usage3 = await usage(cache, url, { method: 'POST' }); + const usage3b = await usage(cache, url, { method: 'POST' }); + assert_equals(usage3, usage3b, + "Usage should be same if the request does not vary."); + + // It should only be possible to create opaque responses with CORS + // safelisted methods. + await promise_rejects_js(t, TypeError, usage(cache, url, { method: 'OPTIONS' })); + await promise_rejects_js(t, TypeError, usage(cache, url, { method: 'CONNECT' })); + await promise_rejects_js(t, TypeError, usage(cache, url, { method: 'TRACE' })); + await promise_rejects_js(t, TypeError, usage(cache, url, { method: 'TRACK' })); + await promise_rejects_js(t, TypeError, usage(cache, url, { method: 'PUT' })); + await promise_rejects_js(t, TypeError, usage(cache, url, { method: 'PATCH' })); + await promise_rejects_js(t, TypeError, usage(cache, url, { method: 'FOO' })); + + assert_not_equals(usage1, usage2, + "Methods 'GET' and 'HEAD' should result in different " + + "padding sizes."); + assert_not_equals(usage1, usage3, + "Methods 'GET' and 'POST' should result in different " + + "padding sizes."); + assert_not_equals(usage2, usage3, + "Methods 'HEAD' and 'POST' should result in different " + + "padding sizes."); +}, 'Cache padding varies based on Response original request method.'); + +promise_test(async t => { + const cache = await caches.open('padding'); + const url = 'http://localhost:8000/cachestorage/resources/simple.txt'; + const init = { method: 'GET', credentials: 'include' }; + + const usage1 = await usage(cache, url, init, /* clone=*/ false); + const usage2 = await usage(cache, url, init, /* clone=*/ true); + assert_equals(usage1, usage2, "Usage should not vary based on cloning."); +}, 'Cache padding does not change when cloned.'); + </script>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/content-security-policy-issue-with-src-location.html b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/content-security-policy-issue-with-src-location.html index 39c0dff..735c7b3e 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/content-security-policy-issue-with-src-location.html +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/content-security-policy-issue-with-src-location.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<meta http-equiv="Content-Security-Policy" content="style-src 'https://thirdparty.test/network/resources/';"> +<meta http-equiv="Content-Security-Policy" content="style-src https://thirdparty.test/network/resources/;"> <link rel="stylesheet" type="text/css" href="style.css">
diff --git a/third_party/blink/web_tests/media/controls-strict.html b/third_party/blink/web_tests/media/controls-strict.html index 9db9a26..a553a62 100644 --- a/third_party/blink/web_tests/media/controls-strict.html +++ b/third_party/blink/web_tests/media/controls-strict.html
@@ -1,26 +1,16 @@ <!DOCTYPE HTML> <html> <head> - <script src="../resources/run-after-layout-and-paint.js"></script> + <script src="media-file.js"></script> + <script src="video-paint-test.js"></script> <script src="media-controls.js"></script> </head> - <body> + <body onload="setSrcByTagName('video', 'content/test.ogv'); init()"> <p>Drawing the controls in strict mode.</p> - <video controls src='content/test.ogv'></video> + <video controls></video> </body> <script> const video = document.querySelector('video'); enableTestMode(video); - - if (window.testRunner) { - testRunner.waitUntilDone(); - - video.addEventListener('loadedmetadata', () => { - runAfterLayoutAndPaint(() => { - if (window.testRunner) - testRunner.notifyDone(); - }); - }, { once: true }); - } </script> </html>
diff --git a/third_party/blink/web_tests/svg/dom/SVGGeometryElement-getPointAtLength-detached.html b/third_party/blink/web_tests/svg/dom/SVGGeometryElement-getPointAtLength-detached.html deleted file mode 100644 index 85fbe3a5..0000000 --- a/third_party/blink/web_tests/svg/dom/SVGGeometryElement-getPointAtLength-detached.html +++ /dev/null
@@ -1,52 +0,0 @@ -<!DOCTYPE html> -<title>SVGGeometryElement.getPointAtLength method (element detached)</title> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<script> -test(function() { - var pathElement = document.createElementNS("http://www.w3.org/2000/svg", "path"); - - function pointAtLength(string) { - pathElement.setAttribute("d", string); - - var point = pathElement.getPointAtLength(700); - return [Math.round(point.x), Math.round(point.y)]; - } - - assert_array_equals(pointAtLength('M0,20 L400,20 L640,20'), [640, 20]); - assert_array_equals(pointAtLength('M0,20 L400,20 L640,20 z'), [580, 20]); - assert_array_equals(pointAtLength('M0,20 L400,20 z M 320,20 L640,20'), [100, 20]); - assert_array_equals(pointAtLength('M0,20 L20,40'), [20, 40]); -}, document.title + " with SVGPathElement"); - -test(function() { - var rectElement = document.createElementNS("http://www.w3.org/2000/svg", "rect"); - - function pointAtLength(rx, ry, width, height) { - rectElement.setAttribute("rx", rx); - rectElement.setAttribute("ry", ry); - rectElement.setAttribute("width", width); - rectElement.setAttribute("height", height); - - var point = rectElement.getPointAtLength(300); - return [Math.round(point.x), Math.round(point.y)]; - } - - assert_array_equals(pointAtLength(0, 0, 200, 300), [0, 0]); - assert_array_equals(pointAtLength(50, 50, 200, 300), [0, 0]); -}, document.title + " with SVGRectElement"); - -test(function() { - var circleElement = document.createElementNS("http://www.w3.org/2000/svg", "circle"); - - function pointAtLength(radius) { - circleElement.setAttribute("r", radius); - - var point = circleElement.getPointAtLength(100); - return [Math.round(point.x), Math.round(point.y)]; - } - - assert_array_equals(pointAtLength(10), [0, 0]); - assert_array_equals(pointAtLength(100), [0, 0]); -}, document.title + " with SVGCircleElement"); -</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/svg/dom/SVGPolygonElement-baseVal-list-removal-crash.html b/third_party/blink/web_tests/svg/dom/SVGPolygonElement-baseVal-list-removal-crash.html index e88e80cd..14fd21b1 100644 --- a/third_party/blink/web_tests/svg/dom/SVGPolygonElement-baseVal-list-removal-crash.html +++ b/third_party/blink/web_tests/svg/dom/SVGPolygonElement-baseVal-list-removal-crash.html
@@ -6,8 +6,8 @@ function go() { var oSVGPolygon = document.createElementNS("http://www.w3.org/2000/svg", "polygon"); - var oSVGPath = document.createElementNS("http://www.w3.org/2000/svg", "path"); - var oSVGPoint1 = oSVGPath.getPointAtLength(0.0); + var svgRoot = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + var oSVGPoint1 = svgRoot.createSVGPoint(); oSVGPolygon.points.initialize(oSVGPoint1); oSVGPolygon.points.removeItem(-9223372036854775802); alert("Accessing old oSVGPoint1.x: " + oSVGPoint1.x);
diff --git a/tools/android/asan/third_party/README.chromium b/tools/android/asan/third_party/README.chromium index c35bff0..45d6e0d 100644 --- a/tools/android/asan/third_party/README.chromium +++ b/tools/android/asan/third_party/README.chromium
@@ -5,3 +5,6 @@ Security Critical: no asan_device_setup.sh is a verbatim copy of asan_device_setup in the LLVM trunk. + +Local Modifications: + * Patched in https://reviews.llvm.org/D84237
diff --git a/tools/android/asan/third_party/asan_device_setup.sh b/tools/android/asan/third_party/asan_device_setup.sh index 041bf92..27fedea 100755 --- a/tools/android/asan/third_party/asan_device_setup.sh +++ b/tools/android/asan/third_party/asan_device_setup.sh
@@ -330,7 +330,7 @@ ASAN_OPTIONS=$ASAN_OPTIONS \\ ASAN_ACTIVATION_OPTIONS=include_if_exists=/data/local/tmp/asan.options.%b \\ LD_PRELOAD=$_ld_preload \\ -exec $_to \$@ +exec $_to "\$@" EOF }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 2150cc5..5e315b8 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -28367,7 +28367,7 @@ <int value="3210" label="LegacyLayoutByFlexBox"/> <int value="3211" label="LegacyLayoutByFrameSet"/> <int value="3212" label="LegacyLayoutByGrid"/> - <int value="3213" label="LegacyLayoutByMenuList"/> + <int value="3213" label="OBSOLETE_LegacyLayoutByMenuList"/> <int value="3214" label="LegacyLayoutByMultiCol"/> <int value="3215" label="LegacyLayoutByPrinting"/> <int value="3216" label="LegacyLayoutByRuby"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index dacab0d..0616c4f0 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -103959,7 +103959,7 @@ </histogram> <histogram name="Net.WebSocket.CloseCode" enum="WebSocketCloseCode" - expires_after="M86"> + expires_after="2020-12-01"> <owner>ricea@chromium.org</owner> <owner>yhirano@chromium.org</owner> <owner>yoichio@chromium.org</owner> @@ -125861,9 +125861,9 @@ </histogram> <histogram name="PasswordManager.OsPasswordStatus" - enum="PasswordManagerOsPasswordStatus" expires_after="M83"> - <owner>battre@chromium.org</owner> - <owner>wfh@chromium.org</owner> + enum="PasswordManagerOsPasswordStatus" expires_after="2020-12-12"> + <owner>vasilii@chromium.org</owner> + <owner>jdoerrie@chromium.org</owner> <summary> Indicates whether the user's OS password is blank or not at browser startup. </summary> @@ -151426,7 +151426,7 @@ </histogram> <histogram name="Scheduler.CancelableTaskTracker.TaskDuration2" units="ms" - expires_after="2020-08-01"> + expires_after="2020-12-01"> <!-- Name completed by histogram_suffixes name="CancelableTaskTrackerDurationTypes" --> <owner>wez@chromium.org</owner> @@ -151438,7 +151438,7 @@ </histogram> <histogram name="Scheduler.CancelableTaskTracker.TaskStatus" - enum="CancelableTaskStatus" expires_after="2020-08-01"> + enum="CancelableTaskStatus" expires_after="2020-12-01"> <owner>wez@chromium.org</owner> <owner>scheduler-dev@chromium.org</owner> <summary>
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc index 71cc205..c9fdf449 100644 --- a/ui/accessibility/ax_enum_util.cc +++ b/ui/accessibility/ax_enum_util.cc
@@ -2349,35 +2349,35 @@ return ax::mojom::TextAlign::kNone; } -const char* ToString(ax::mojom::TextDirection text_direction) { +const char* ToString(ax::mojom::WritingDirection text_direction) { switch (text_direction) { - case ax::mojom::TextDirection::kNone: + case ax::mojom::WritingDirection::kNone: return "none"; - case ax::mojom::TextDirection::kLtr: + case ax::mojom::WritingDirection::kLtr: return "ltr"; - case ax::mojom::TextDirection::kRtl: + case ax::mojom::WritingDirection::kRtl: return "rtl"; - case ax::mojom::TextDirection::kTtb: + case ax::mojom::WritingDirection::kTtb: return "ttb"; - case ax::mojom::TextDirection::kBtt: + case ax::mojom::WritingDirection::kBtt: return "btt"; } return ""; } -ax::mojom::TextDirection ParseTextDirection(const char* text_direction) { +ax::mojom::WritingDirection ParseTextDirection(const char* text_direction) { if (0 == strcmp(text_direction, "none")) - return ax::mojom::TextDirection::kNone; + return ax::mojom::WritingDirection::kNone; if (0 == strcmp(text_direction, "ltr")) - return ax::mojom::TextDirection::kLtr; + return ax::mojom::WritingDirection::kLtr; if (0 == strcmp(text_direction, "rtl")) - return ax::mojom::TextDirection::kRtl; + return ax::mojom::WritingDirection::kRtl; if (0 == strcmp(text_direction, "ttb")) - return ax::mojom::TextDirection::kTtb; + return ax::mojom::WritingDirection::kTtb; if (0 == strcmp(text_direction, "btt")) - return ax::mojom::TextDirection::kBtt; - return ax::mojom::TextDirection::kNone; + return ax::mojom::WritingDirection::kBtt; + return ax::mojom::WritingDirection::kNone; } const char* ToString(ax::mojom::TextPosition text_position) {
diff --git a/ui/accessibility/ax_enum_util.h b/ui/accessibility/ax_enum_util.h index 7ed3e88..154a26e8 100644 --- a/ui/accessibility/ax_enum_util.h +++ b/ui/accessibility/ax_enum_util.h
@@ -113,9 +113,9 @@ AX_BASE_EXPORT const char* ToString(ax::mojom::TextAlign text_align); AX_BASE_EXPORT ax::mojom::TextAlign ParseTextAlign(const char* text_align); -// ax::mojom::TextDirection -AX_BASE_EXPORT const char* ToString(ax::mojom::TextDirection text_direction); -AX_BASE_EXPORT ax::mojom::TextDirection ParseTextDirection( +// ax::mojom::WritingDirection +AX_BASE_EXPORT const char* ToString(ax::mojom::WritingDirection text_direction); +AX_BASE_EXPORT ax::mojom::WritingDirection ParseTextDirection( const char* text_direction); // ax::mojom::TextPosition
diff --git a/ui/accessibility/ax_enum_util_unittest.cc b/ui/accessibility/ax_enum_util_unittest.cc index d0cca6b..b0b0c7d 100644 --- a/ui/accessibility/ax_enum_util_unittest.cc +++ b/ui/accessibility/ax_enum_util_unittest.cc
@@ -173,7 +173,7 @@ } TEST(AXEnumUtilTest, TextDirection) { - TestEnumStringConversion<ax::mojom::TextDirection>(ParseTextDirection); + TestEnumStringConversion<ax::mojom::WritingDirection>(ParseTextDirection); } TEST(AXEnumUtilTest, TextPosition) {
diff --git a/ui/accessibility/ax_enums.mojom b/ui/accessibility/ax_enums.mojom index 2b34744..82370df 100644 --- a/ui/accessibility/ax_enums.mojom +++ b/ui/accessibility/ax_enums.mojom
@@ -906,7 +906,7 @@ kJustify, }; -enum TextDirection { +enum WritingDirection { kNone, kLtr, kRtl,
diff --git a/ui/accessibility/ax_event_generator_unittest.cc b/ui/accessibility/ax_event_generator_unittest.cc index 9387a99..ad755374 100644 --- a/ui/accessibility/ax_event_generator_unittest.cc +++ b/ui/accessibility/ax_event_generator_unittest.cc
@@ -728,7 +728,7 @@ update.nodes[2].AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor, 0); update.nodes[3].AddIntAttribute( ax::mojom::IntAttribute::kTextDirection, - static_cast<int32_t>(ax::mojom::TextDirection::kRtl)); + static_cast<int32_t>(ax::mojom::WritingDirection::kRtl)); update.nodes[4].AddIntAttribute( ax::mojom::IntAttribute::kTextPosition, static_cast<int32_t>(ax::mojom::TextPosition::kSuperscript));
diff --git a/ui/accessibility/ax_node_data.cc b/ui/accessibility/ax_node_data.cc index a39643db..444960b 100644 --- a/ui/accessibility/ax_node_data.cc +++ b/ui/accessibility/ax_node_data.cc
@@ -904,15 +904,15 @@ static_cast<int32_t>(text_align)); } -ax::mojom::TextDirection AXNodeData::GetTextDirection() const { - return static_cast<ax::mojom::TextDirection>( +ax::mojom::WritingDirection AXNodeData::GetTextDirection() const { + return static_cast<ax::mojom::WritingDirection>( GetIntAttribute(ax::mojom::IntAttribute::kTextDirection)); } -void AXNodeData::SetTextDirection(ax::mojom::TextDirection text_direction) { +void AXNodeData::SetTextDirection(ax::mojom::WritingDirection text_direction) { if (HasIntAttribute(ax::mojom::IntAttribute::kTextDirection)) RemoveIntAttribute(ax::mojom::IntAttribute::kTextDirection); - if (text_direction != ax::mojom::TextDirection::kNone) { + if (text_direction != ax::mojom::WritingDirection::kNone) { AddIntAttribute(ax::mojom::IntAttribute::kTextDirection, static_cast<int32_t>(text_direction)); } @@ -1260,17 +1260,18 @@ static_cast<ax::mojom::TextAlign>(int_attribute.second)); break; case ax::mojom::IntAttribute::kTextDirection: - switch (static_cast<ax::mojom::TextDirection>(int_attribute.second)) { - case ax::mojom::TextDirection::kLtr: + switch ( + static_cast<ax::mojom::WritingDirection>(int_attribute.second)) { + case ax::mojom::WritingDirection::kLtr: result += " text_direction=ltr"; break; - case ax::mojom::TextDirection::kRtl: + case ax::mojom::WritingDirection::kRtl: result += " text_direction=rtl"; break; - case ax::mojom::TextDirection::kTtb: + case ax::mojom::WritingDirection::kTtb: result += " text_direction=ttb"; break; - case ax::mojom::TextDirection::kBtt: + case ax::mojom::WritingDirection::kBtt: result += " text_direction=btt"; break; default:
diff --git a/ui/accessibility/ax_node_data.h b/ui/accessibility/ax_node_data.h index 9f70e4a..a531f40 100644 --- a/ui/accessibility/ax_node_data.h +++ b/ui/accessibility/ax_node_data.h
@@ -196,8 +196,8 @@ void SetListStyle(ax::mojom::ListStyle list_style); ax::mojom::TextAlign GetTextAlign() const; void SetTextAlign(ax::mojom::TextAlign text_align); - ax::mojom::TextDirection GetTextDirection() const; - void SetTextDirection(ax::mojom::TextDirection text_direction); + ax::mojom::WritingDirection GetTextDirection() const; + void SetTextDirection(ax::mojom::WritingDirection text_direction); ax::mojom::ImageAnnotationStatus GetImageAnnotationStatus() const; void SetImageAnnotationStatus(ax::mojom::ImageAnnotationStatus status);
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc index 4f4614f..1be154f 100644 --- a/ui/accessibility/platform/ax_platform_node_base.cc +++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -2082,21 +2082,21 @@ attributes.push_back(std::make_pair("language", language)); } - auto text_direction = static_cast<ax::mojom::TextDirection>( + auto text_direction = static_cast<ax::mojom::WritingDirection>( GetIntAttribute(ax::mojom::IntAttribute::kTextDirection)); switch (text_direction) { - case ax::mojom::TextDirection::kNone: + case ax::mojom::WritingDirection::kNone: break; - case ax::mojom::TextDirection::kLtr: + case ax::mojom::WritingDirection::kLtr: attributes.push_back(std::make_pair("writing-mode", "lr")); break; - case ax::mojom::TextDirection::kRtl: + case ax::mojom::WritingDirection::kRtl: attributes.push_back(std::make_pair("writing-mode", "rl")); break; - case ax::mojom::TextDirection::kTtb: + case ax::mojom::WritingDirection::kTtb: attributes.push_back(std::make_pair("writing-mode", "tb")); break; - case ax::mojom::TextDirection::kBtt: + case ax::mojom::WritingDirection::kBtt: // Not listed in the IA2 Spec. attributes.push_back(std::make_pair("writing-mode", "bt")); break;
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc index 6e744360..e1925cff6 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc
@@ -3616,7 +3616,7 @@ 0xDEADBEEFU); text_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU); text_data.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "fr-CA"); - text_data.SetTextDirection(ax::mojom::TextDirection::kRtl); + text_data.SetTextDirection(ax::mojom::WritingDirection::kRtl); text_data.AddTextStyle(ax::mojom::TextStyle::kItalic); text_data.SetTextPosition(ax::mojom::TextPosition::kSubscript); text_data.SetRestriction(ax::mojom::Restriction::kReadOnly); @@ -3637,7 +3637,7 @@ heading_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor, 0xDEADBEEFU); heading_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU); - heading_data.SetTextDirection(ax::mojom::TextDirection::kRtl); + heading_data.SetTextDirection(ax::mojom::WritingDirection::kRtl); heading_data.SetTextPosition(ax::mojom::TextPosition::kSuperscript); heading_data.AddState(ax::mojom::State::kEditable); heading_data.child_ids = {4}; @@ -3650,7 +3650,7 @@ 0xDEADBEEFU); heading_text_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU); - heading_text_data.SetTextDirection(ax::mojom::TextDirection::kRtl); + heading_text_data.SetTextDirection(ax::mojom::WritingDirection::kRtl); heading_text_data.SetTextPosition(ax::mojom::TextPosition::kSuperscript); heading_text_data.AddState(ax::mojom::State::kEditable); heading_text_data.SetTextAlign(ax::mojom::TextAlign::kJustify); @@ -3669,7 +3669,7 @@ mark_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor, 0xDEADBEEFU); mark_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU); - mark_data.SetTextDirection(ax::mojom::TextDirection::kRtl); + mark_data.SetTextDirection(ax::mojom::WritingDirection::kRtl); mark_data.child_ids = {6}; ui::AXNodeData mark_text_data; @@ -3678,7 +3678,7 @@ mark_text_data.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor, 0xDEADBEEFU); mark_text_data.AddIntAttribute(ax::mojom::IntAttribute::kColor, 0xDEADC0DEU); - mark_text_data.SetTextDirection(ax::mojom::TextDirection::kRtl); + mark_text_data.SetTextDirection(ax::mojom::WritingDirection::kRtl); mark_text_data.SetTextAlign(ax::mojom::TextAlign::kNone); mark_text_data.SetName("marked text");
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index 369c61a..06fc94c7 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -4879,17 +4879,17 @@ // static FlowDirections AXPlatformNodeWin::TextDirectionToFlowDirections( - ax::mojom::TextDirection text_direction) { + ax::mojom::WritingDirection text_direction) { switch (text_direction) { - case ax::mojom::TextDirection::kNone: + case ax::mojom::WritingDirection::kNone: return FlowDirections::FlowDirections_Default; - case ax::mojom::TextDirection::kLtr: + case ax::mojom::WritingDirection::kLtr: return FlowDirections::FlowDirections_Default; - case ax::mojom::TextDirection::kRtl: + case ax::mojom::WritingDirection::kRtl: return FlowDirections::FlowDirections_RightToLeft; - case ax::mojom::TextDirection::kTtb: + case ax::mojom::WritingDirection::kTtb: return FlowDirections::FlowDirections_Vertical; - case ax::mojom::TextDirection::kBtt: + case ax::mojom::WritingDirection::kBtt: return FlowDirections::FlowDirections_BottomToTop; } }
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h index 682149b..ef1959b 100644 --- a/ui/accessibility/platform/ax_platform_node_win.h +++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -1374,7 +1374,8 @@ // Converts a ListStyle to UIA StyleId enumeration static LONG AXListStyleToUIAStyleId(ax::mojom::ListStyle list_style); // Convert mojom TextDirection to UIA FlowDirections enumeration - static FlowDirections TextDirectionToFlowDirections(ax::mojom::TextDirection); + static FlowDirections TextDirectionToFlowDirections( + ax::mojom::WritingDirection); // Helper method for |GetMarkerTypeFromRange| which aggregates all // of the ranges for |marker_type| attached to |node|.
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc index 873ab5c..45d3274a 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.cc +++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -966,11 +966,11 @@ gfx::RectF location = GetLocation(); gfx::RectF bounds; - switch (static_cast<ax::mojom::TextDirection>( + switch (static_cast<ax::mojom::WritingDirection>( GetData().GetIntAttribute(ax::mojom::IntAttribute::kTextDirection))) { // Currently only kNone and kLtr are supported text direction. - case ax::mojom::TextDirection::kNone: - case ax::mojom::TextDirection::kLtr: { + case ax::mojom::WritingDirection::kNone: + case ax::mojom::WritingDirection::kLtr: { int start_pixel_offset = start_offset > 0 ? character_offsets[start_offset - 1] : location.x(); int end_pixel_offset =
diff --git a/ui/accessibility/test_ax_node_helper.cc b/ui/accessibility/test_ax_node_helper.cc index ba257f7..a2cfcf0 100644 --- a/ui/accessibility/test_ax_node_helper.cc +++ b/ui/accessibility/test_ax_node_helper.cc
@@ -158,11 +158,11 @@ gfx::RectF location = GetLocation(); gfx::RectF bounds; - switch (static_cast<ax::mojom::TextDirection>( + switch (static_cast<ax::mojom::WritingDirection>( GetData().GetIntAttribute(ax::mojom::IntAttribute::kTextDirection))) { // Currently only kNone and kLtr are supported text direction. - case ax::mojom::TextDirection::kNone: - case ax::mojom::TextDirection::kLtr: { + case ax::mojom::WritingDirection::kNone: + case ax::mojom::WritingDirection::kLtr: { int start_pixel_offset = start_offset > 0 ? character_offsets[start_offset - 1] : location.x(); int end_pixel_offset =
diff --git a/ui/base/clipboard/clipboard_non_backed.cc b/ui/base/clipboard/clipboard_non_backed.cc index f2a1922..29c632b3 100644 --- a/ui/base/clipboard/clipboard_non_backed.cc +++ b/ui/base/clipboard/clipboard_non_backed.cc
@@ -33,14 +33,8 @@ namespace ui { -namespace { - -const size_t kMaxClipboardSize = 1; - -} // namespace - // Simple, internal implementation of a clipboard, handling things like format -// conversion, versioning, etc. +// conversion, sequence numbers, etc. class ClipboardInternal { public: ClipboardInternal() = default; @@ -48,41 +42,35 @@ ~ClipboardInternal() = default; void Clear() { - sequence_number_++; - data_list_.clear(); + ++sequence_number_; + data_.reset(); ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged(); } uint64_t sequence_number() const { return sequence_number_; } - // Returns the data currently on the top of the clipboard stack, nullptr if - // the clipboard stack is empty. - const ClipboardData* GetData() const { - if (data_list_.empty()) - return nullptr; - return data_list_.front().get(); - } + // Returns the current clipboard data, which may be nullptr if nothing has + // been written since the last Clear(). + const ClipboardData* GetData() const { return data_.get(); } // Returns true if the data on top of the clipboard stack has format |format| // or another format that can be converted to |format|. bool IsFormatAvailable(ClipboardInternalFormat format) const { - switch (format) { - case ClipboardInternalFormat::kText: - return HasFormat(ClipboardInternalFormat::kText) || - HasFormat(ClipboardInternalFormat::kBookmark); - default: - return HasFormat(format); + if (format == ClipboardInternalFormat::kText) { + return HasFormat(ClipboardInternalFormat::kText) || + HasFormat(ClipboardInternalFormat::kBookmark); } + return HasFormat(format); } - // Reads text from the data at the top of clipboard stack. + // Reads text from the ClipboardData. void ReadText(base::string16* result) const { std::string utf8_result; ReadAsciiText(&utf8_result); *result = base::UTF8ToUTF16(utf8_result); } - // Reads ASCII text from the data at the top of clipboard stack. + // Reads ASCII text from the ClipboardData. void ReadAsciiText(std::string* result) const { result->clear(); const ClipboardData* data = GetData(); @@ -96,7 +84,7 @@ *result = data->bookmark_url(); } - // Reads HTML from the data at the top of clipboard stack. + // Reads HTML from the ClipboardData. void ReadHTML(base::string16* markup, std::string* src_url, uint32_t* fragment_start, @@ -119,7 +107,7 @@ *fragment_end = static_cast<uint32_t>(markup->length()); } - // Reads RTF from the data at the top of clipboard stack. + // Reads RTF from the ClipboardData. void ReadRTF(std::string* result) const { result->clear(); const ClipboardData* data = GetData(); @@ -129,7 +117,7 @@ *result = data->rtf_data(); } - // Reads image from the data at the top of clipboard stack. + // Reads image from the ClipboardData. SkBitmap ReadImage() const { SkBitmap img; if (!HasFormat(ClipboardInternalFormat::kBitmap)) @@ -144,7 +132,7 @@ return img; } - // Reads data of type |type| from the data at the top of clipboard stack. + // Reads data of type |type| from the ClipboardData. void ReadCustomData(const base::string16& type, base::string16* result) const { result->clear(); @@ -156,7 +144,7 @@ data->custom_data_data().size(), type, result); } - // Reads bookmark from the data at the top of clipboard stack. + // Reads bookmark from the ClipboardData. void ReadBookmark(base::string16* title, std::string* url) const { if (title) title->clear(); @@ -182,10 +170,11 @@ *result = data->custom_data_data(); } - // Writes |data| to the top of the clipboard stack. + // Writes |data| to the ClipboardData. void WriteData(std::unique_ptr<ClipboardData> data) { DCHECK(data); - AddToListEnsuringSize(std::move(data)); + ++sequence_number_; + data_ = std::move(data); ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged(); } @@ -201,26 +190,14 @@ } private: - // True if the data on top of the clipboard stack has format |format|. + // True if the ClipboardData has format |format|. bool HasFormat(ClipboardInternalFormat format) const { const ClipboardData* data = GetData(); return data ? data->format() & static_cast<int>(format) : false; } - void AddToListEnsuringSize(std::unique_ptr<ClipboardData> data) { - DCHECK(data); - sequence_number_++; - data_list_.push_front(std::move(data)); - - // If the size of list becomes more than the maximum allowed, we delete the - // last element. - if (data_list_.size() > kMaxClipboardSize) { - data_list_.pop_back(); - } - } - - // Stack containing various versions of ClipboardData. - std::list<std::unique_ptr<ClipboardData>> data_list_; + // Current ClipboardData. + std::unique_ptr<ClipboardData> data_; // Sequence number uniquely identifying clipboard state. uint64_t sequence_number_ = 0;
diff --git a/ui/latency/latency_info.dot b/ui/latency/latency_info.dot index 3490ac1..887d4e9 100644 --- a/ui/latency/latency_info.dot +++ b/ui/latency/latency_info.dot
@@ -8,8 +8,6 @@ node[style="dotted,rounded"]; "Event.Latency.EventToRender.TouchpadPinch"; - "Event.Latency.QueueingTime.<event_name><default_action_status>"; - "Event.Latency.BlockingTime.<event_name><default_action_status>"; end_to_end_metrics [label="\ Event.Latency.EndToEnd.KeyPress\n\ @@ -56,11 +54,7 @@ // Layout the rest of the components. INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT-> "Event.Latency.EventToRender.TouchpadPinch"-> - INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT-> - "Event.Latency.QueueingTime.<event_name><default_action_status>"-> - INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT-> - "Event.Latency.BlockingTime.<event_name><default_action_status>"-> - INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT + INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT [weight=3]; INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT-> @@ -94,7 +88,7 @@ "Event.Latency.<scroll_name>.Touch.RAFTimeToFrameSwapEnd"-> INPUT_EVENT_LATENCY_FRAME_SWAP_COMPONENT; - // Add legend and position it under INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT. + // Add legend and position it under INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT. legend [shape=plaintext,label="\ LEGEND:\l\ @@ -102,7 +96,7 @@ <input_modality> = (Wheel | Touch)\l\ <scroll_name> = (ScrollBegin | ScrollUpdate)\l\ <thread_name> = (Main | Impl)\l"]; - INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT-> + INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT-> legend - [style=invis,minlen=3]; + [style=invis,minlen=7]; }
diff --git a/ui/ozone/platform/wayland/common/wayland_util.cc b/ui/ozone/platform/wayland/common/wayland_util.cc index 14593b1..19d33ef4 100644 --- a/ui/ozone/platform/wayland/common/wayland_util.cc +++ b/ui/ozone/platform/wayland/common/wayland_util.cc
@@ -10,6 +10,8 @@ #include "ui/base/hit_test.h" #include "ui/ozone/platform/wayland/host/wayland_connection.h" #include "ui/ozone/platform/wayland/host/wayland_shm_buffer.h" +#include "ui/ozone/platform/wayland/host/wayland_surface.h" +#include "ui/ozone/platform/wayland/host/wayland_window.h" namespace wl { @@ -160,4 +162,14 @@ type == ui::PlatformWindowType::kPopup; } +ui::WaylandWindow* RootWindowFromWlSurface(wl_surface* surface) { + if (!surface) + return nullptr; + auto* wayland_surface = static_cast<ui::WaylandSurface*>( + wl_proxy_get_user_data(reinterpret_cast<wl_proxy*>(surface))); + if (!wayland_surface) + return nullptr; + return wayland_surface->root_window(); +} + } // namespace wl
diff --git a/ui/ozone/platform/wayland/common/wayland_util.h b/ui/ozone/platform/wayland/common/wayland_util.h index 3db3696..918f4c6 100644 --- a/ui/ozone/platform/wayland/common/wayland_util.h +++ b/ui/ozone/platform/wayland/common/wayland_util.h
@@ -22,6 +22,7 @@ namespace ui { class WaylandConnection; class WaylandShmBuffer; +class WaylandWindow; } // namespace ui namespace gfx { @@ -62,6 +63,9 @@ // Says if the type is kPopup or kMenu. bool IsMenuType(ui::PlatformWindowType type); +// Returns the root WaylandWindow for the given wl_surface. +ui::WaylandWindow* RootWindowFromWlSurface(wl_surface* surface); + } // namespace wl #endif // UI_OZONE_PLATFORM_WAYLAND_COMMON_WAYLAND_UTIL_H_
diff --git a/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc b/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc index 02ec5b80..e5cdaf1 100644 --- a/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc +++ b/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc
@@ -21,8 +21,8 @@ std::unique_ptr<wl_egl_window, EGLWindowDeleter> CreateWaylandEglWindow( WaylandWindow* window) { gfx::Size size = window->GetBounds().size(); - return std::unique_ptr<wl_egl_window, EGLWindowDeleter>( - wl_egl_window_create(window->surface(), size.width(), size.height())); + return std::unique_ptr<wl_egl_window, EGLWindowDeleter>(wl_egl_window_create( + window->root_surface()->surface(), size.width(), size.height())); } GLSurfaceWayland::GLSurfaceWayland(WaylandEglWindowPtr egl_window)
diff --git a/ui/ozone/platform/wayland/host/wayland_auxiliary_window.cc b/ui/ozone/platform/wayland/host/wayland_auxiliary_window.cc index 0a1d243..9575fe7 100644 --- a/ui/ozone/platform/wayland/host/wayland_auxiliary_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_auxiliary_window.cc
@@ -68,7 +68,7 @@ GetBounds(), parent_window()->GetBounds(), ui_scale(), buffer_scale()); wl_subsurface_set_position(subsurface_.get(), bounds_px.x() / buffer_scale(), bounds_px.y() / buffer_scale()); - wl_surface_commit(surface()); + root_surface()->Commit(); connection()->ScheduleFlush(); } @@ -97,10 +97,7 @@ if (!parent) return; - wl_subcompositor* subcompositor = connection()->subcompositor(); - DCHECK(subcompositor); - subsurface_.reset(wl_subcompositor_get_subsurface(subcompositor, surface(), - parent->surface())); + subsurface_ = root_surface()->CreateSubsurface(parent->root_surface()); // Chromium positions tooltip windows in screen coordinates, but Wayland // requires them to be in local surface coordinates a.k.a relative to parent @@ -113,7 +110,7 @@ wl_subsurface_set_position(subsurface_.get(), bounds_px.x() / buffer_scale(), bounds_px.y() / buffer_scale()); wl_subsurface_set_desync(subsurface_.get()); - wl_surface_commit(parent->surface()); + parent->root_surface()->Commit(); connection()->ScheduleFlush(); // Notify the observers the window has been configured. Please note that
diff --git a/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc b/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc index 6e2f2d7..4e6dd950d 100644 --- a/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc +++ b/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
@@ -153,8 +153,8 @@ if (!wayland_surface_) return; - wl_surface_attach(wayland_surface_->surface(), nullptr, 0, 0); - wl_surface_commit(wayland_surface_->surface()); + wayland_surface_->AttachBuffer(nullptr); + wayland_surface_->Commit(); // ResetSurfaceContents happens upon WaylandWindow::Hide call, which // destroys xdg_surface, xdg_popup, etc. They are going to be reinitialized @@ -251,48 +251,17 @@ pending_damage_region.set_size(buffer->size); DCHECK(!pending_damage_region.size().IsEmpty()); - if (connection_->compositor_version() >= - WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION) { - // wl_surface_damage_buffer relies on compositor API version 4. See - // https://bit.ly/2u00lv6 for details. - // We don't need to apply any scaling because pending_damage_region is - // already in buffer coordinates. - wl_surface_damage_buffer( - wayland_surface_->surface(), pending_damage_region.x(), - pending_damage_region.y(), pending_damage_region.width(), - pending_damage_region.height()); - } else { - // The calculation for damage region relies on two assumptions: - // 1) The buffer is always attached at surface location (0, 0) - // 2) The API wl_surface::set_buffer_transform is not used. - // It's possible to write logic that accounts for both cases above, but - // it's currently unnecessary. - // - // Note: The damage region may not be an integer multiple of scale. To - // keep the implementation simple, the x() and y() coordinates round down, - // and the width() and height() calculations always add an extra pixel. - int scale = wayland_surface_->buffer_scale(); - wl_surface_damage(wayland_surface_->surface(), - pending_damage_region.x() / scale, - pending_damage_region.y() / scale, - pending_damage_region.width() / scale + 1, - pending_damage_region.height() / scale + 1); - } + wayland_surface_->Damage(pending_damage_region); } void AttachBuffer(WaylandBuffer* buffer) { DCHECK(wayland_surface_ && configured_); - - // The logic in DamageBuffer currently relies on attachment coordinates of - // (0, 0). If this changes, then the calculation in DamageBuffer will also - // need to be updated. - wl_surface_attach(wayland_surface_->surface(), buffer->wl_buffer.get(), 0, - 0); + wayland_surface_->AttachBuffer(buffer->wl_buffer.get()); } void CommitSurface() { DCHECK(wayland_surface_); - wl_surface_commit(wayland_surface_->surface()); + wayland_surface_->Commit(); } void SetupFrameCallback() { @@ -569,8 +538,8 @@ // Widget this helper surface backs and has 1:1 relationship with the // WaylandWindow. - // Non-owned. The window this helper surface stores and submits buffers for. - const WaylandSurface* wayland_surface_; + // Non-owned. The surface this helper stores and submits buffers for. + WaylandSurface* wayland_surface_; // Non-owned pointer to the connection. WaylandConnection* const connection_; @@ -624,7 +593,7 @@ void WaylandBufferManagerHost::OnWindowAdded(WaylandWindow* window) { DCHECK(window); surfaces_[window->GetWidget()] = - std::make_unique<Surface>(window->wayland_surface(), connection_, this); + std::make_unique<Surface>(window->root_surface(), connection_, this); } void WaylandBufferManagerHost::OnWindowRemoved(WaylandWindow* window) {
diff --git a/ui/ozone/platform/wayland/host/wayland_data_device.cc b/ui/ozone/platform/wayland/host/wayland_data_device.cc index edbb6d472..932b1e4 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_device.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_device.cc
@@ -43,8 +43,8 @@ drag_delegate_ = delegate; wl_data_device_start_drag(data_device_.get(), data_source.data_source(), - origin_window.surface(), icon_surface, - connection()->serial()); + origin_window.root_surface()->surface(), + icon_surface, connection()->serial()); drag_delegate_->DrawIcon(); connection()->ScheduleFlush(); } @@ -109,7 +109,7 @@ wl_fixed_t x, wl_fixed_t y, wl_data_offer* offer) { - WaylandWindow* window = WaylandWindow::FromSurface(surface); + WaylandWindow* window = wl::RootWindowFromWlSurface(surface); if (!window) { LOG(ERROR) << "Failed to get window."; return;
diff --git a/ui/ozone/platform/wayland/host/wayland_keyboard.cc b/ui/ozone/platform/wayland/host/wayland_keyboard.cc index 7de0fe69..a4c905b 100644 --- a/ui/ozone/platform/wayland/host/wayland_keyboard.cc +++ b/ui/ozone/platform/wayland/host/wayland_keyboard.cc
@@ -20,6 +20,7 @@ #include "ui/events/ozone/layout/keyboard_layout_engine.h" #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" #include "ui/events/types/event_type.h" +#include "ui/ozone/platform/wayland/common/wayland_util.h" #include "ui/ozone/platform/wayland/host/wayland_connection.h" #include "ui/ozone/platform/wayland/host/wayland_window.h" @@ -101,7 +102,7 @@ wl_surface* surface, wl_array* keys) { // wl_surface might have been destroyed by this time. - if (auto* window = WaylandWindow::FromSurface(surface)) { + if (auto* window = wl::RootWindowFromWlSurface(surface)) { auto* self = static_cast<WaylandKeyboard*>(data); self->delegate_->OnKeyboardFocusChanged(window, /*focused=*/true); } @@ -113,7 +114,7 @@ wl_surface* surface) { // wl_surface might have been destroyed by this time. auto* self = static_cast<WaylandKeyboard*>(data); - if (auto* window = WaylandWindow::FromSurface(surface)) + if (auto* window = wl::RootWindowFromWlSurface(surface)) self->delegate_->OnKeyboardFocusChanged(window, /*focused=*/false); // Upon window focus lose, reset the key repeat timers.
diff --git a/ui/ozone/platform/wayland/host/wayland_pointer.cc b/ui/ozone/platform/wayland/host/wayland_pointer.cc index 1658a68c..13cb8c0 100644 --- a/ui/ozone/platform/wayland/host/wayland_pointer.cc +++ b/ui/ozone/platform/wayland/host/wayland_pointer.cc
@@ -10,6 +10,7 @@ #include "ui/events/event.h" #include "ui/events/types/event_type.h" +#include "ui/ozone/platform/wayland/common/wayland_util.h" #include "ui/ozone/platform/wayland/host/wayland_connection.h" #include "ui/ozone/platform/wayland/host/wayland_window.h" @@ -45,7 +46,7 @@ wl_fixed_t surface_y) { DCHECK(data); WaylandPointer* pointer = static_cast<WaylandPointer*>(data); - WaylandWindow* window = WaylandWindow::FromSurface(surface); + WaylandWindow* window = wl::RootWindowFromWlSurface(surface); gfx::PointF location{wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)}; pointer->delegate_->OnPointerFocusChanged(window, location);
diff --git a/ui/ozone/platform/wayland/host/wayland_popup.cc b/ui/ozone/platform/wayland/host/wayland_popup.cc index ba52979..1fda80c5 100644 --- a/ui/ozone/platform/wayland/host/wayland_popup.cc +++ b/ui/ozone/platform/wayland/host/wayland_popup.cc
@@ -75,7 +75,7 @@ DCHECK(shell_popup()); DCHECK(parent_window()); - SetBufferScale(parent_window()->buffer_scale(), true); + root_surface()->SetBufferScale(parent_window()->buffer_scale(), true); gfx::Rect new_bounds_dip = bounds_dip; @@ -138,7 +138,7 @@ return false; } // If parent window is known in advanced, we may set the scale early. - SetBufferScale(parent_window()->buffer_scale(), false); + root_surface()->SetBufferScale(parent_window()->buffer_scale(), false); set_ui_scale(parent_window()->ui_scale()); return true; }
diff --git a/ui/ozone/platform/wayland/host/wayland_surface.cc b/ui/ozone/platform/wayland/host/wayland_surface.cc index 3cb2df6..f612f168 100644 --- a/ui/ozone/platform/wayland/host/wayland_surface.cc +++ b/ui/ozone/platform/wayland/host/wayland_surface.cc
@@ -11,9 +11,16 @@ WaylandSurface::WaylandSurface(WaylandConnection* connection, WaylandWindow* root_window) - : root_window_(root_window), surface_(connection->CreateSurface()) {} + : connection_(connection), + root_window_(root_window), + surface_(connection->CreateSurface()) {} -WaylandSurface::~WaylandSurface() = default; +WaylandSurface::~WaylandSurface() { + if (surface_) { + wl_surface_add_listener(surface_.get(), nullptr, nullptr); + wl_surface_set_user_data(surface_.get(), nullptr); + } +} gfx::AcceleratedWidget WaylandSurface::GetWidget() const { if (!surface_) @@ -25,4 +32,111 @@ return root_window_->GetWidget(); } +bool WaylandSurface::Initialize() { + if (!surface_) + return false; + + wl_surface_set_user_data(surface_.get(), this); + + static struct wl_surface_listener surface_listener = { + &WaylandSurface::Enter, + &WaylandSurface::Leave, + }; + wl_surface_add_listener(surface_.get(), &surface_listener, this); + + return true; +} + +void WaylandSurface::AttachBuffer(wl_buffer* buffer) { + // The logic in DamageBuffer currently relies on attachment coordinates of + // (0, 0). If this changes, then the calculation in DamageBuffer will also + // need to be updated. + wl_surface_attach(surface_.get(), buffer, 0, 0); + connection_->ScheduleFlush(); +} + +void WaylandSurface::Damage(const gfx::Rect& pending_damage_region) { + if (connection_->compositor_version() >= + WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION) { + // wl_surface_damage_buffer relies on compositor API version 4. See + // https://bit.ly/2u00lv6 for details. + // We don't need to apply any scaling because pending_damage_region is + // already in buffer coordinates. + wl_surface_damage_buffer( + surface_.get(), pending_damage_region.x(), pending_damage_region.y(), + pending_damage_region.width(), pending_damage_region.height()); + } else { + // The calculation for damage region relies on two assumptions: + // 1) The buffer is always attached at surface location (0, 0) + // 2) The API wl_surface::set_buffer_transform is not used. + // It's possible to write logic that accounts for both cases above, but + // it's currently unnecessary. + // + // Note: The damage region may not be an integer multiple of scale. To + // keep the implementation simple, the x() and y() coordinates round down, + // and the width() and height() calculations always add an extra pixel. + wl_surface_damage(surface_.get(), pending_damage_region.x() / buffer_scale_, + pending_damage_region.y() / buffer_scale_, + pending_damage_region.width() / buffer_scale_ + 1, + pending_damage_region.height() / buffer_scale_ + 1); + } + connection_->ScheduleFlush(); +} + +void WaylandSurface::Commit() { + wl_surface_commit(surface_.get()); + connection_->ScheduleFlush(); +} + +void WaylandSurface::SetBufferScale(int32_t new_scale, bool update_bounds) { + DCHECK_GT(new_scale, 0); + + if (new_scale == buffer_scale_) + return; + + buffer_scale_ = new_scale; + wl_surface_set_buffer_scale(surface_.get(), buffer_scale_); + connection_->ScheduleFlush(); +} + +void WaylandSurface::SetBounds(const gfx::Rect& bounds_px) { + // It's important to set opaque region for opaque windows (provides + // optimization hint for the Wayland compositor). + if (!root_window_->IsOpaqueWindow()) + return; + + wl::Object<wl_region> region( + wl_compositor_create_region(connection_->compositor())); + wl_region_add(region.get(), 0, 0, bounds_px.width(), bounds_px.height()); + + wl_surface_set_opaque_region(surface_.get(), region.get()); + + connection_->ScheduleFlush(); +} + +wl::Object<wl_subsurface> WaylandSurface::CreateSubsurface( + WaylandSurface* parent) { + DCHECK(parent); + wl_subcompositor* subcompositor = connection_->subcompositor(); + DCHECK(subcompositor); + wl::Object<wl_subsurface> subsurface(wl_subcompositor_get_subsurface( + subcompositor, surface_.get(), parent->surface_.get())); + return subsurface; +} + +// static +void WaylandSurface::Enter(void* data, + struct wl_surface* wl_surface, + struct wl_output* output) { + static_cast<WaylandSurface*>(data)->root_window_->AddEnteredOutputId(output); +} + +// static +void WaylandSurface::Leave(void* data, + struct wl_surface* wl_surface, + struct wl_output* output) { + static_cast<WaylandSurface*>(data)->root_window_->RemoveEnteredOutputId( + output); +} + } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_surface.h b/ui/ozone/platform/wayland/host/wayland_surface.h index cfe616f..046af093 100644 --- a/ui/ozone/platform/wayland/host/wayland_surface.h +++ b/ui/ozone/platform/wayland/host/wayland_surface.h
@@ -7,6 +7,7 @@ #include <cstdint> +#include "ui/gfx/geometry/rect.h" #include "ui/gfx/native_widget_types.h" #include "ui/ozone/platform/wayland/common/wayland_object.h" @@ -34,13 +35,47 @@ gfx::AcceleratedWidget GetWidget() const; gfx::AcceleratedWidget GetRootWidget() const; + // Initializes the WaylandSurface and returns true iff success. + // This may return false if a wl_surface could not be created, for example. + bool Initialize(); + + // Attaches the given wl_buffer to the underlying wl_surface at (0, 0). + void AttachBuffer(wl_buffer* buffer); + + // Damages the surface according to |pending_damage_region|, which should be + // in surface coordinates (dp). + void Damage(const gfx::Rect& pending_damage_region); + + // Commits the underlying wl_surface. + void Commit(); + + // Sets the buffer scale for this surface. + void SetBufferScale(int32_t scale, bool update_bounds); + + // Sets the bounds on this surface. This is used for determining the opaque + // region. + void SetBounds(const gfx::Rect& bounds_px); + + // Creates a wl_subsurface relating this surface and a parent surface, + // |parent|. Callers take ownership of the wl_subsurface. + wl::Object<wl_subsurface> CreateSubsurface(WaylandSurface* parent); + private: + WaylandConnection* const connection_; WaylandWindow* root_window_ = nullptr; wl::Object<wl_surface> surface_; // Wayland's scale factor for the output that this window currently belongs // to. int32_t buffer_scale_ = 1; + + // wl_surface_listener + static void Enter(void* data, + struct wl_surface* wl_surface, + struct wl_output* output); + static void Leave(void* data, + struct wl_surface* wl_surface, + struct wl_output* output); }; } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_touch.cc b/ui/ozone/platform/wayland/host/wayland_touch.cc index aff5c24..9298a43d 100644 --- a/ui/ozone/platform/wayland/host/wayland_touch.cc +++ b/ui/ozone/platform/wayland/host/wayland_touch.cc
@@ -8,6 +8,7 @@ #include "base/time/time.h" #include "ui/gfx/geometry/point_f.h" +#include "ui/ozone/platform/wayland/common/wayland_util.h" #include "ui/ozone/platform/wayland/host/wayland_connection.h" #include "ui/ozone/platform/wayland/host/wayland_window.h" @@ -47,7 +48,7 @@ DCHECK(touch); touch->connection_->set_serial(serial); - WaylandWindow* window = WaylandWindow::FromSurface(surface); + WaylandWindow* window = wl::RootWindowFromWlSurface(surface); gfx::PointF location(wl_fixed_to_double(x), wl_fixed_to_double(y)); base::TimeTicks timestamp = base::TimeTicks() + base::TimeDelta::FromMilliseconds(time);
diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc index 378eb32..1e22574 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_window.cc
@@ -30,24 +30,15 @@ WaylandWindow::~WaylandWindow() { shutting_down_ = true; - RemoveSurfaceListener(); PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); - if (wayland_surface_) + if (root_surface_) connection_->wayland_window_manager()->RemoveWindow(GetWidget()); if (parent_window_) parent_window_->set_child_window(nullptr); } -// static -WaylandWindow* WaylandWindow::FromSurface(wl_surface* surface) { - if (!surface) - return nullptr; - return static_cast<WaylandWindow*>( - wl_proxy_get_user_data(reinterpret_cast<wl_proxy*>(surface))); -} - void WaylandWindow::OnWindowLostCapture() { delegate_->OnLostCapture(); } @@ -79,12 +70,16 @@ else ui_scale_ = display.device_scale_factor(); } - SetBufferScale(new_scale, update_bounds); + // At this point, buffer_scale() still returns the old scale. + if (update_bounds) + SetBoundsDip(gfx::ScaleToRoundedRect(bounds_px_, 1.0 / buffer_scale())); + + root_surface_->SetBufferScale(new_scale, update_bounds); } gfx::AcceleratedWidget WaylandWindow::GetWidget() const { - DCHECK(wayland_surface_); - return wayland_surface_->GetWidget(); + DCHECK(root_surface_); + return root_surface_->GetWidget(); } void WaylandWindow::SetPointerFocus(bool focus) { @@ -121,10 +116,7 @@ return; bounds_px_ = bounds_px; - // Opaque region is based on the size of the window. Thus, update the region - // on each update. - MaybeUpdateOpaqueRegion(); - + root_surface_->SetBounds(bounds_px); delegate_->OnBoundsChanged(bounds_px_); } @@ -321,8 +313,8 @@ } bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) { - wayland_surface_ = std::make_unique<WaylandSurface>(connection_, this); - if (!surface()) { + root_surface_ = std::make_unique<WaylandSurface>(connection_, this); + if (!root_surface_->Initialize()) { LOG(ERROR) << "Failed to create wl_surface"; return false; } @@ -330,13 +322,10 @@ // Properties contain DIP bounds but the buffer scale is initially 1 so it's // OK to assign. The bounds will be recalculated when the buffer scale // changes. - DCHECK_EQ(buffer_scale(), 1); bounds_px_ = properties.bounds; opacity_ = properties.opacity; type_ = properties.type; - AddSurfaceListener(); - connection_->wayland_window_manager()->AddWindow(GetWidget(), this); if (!OnInitialize(std::move(properties))) @@ -349,29 +338,11 @@ // Will do nothing for menus because they have got their scale above. UpdateBufferScale(false); + root_surface_->SetBounds(bounds_px_); - MaybeUpdateOpaqueRegion(); return true; } -// TODO(crbug.com/1099838): Move wl_surface calls to WaylandSurface -void WaylandWindow::SetBufferScale(int32_t new_scale, bool update_bounds) { - DCHECK_GT(new_scale, 0); - DCHECK(wayland_surface_); - - if (new_scale == buffer_scale()) - return; - - auto old_scale = buffer_scale(); - wayland_surface_->set_buffer_scale(new_scale); - if (update_bounds) - SetBoundsDip(gfx::ScaleToRoundedRect(bounds_px_, 1.0 / old_scale)); - - DCHECK(surface()); - wl_surface_set_buffer_scale(surface(), buffer_scale()); - connection_->ScheduleFlush(); -} - WaylandWindow* WaylandWindow::GetParentWindow( gfx::AcceleratedWidget parent_widget) { auto* parent_window = @@ -398,23 +369,6 @@ return parent_window_ ? parent_window_->GetRootParentWindow() : this; } -// TODO(crbug.com/1099838): Move wl_surface calls to WaylandSurface -void WaylandWindow::AddSurfaceListener() { - static struct wl_surface_listener surface_listener = { - &WaylandWindow::Enter, - &WaylandWindow::Leave, - }; - wl_surface_add_listener(surface(), &surface_listener, nullptr); - wl_surface_set_user_data(surface(), this); -} - -void WaylandWindow::RemoveSurfaceListener() { - if (surface()) { - wl_surface_add_listener(surface(), nullptr, nullptr); - wl_surface_set_user_data(surface(), nullptr); - } -} - void WaylandWindow::AddEnteredOutputId(struct wl_output* output) { // Wayland does weird things for menus so instead of tracking outputs that // we entered or left, we take that from the parent window and ignore this @@ -491,19 +445,6 @@ return child_window_ ? child_window_->GetTopMostChildWindow() : this; } -void WaylandWindow::MaybeUpdateOpaqueRegion() { - if (!IsOpaqueWindow()) - return; - - wl::Object<wl_region> region( - wl_compositor_create_region(connection_->compositor())); - wl_region_add(region.get(), 0, 0, bounds_px_.width(), bounds_px_.height()); - - wl_surface_set_opaque_region(surface(), region.get()); - - connection_->ScheduleFlush(); -} - bool WaylandWindow::IsOpaqueWindow() const { return opacity_ == ui::PlatformWindowOpacity::kOpaqueWindow; } @@ -520,26 +461,10 @@ return handled ? POST_DISPATCH_STOP_PROPAGATION : POST_DISPATCH_NONE; } -// static -void WaylandWindow::Enter(void* data, - struct wl_surface* wl_surface, - struct wl_output* output) { - if (auto* window = FromSurface(wl_surface)) - window->AddEnteredOutputId(output); -} - -// static -void WaylandWindow::Leave(void* data, - struct wl_surface* wl_surface, - struct wl_output* output) { - if (auto* window = FromSurface(wl_surface)) - window->RemoveEnteredOutputId(output); -} - std::unique_ptr<WaylandSurface> WaylandWindow::TakeWaylandSurface() { DCHECK(shutting_down_); - DCHECK(wayland_surface_); - return std::move(wayland_surface_); + DCHECK(root_surface_); + return std::move(root_surface_); } } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h index 937fdd6..41d3900 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.h +++ b/ui/ozone/platform/wayland/host/wayland_window.h
@@ -44,8 +44,6 @@ WaylandConnection* connection, PlatformWindowInitProperties properties); - static WaylandWindow* FromSurface(wl_surface* surface); - void OnWindowLostCapture(); // Updates the surface buffer scale of the window. Top level windows take @@ -55,8 +53,7 @@ // to do so (this is not needed upon window initialization). void UpdateBufferScale(bool update_bounds); - WaylandSurface* wayland_surface() { return wayland_surface_.get(); } - wl_surface* surface() const { return wayland_surface_->surface(); } + WaylandSurface* root_surface() const { return root_surface_.get(); } void set_parent_window(WaylandWindow* parent_window) { parent_window_ = parent_window; @@ -83,7 +80,7 @@ void set_child_window(WaylandWindow* window) { child_window_ = window; } WaylandWindow* child_window() const { return child_window_; } - int32_t buffer_scale() const { return wayland_surface_->buffer_scale(); } + int32_t buffer_scale() const { return root_surface_->buffer_scale(); } int32_t ui_scale() const { return ui_scale_; } const base::flat_set<uint32_t>& entered_outputs_ids() const { @@ -157,6 +154,17 @@ // Returns a top most child window within the same hierarchy. WaylandWindow* GetTopMostChildWindow(); + // This should be called when a WaylandSurface part of this window becomes + // partially or fully within the scanout region of |output|. + void AddEnteredOutputId(struct wl_output* output); + + // This should be called when a WaylandSurface part of this window becomes + // fully outside of the scanout region of |output|. + void RemoveEnteredOutputId(struct wl_output* output); + + // Returns true iff this window is opaque. + bool IsOpaqueWindow() const; + protected: WaylandWindow(PlatformWindowDelegate* delegate, WaylandConnection* connection); @@ -170,10 +178,6 @@ // Gets a parent window for this window. WaylandWindow* GetParentWindow(gfx::AcceleratedWidget parent_widget); - // Sets the buffer scale. - void SetBufferScale(int32_t scale, bool update_bounds); - - // Sets the ui scale. void set_ui_scale(int32_t ui_scale) { ui_scale_ = ui_scale; } private: @@ -182,37 +186,15 @@ // Initializes the WaylandWindow with supplied properties. bool Initialize(PlatformWindowInitProperties properties); - // Registers/unregisters a surface listener, so wl_output enter/leave events - // can be received. - void AddSurfaceListener(); - void RemoveSurfaceListener(); - - void AddEnteredOutputId(struct wl_output* output); - void RemoveEnteredOutputId(struct wl_output* output); - void UpdateCursorPositionFromEvent(std::unique_ptr<Event> event); WaylandWindow* GetTopLevelWindow(); - // It's important to set opaque region for opaque windows (provides - // optimization hint for the Wayland compositor). - void MaybeUpdateOpaqueRegion(); - - bool IsOpaqueWindow() const; - uint32_t DispatchEventToDelegate(const PlatformEvent& native_event); // Additional initialization of derived classes. virtual bool OnInitialize(PlatformWindowInitProperties properties) = 0; - // wl_surface_listener - static void Enter(void* data, - struct wl_surface* wl_surface, - struct wl_output* output); - static void Leave(void* data, - struct wl_surface* wl_surface, - struct wl_output* output); - // WaylandWindowDragController might need to take ownership of the wayland // surface whether the window that originated the DND session gets destroyed // in the middle of that session (e.g: when it is snapped into a tab strip). @@ -227,7 +209,7 @@ WaylandWindow* parent_window_ = nullptr; WaylandWindow* child_window_ = nullptr; - std::unique_ptr<WaylandSurface> wayland_surface_; + std::unique_ptr<WaylandSurface> root_surface_; // The current cursor bitmap (immutable). scoped_refptr<BitmapCursorOzone> bitmap_;
diff --git a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc index 758ae1f..99eb2e701 100644 --- a/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc +++ b/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc
@@ -329,7 +329,7 @@ } xdg_popup_add_listener(xdg_popup_.get(), &xdg_popup_listener, this); - wl_surface_commit(wayland_window_->surface()); + wayland_window_->root_surface()->Commit(); return true; } @@ -393,7 +393,7 @@ zxdg_popup_v6_add_listener(zxdg_popup_v6_.get(), &zxdg_popup_v6_listener, this); - wl_surface_commit(wayland_window_->surface()); + wayland_window_->root_surface()->Commit(); return true; }
diff --git a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc index ae1ca15..cbc75a0f 100644 --- a/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc +++ b/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc
@@ -267,8 +267,8 @@ // configuration acknowledgement on each configure event. surface_for_popup_ = !with_toplevel; - xdg_surface_.reset(xdg_wm_base_get_xdg_surface(connection_->shell(), - wayland_window_->surface())); + xdg_surface_.reset(xdg_wm_base_get_xdg_surface( + connection_->shell(), wayland_window_->root_surface()->surface())); if (!xdg_surface_) { LOG(ERROR) << "Failed to create xdg_surface"; return false; @@ -287,8 +287,7 @@ return false; } xdg_toplevel_add_listener(xdg_toplevel_.get(), &xdg_toplevel_listener, this); - wl_surface_commit(wayland_window_->surface()); - + wayland_window_->root_surface()->Commit(); connection_->ScheduleFlush(); return true; } @@ -307,7 +306,7 @@ surface_for_popup_ = !with_toplevel; zxdg_surface_v6_.reset(zxdg_shell_v6_get_xdg_surface( - connection_->shell_v6(), wayland_window_->surface())); + connection_->shell_v6(), wayland_window_->root_surface()->surface())); if (!zxdg_surface_v6_) { LOG(ERROR) << "Failed to create zxdg_surface"; return false; @@ -328,8 +327,7 @@ } zxdg_toplevel_v6_add_listener(zxdg_toplevel_v6_.get(), &zxdg_toplevel_v6_listener, this); - wl_surface_commit(wayland_window_->surface()); - + wayland_window_->root_surface()->Commit(); connection_->ScheduleFlush(); return true; }
diff --git a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc index 7b72165b4..b1c021ad3 100644 --- a/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc +++ b/ui/ozone/platform/wayland/host/zwp_text_input_wrapper_v1.cc
@@ -57,7 +57,7 @@ void ZWPTextInputWrapperV1::Activate(WaylandWindow* window) { zwp_text_input_v1_activate(obj_.get(), connection_->seat(), - window->surface()); + window->root_surface()->surface()); } void ZWPTextInputWrapperV1::Deactivate() {
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc index fa791c47..b8071d2 100644 --- a/ui/views/controls/table/table_view.cc +++ b/ui/views/controls/table/table_view.cc
@@ -1234,7 +1234,7 @@ cell_data.AddIntAttribute(ax::mojom::IntAttribute::kTableCellColumnSpan, 1); if (base::i18n::IsRTL()) - cell_data.SetTextDirection(ax::mojom::TextDirection::kRtl); + cell_data.SetTextDirection(ax::mojom::WritingDirection::kRtl); auto sort_direction = ax::mojom::SortDirection::kUnsorted; if (column.sortable && primary_sorted_column_id.has_value() && @@ -1323,7 +1323,7 @@ cell_data.SetName(model_->GetText(model_index, column.id)); if (base::i18n::IsRTL()) - cell_data.SetTextDirection(ax::mojom::TextDirection::kRtl); + cell_data.SetTextDirection(ax::mojom::WritingDirection::kRtl); auto sort_direction = ax::mojom::SortDirection::kUnsorted; if (column.sortable && primary_sorted_column_id.has_value() &&
diff --git a/ui/views/controls/tree/tree_view.cc b/ui/views/controls/tree/tree_view.cc index 69333ebe..729d447 100644 --- a/ui/views/controls/tree/tree_view.cc +++ b/ui/views/controls/tree/tree_view.cc
@@ -890,7 +890,7 @@ ui::AXNodeData& node_data = ax_view->GetCustomData(); node_data.role = ax::mojom::Role::kTreeItem; if (base::i18n::IsRTL()) - node_data.SetTextDirection(ax::mojom::TextDirection::kRtl); + node_data.SetTextDirection(ax::mojom::WritingDirection::kRtl); base::RepeatingCallback<void(ui::AXNodeData*)> selected_callback = base::BindRepeating(&TreeView::PopulateAccessibilityData,