diff --git a/DEPS b/DEPS index eb18453..2fada0a 100644 --- a/DEPS +++ b/DEPS
@@ -253,11 +253,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': '66efe821b72f995f9e9a32cfd7050cba27a0e3aa', + 'skia_revision': '3d381dcbd2fd94eead35d3fb95cb4af2b86f152a', # 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': '84e10038cd86725be18eab63e6866d2091874f52', + 'v8_revision': 'f311a18650a2c679503e80242d75be86fd41ea60', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -265,7 +265,7 @@ # 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': 'c27e99245d423648fe5f0eafa73d49ce7b53d201', + 'swiftshader_revision': 'b3b1a3fe8351b2feae986b124142cc74e0aa4e8e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -328,7 +328,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': 'b9d36166b65b2ab9666f5c9e5eb1003224b0f6fa', + 'devtools_frontend_revision': '4d17e989f0f5bad0f9d4d5badff16fd6da09ae33', # 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. @@ -368,7 +368,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '2baa3467d996446db4d9a62139da9ac7ff7838bd', + 'dawn_revision': '25d7e333206c14edc865b7be4ecebb93557abece', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -809,7 +809,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': 'P4qBSseJmvWmZlQIzoHQ4DMHg0GKIBtDtKL6P3UQoUUC', + 'version': 'eEKxTcWI5TCbL_dNqak7VgCt705-dYKLw6O697CNiSoC', }, ], 'dep_type': 'cipd', @@ -820,7 +820,7 @@ 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'tpt6BzVqkkpz2j2fGso8GkB1rcdgDjqBKDUKOoSjL8oC', + 'version': 'nXXmYVXgcExxRTjx7e9SgpsJzxsTolp9ObHPfX1DKXIC', }, ], 'dep_type': 'cipd', @@ -892,7 +892,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'o519o3phZFQGY6K0mO0EJ-xJQUoucapeX-jwNBAal5wC', + 'version': '4144ITIgXUisP3mBnV8td3mdaIKKku5UW_bQjgoP9r8C', }, ], 'condition': 'checkout_android', @@ -1100,7 +1100,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '71d6cd90214d4ae857c1a94e21ef2cd0175a8d3d', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '32317b1903affb8798ac58ecc15ab503d5bb6127', 'condition': 'checkout_chromeos', }, @@ -1503,7 +1503,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'bc7a9c2bb682f97e2c5666bf19ec0a742c26ae26', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'c899a37e18fcc1e4f0fcac2b648e491ac2e6c18a', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1581,7 +1581,7 @@ 'packages': [ { 'package': 'fuchsia/third_party/android/aemu/release/linux-amd64', - 'version': 'ua1BrIds-RI-QFJX8UfAJzEgMzmNPkYDPbV_WSf2pG8C' + 'version': 'Jd7H1L5yq-3E50xh7PJcQXhYKh4arojFgYADEd9s8x0C' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -1600,7 +1600,7 @@ }, 'src/third_party/re2/src': - Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + 'f2eff71ac32b81ecb93396f9e51973f52a22c4d4', + Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + '1a7dc61c03941e8fd4e6ff21c2a466bb8efbaa8d', 'src/third_party/r8': { 'packages': [ @@ -1721,7 +1721,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'cf04aebdf9b53bb2853f22a81465688daf879ec6', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'd4ab434e91c1a578f6a43c7418eae2b92856ee05', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '90654f28f4092a4993e91726cb18f697aefb201f', 'src/third_party/webrtc': Var('webrtc_git') + '/src.git' + '@' + '8f56242e984022821f1b630c94e107d0006d4b64', @@ -1794,7 +1794,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c81527fdf3300c59c7f4c941c2f5dba1f6b674d0', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@4a50cf59e3f0b22d23e653cd48ccf51fa5347ff6', 'condition': 'checkout_src_internal', }, @@ -1824,7 +1824,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'qmOdhceXhbiRQaLH3daJFi-BnBFE5TYeDhX1dLyfR9oC', + 'version': 'pT8LaiqCoa5lm3HWqD8ZoHWiCo_hdvy_NhldI8QQjtwC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1835,7 +1835,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': '-qW-FqtbWmLBB13-MErgAEDAU-LgGUuuiugd7q0N2uwC', + 'version': 'jrLhP-V80o1Z-u1LbNe_K_dPWWsnqa-DeUgZFO7yL_kC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 2ebda3e3..89a8ccd 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -7,6 +7,11 @@ See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for more details about the presubmit API built into depot_tools. """ + +from typing import Optional +from typing import Sequence +from dataclasses import dataclass + PRESUBMIT_VERSION = '2.0.0' # This line is 'magic' in that git-cl looks for it to decide whether to @@ -104,51 +109,75 @@ 'release apk.') -_INCLUDE_ORDER_WARNING = ( - 'Your #include order seems to be broken. Remember to use the right ' - 'collation (LC_COLLATE=C) and check\nhttps://google.github.io/styleguide/' - 'cppguide.html#Names_and_Order_of_Includes') +@dataclass +class BanRule: + # String pattern. If the pattern begins with a slash, the pattern will be + # treated as a regular expression instead. + pattern: str + # Explanation as a sequence of strings. Each string in the sequence will be + # printed on its own line. + explanation: Sequence[str] + # Whether or not to treat this ban as a fatal error. If unspecified, defaults + # to true. + treat_as_error: Optional[bool] = None + # Paths that should be excluded from the ban check. Each string is a regular + # expression that will be matched against the path of the file being checked + # relative to the root of the source tree. + excluded_paths: Optional[Sequence[str]] = None -# Format: Sequence of tuples containing: -# * Full import path. -# * Sequence of strings to show when the pattern matches. -# * Sequence of path or filename exceptions to this rule -_BANNED_JAVA_IMPORTS = (( - 'java.net.URI;', - ('Use org.chromium.url.GURL instead of java.net.URI, where possible.', ), - ( - 'net/android/javatests/src/org/chromium/net/' - 'AndroidProxySelectorTest.java', - 'components/cronet/', - 'third_party/robolectric/local/', + +# Format: Sequence of BanRule: +_BANNED_JAVA_IMPORTS = ( + BanRule( + 'import java.net.URI;', + ( + 'Use org.chromium.url.GURL instead of java.net.URI, where possible.', + ), + excluded_paths=( + (r'net/android/javatests/src/org/chromium/net/' + 'AndroidProxySelectorTest\.java'), + r'components/cronet/', + r'third_party/robolectric/local/', + ), ), -), ( - 'android.annotation.TargetApi;', - ('Do not use TargetApi, use @androidx.annotation.RequiresApi instead. ' - 'RequiresApi ensures that any calls are guarded by the appropriate ' - 'SDK_INT check. See https://crbug.com/1116486.', ), - (), -), ( - 'android.support.test.rule.UiThreadTestRule;', - ('Do not use UiThreadTestRule, just use ' - '@org.chromium.base.test.UiThreadTest on test methods that should run ' - 'on the UI thread. See https://crbug.com/1111893.', ), - (), -), ('android.support.test.annotation.UiThreadTest;', - ('Do not use android.support.test.annotation.UiThreadTest, use ' - 'org.chromium.base.test.UiThreadTest instead. See ' - 'https://crbug.com/1111893.', ), - ()), ('android.support.test.rule.ActivityTestRule;', - ('Do not use ActivityTestRule, use ' - 'org.chromium.base.test.BaseActivityTestRule instead.', ), - ('components/cronet/', ))) + BanRule( + 'import android.annotation.TargetApi;', + ( + 'Do not use TargetApi, use @androidx.annotation.RequiresApi instead. ' + 'RequiresApi ensures that any calls are guarded by the appropriate ' + 'SDK_INT check. See https://crbug.com/1116486.', + ), + ), + BanRule( + 'import android.support.test.rule.UiThreadTestRule;', + ( + 'Do not use UiThreadTestRule, just use ' + '@org.chromium.base.test.UiThreadTest on test methods that should run ' + 'on the UI thread. See https://crbug.com/1111893.', + ), + ), + BanRule( + 'import android.support.test.annotation.UiThreadTest;', + ('Do not use android.support.test.annotation.UiThreadTest, use ' + 'org.chromium.base.test.UiThreadTest instead. See ' + 'https://crbug.com/1111893.', + ), + ), + BanRule( + 'import android.support.test.rule.ActivityTestRule;', + ( + 'Do not use ActivityTestRule, use ' + 'org.chromium.base.test.BaseActivityTestRule instead.', + ), + excluded_paths=( + 'components/cronet/', + ), + ), +) -# Format: Sequence of tuples containing: -# * String pattern or, if starting with a slash, a regular expression. -# * Sequence of strings to show when the pattern matches. -# * Error flag. True if a match is a presubmit error, otherwise it's a warning. +# Format: Sequence of BanRule: _BANNED_JAVA_FUNCTIONS = ( - ( + BanRule( 'StrictMode.allowThreadDiskReads()', ( 'Prefer using StrictModeContext.allowDiskReads() to using StrictMode ' @@ -156,7 +185,7 @@ ), False, ), - ( + BanRule( 'StrictMode.allowThreadDiskWrites()', ( 'Prefer using StrictModeContext.allowDiskWrites() to using StrictMode ' @@ -174,12 +203,9 @@ ), ) -# Format: Sequence of tuples containing: -# * String pattern or, if starting with a slash, a regular expression. -# * Sequence of strings to show when the pattern matches. -# * Error flag. True if a match is a presubmit error, otherwise it's a warning. +# Format: Sequence of BanRule: _BANNED_OBJC_FUNCTIONS = ( - ( + BanRule( 'addTrackingRect:', ( 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is' @@ -188,7 +214,7 @@ ), False, ), - ( + BanRule( r'/NSTrackingArea\W', ( 'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea', @@ -197,7 +223,7 @@ ), False, ), - ( + BanRule( 'convertPointFromBase:', ( 'The use of -[NSView convertPointFromBase:] is almost certainly wrong.', @@ -206,7 +232,7 @@ ), True, ), - ( + BanRule( 'convertPointToBase:', ( 'The use of -[NSView convertPointToBase:] is almost certainly wrong.', @@ -215,7 +241,7 @@ ), True, ), - ( + BanRule( 'convertRectFromBase:', ( 'The use of -[NSView convertRectFromBase:] is almost certainly wrong.', @@ -224,7 +250,7 @@ ), True, ), - ( + BanRule( 'convertRectToBase:', ( 'The use of -[NSView convertRectToBase:] is almost certainly wrong.', @@ -233,7 +259,7 @@ ), True, ), - ( + BanRule( 'convertSizeFromBase:', ( 'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.', @@ -242,7 +268,7 @@ ), True, ), - ( + BanRule( 'convertSizeToBase:', ( 'The use of -[NSView convertSizeToBase:] is almost certainly wrong.', @@ -251,7 +277,7 @@ ), True, ), - ( + BanRule( r"/\s+UTF8String\s*]", ( 'The use of -[NSString UTF8String] is dangerous as it can return null', @@ -260,7 +286,7 @@ ), True, ), - ( + BanRule( r'__unsafe_unretained', ( 'The use of __unsafe_unretained is almost certainly wrong, unless', @@ -269,7 +295,7 @@ ), False, ), - ( + BanRule( 'freeWhenDone:NO', ( 'The use of "freeWhenDone:NO" with the NoCopy creation of ', @@ -279,12 +305,9 @@ ), ) -# Format: Sequence of tuples containing: -# * String pattern or, if starting with a slash, a regular expression. -# * Sequence of strings to show when the pattern matches. -# * Error flag. True if a match is a presubmit error, otherwise it's a warning. +# Format: Sequence of BanRule: _BANNED_IOS_OBJC_FUNCTIONS = ( - ( + BanRule( r'/\bTEST[(]', ( 'TEST() macro should not be used in Objective-C++ code as it does not ', @@ -294,7 +317,7 @@ ), True, ), - ( + BanRule( r'/\btesting::Test\b', ( 'testing::Test should not be used in Objective-C++ code as it does ', @@ -305,12 +328,9 @@ ), ) -# Format: Sequence of tuples containing: -# * String pattern or, if starting with a slash, a regular expression. -# * Sequence of strings to show when the pattern matches. -# * Error flag. True if a match is a presubmit error, otherwise it's a warning. +# Format: Sequence of BanRule: _BANNED_IOS_EGTEST_FUNCTIONS = ( - ( + BanRule( r'/\bEXPECT_OCMOCK_VERIFY\b', ( 'EXPECT_OCMOCK_VERIFY should not be used in EarlGrey tests because ', @@ -320,13 +340,9 @@ ), ) -# Format: Sequence of tuples containing: -# * String pattern or, if starting with a slash, a regular expression. -# * Sequence of strings to show when the pattern matches. -# * Error flag. True if a match is a presubmit error, otherwise it's a warning. -# * Sequence of paths to *not* check (regexps). +# Format: Sequence of BanRule: _BANNED_CPP_FUNCTIONS = ( - ( + BanRule( r'/\busing namespace ', ( 'Using directives ("using namespace x") are banned by the Google Style', @@ -339,7 +355,7 @@ # Make sure that gtest's FRIEND_TEST() macro is not used; the # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be # used instead since that allows for FLAKY_ and DISABLED_ prefixes. - ( + BanRule( 'FRIEND_TEST(', ( 'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include', @@ -348,7 +364,7 @@ False, (), ), - ( + BanRule( 'setMatrixClip', ( 'Overriding setMatrixClip() is prohibited; ', @@ -357,7 +373,7 @@ True, (), ), - ( + BanRule( 'SkRefPtr', ( 'The use of SkRefPtr is prohibited. ', @@ -366,7 +382,7 @@ True, (), ), - ( + BanRule( 'SkAutoRef', ( 'The indirect use of SkRefPtr via SkAutoRef is prohibited. ', @@ -375,7 +391,7 @@ True, (), ), - ( + BanRule( 'SkAutoTUnref', ( 'The use of SkAutoTUnref is dangerous because it implicitly ', @@ -384,7 +400,7 @@ True, (), ), - ( + BanRule( 'SkAutoUnref', ( 'The indirect use of SkAutoTUnref through SkAutoUnref is dangerous ', @@ -394,7 +410,7 @@ True, (), ), - ( + BanRule( r'/HANDLE_EINTR\(.*close', ( 'HANDLE_EINTR(close) is invalid. If close fails with EINTR, the file', @@ -405,7 +421,7 @@ True, (), ), - ( + BanRule( r'/IGNORE_EINTR\((?!.*close)', ( 'IGNORE_EINTR is only valid when wrapping close. To wrap other system', @@ -418,7 +434,7 @@ r'^ppapi[\\/]tests[\\/]test_broker\.cc$', ), ), - ( + BanRule( r'/v8::Extension\(', ( 'Do not introduce new v8::Extensions into the code base, use', @@ -429,7 +445,7 @@ r'extensions[\\/]renderer[\\/]safe_builtins\.*', ), ), - ( + BanRule( '#pragma comment(lib,', ( 'Specify libraries to link with in build files and not in the source.', @@ -440,7 +456,7 @@ r'^third_party[\\/]abseil-cpp[\\/].*', ), ), - ( + BanRule( r'/base::SequenceChecker\b', ( 'Consider using SEQUENCE_CHECKER macros instead of the class directly.', @@ -448,7 +464,7 @@ False, (), ), - ( + BanRule( r'/base::ThreadChecker\b', ( 'Consider using THREAD_CHECKER macros instead of the class directly.', @@ -456,7 +472,7 @@ False, (), ), - ( + BanRule( r'/(Time(|Delta|Ticks)|ThreadTicks)::FromInternalValue|ToInternalValue', ( 'base::TimeXXX::FromInternalValue() and ToInternalValue() are', @@ -471,7 +487,7 @@ False, (), ), - ( + BanRule( 'CallJavascriptFunctionUnsafe', ( "Don't use CallJavascriptFunctionUnsafe() in new code. Instead, use", @@ -485,7 +501,7 @@ r'^content[\\/]public[\\/]test[\\/]test_web_ui\.(cc|h)$', ), ), - ( + BanRule( 'leveldb::DB::Open', ( 'Instead of leveldb::DB::Open() use leveldb_env::OpenDB() from', @@ -497,7 +513,7 @@ r'^third_party/leveldatabase/.*\.(cc|h)$', ), ), - ( + BanRule( 'leveldb::NewMemEnv', ( 'Instead of leveldb::NewMemEnv() use leveldb_chrome::NewMemEnv() from', @@ -509,7 +525,7 @@ r'^third_party/leveldatabase/.*\.(cc|h)$', ), ), - ( + BanRule( 'RunLoop::QuitCurrent', ( 'Please migrate away from RunLoop::QuitCurrent*() methods. Use member', @@ -518,7 +534,7 @@ False, (), ), - ( + BanRule( 'base::ScopedMockTimeMessageLoopTaskRunner', ( 'ScopedMockTimeMessageLoopTaskRunner is deprecated. Prefer', @@ -530,7 +546,7 @@ False, (), ), - ( + BanRule( 'std::regex', ( 'Using std::regex adds unnecessary binary size to Chrome. Please use', @@ -540,7 +556,7 @@ # Abseil's benchmarks never linked into chrome. ['third_party/abseil-cpp/.*_benchmark.cc'], ), - ( + BanRule( r'/\bstd::stoi\b', ( 'std::stoi uses exceptions to communicate results. ', @@ -549,7 +565,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. ), - ( + BanRule( r'/\bstd::stol\b', ( 'std::stol uses exceptions to communicate results. ', @@ -558,7 +574,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. ), - ( + BanRule( r'/\bstd::stoul\b', ( 'std::stoul uses exceptions to communicate results. ', @@ -567,7 +583,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. ), - ( + BanRule( r'/\bstd::stoll\b', ( 'std::stoll uses exceptions to communicate results. ', @@ -576,7 +592,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. ), - ( + BanRule( r'/\bstd::stoull\b', ( 'std::stoull uses exceptions to communicate results. ', @@ -585,7 +601,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. ), - ( + BanRule( r'/\bstd::stof\b', ( 'std::stof uses exceptions to communicate results. ', @@ -596,7 +612,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. ), - ( + BanRule( r'/\bstd::stod\b', ( 'std::stod uses exceptions to communicate results. ', @@ -607,7 +623,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. ), - ( + BanRule( r'/\bstd::stold\b', ( 'std::stold uses exceptions to communicate results. ', @@ -618,7 +634,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. ), - ( + BanRule( r'/\bstd::to_string\b', ( 'std::to_string is locale dependent and slower than alternatives.', @@ -630,7 +646,7 @@ False, # Only a warning since it is already used. [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. ), - ( + BanRule( r'/\bstd::shared_ptr\b', ( 'std::shared_ptr should not be used. Use scoped_refptr instead.', @@ -654,7 +670,7 @@ '^tools/clang/plugins/tests/', _THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. ), - ( + BanRule( r'/\bstd::weak_ptr\b', ( 'std::weak_ptr should not be used. Use base::WeakPtr instead.', @@ -662,7 +678,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. ), - ( + BanRule( r'/\blong long\b', ( 'long long is banned. Use stdint.h if you need a 64 bit number.', @@ -670,16 +686,16 @@ False, # Only a warning since it is already used. [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. ), - ( + BanRule( r'\b(absl|std)::any\b', ( - 'absl::any / std::any are not safe to use in a component build.' + 'absl::any / std::any are not safe to use in a component build.', ), True, # Not an error in third party folders, though it probably should be :) [_THIRD_PARTY_EXCEPT_BLINK], ), - ( + BanRule( r'/\bstd::bind\b', ( 'std::bind is banned because of lifetime risks.', @@ -688,7 +704,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. ), - ( + BanRule( r'/\bstd::optional\b', ( 'std::optional is banned. Use absl::optional instead.', @@ -696,7 +712,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. ), - ( + BanRule( r'/\b#include <chrono>\b', ( '<chrono> overlaps with Time APIs in base. Keep using', @@ -705,7 +721,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. ), - ( + BanRule( r'/\b#include <exception>\b', ( 'Exceptions are banned and disabled in Chromium.', @@ -713,7 +729,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. ), - ( + BanRule( r'/\bstd::function\b', ( 'std::function is banned. Instead use base::OnceCallback or ', @@ -723,7 +739,7 @@ False, # Only a warning since it is already used. [_THIRD_PARTY_EXCEPT_BLINK], # Do not warn in third_party folders. ), - ( + BanRule( r'/\b#include <random>\b', ( 'Do not use any random number engines from <random>. Instead', @@ -732,7 +748,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. ), - ( + BanRule( r'/\b#include <X11/', ( 'Do not use Xlib. Use xproto (from //ui/gfx/x:xproto) instead.', @@ -740,7 +756,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. ), - ( + BanRule( r'/\bstd::ratio\b', ( 'std::ratio is banned by the Google Style Guide.', @@ -748,7 +764,7 @@ True, [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. ), - ( + BanRule( ('base::ThreadRestrictions::ScopedAllowIO'), ( 'ScopedAllowIO is deprecated, use ScopedAllowBlocking instead.', @@ -756,7 +772,7 @@ False, (), ), - ( + BanRule( r'/\bRunMessageLoop\b', ( 'RunMessageLoop is deprecated, use RunLoop instead.', @@ -764,7 +780,7 @@ False, (), ), - ( + BanRule( 'RunThisRunLoop', ( 'RunThisRunLoop is deprecated, use RunLoop directly instead.', @@ -772,7 +788,7 @@ False, (), ), - ( + BanRule( 'RunAllPendingInMessageLoop()', ( "Prefer RunLoop over RunAllPendingInMessageLoop, please contact gab@", @@ -781,7 +797,7 @@ False, (), ), - ( + BanRule( 'RunAllPendingInMessageLoop(BrowserThread', ( 'RunAllPendingInMessageLoop is deprecated. Use RunLoop for', @@ -792,7 +808,7 @@ False, (), ), - ( + BanRule( r'MessageLoopRunner', ( 'MessageLoopRunner is deprecated, use RunLoop instead.', @@ -800,7 +816,7 @@ False, (), ), - ( + BanRule( 'GetDeferredQuitTaskForRunLoop', ( "GetDeferredQuitTaskForRunLoop shouldn't be needed, please contact", @@ -809,7 +825,7 @@ False, (), ), - ( + BanRule( 'sqlite3_initialize(', ( 'Instead of calling sqlite3_initialize(), depend on //sql, ', @@ -821,7 +837,7 @@ r'^third_party/sqlite/.*\.(c|cc|h)$', ), ), - ( + BanRule( 'std::random_shuffle', ( 'std::random_shuffle is deprecated in C++14, and removed in C++17. Use', @@ -830,7 +846,7 @@ True, (), ), - ( + BanRule( 'ios/web/public/test/http_server', ( 'web::HTTPserver is deprecated use net::EmbeddedTestServer instead.', @@ -838,7 +854,7 @@ False, (), ), - ( + BanRule( 'GetAddressOf', ( 'Improper use of Microsoft::WRL::ComPtr<T>::GetAddressOf() has been ', @@ -849,7 +865,7 @@ True, (), ), - ( + BanRule( 'SHFileOperation', ( 'SHFileOperation was deprecated in Windows Vista, and there are less ', @@ -859,7 +875,7 @@ True, (), ), - ( + BanRule( 'StringFromGUID2', ( 'StringFromGUID2 introduces an unnecessary dependency on ole32.dll.', @@ -867,10 +883,10 @@ ), True, ( - r'/base/win/win_util_unittest.cc' + r'/base/win/win_util_unittest.cc', ), ), - ( + BanRule( 'StringFromCLSID', ( 'StringFromCLSID introduces an unnecessary dependency on ole32.dll.', @@ -878,10 +894,10 @@ ), True, ( - r'/base/win/win_util_unittest.cc' + r'/base/win/win_util_unittest.cc', ), ), - ( + BanRule( 'kCFAllocatorNull', ( 'The use of kCFAllocatorNull with the NoCopy creation of ', @@ -890,7 +906,7 @@ True, (), ), - ( + BanRule( 'mojo::ConvertTo', ( 'mojo::ConvertTo and TypeConverter are deprecated. Please consider', @@ -906,7 +922,7 @@ r'^content/renderer/.*\.(cc|h)$', ), ), - ( + BanRule( 'GetInterfaceProvider', ( 'InterfaceProvider is deprecated.', @@ -916,7 +932,7 @@ False, (), ), - ( + BanRule( 'CComPtr', ( 'New code should use Microsoft::WRL::ComPtr from wrl/client.h as a ', @@ -926,7 +942,7 @@ False, (), ), - ( + BanRule( r'/\b(IFACE|STD)METHOD_?\(', ( 'IFACEMETHOD() and STDMETHOD() make code harder to format and read.', @@ -935,7 +951,7 @@ False, [_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders. ), - ( + BanRule( 'set_owned_by_client', ( 'set_owned_by_client is deprecated.', @@ -946,7 +962,7 @@ False, (), ), - ( + BanRule( 'RemoveAllChildViewsWithoutDeleting', ( 'RemoveAllChildViewsWithoutDeleting is deprecated.', @@ -956,7 +972,7 @@ False, (), ), - ( + BanRule( r'/\bTRACE_EVENT_ASYNC_', ( 'Please use TRACE_EVENT_NESTABLE_ASYNC_.. macros instead', @@ -968,7 +984,7 @@ r'^base/tracing/.*', ), ), - ( + BanRule( r'/\bbase::debug::DumpWithoutCrashingUnthrottled[(][)]', ( 'base::debug::DumpWithoutCrashingUnthrottled() does not throttle', @@ -978,7 +994,7 @@ False, (), ), - ( + BanRule( 'RoInitialize', ( 'Improper use of [base::win]::RoInitialize() has been implicated in a ', @@ -987,27 +1003,16 @@ ), True, ( - r'^base[\\/]win[\\/]scoped_winrt_initializer\.cc$' + r'^base[\\/]win[\\/]scoped_winrt_initializer\.cc$', ), ), - ( - r'/base::(size|empty|data)', - ( - 'Please use the STL equivalent (std::size/std::empty/std::data) ', - 'instead. The base versions are being removed: ', - 'https://crbug.com/1299695' - - ), - False, - [_THIRD_PARTY_EXCEPT_BLINK], # Don't warn in third_party folders. - ), ) # Format: Sequence of tuples containing: # * String pattern or, if starting with a slash, a regular expression. # * Sequence of strings to show when the pattern matches. _DEPRECATED_MOJO_TYPES = ( - ( + BanRule( r'/\bmojo::AssociatedInterfacePtrInfo\b', ( 'mojo::AssociatedInterfacePtrInfo<Interface> is deprecated.', @@ -1576,7 +1581,7 @@ def _GetMessageForMatchingType(input_api, affected_file, line_number, line, - type_name, message): + ban_rule): """Helper method for CheckNoBannedFunctions and CheckNoDeprecatedMojoTypes. Returns an string composed of the name of the file, the line number where the @@ -1585,25 +1590,25 @@ """ result = [] - if input_api.re.search(r"^ *//", - line): # Ignore comments about banned types. + # Ignore comments about banned types. + if input_api.re.search(r"^ *//", line): return result - if line.endswith( - " nocheck"): # A // nocheck comment will bypass this error. + # A // nocheck comment will bypass this error. + if line.endswith(" nocheck"): return result matched = False - if type_name[0:1] == '/': - regex = type_name[1:] + if ban_rule.pattern[0:1] == '/': + regex = ban_rule.pattern[1:] if input_api.re.search(regex, line): matched = True - elif type_name in line: + elif ban_rule.pattern in line: matched = True if matched: result.append(' %s:%d:' % (affected_file.LocalPath(), line_number)) - for message_line in message: - result.append(' %s' % message_line) + for line in ban_rule.explanation: + result.append(' %s' % line) return result @@ -1614,6 +1619,9 @@ errors = [] def IsExcludedFile(affected_file, excluded_paths): + if not excluded_paths: + return False + local_path = affected_file.LocalPath() for item in excluded_paths: if input_api.re.match(item, local_path): @@ -1633,12 +1641,15 @@ return True return False - def CheckForMatch(affected_file, line_num, line, func_name, message, - error): + def CheckForMatch(affected_file, line_num: int, line: str, + ban_rule: BanRule): + if IsExcludedFile(affected_file, ban_rule.excluded_paths): + return + problems = _GetMessageForMatchingType(input_api, f, line_num, line, - func_name, message) + ban_rule) if problems: - if error: + if ban_rule.treat_as_error is not None and ban_rule.treat_as_error: errors.extend(problems) else: warnings.extend(problems) @@ -1646,33 +1657,31 @@ file_filter = lambda f: f.LocalPath().endswith(('.java')) for f in input_api.AffectedFiles(file_filter=file_filter): for line_num, line in f.ChangedContents(): - for func_name, message, error in _BANNED_JAVA_FUNCTIONS: - CheckForMatch(f, line_num, line, func_name, message, error) + for ban_rule in _BANNED_JAVA_FUNCTIONS: + CheckForMatch(f, line_num, line, ban_rule) file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h')) for f in input_api.AffectedFiles(file_filter=file_filter): for line_num, line in f.ChangedContents(): - for func_name, message, error in _BANNED_OBJC_FUNCTIONS: - CheckForMatch(f, line_num, line, func_name, message, error) + for ban_rule in _BANNED_OBJC_FUNCTIONS: + CheckForMatch(f, line_num, line, ban_rule) for f in input_api.AffectedFiles(file_filter=IsIosObjcFile): for line_num, line in f.ChangedContents(): - for func_name, message, error in _BANNED_IOS_OBJC_FUNCTIONS: - CheckForMatch(f, line_num, line, func_name, message, error) + for ban_rule in _BANNED_IOS_OBJC_FUNCTIONS: + CheckForMatch(f, line_num, line, ban_rule) egtest_filter = lambda f: f.LocalPath().endswith(('_egtest.mm')) for f in input_api.AffectedFiles(file_filter=egtest_filter): for line_num, line in f.ChangedContents(): - for func_name, message, error in _BANNED_IOS_EGTEST_FUNCTIONS: - CheckForMatch(f, line_num, line, func_name, message, error) + for ban_rule in _BANNED_IOS_EGTEST_FUNCTIONS: + CheckForMatch(f, line_num, line, ban_rule) file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h')) for f in input_api.AffectedFiles(file_filter=file_filter): for line_num, line in f.ChangedContents(): - for func_name, message, error, excluded_paths in _BANNED_CPP_FUNCTIONS: - if IsExcludedFile(f, excluded_paths): - continue - CheckForMatch(f, line_num, line, func_name, message, error) + for ban_rule in _BANNED_CPP_FUNCTIONS: + CheckForMatch(f, line_num, line, ban_rule) result = [] if (warnings): @@ -1690,22 +1699,16 @@ """Make sure that banned java imports are not used.""" errors = [] - def IsException(path, exceptions): - for exception in exceptions: - if (path.startswith(exception)): - return True - return False - file_filter = lambda f: f.LocalPath().endswith(('.java')) for f in input_api.AffectedFiles(file_filter=file_filter): for line_num, line in f.ChangedContents(): - for import_name, message, exceptions in _BANNED_JAVA_IMPORTS: - if IsException(f.LocalPath(), exceptions): - continue + for ban_rule in _BANNED_JAVA_IMPORTS: + # Consider merging this into the above function. There is no + # real difference anymore other than helping with a little + # bit of boilerplate text. Doing so means things like + # `treat_as_error` will also be uniformly handled. problems = _GetMessageForMatchingType(input_api, f, line_num, - line, - 'import ' + import_name, - message) + line, ban_rule) if problems: errors.extend(problems) result = [] @@ -1733,9 +1736,9 @@ continue for line_num, line in f.ChangedContents(): - for func_name, message in _DEPRECATED_MOJO_TYPES: + for ban_rule in _DEPRECATED_MOJO_TYPES: problems = _GetMessageForMatchingType(input_api, f, line_num, - line, func_name, message) + line, ban_rule) if problems: # Raise errors inside |error_paths| and warnings everywhere else.
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index 493ea175..7b7e98f 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -296,5 +296,7 @@ "Enables the use of sec-ch-viewport-height client hint."), Flag.baseFeature(BlinkFeatures.USER_AGENT_OVERRIDE_EXPERIMENT, "Collects metrics on when the User-Agent string is overridden and how"), + Flag.baseFeature(GpuFeatures.CANVAS_CONTEXT_LOST_IN_BACKGROUND, + "Free Canvas2D resources when the webview is in the background."), }; }
diff --git a/ash/ambient/ambient_photo_controller.cc b/ash/ambient/ambient_photo_controller.cc index 225db1b7..0c0b4a6 100644 --- a/ash/ambient/ambient_photo_controller.cc +++ b/ash/ambient/ambient_photo_controller.cc
@@ -150,7 +150,7 @@ AmbientPhotoController::~AmbientPhotoController() = default; void AmbientPhotoController::Init() { - state_ = State::kPreparingInitialTopicSets; + state_ = State::kPreparingNextTopicSet; topic_index_ = 0; retries_to_read_from_cache_ = kMaxNumberOfCachedImages; backup_retries_to_read_from_cache_ = GetBackupPhotoUrls().size(); @@ -202,26 +202,24 @@ } DVLOG(3) << "UI event " << marker << " triggering topic refresh"; - switch (state_) { - case State::kInactive: - case State::kPreparingInitialTopicSets: - // In these states, the UI shouldn't be active, so it it's unexpected for - // the controller to receive a UI event. - LOG(ERROR) << "Received unexpected UI marker " << marker << " in state " - << state_; - break; - case State::kWaitingForNextMarker: - state_ = State::kPreparingNextTopicSet; - num_topics_prepared_ = 0; - StartPreparingNextTopic(); - break; - case State::kPreparingNextTopicSet: - // The controller is still in the middle of preparing a topic from the - // previous set (i.e. waiting on a callback or timer to fire). Resetting - // |num_topics_prepared_| to 0 is enough, and the topic currently being - // prepared will count towards the next set. - num_topics_prepared_ = 0; - break; + if (state_ == State::kInactive) { + LOG(DFATAL) << "Received unexpected UI marker " << marker + << " while inactive"; + return; + } + + bool is_still_preparing_topics = state_ != State::kWaitingForNextMarker; + state_ = State::kPreparingNextTopicSet; + num_topics_prepared_ = 0; + if (is_still_preparing_topics) { + // The controller is still in the middle of preparing a topic from the + // previous set (i.e. waiting on a callback or timer to fire). Resetting + // |num_topics_prepared_| to 0 above is enough, and the topic currently + // being prepared will count towards the next set. + DVLOG(4) << "Did not finished preparing current topic set in time. " + "Starting new set..."; + } else { + StartPreparingNextTopic(); } } @@ -231,10 +229,10 @@ ScheduleFetchTopics(/*backoff=*/false); // Only call FetchPhotoRawData() for on-demand fetches. If a scheduled topic - // fetch happens to occur during the PREPARING_INITIAL_TOPIC_SETS or - // PREPARING_NEXT_TOPIC_SET state and FetchPhotoRawData() is called, not only - // is that unnecessary but it could also result in the controller decoding - // multiple topics simultaneously, which is currently not supported. + // fetch happens to occur during the |kPreparingNextTopicSet| state and + // FetchPhotoRawData() is called, not only is that unnecessary but it could + // also result in the controller decoding multiple topics simultaneously, + // which is currently not supported. if (latest_fetch_topic_request_type_ == FetchTopicRequestType::kOnDemand) { FetchPhotoRawData(); } @@ -575,43 +573,28 @@ ResetImageData(); + if (state_ != State::kPreparingNextTopicSet) { + LOG(ERROR) << "Topic prepared when controller should be idle in state " + << state_; + return; + } + // AddNextImage() can call out to observers, who can synchronously interact // with the controller within their observer notification methods. So the // internal |state_| should be updated before calling AddNextImage() so that // it is consistent with the model. - State previous_state = state_; - size_t target_num_topics_to_prepare = 0; - switch (state_) { - case State::kInactive: - case State::kWaitingForNextMarker: - LOG(ERROR) << "Topic prepared when controller should be idle in state " - << state_; - return; - case State::kPreparingInitialTopicSets: - target_num_topics_to_prepare = - ambient_backend_model_.photo_config().GetNumDecodedTopicsToBuffer(); - break; - case State::kPreparingNextTopicSet: - target_num_topics_to_prepare = - ambient_backend_model_.photo_config().topic_set_size; - break; - } - + size_t target_num_topics_to_prepare = + ambient_backend_model_.ImagesReady() + ? ambient_backend_model_.photo_config().topic_set_size + : ambient_backend_model_.photo_config().GetNumDecodedTopicsToBuffer(); ++num_topics_prepared_; - if (num_topics_prepared_ == target_num_topics_to_prepare) + if (num_topics_prepared_ >= target_num_topics_to_prepare) state_ = State::kWaitingForNextMarker; ambient_backend_model_.AddNextImage(std::move(detailed_photo)); - if (previous_state == State::kPreparingInitialTopicSets && - state_ == State::kWaitingForNextMarker) { - DCHECK(ambient_backend_model_.ImagesReady()); - } - - if (state_ == State::kPreparingInitialTopicSets || - state_ == State::kPreparingNextTopicSet) { + if (state_ == State::kPreparingNextTopicSet) StartPreparingNextTopic(); - } } void AmbientPhotoController::StartDownloadingWeatherConditionIcon( @@ -677,8 +660,7 @@ } void AmbientPhotoController::StartPreparingNextTopic() { - DCHECK(state_ == State::kPreparingInitialTopicSets || - state_ == State::kPreparingNextTopicSet); + DCHECK_EQ(state_, State::kPreparingNextTopicSet); if (HasExhaustedAllTopicsInModel() && !HasModelReachedMaxTopicCapacity()) { FetchTopics(FetchTopicRequestType::kOnDemand); } else { @@ -691,8 +673,6 @@ switch (state) { case AmbientPhotoController::State::kInactive: return os << "INACTIVE"; - case AmbientPhotoController::State::kPreparingInitialTopicSets: - return os << "PREPARING_INITIAL_TOPIC_SETS"; case AmbientPhotoController::State::kWaitingForNextMarker: return os << "WAITING_FOR_NEXT_MARKER"; case AmbientPhotoController::State::kPreparingNextTopicSet:
diff --git a/ash/ambient/ambient_photo_controller.h b/ash/ambient/ambient_photo_controller.h index 48f1599..ffb2773f 100644 --- a/ash/ambient/ambient_photo_controller.h +++ b/ash/ambient/ambient_photo_controller.h
@@ -68,47 +68,44 @@ // // The controller's state machine: // -// INACTIVE +// kInactive // | // | // v -// PREPARING_INITIAL_TOPIC_SETS -// | -// | -// v -// WAITING_FOR_NEXT_MARKER <----- -// | | -// | | -// v | -// PREPARING_NEXT_TOPIC_SET ----- +// kPreparingNextTopicSet <----- +// | | +// | | +// v | +// kWaitingForNextMarker ------- // -// INACTIVE: +// kInactive: // The controller is idle, and the model has no decoded topics in it. This is // the initial state when the controller is constructed. Although not // illustrated above, the controller can transition to this state from any of // the other states via a call to StopScreenUpdate(). // -// PREPARING_INITIAL_TOPIC_SETS: -// At this point, the UI has not started rendering yet, and the controller is -// preparing initial sets of topics. The AmbientPhotoConfig dictates how many -// sets to prepare initially. This state is triggered by a call to -// StartScreenUpdate(). It is complete when the desired number of initial topic -// sets have been prepared. // -// WAITING_FOR_NEXT_MARKER: +// kPreparingNextTopicSet (a.k.a. "refreshing" the model's topics): +// The very first time this state is reached, the UI has not started rendering +// yet, and the controller is preparing initial sets of topics. The +// AmbientPhotoConfig dictates how many sets to prepare initially. This state is +// initially triggered by a call to StartScreenUpdate(), and it ends when +// AmbientBackendModel::ImagesReady() is true. +// +// kWaitingForNextMarker: // The UI is rendering the decoded topics currently in the model, and the // controller is idle. It's waiting for the right marker(s) to be hit in the UI // before it becomes active and starts preparing the next set of topics. // -// PREPARING_NEXT_TOPIC_SET (a.k.a. "refreshing" the model's topics): +// kPreparingNextTopicSet (again): // A target marker has been hit, and the controller immediately starts preparing -// the next set of topics. Unlike the PREPARING_INITIAL_TOPIC_SETS state, there -// is only ever 1 topic set prepared in this state, and the UI is rendering -// while the topics are being prepared. After the topic set is completely -// prepared, the controller goes back to WAITING_FOR_NEXT_MARKER. If another -// target marker is received while the controller is still preparing a topic -// set, the controller will simply reset its internal "counter" to 0 and start -// preparing a brand new set. +// the next set of topics. Unlike the first time this state was hit, there +// is only ever 1 topic set prepared, and the UI is rendering while the topics +// are being prepared. After the topic set is completely prepared, the +// controller goes back to WAITING_FOR_NEXT_MARKER. If another target marker is +// received while the controller is still preparing a topic set, the controller +// will simply reset its internal "counter" to 0 and start preparing a brand new +// set. class ASH_EXPORT AmbientPhotoController : public AmbientBackendModelObserver, public AmbientViewEventHandler { public: @@ -146,27 +143,21 @@ void ClearCache(); private: - enum class State { - kInactive, - kPreparingInitialTopicSets, - kWaitingForNextMarker, - kPreparingNextTopicSet - }; + enum class State { kInactive, kWaitingForNextMarker, kPreparingNextTopicSet }; // Describes the 2 cases for when new topics are fetched from the IMAX sever. enum class FetchTopicRequestType { - // The controller is in the PREPARING_INITIAL_TOPIC_SETS or - // PREPARING_NEXT_TOPIC_SET state and hence, there is an immediate demand to - // prepare more topics. If it has exhausted all of the existing topics in - // the model and the model has capacity to store more topics, the controller - // will fetch a new set of topics and will immediately download/save/decode - // topics from the new set afterwards. + // The controller is in the |kPreparingNextTopicSet| state and hence, there + // is an immediate demand to prepare more topics. If it has exhausted all of + // the existing topics in the model and the model has capacity to store more + // topics, the controller will fetch a new set of topics and will + // immediately download/save/decode topics from the new set afterwards. kOnDemand, - // The controller can be in any state other than INACTIVE. It will fetch a - // new set of topics if the |kTopicFetchInterval| has elapsed since the last - // topic fetch completed, regardless of that fetch's request type. This is - // done to guarantee that a sufficient amount of topics are available in the - // model before the access token required to fetch new topics from the + // The controller can be in any state other than |kInactive|. It will fetch + // a new set of topics if the |kTopicFetchInterval| has elapsed since the + // last topic fetch completed, regardless of that fetch's request type. This + // is done to guarantee that a sufficient amount of topics are available in + // the model before the access token required to fetch new topics from the // server expires. In other words, a topic fetch is guaranteed to occur at // least every |kTopicFetchInterval| seconds until // |kMaxNumberOfCachedImages| topics are available in the model. @@ -339,8 +330,7 @@ gfx::ImageSkia related_image_; // Tracks the number of topics that have been prepared since the controller - // last transitioned to either the PREPARING_INITIAL_TOPIC_SETS or - // PREPARING_NEXT_TOPIC_SET state. + // last transitioned to the |kPreparingNextTopicSet| state. size_t num_topics_prepared_ = 0; // Transient variable. Type of the most recent successful topic fetch.
diff --git a/ash/ambient/ambient_photo_controller_unittest.cc b/ash/ambient/ambient_photo_controller_unittest.cc index 24f37f0..ab761468 100644 --- a/ash/ambient/ambient_photo_controller_unittest.cc +++ b/ash/ambient/ambient_photo_controller_unittest.cc
@@ -4,11 +4,14 @@ #include "ash/ambient/ambient_photo_controller.h" +#include <array> #include <memory> +#include <tuple> #include <utility> #include "ash/ambient/ambient_constants.h" #include "ash/ambient/ambient_controller.h" +#include "ash/ambient/model/ambient_animation_photo_config.h" #include "ash/ambient/model/ambient_backend_model.h" #include "ash/ambient/model/ambient_backend_model_observer.h" #include "ash/ambient/model/ambient_photo_config.h" @@ -22,6 +25,7 @@ #include "base/base_paths.h" #include "base/bind.h" #include "base/callback.h" +#include "base/check.h" #include "base/containers/contains.h" #include "base/files/file_enumerator.h" #include "base/files/file_path.h" @@ -35,6 +39,7 @@ #include "base/test/scoped_run_loop_timeout.h" #include "base/time/time.h" #include "base/timer/timer.h" +#include "cc/paint/skottie_resource_metadata.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/gfx/image/image_skia.h" @@ -44,6 +49,7 @@ using ::testing::Contains; using ::testing::Eq; using ::testing::Not; +using ::testing::Pointwise; using ::testing::SizeIs; namespace { @@ -57,9 +63,18 @@ MOCK_METHOD(void, OnImagesReady, (), (override)); }; +bool AreBackedBySameImage(const PhotoWithDetails& topic_l, + const PhotoWithDetails& topic_r) { + return !topic_l.photo.isNull() && !topic_r.photo.isNull() && + topic_l.photo.BackedBySameObjectAs(topic_r.photo); +} + +MATCHER(BackedBySameImage, "") { + return AreBackedBySameImage(std::get<0>(arg), std::get<1>(arg)); +} + MATCHER_P(BackedBySameImageAs, photo_with_details, "") { - return !arg.photo.isNull() && !photo_with_details.photo.isNull() && - arg.photo.BackedBySameObjectAs(photo_with_details.photo); + return AreBackedBySameImage(arg, photo_with_details); } } // namespace @@ -158,14 +173,32 @@ } }; +// Has 2 positions in the animation for photos and 2 dynamic assets per +// position. class AmbientPhotoControllerAnimationTest : public AmbientPhotoControllerTest { protected: - static constexpr int kNumDynamicAssets = 4; - void SetUp() override { AmbientAshTestBase::SetUp(); + + cc::SkottieResourceMetadataMap resource_metadata; + std::array<std::string, 4> all_dynamic_asset_ids = { + GenerateLottieDynamicAssetIdForTesting(/*position=*/"A", /*idx=*/1), + GenerateLottieDynamicAssetIdForTesting(/*position=*/"A", /*idx=*/2), + GenerateLottieDynamicAssetIdForTesting(/*position=*/"B", /*idx=*/1), + GenerateLottieDynamicAssetIdForTesting(/*position=*/"B", /*idx=*/2)}; + for (const std::string& asset_id : all_dynamic_asset_ids) { + CHECK(resource_metadata.RegisterAsset("test-path", "test-name", asset_id, + /*size=*/absl::nullopt)); + } + photo_controller()->ambient_backend_model()->SetPhotoConfig( - GenerateAnimationConfigWithNAssets(kNumDynamicAssets)); + CreateAmbientAnimationPhotoConfig(resource_metadata)); + CHECK_EQ(photo_config().GetNumDecodedTopicsToBuffer(), 4u); + CHECK_EQ(photo_config().topic_set_size, 2u); + } + + const AmbientPhotoConfig& photo_config() { + return photo_controller()->ambient_backend_model()->photo_config(); } }; @@ -640,7 +673,7 @@ photo_controller()->StartScreenUpdate(); RunUntilImagesReady(); EXPECT_THAT(photo_controller()->ambient_backend_model()->all_decoded_topics(), - SizeIs(kNumDynamicAssets)); + SizeIs(photo_config().GetNumDecodedTopicsToBuffer())); } TEST_F(AmbientPhotoControllerAnimationTest, @@ -655,32 +688,31 @@ AmbientPhotoConfig::Marker::kUiStartRendering); // Simulate cycle ending. This should trigger an image refresh. photo_controller()->OnMarkerHit(AmbientPhotoConfig::Marker::kUiCycleEnded); - RunUntilNextTopicsAdded(kNumDynamicAssets); + RunUntilNextTopicsAdded(photo_config().topic_set_size); base::circular_deque<PhotoWithDetails> new_photos = photo_controller()->ambient_backend_model()->all_decoded_topics(); - EXPECT_THAT(new_photos, SizeIs(kNumDynamicAssets)); + EXPECT_THAT(new_photos, SizeIs(photo_config().GetNumDecodedTopicsToBuffer())); ASSERT_THAT(old_photos.size(), Eq(new_photos.size())); - // Verify that the new set actually has different photos from the initial set. - EXPECT_THAT(new_photos, - Not(AnyOf(Contains(BackedBySameImageAs(old_photos[0])), - Contains(BackedBySameImageAs(old_photos[1])), - Contains(BackedBySameImageAs(old_photos[2])), - Contains(BackedBySameImageAs(old_photos[3]))))); + // Verify that the new set actually has 2 new photos and 2 photos from the + // old set. + EXPECT_THAT(new_photos[0], BackedBySameImageAs(old_photos[2])); + EXPECT_THAT(new_photos[1], BackedBySameImageAs(old_photos[3])); + EXPECT_THAT(old_photos, Not(Contains(BackedBySameImageAs(new_photos[2])))); + EXPECT_THAT(old_photos, Not(Contains(BackedBySameImageAs(new_photos[3])))); old_photos = new_photos; // One more cycle. photo_controller()->OnMarkerHit(AmbientPhotoConfig::Marker::kUiCycleEnded); - RunUntilNextTopicsAdded(kNumDynamicAssets); + RunUntilNextTopicsAdded(photo_config().topic_set_size); new_photos = photo_controller()->ambient_backend_model()->all_decoded_topics(); - EXPECT_THAT(new_photos, SizeIs(kNumDynamicAssets)); + EXPECT_THAT(new_photos, SizeIs(photo_config().GetNumDecodedTopicsToBuffer())); ASSERT_THAT(old_photos.size(), Eq(new_photos.size())); - EXPECT_THAT(new_photos, - Not(AnyOf(Contains(BackedBySameImageAs(old_photos[0])), - Contains(BackedBySameImageAs(old_photos[1])), - Contains(BackedBySameImageAs(old_photos[2])), - Contains(BackedBySameImageAs(old_photos[3]))))); + EXPECT_THAT(new_photos[0], BackedBySameImageAs(old_photos[2])); + EXPECT_THAT(new_photos[1], BackedBySameImageAs(old_photos[3])); + EXPECT_THAT(old_photos, Not(Contains(BackedBySameImageAs(new_photos[2])))); + EXPECT_THAT(old_photos, Not(Contains(BackedBySameImageAs(new_photos[3])))); } TEST_F(AmbientPhotoControllerAnimationTest, @@ -691,13 +723,18 @@ photo_controller()->OnMarkerHit( AmbientPhotoConfig::Marker::kUiStartRendering); photo_controller()->OnMarkerHit(AmbientPhotoConfig::Marker::kUiCycleEnded); - RunUntilNextTopicsAdded(kNumDynamicAssets); + RunUntilNextTopicsAdded(photo_config().topic_set_size); // Fast forward time to make sure no more images are prepared after // |kNumDynamicAssets| has been added. + base::circular_deque<PhotoWithDetails> old_photos = + photo_controller()->ambient_backend_model()->all_decoded_topics(); task_environment()->FastForwardBy(base::Minutes(1)); + base::circular_deque<PhotoWithDetails> new_photos = + photo_controller()->ambient_backend_model()->all_decoded_topics(); EXPECT_THAT(photo_controller()->ambient_backend_model()->all_decoded_topics(), - SizeIs(kNumDynamicAssets)); + SizeIs(photo_config().GetNumDecodedTopicsToBuffer())); + EXPECT_THAT(new_photos, Pointwise(BackedBySameImage(), old_photos)); } TEST_F(AmbientPhotoControllerAnimationTest, @@ -710,33 +747,62 @@ photo_controller()->OnMarkerHit( AmbientPhotoConfig::Marker::kUiStartRendering); photo_controller()->OnMarkerHit(AmbientPhotoConfig::Marker::kUiCycleEnded); - RunUntilNextTopicsAdded(kNumDynamicAssets / 2); + RunUntilNextTopicsAdded(photo_config().topic_set_size / 2); base::circular_deque<PhotoWithDetails> new_photos = photo_controller()->ambient_backend_model()->all_decoded_topics(); - EXPECT_THAT(new_photos, SizeIs(kNumDynamicAssets)); + EXPECT_THAT(new_photos, SizeIs(photo_config().GetNumDecodedTopicsToBuffer())); ASSERT_THAT(old_photos.size(), Eq(new_photos.size())); - EXPECT_THAT(new_photos[0], BackedBySameImageAs(old_photos[2])); - EXPECT_THAT(new_photos[1], BackedBySameImageAs(old_photos[3])); - EXPECT_THAT(old_photos, Not(Contains(BackedBySameImageAs(new_photos[2])))); + EXPECT_THAT(new_photos[0], BackedBySameImageAs(old_photos[1])); + EXPECT_THAT(new_photos[1], BackedBySameImageAs(old_photos[2])); + EXPECT_THAT(new_photos[2], BackedBySameImageAs(old_photos[3])); EXPECT_THAT(old_photos, Not(Contains(BackedBySameImageAs(new_photos[3])))); old_photos = new_photos; // Cycle ends when only half of target amount refreshed. photo_controller()->OnMarkerHit(AmbientPhotoConfig::Marker::kUiCycleEnded); - RunUntilNextTopicsAdded(kNumDynamicAssets); + RunUntilNextTopicsAdded(photo_config().topic_set_size); // Fast forward time to make sure no more images are prepared after - // |kNumDynamicAssets| has been added. + // |photo_config().topic_set_size| has been added. task_environment()->FastForwardBy(base::Minutes(1)); new_photos = photo_controller()->ambient_backend_model()->all_decoded_topics(); - EXPECT_THAT(new_photos, SizeIs(kNumDynamicAssets)); + EXPECT_THAT(new_photos, SizeIs(photo_config().GetNumDecodedTopicsToBuffer())); ASSERT_THAT(old_photos.size(), Eq(new_photos.size())); - EXPECT_THAT(new_photos, - Not(AnyOf(Contains(BackedBySameImageAs(old_photos[0])), - Contains(BackedBySameImageAs(old_photos[1])), - Contains(BackedBySameImageAs(old_photos[2])), - Contains(BackedBySameImageAs(old_photos[3]))))); + EXPECT_THAT(new_photos[0], BackedBySameImageAs(old_photos[2])); + EXPECT_THAT(new_photos[1], BackedBySameImageAs(old_photos[3])); + EXPECT_THAT(old_photos, Not(Contains(BackedBySameImageAs(new_photos[2])))); + EXPECT_THAT(old_photos, Not(Contains(BackedBySameImageAs(new_photos[3])))); +} + +TEST_F(AmbientPhotoControllerAnimationTest, + HandlesMarkerWhenInitialTopicSetIncomplete) { + constexpr base::TimeDelta kPhotoDownloadDelay = base::Seconds(5); + constexpr base::TimeDelta kTimeoutAfterFirstPhoto = base::Seconds(10); + SetPhotoDownloadDelay(kPhotoDownloadDelay); + photo_controller()->StartScreenUpdate(); + task_environment()->FastForwardBy(kPhotoDownloadDelay + + kTimeoutAfterFirstPhoto); + ASSERT_TRUE(photo_controller()->ambient_backend_model()->ImagesReady()); + ASSERT_THAT(photo_controller()->ambient_backend_model()->all_decoded_topics(), + SizeIs(3)); + + // UI starts rendering when only 3/4 of the initial topic set is prepared. + // The controller should immediately start preparing another 2 topics (the + // size of 1 topic set). + photo_controller()->OnMarkerHit( + AmbientPhotoConfig::Marker::kUiStartRendering); + task_environment()->FastForwardBy(kPhotoDownloadDelay * 2); + ASSERT_THAT(photo_controller()->ambient_backend_model()->all_decoded_topics(), + SizeIs(photo_config().GetNumDecodedTopicsToBuffer())); + // Fast forward time to make sure no more images are prepared after + // |photo_config().topic_set_size| has been added. + base::circular_deque<PhotoWithDetails> photos_before = + photo_controller()->ambient_backend_model()->all_decoded_topics(); + task_environment()->FastForwardBy(base::Minutes(1)); + base::circular_deque<PhotoWithDetails> photos_after = + photo_controller()->ambient_backend_model()->all_decoded_topics(); + EXPECT_THAT(photos_after, Pointwise(BackedBySameImage(), photos_before)); } } // namespace ash
diff --git a/ash/ambient/test/ambient_ash_test_base.cc b/ash/ambient/test/ambient_ash_test_base.cc index 0edac98..2b7b1f0 100644 --- a/ash/ambient/test/ambient_ash_test_base.cc +++ b/ash/ambient/test/ambient_ash_test_base.cc
@@ -69,7 +69,7 @@ // Pretend to respond asynchronously. base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::BindOnce(std::move(callback), std::move(data)), - base::Milliseconds(1)); + photo_download_delay_); } void DownloadPhotoToFile(const std::string& url, @@ -146,6 +146,10 @@ void SetDecodedPhoto(const gfx::ImageSkia& image) { decoded_image_ = image; } + void SetPhotoDownloadDelay(base::TimeDelta delay) { + photo_download_delay_ = delay; + } + const std::map<int, ::ambient::PhotoCacheEntry>& get_files() { return files_; } @@ -162,6 +166,8 @@ absl::optional<gfx::ImageSkia> decoded_image_; std::map<int, ::ambient::PhotoCacheEntry> files_; + + base::TimeDelta photo_download_delay_ = base::Milliseconds(1); }; AmbientAshTestBase::AmbientAshTestBase() @@ -577,4 +583,11 @@ photo_cache->SetDecodedPhoto(image); } +void AmbientAshTestBase::SetPhotoDownloadDelay(base::TimeDelta delay) { + auto* photo_cache = static_cast<TestAmbientPhotoCacheImpl*>( + photo_controller()->get_photo_cache_for_testing()); + + photo_cache->SetPhotoDownloadDelay(delay); +} + } // namespace ash
diff --git a/ash/ambient/test/ambient_ash_test_base.h b/ash/ambient/test/ambient_ash_test_base.h index 4bb1a43b..3594a0a 100644 --- a/ash/ambient/test/ambient_ash_test_base.h +++ b/ash/ambient/test/ambient_ash_test_base.h
@@ -18,6 +18,7 @@ #include "ash/public/cpp/test/test_image_downloader.h" #include "ash/test/ash_test_base.h" #include "base/callback.h" +#include "base/time/time.h" #include "services/media_session/public/mojom/media_session.mojom.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" @@ -189,6 +190,8 @@ void SetDecodePhotoImage(const gfx::ImageSkia& image); + void SetPhotoDownloadDelay(base::TimeDelta delay); + private: void SpinWaitForAmbientViewAvailable( const base::RepeatingClosure& quit_closure);
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index e2e26315..69bd26dd 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -1196,6 +1196,12 @@ } } +void AppListControllerImpl::StartZeroStateSearch(base::OnceClosure callback, + base::TimeDelta timeout) { + if (client_) + client_->StartZeroStateSearch(std::move(callback), timeout); +} + void AppListControllerImpl::OpenSearchResult(const std::string& result_id, int event_flags, AppListLaunchedFrom launched_from,
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h index c279e7a..7f6dd3c 100644 --- a/ash/app_list/app_list_controller_impl.h +++ b/ash/app_list/app_list_controller_impl.h
@@ -152,6 +152,8 @@ AppListNotifier* GetNotifier() override; void StartAssistant() override; void StartSearch(const std::u16string& raw_query) override; + void StartZeroStateSearch(base::OnceClosure callback, + base::TimeDelta timeout) override; void OpenSearchResult(const std::string& result_id, int event_flags, AppListLaunchedFrom launched_from,
diff --git a/ash/app_list/app_list_presenter_impl.cc b/ash/app_list/app_list_presenter_impl.cc index a6867dea..6ee1bca 100644 --- a/ash/app_list/app_list_presenter_impl.cc +++ b/ash/app_list/app_list_presenter_impl.cc
@@ -300,6 +300,7 @@ void AppListPresenterImpl::SetViewVisibility(bool visible) { if (!view_) return; + view_->OnAppListVisibilityWillChange(visible); view_->SetVisible(visible); view_->search_box_view()->SetVisible(visible); }
diff --git a/ash/app_list/app_list_test_view_delegate.cc b/ash/app_list/app_list_test_view_delegate.cc index 57854cd..181b0e06 100644 --- a/ash/app_list/app_list_test_view_delegate.cc +++ b/ash/app_list/app_list_test_view_delegate.cc
@@ -30,6 +30,11 @@ return true; } +void AppListTestViewDelegate::StartZeroStateSearch(base::OnceClosure callback, + base::TimeDelta timeout) { + std::move(callback).Run(); +} + void AppListTestViewDelegate::OpenSearchResult( const std::string& result_id, int event_flags,
diff --git a/ash/app_list/app_list_test_view_delegate.h b/ash/app_list/app_list_test_view_delegate.h index a03204d..0711794 100644 --- a/ash/app_list/app_list_test_view_delegate.h +++ b/ash/app_list/app_list_test_view_delegate.h
@@ -65,6 +65,8 @@ bool KeyboardTraversalEngaged() override; void StartAssistant() override {} void StartSearch(const std::u16string& raw_query) override {} + void StartZeroStateSearch(base::OnceClosure callback, + base::TimeDelta timeout) override; void OpenSearchResult(const std::string& result_id, int event_flags, ash::AppListLaunchedFrom launched_from,
diff --git a/ash/app_list/app_list_view_delegate.h b/ash/app_list/app_list_view_delegate.h index f3c39b2..3f2b5d4 100644 --- a/ash/app_list/app_list_view_delegate.h +++ b/ash/app_list/app_list_view_delegate.h
@@ -49,6 +49,13 @@ // box by the user. virtual void StartSearch(const std::u16string& raw_query) = 0; + // Starts zero state search to load suggested content shown in productivity + // launcher. Called when the tablet mode productivity launcher visibility + // starts changing to visible. `callback` is called when the zero state search + // completes, or times out (i.e. takes more time than `timeout`). + virtual void StartZeroStateSearch(base::OnceClosure callback, + base::TimeDelta timeout) = 0; + // Invoked to open the search result and log a click. If the result is // represented by a SuggestedChipView or is a zero state result, // |suggested_index| is the index of the view in the list of suggestions.
diff --git a/ash/app_list/views/app_list_bubble_apps_page.cc b/ash/app_list/views/app_list_bubble_apps_page.cc index 6249e7c..6cafec4 100644 --- a/ash/app_list/views/app_list_bubble_apps_page.cc +++ b/ash/app_list/views/app_list_bubble_apps_page.cc
@@ -639,8 +639,8 @@ // Hide the undo toast instantly before starting the toast fade in animation. toast_container_->layer()->SetOpacity(0.f); - animation_builder.GetCurrentSequence().SetOpacity(toast_container_->layer(), - 1.f); + animation_builder.GetCurrentSequence().SetOpacity( + toast_container_->layer(), 1.f, gfx::Tween::ACCEL_5_70_DECEL_90); } void AppListBubbleAppsPage::OnAppsGridViewFadeInAnimationEnded(bool aborted) {
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index fb788cb..47ddf6949 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -1706,6 +1706,10 @@ } } +void AppListView::OnAppListVisibilityWillChange(bool visible) { + GetAppsContainerView()->OnAppListVisibilityWillChange(visible); +} + void AppListView::OnAppListVisibilityChanged(bool shown) { GetAppsContainerView()->OnAppListVisibilityChanged(shown); }
diff --git a/ash/app_list/views/app_list_view.h b/ash/app_list/views/app_list_view.h index a404442..5550679 100644 --- a/ash/app_list/views/app_list_view.h +++ b/ash/app_list/views/app_list_view.h
@@ -410,6 +410,7 @@ void UpdateWindowTitle(); // Called when app list visibility changed. + void OnAppListVisibilityWillChange(bool visible); void OnAppListVisibilityChanged(bool shown); private:
diff --git a/ash/app_list/views/apps_container_view.cc b/ash/app_list/views/apps_container_view.cc index 62b6634..af8432b 100644 --- a/ash/app_list/views/apps_container_view.cc +++ b/ash/app_list/views/apps_container_view.cc
@@ -139,6 +139,10 @@ // `scrollable_container_`. constexpr int kDefaultFadeoutMaskHeight = 16; +// Max amount of time to wait for zero state results when refreshing recent apps +// and continue section when launcher becomes visible. +constexpr base::TimeDelta kZeroStateSearchTimeout = base::Milliseconds(16); + } // namespace // A view that contains continue section, recent apps and a separator view, @@ -500,6 +504,17 @@ show_state_ = AppsContainerView::SHOW_APPS; } +void AppsContainerView::OnAppListVisibilityWillChange(bool visible) { + // Start zero state search to refresh contents of the continue section and + // recent apps (which are only shown for productivity launcher). + if (visible && features::IsProductivityLauncherEnabled()) { + contents_view_->GetAppListMainView()->view_delegate()->StartZeroStateSearch( + base::BindOnce(&AppsContainerView::UpdateRecentApps, + weak_ptr_factory_.GetWeakPtr()), + kZeroStateSearchTimeout); + } +} + void AppsContainerView::OnAppListVisibilityChanged(bool shown) { if (!toast_container_) return; @@ -1513,14 +1528,14 @@ // Hide the toast to prepare for the fade in animation, toast_container_->layer()->SetOpacity(0.f); - animation_builder.GetCurrentSequence().SetOpacity(toast_container_->layer(), - 1.f); + animation_builder.GetCurrentSequence().SetOpacity( + toast_container_->layer(), 1.f, gfx::Tween::ACCEL_5_70_DECEL_90); // Continue section should be faded in only when the page changes. if (page_change) { continue_container_->layer()->SetOpacity(0.f); animation_builder.GetCurrentSequence().SetOpacity( - continue_container_->layer(), 1.f); + continue_container_->layer(), 1.f, gfx::Tween::ACCEL_5_70_DECEL_90); } }
diff --git a/ash/app_list/views/apps_container_view.h b/ash/app_list/views/apps_container_view.h index 3f416cad..e4dba36 100644 --- a/ash/app_list/views/apps_container_view.h +++ b/ash/app_list/views/apps_container_view.h
@@ -183,6 +183,12 @@ void OnTemporarySortOrderChanged( const absl::optional<AppListSortOrder>& new_order); + // Called by app list controller when the app list visibility is about to + // change - when the app list is about to be shown, initiates zero state + // search in order to update set of apps shown in recent apps and continue + // section contents. + void OnAppListVisibilityWillChange(bool visible); + // Updates the nudge in `toast_container_` when app list visibility changes. void OnAppListVisibilityChanged(bool shown);
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 7713d41..ae86f0e 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -2095,22 +2095,6 @@ reorder_animation_tracker_->Start(metrics_util::ForSmoothness( base::BindRepeating(&ReportReorderAnimationSmoothness, IsTabletMode()))); - const absl::optional<VisibleItemIndexRange> range = - GetVisibleItemIndexRange(); - - // TODO(https://crbug.com/1289411): handle the case that `range` is null. - DCHECK(range); - - // Assume all the items matched by the indices in `range` are placed on the - // same page. - const int page_index = - view_structure_.GetIndexFromModelIndex(range->first_index).page; - const int offset = - kFadeAnimationOffsetRatio * GetTotalTileSize(page_index).height(); - - gfx::Transform translate_offset; - translate_offset.Translate(0, offset); - { views::AnimationBuilder animation_builder; reorder_animation_abort_handle_ = animation_builder.GetAbortHandle(); @@ -2123,9 +2107,7 @@ /*abort=*/true)) .Once() .SetDuration(kFadeOutAnimationDuration) - .SetOpacity(layer(), 0.f, gfx::Tween::LINEAR) - .SetTransform(layer(), translate_offset, - gfx::Tween::LINEAR_OUT_SLOW_IN); + .SetOpacity(layer(), 0.f, gfx::Tween::LINEAR); } if (fade_out_start_closure_for_test_) @@ -2170,7 +2152,7 @@ /*abort=*/true)) .Once() .SetDuration(kFadeInAnimationDuration) - .SetOpacity(layer(), 1.f, gfx::Tween::LINEAR); + .SetOpacity(layer(), 1.f, gfx::Tween::ACCEL_5_70_DECEL_90); // Assume all the items matched by the indices in `range` are // placed on the same page. @@ -2197,7 +2179,7 @@ // existing time duration. SlideViewIntoPositionWithSequenceBlock( animated_view, offset, - /*time_delta=*/absl::nullopt, gfx::Tween::LINEAR, + /*time_delta=*/absl::nullopt, gfx::Tween::ACCEL_5_70_DECEL_90, &animation_builder.GetCurrentSequence()); }
diff --git a/ash/metrics/user_metrics_action.h b/ash/metrics/user_metrics_action.h index 38c161d..d4cc99a7 100644 --- a/ash/metrics/user_metrics_action.h +++ b/ash/metrics/user_metrics_action.h
@@ -12,18 +12,9 @@ // instead of adding things here. enum UserMetricsAction { UMA_DESKTOP_SWITCH_TASK, - UMA_LAUNCHER_BUTTON_PRESSED_WITH_MOUSE, - UMA_LAUNCHER_BUTTON_PRESSED_WITH_TOUCH, - UMA_LAUNCHER_CLICK_ON_APP, - UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON, UMA_LAUNCHER_LAUNCH_TASK, UMA_LAUNCHER_MINIMIZE_TASK, UMA_LAUNCHER_SWITCH_TASK, - UMA_SHELF_ALIGNMENT_SET_BOTTOM, - UMA_SHELF_ALIGNMENT_SET_LEFT, - UMA_SHELF_ALIGNMENT_SET_RIGHT, - UMA_SHELF_ITEM_PINNED, - UMA_SHELF_ITEM_UNPINNED, UMA_STATUS_AREA_AUDIO_CURRENT_INPUT_DEVICE, UMA_STATUS_AREA_AUDIO_CURRENT_OUTPUT_DEVICE, UMA_STATUS_AREA_AUDIO_SWITCH_INPUT_DEVICE,
diff --git a/ash/metrics/user_metrics_recorder.cc b/ash/metrics/user_metrics_recorder.cc index 89ad614..e6cabf8 100644 --- a/ash/metrics/user_metrics_recorder.cc +++ b/ash/metrics/user_metrics_recorder.cc
@@ -17,17 +17,14 @@ #include "ash/public/cpp/accessibility_controller_enums.h" #include "ash/public/cpp/shelf_item.h" #include "ash/public/cpp/shelf_model.h" -#include "ash/public/cpp/shell_window_ids.h" #include "ash/session/session_controller_impl.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_view.h" #include "ash/shell.h" -#include "ash/wm/desks/desks_util.h" #include "ash/wm/window_state.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "components/prefs/pref_service.h" -#include "ui/aura/window.h" namespace ash { @@ -100,62 +97,6 @@ return session->IsActiveUserSessionStarted() && !session->IsScreenLocked(); } -// Returns a list of window container ids that contain visible windows to be -// counted for UMA statistics. Note the containers are ordered from top most -// visible container to the lowest to allow the |GetNumVisibleWindows| method to -// short circuit when processing a maximized or fullscreen window. -std::vector<int> GetVisibleWindowContainerIds() { - std::vector<int> ids{kShellWindowId_PipContainer, - kShellWindowId_AlwaysOnTopContainer}; - // TODO(afakhry): Add metrics for the inactive desks. - ids.emplace_back(desks_util::GetActiveDeskContainerId()); - return ids; -} - -// Returns an approximate count of how many windows are currently visible in the -// primary root window. -int GetNumVisibleWindowsInPrimaryDisplay() { - int visible_window_count = 0; - bool maximized_or_fullscreen_window_present = false; - - for (const int& current_container_id : GetVisibleWindowContainerIds()) { - if (maximized_or_fullscreen_window_present) - break; - - const aura::Window::Windows& children = - Shell::GetContainer(Shell::Get()->GetPrimaryRootWindow(), - current_container_id) - ->children(); - // Reverse iterate over the child windows so that they are processed in - // visible stacking order. - for (aura::Window::Windows::const_reverse_iterator it = children.rbegin(), - rend = children.rend(); - it != rend; ++it) { - const aura::Window* child_window = *it; - const WindowState* child_window_state = WindowState::Get(child_window); - - if (!child_window->IsVisible() || child_window_state->IsMinimized()) - continue; - - // Only count activatable windows for 1 reason: - // - Ensures that a browser window and its transient, modal child will - // only count as 1 visible window. - if (child_window_state->CanActivate()) - ++visible_window_count; - - // Stop counting windows that will be hidden by maximized or fullscreen - // windows. Only windows in the active desk container and - // kShellWindowId_AlwaysOnTopContainer can be maximized or fullscreened - // and completely obscure windows beneath them. - if (child_window_state->IsMaximizedOrFullscreenOrPinned()) { - maximized_or_fullscreen_window_present = true; - break; - } - } - } - return visible_window_count; -} - // Records the number of items in the shelf as an UMA statistic. void RecordShelfItemCounts() { int pinned_item_count = 0; @@ -222,18 +163,6 @@ RecordAction(UserMetricsAction("Desktop_SwitchTask")); task_switch_metrics_recorder_.OnTaskSwitch(TaskSwitchSource::DESKTOP); break; - case UMA_LAUNCHER_BUTTON_PRESSED_WITH_MOUSE: - RecordAction(UserMetricsAction("Launcher_ButtonPressed_Mouse")); - break; - case UMA_LAUNCHER_BUTTON_PRESSED_WITH_TOUCH: - RecordAction(UserMetricsAction("Launcher_ButtonPressed_Touch")); - break; - case UMA_LAUNCHER_CLICK_ON_APP: - RecordAction(UserMetricsAction("Launcher_ClickOnApp")); - break; - case UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON: - RecordAction(UserMetricsAction("Launcher_ClickOnApplistButton")); - break; case UMA_LAUNCHER_LAUNCH_TASK: RecordAction(UserMetricsAction("Launcher_LaunchTask")); task_switch_metrics_recorder_.OnTaskSwitch(TaskSwitchSource::SHELF); @@ -245,21 +174,6 @@ RecordAction(UserMetricsAction("Launcher_SwitchTask")); task_switch_metrics_recorder_.OnTaskSwitch(TaskSwitchSource::SHELF); break; - case UMA_SHELF_ALIGNMENT_SET_BOTTOM: - RecordAction(UserMetricsAction("Shelf_AlignmentSetBottom")); - break; - case UMA_SHELF_ALIGNMENT_SET_LEFT: - RecordAction(UserMetricsAction("Shelf_AlignmentSetLeft")); - break; - case UMA_SHELF_ALIGNMENT_SET_RIGHT: - RecordAction(UserMetricsAction("Shelf_AlignmentSetRight")); - break; - case UMA_SHELF_ITEM_PINNED: - RecordAction(UserMetricsAction("Shelf_ItemPinned")); - break; - case UMA_SHELF_ITEM_UNPINNED: - RecordAction(UserMetricsAction("Shelf_ItemUnpinned")); - break; case UMA_STATUS_AREA_AUDIO_CURRENT_INPUT_DEVICE: RecordAction(UserMetricsAction("StatusArea_Audio_CurrentInputDevice")); break; @@ -490,8 +404,6 @@ if (IsUserInActiveDesktopEnvironment()) { RecordShelfItemCounts(); RecordPeriodicAppListMetrics(); - UMA_HISTOGRAM_COUNTS_100("Ash.NumberOfVisibleWindowsInPrimaryDisplay", - GetNumVisibleWindowsInPrimaryDisplay()); base::UmaHistogramBoolean( "Ash.AppNotificationBadgingPref",
diff --git a/ash/metrics/user_metrics_recorder_unittest.cc b/ash/metrics/user_metrics_recorder_unittest.cc index abaf391d..0fe4a3e 100644 --- a/ash/metrics/user_metrics_recorder_unittest.cc +++ b/ash/metrics/user_metrics_recorder_unittest.cc
@@ -21,9 +21,6 @@ namespace ash { namespace { -const char kAsh_NumberOfVisibleWindowsInPrimaryDisplay[] = - "Ash.NumberOfVisibleWindowsInPrimaryDisplay"; - const char kAsh_ActiveWindowShowTypeOverTime[] = "Ash.ActiveWindowShowTypeOverTime"; @@ -103,7 +100,6 @@ ASSERT_FALSE(test_api().IsUserInActiveDesktopEnvironment()); test_api().RecordPeriodicMetrics(); - histograms().ExpectTotalCount(kAsh_NumberOfVisibleWindowsInPrimaryDisplay, 0); histograms().ExpectTotalCount(kAsh_Shelf_NumberOfItems, 0); histograms().ExpectTotalCount(kAsh_Shelf_NumberOfPinnedItems, 0); histograms().ExpectTotalCount(kAsh_Shelf_NumberOfUnpinnedItems, 0); @@ -118,7 +114,6 @@ ASSERT_TRUE(test_api().IsUserInActiveDesktopEnvironment()); test_api().RecordPeriodicMetrics(); - histograms().ExpectTotalCount(kAsh_NumberOfVisibleWindowsInPrimaryDisplay, 1); histograms().ExpectTotalCount(kAsh_Shelf_NumberOfItems, 1); histograms().ExpectTotalCount(kAsh_Shelf_NumberOfPinnedItems, 1); histograms().ExpectTotalCount(kAsh_Shelf_NumberOfUnpinnedItems, 1);
diff --git a/ash/quick_pair/repository/BUILD.gn b/ash/quick_pair/repository/BUILD.gn index 063acb1..4a8058d0 100644 --- a/ash/quick_pair/repository/BUILD.gn +++ b/ash/quick_pair/repository/BUILD.gn
@@ -110,6 +110,8 @@ "fast_pair/pending_write_store_unittest.cc", "fast_pair/saved_device_registry_unittest.cc", "fast_pair_repository_impl_unittest.cc", + "oauth_http_fetcher_unittest.cc", + "unauthenticated_http_fetcher_unittest.cc", ] deps = [ @@ -124,8 +126,10 @@ "//base/test:test_support", "//chromeos/services/bluetooth_config/public/cpp", "//components/prefs:test_support", + "//components/signin/public/identity_manager:test_support", "//device/bluetooth:mocks", "//net", + "//net/traffic_annotation:test_support", "//services/data_decoder/public/cpp:test_support", "//services/network:test_support", "//services/network/public/cpp",
diff --git a/ash/quick_pair/repository/oauth_http_fetcher.cc b/ash/quick_pair/repository/oauth_http_fetcher.cc index ff771d2..8fd030e 100644 --- a/ash/quick_pair/repository/oauth_http_fetcher.cc +++ b/ash/quick_pair/repository/oauth_http_fetcher.cc
@@ -96,7 +96,7 @@ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory = QuickPairBrowserDelegate::Get()->GetURLLoaderFactory(); if (!url_loader_factory) { - QP_LOG(WARNING) << __func__ << ": No SharedURLLoaderFactory is available."; + QP_LOG(WARNING) << __func__ << ": URLLoaderFactory is not available."; std::move(callback_).Run(nullptr, nullptr); return; }
diff --git a/ash/quick_pair/repository/oauth_http_fetcher.h b/ash/quick_pair/repository/oauth_http_fetcher.h index 8571f978d..f1509594 100644 --- a/ash/quick_pair/repository/oauth_http_fetcher.h +++ b/ash/quick_pair/repository/oauth_http_fetcher.h
@@ -7,6 +7,7 @@ #include "ash/quick_pair/repository/http_fetcher.h" #include "base/callback.h" +#include "base/gtest_prod_util.h" #include "base/memory/weak_ptr.h" #include "components/signin/public/identity_manager/access_token_info.h" #include "google_apis/gaia/google_service_auth_error.h" @@ -60,6 +61,9 @@ std::string GetRequestTypeForBody(const std::string& body) override; private: + FRIEND_TEST_ALL_PREFIXES(OAuthHttpFetcherTest, + ExecuteGetRequest_MultipleRaceCondition); + void StartRequest(const GURL& url, FetchCompleteCallback callback); void OnAccessTokenFetched(GoogleServiceAuthError error, signin::AccessTokenInfo access_token_info);
diff --git a/ash/quick_pair/repository/oauth_http_fetcher_unittest.cc b/ash/quick_pair/repository/oauth_http_fetcher_unittest.cc new file mode 100644 index 0000000..caaa9fa --- /dev/null +++ b/ash/quick_pair/repository/oauth_http_fetcher_unittest.cc
@@ -0,0 +1,241 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/quick_pair/repository/oauth_http_fetcher.h" + +#include "ash/quick_pair/common/mock_quick_pair_browser_delegate.h" +#include "base/memory/scoped_refptr.h" +#include "base/test/task_environment.h" +#include "components/signin/public/identity_manager/identity_test_environment.h" +#include "components/signin/public/identity_manager/identity_test_utils.h" +#include "net/http/http_util.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +constexpr char kBody[] = "body"; +constexpr char kTestUrl[] = "http://www.test.com/"; +constexpr char kTestScope[] = "http://www.test.com/scope"; +const net::PartialNetworkTrafficAnnotationTag kTrafficAnnotation = + net::DefinePartialNetworkTrafficAnnotation("test_request", + "oauth2_api_call_flow", + R"( + semantics { + sender: "Test Request" + description: + "Test request." + trigger: + "Test request." + data: "Test Request." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: NO + setting: + "Test Request." + })"); + +} // namespace + +namespace ash { +namespace quick_pair { + +class OAuthHttpFetcherTest : public testing::Test { + public: + OAuthHttpFetcherTest() : identity_test_env_(&url_loader_factory_) { + identity_test_env_.MakePrimaryAccountAvailable("1@mail.com", + signin::ConsentLevel::kSync); + } + + void SetUp() override { + http_fetcher_ = + std::make_unique<OAuthHttpFetcher>(kTrafficAnnotation, kTestScope); + browser_delegate_ = std::make_unique<MockQuickPairBrowserDelegate>(); + ON_CALL(*browser_delegate_, GetURLLoaderFactory()) + .WillByDefault( + testing::Return(url_loader_factory_.GetSafeWeakWrapper())); + ON_CALL(*browser_delegate_, GetIdentityManager()) + .WillByDefault(testing::Return(identity_test_env_.identity_manager())); + identity_test_env_.SetAutomaticIssueOfAccessTokens(true); + } + + void TearDown() override { url_loader_factory_.ClearResponses(); } + + protected: + base::test::TaskEnvironment task_environment_; + std::unique_ptr<OAuthHttpFetcher> http_fetcher_; + std::unique_ptr<MockQuickPairBrowserDelegate> browser_delegate_; + network::TestURLLoaderFactory url_loader_factory_; + signin::IdentityTestEnvironment identity_test_env_; +}; + +TEST_F(OAuthHttpFetcherTest, ExecuteGetRequest_Success) { + GURL url(kTestUrl); + std::string body(kBody); + auto head = network::mojom::URLResponseHead::New(); + head->headers = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders("")); + head->headers->GetMimeType(&head->mime_type); + network::URLLoaderCompletionStatus status(net::Error::OK); + status.decoded_body_length = body.size(); + url_loader_factory_.AddResponse(url, std::move(head), body, status); + + http_fetcher_->ExecuteGetRequest( + url, base::BindOnce([](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { + ASSERT_EQ(kBody, *response); + ASSERT_TRUE(result->IsSuccess()); + })); + task_environment_.RunUntilIdle(); +} + +TEST_F(OAuthHttpFetcherTest, ExecuteGetRequest_Failure) { + url_loader_factory_.AddResponse(kTestUrl, "", + net::HTTP_INTERNAL_SERVER_ERROR); + + http_fetcher_->ExecuteGetRequest( + GURL(kTestUrl), + base::BindOnce([](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { + ASSERT_EQ(nullptr, response); + ASSERT_FALSE(result->IsSuccess()); + ASSERT_EQ(result->http_response_error(), + net::HTTP_INTERNAL_SERVER_ERROR); + })); + task_environment_.RunUntilIdle(); +} + +TEST_F(OAuthHttpFetcherTest, ExecuteGetRequest_MultipleCalls) { + url_loader_factory_.AddResponse(kTestUrl, "", + net::HTTP_INTERNAL_SERVER_ERROR); + + http_fetcher_->ExecuteGetRequest( + GURL(kTestUrl), + base::BindOnce([](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { + ASSERT_EQ(nullptr, response); + ASSERT_FALSE(result->IsSuccess()); + ASSERT_EQ(result->http_response_error(), + net::HTTP_INTERNAL_SERVER_ERROR); + })); +#if DCHECK_IS_ON() + EXPECT_DEATH( + http_fetcher_->ExecuteGetRequest(GURL(kTestUrl), base::DoNothing()), ""); +#else + http_fetcher_->ExecuteGetRequest( + GURL(kTestUrl), + base::BindOnce( + [](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { FAIL(); })); +#endif + task_environment_.RunUntilIdle(); +} + +TEST_F(OAuthHttpFetcherTest, ExecuteGetRequest_NoToken) { + identity_test_env_.SetAutomaticIssueOfAccessTokens(false); + url_loader_factory_.AddResponse(kTestUrl, "", + net::HTTP_INTERNAL_SERVER_ERROR); + http_fetcher_->ExecuteGetRequest( + GURL(kTestUrl), + base::BindOnce([](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { + ASSERT_EQ(nullptr, response); + ASSERT_EQ(nullptr, result); + })); + task_environment_.RunUntilIdle(); +} + +TEST_F(OAuthHttpFetcherTest, ExecuteGetRequest_NoUrlFactory) { + ON_CALL(*browser_delegate_, GetURLLoaderFactory()) + .WillByDefault(testing::Return(nullptr)); + url_loader_factory_.AddResponse(kTestUrl, "", + net::HTTP_INTERNAL_SERVER_ERROR); + http_fetcher_->ExecuteGetRequest( + GURL(kTestUrl), + base::BindOnce([](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { + ASSERT_EQ(nullptr, response); + ASSERT_EQ(nullptr, result); + })); + task_environment_.RunUntilIdle(); +} + +TEST_F(OAuthHttpFetcherTest, ExecuteGetRequest_NoIdentityManager) { + ON_CALL(*browser_delegate_, GetIdentityManager()) + .WillByDefault(testing::Return(nullptr)); + +#if DCHECK_IS_ON() + EXPECT_DEATH( + http_fetcher_->ExecuteGetRequest(GURL(kTestUrl), base::DoNothing()), ""); +#else + http_fetcher_->ExecuteGetRequest( + GURL(kTestUrl), + base::BindOnce( + [](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { FAIL(); })); +#endif + + task_environment_.RunUntilIdle(); +} + +TEST_F(OAuthHttpFetcherTest, ExecuteGetRequest_MultipleRaceCondition) { + http_fetcher_->ExecuteGetRequest(GURL(kTestUrl), base::DoNothing()); +#if DCHECK_IS_ON() + EXPECT_DEATH( + http_fetcher_->ExecuteGetRequest(GURL(kTestUrl), base::DoNothing()), ""); +#else + http_fetcher_->ExecuteGetRequest( + GURL(kTestUrl), + base::BindOnce( + [](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { FAIL(); })); +#endif + task_environment_.RunUntilIdle(); +} + +TEST_F(OAuthHttpFetcherTest, ExecutePostRequest_Success) { + GURL url(kTestUrl); + std::string body(kBody); + auto head = network::mojom::URLResponseHead::New(); + head->headers = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders("")); + head->headers->GetMimeType(&head->mime_type); + network::URLLoaderCompletionStatus status(net::Error::OK); + status.decoded_body_length = body.size(); + url_loader_factory_.AddResponse(url, std::move(head), body, status); + + http_fetcher_->ExecutePostRequest( + url, kBody, + base::BindOnce([](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { + ASSERT_TRUE(result->IsSuccess()); + })); + task_environment_.RunUntilIdle(); +} + +TEST_F(OAuthHttpFetcherTest, ExecuteDeleteRequest_Success) { + GURL url(kTestUrl); + std::string body(kBody); + auto head = network::mojom::URLResponseHead::New(); + head->headers = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders("")); + head->headers->GetMimeType(&head->mime_type); + network::URLLoaderCompletionStatus status(net::Error::OK); + status.decoded_body_length = body.size(); + url_loader_factory_.AddResponse(url, std::move(head), body, status); + + http_fetcher_->ExecuteDeleteRequest( + url, base::BindOnce([](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { + ASSERT_TRUE(result->IsSuccess()); + })); + task_environment_.RunUntilIdle(); +} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/quick_pair/repository/unauthenticated_http_fetcher.cc b/ash/quick_pair/repository/unauthenticated_http_fetcher.cc index 85a94e9..a047ab7 100644 --- a/ash/quick_pair/repository/unauthenticated_http_fetcher.cc +++ b/ash/quick_pair/repository/unauthenticated_http_fetcher.cc
@@ -14,7 +14,7 @@ namespace { -// Max size set to 2MB. This is well over the expected maximum for our +// Max size set to 2MB. This is well over the expected maximum for our // expected responses, however it can be increased if needed in the future. constexpr int kMaxDownloadBytes = 2 * 1024 * 1024;
diff --git a/ash/quick_pair/repository/unauthenticated_http_fetcher_unittest.cc b/ash/quick_pair/repository/unauthenticated_http_fetcher_unittest.cc new file mode 100644 index 0000000..3ce0fe88 --- /dev/null +++ b/ash/quick_pair/repository/unauthenticated_http_fetcher_unittest.cc
@@ -0,0 +1,98 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/quick_pair/repository/unauthenticated_http_fetcher.h" + +#include "ash/quick_pair/common/mock_quick_pair_browser_delegate.h" +#include "base/memory/scoped_refptr.h" +#include "base/test/task_environment.h" +#include "net/http/http_util.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +constexpr char kBody[] = "body"; +constexpr char kTestUrl[] = "http://www.test.com/"; + +} // namespace + +namespace ash { +namespace quick_pair { + +class UnauthenticatedHttpFetcherTest : public testing::Test { + public: + void SetUp() override { + http_fetcher_ = std::make_unique<UnauthenticatedHttpFetcher>( + TRAFFIC_ANNOTATION_FOR_TESTS); + browser_delegate_ = std::make_unique<MockQuickPairBrowserDelegate>(); + ON_CALL(*browser_delegate_, GetURLLoaderFactory()) + .WillByDefault( + testing::Return(url_loader_factory_.GetSafeWeakWrapper())); + } + + void TearDown() override { url_loader_factory_.ClearResponses(); } + + protected: + base::test::TaskEnvironment task_environment_; + std::unique_ptr<UnauthenticatedHttpFetcher> http_fetcher_; + std::unique_ptr<MockQuickPairBrowserDelegate> browser_delegate_; + network::TestURLLoaderFactory url_loader_factory_; +}; + +TEST_F(UnauthenticatedHttpFetcherTest, ExecuteGetRequest_Success) { + GURL url(kTestUrl); + std::string body(kBody); + auto head = network::mojom::URLResponseHead::New(); + head->headers = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders("")); + head->headers->GetMimeType(&head->mime_type); + network::URLLoaderCompletionStatus status(net::Error::OK); + status.decoded_body_length = body.size(); + url_loader_factory_.AddResponse(url, std::move(head), body, status); + + http_fetcher_->ExecuteGetRequest( + url, base::BindOnce([](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { + ASSERT_EQ(kBody, *response); + ASSERT_TRUE(result->IsSuccess()); + })); + task_environment_.RunUntilIdle(); +} + +TEST_F(UnauthenticatedHttpFetcherTest, ExecuteGetRequest_Failure) { + url_loader_factory_.AddResponse(kTestUrl, "", + net::HTTP_INTERNAL_SERVER_ERROR); + + http_fetcher_->ExecuteGetRequest( + GURL(kTestUrl), + base::BindOnce([](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { + ASSERT_EQ(nullptr, response); + ASSERT_FALSE(result->IsSuccess()); + ASSERT_EQ(result->http_response_error(), + net::HTTP_INTERNAL_SERVER_ERROR); + })); + task_environment_.RunUntilIdle(); +} + +TEST_F(UnauthenticatedHttpFetcherTest, ExecuteGetRequest_Failure_NoUrlLoader) { + ON_CALL(*browser_delegate_, GetURLLoaderFactory()) + .WillByDefault(testing::Return(nullptr)); + + http_fetcher_->ExecuteGetRequest( + GURL(kTestUrl), + base::BindOnce([](std::unique_ptr<std::string> response, + std::unique_ptr<FastPairHttpResult> result) { + ASSERT_EQ(nullptr, response); + ASSERT_EQ(nullptr, result); + })); + task_environment_.RunUntilIdle(); +} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/shelf/shelf_button_pressed_metric_tracker.cc b/ash/shelf/shelf_button_pressed_metric_tracker.cc index 03967d5..56c1afc 100644 --- a/ash/shelf/shelf_button_pressed_metric_tracker.cc +++ b/ash/shelf/shelf_button_pressed_metric_tracker.cc
@@ -7,6 +7,7 @@ #include "ash/metrics/user_metrics_recorder.h" #include "ash/shell.h" #include "base/metrics/histogram_macros.h" +#include "base/metrics/user_metrics.h" #include "base/time/default_tick_clock.h" #include "ui/views/controls/button/button.h" @@ -46,12 +47,12 @@ void ShelfButtonPressedMetricTracker::RecordButtonPressedSource( const ui::Event& event) { + // NOTE: These metrics are called "launcher" instead of "shelf" because the + // original name of the shelf UI was "launcher". if (event.IsMouseEvent()) { - Shell::Get()->metrics()->RecordUserMetricsAction( - UMA_LAUNCHER_BUTTON_PRESSED_WITH_MOUSE); + base::RecordAction(base::UserMetricsAction("Launcher_ButtonPressed_Mouse")); } else if (event.IsGestureEvent()) { - Shell::Get()->metrics()->RecordUserMetricsAction( - UMA_LAUNCHER_BUTTON_PRESSED_WITH_TOUCH); + base::RecordAction(base::UserMetricsAction("Launcher_ButtonPressed_Touch")); } }
diff --git a/ash/shelf/shelf_context_menu_model.cc b/ash/shelf/shelf_context_menu_model.cc index 5fb4c36..ce900836 100644 --- a/ash/shelf/shelf_context_menu_model.cc +++ b/ash/shelf/shelf_context_menu_model.cc
@@ -87,7 +87,6 @@ if (!prefs) // Null during startup. return; - UserMetricsRecorder* metrics = shell->metrics(); // Clamshell mode only options should not activate in tablet mode. const bool is_tablet_mode = shell->tablet_mode_controller()->InTabletMode(); switch (command_id) { @@ -101,17 +100,17 @@ break; case MENU_ALIGNMENT_LEFT: DCHECK(!is_tablet_mode); - metrics->RecordUserMetricsAction(UMA_SHELF_ALIGNMENT_SET_LEFT); + base::RecordAction(base::UserMetricsAction("Shelf_AlignmentSetLeft")); SetShelfAlignmentPref(prefs, display_id_, ShelfAlignment::kLeft); break; case MENU_ALIGNMENT_RIGHT: DCHECK(!is_tablet_mode); - metrics->RecordUserMetricsAction(UMA_SHELF_ALIGNMENT_SET_RIGHT); + base::RecordAction(base::UserMetricsAction("Shelf_AlignmentSetRight")); SetShelfAlignmentPref(prefs, display_id_, ShelfAlignment::kRight); break; case MENU_ALIGNMENT_BOTTOM: DCHECK(!is_tablet_mode); - metrics->RecordUserMetricsAction(UMA_SHELF_ALIGNMENT_SET_BOTTOM); + base::RecordAction(base::UserMetricsAction("Shelf_AlignmentSetBottom")); SetShelfAlignmentPref(prefs, display_id_, ShelfAlignment::kBottom); break; case MENU_CHANGE_WALLPAPER:
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index eff652eb..47316ed 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -14,7 +14,6 @@ #include "ash/constants/ash_features.h" #include "ash/keyboard/keyboard_util.h" #include "ash/keyboard/ui/keyboard_ui_controller.h" -#include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/metrics_util.h" #include "ash/public/cpp/shelf_model.h" #include "ash/public/cpp/shelf_types.h" @@ -51,6 +50,7 @@ #include "base/cxx17_backports.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "base/metrics/user_metrics.h" #include "base/scoped_observation.h" #include "base/strings/utf_string_conversions.h" #include "base/timer/timer.h" @@ -257,8 +257,11 @@ // Records the user metric action for whenever a shelf item is pinned or // unpinned. void RecordPinUnpinUserAction(bool pinned) { - Shell::Get()->metrics()->RecordUserMetricsAction( - pinned ? UMA_SHELF_ITEM_PINNED : UMA_SHELF_ITEM_UNPINNED); + if (pinned) { + base::RecordAction(base::UserMetricsAction("Shelf_ItemPinned")); + } else { + base::RecordAction(base::UserMetricsAction("Shelf_ItemUnpinned")); + } } } // namespace @@ -793,8 +796,7 @@ case TYPE_BROWSER_SHORTCUT: case TYPE_APP: case TYPE_UNPINNED_BROWSER_SHORTCUT: - Shell::Get()->metrics()->RecordUserMetricsAction( - UMA_LAUNCHER_CLICK_ON_APP); + base::RecordAction(base::UserMetricsAction("Launcher_ClickOnApp")); break; case TYPE_DIALOG:
diff --git a/ash/shortcut_viewer/views/keyboard_shortcut_view.cc b/ash/shortcut_viewer/views/keyboard_shortcut_view.cc index bf756ec..fc63030 100644 --- a/ash/shortcut_viewer/views/keyboard_shortcut_view.cc +++ b/ash/shortcut_viewer/views/keyboard_shortcut_view.cc
@@ -27,7 +27,6 @@ #include "ash/shortcut_viewer/views/ksv_search_box_view.h" #include "base/bind.h" #include "base/i18n/string_search.h" -#include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/strings/string_number_conversions.h" @@ -41,11 +40,9 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/chromeos/events/keyboard_layout_util.h" -#include "ui/compositor/compositor.h" #include "ui/events/event_constants.h" #include "ui/events/types/event_type.h" #include "ui/gfx/paint_vector_icon.h" -#include "ui/gfx/presentation_feedback.h" #include "ui/views/accessibility/accessibility_paint_checks.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/background.h" @@ -175,7 +172,6 @@ else g_ksv_view->GetWidget()->Activate(); } else { - const base::TimeTicks start_time = base::TimeTicks::Now(); TRACE_EVENT0("shortcut_viewer", "CreateWidget"); base::RecordAction( base::UserMetricsAction("KeyboardShortcutViewer.CreateWindow")); @@ -229,14 +225,6 @@ g_ksv_view->did_first_paint_ = false; g_ksv_view->GetWidget()->Show(); g_ksv_view->search_box_view_->search_box()->RequestFocus(); - - widget->GetCompositor()->RequestPresentationTimeForNextFrame(base::BindOnce( - [](base::TimeTicks start_time, - const gfx::PresentationFeedback& feedback) { - UMA_HISTOGRAM_TIMES("Keyboard.ShortcutViewer.StartupTime", - feedback.timestamp - start_time); - }, - start_time)); } return g_ksv_view->GetWidget(); }
diff --git a/ash/shortcut_viewer/views/keyboard_shortcut_view_unittest.cc b/ash/shortcut_viewer/views/keyboard_shortcut_view_unittest.cc index 0d09ae2..b96834b 100644 --- a/ash/shortcut_viewer/views/keyboard_shortcut_view_unittest.cc +++ b/ash/shortcut_viewer/views/keyboard_shortcut_view_unittest.cc
@@ -11,11 +11,9 @@ #include "ash/shortcut_viewer/views/ksv_search_box_view.h" #include "ash/test/ash_test_base.h" #include "base/bind.h" -#include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/window.h" -#include "ui/compositor/test/test_utils.h" #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/events/devices/device_data_manager_test_api.h" @@ -82,8 +80,6 @@ } } - base::HistogramTester histograms_; - private: KeyboardShortcutView* GetView() const { return KeyboardShortcutView::GetInstanceForTesting(); @@ -100,13 +96,6 @@ widget->CloseNow(); } -TEST_F(KeyboardShortcutViewTest, StartupTimeHistogram) { - views::Widget* widget = Toggle(); - EXPECT_TRUE(ui::WaitForNextFrameToBePresented(widget->GetCompositor())); - histograms_.ExpectTotalCount("Keyboard.ShortcutViewer.StartupTime", 1); - widget->CloseNow(); -} - // KeyboardShortcutViewer window should be centered in screen. TEST_F(KeyboardShortcutViewTest, CenterWindowInScreen) { // Show the widget.
diff --git a/ash/webui/personalization_app/mojom/personalization_app.mojom b/ash/webui/personalization_app/mojom/personalization_app.mojom index 81a41fe..8be0c0ea 100644 --- a/ash/webui/personalization_app/mojom/personalization_app.mojom +++ b/ash/webui/personalization_app/mojom/personalization_app.mojom
@@ -52,6 +52,19 @@ kDark = 2, }; +// Values for the user-level setting indicating access to Google Photos data. +enum GooglePhotosEnablementState { + // Setting could not be retrieved due to a network or server error, or the + // server returned an unknown setting state. + kError = 0, + + // An enterprise setting prevents this user from accessing Google Photos data. + kDisabled = 1, + + // This user can access Google Photos data. + kEnabled = 2, +}; + // WallpaperCollection contains a list of |WallpaperImage| objects. struct WallpaperCollection { // This ID is used as the argument to |FetchImagesForCollection|. @@ -197,6 +210,9 @@ // will be -1 on failure. FetchGooglePhotosCount() => (int32 count); + // Fetch whether the user is allowed to access Google Photos data. + FetchGooglePhotosEnabled() => (GooglePhotosEnablementState state); + // Fetch photo(s) the user has stored in Google Photos. If provided, // |item_id| specifies one photo to fetch. If provided, |album_id| specifies // an album whose photos are fetched. At most one of |item_id| or |album_id|
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_element.html b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_element.html index 2ef387e5..806da6b6 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_element.html +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_element.html
@@ -3,6 +3,7 @@ overflow: hidden; } + iron-scroll-threshold, iron-list { height: 100%; width: 100%; @@ -39,28 +40,32 @@ width: 100%; } </style> -<iron-list id="grid" items="[[photosByRow_]]" as="row"> - <template> - <div class="row" rowindex$="[[index]]" tabindex$="[[tabIndex]]" - on-focus="onGridRowFocused_" on-keydown="onGridRowKeyDown_"> - <template is="dom-if" - if="[[isGridRowTitleVisible_(row, photosBySection_)]]"> - <p class="title">[[getGridRowTitle_(row, photosBySection_)]]</p> - </template> - <div class="photos"> - <template is="dom-repeat" items="[[row]]" as="photo"> - <wallpaper-grid-item - class="photo" - colindex$="[[index]]" - image-src="[[photo.url.url]]" - on-click="onPhotoSelected_" - on-keypress="onPhotoSelected_" - selected="[[isPhotoSelected_( - photo, currentSelected_, pendingSelected_)]]" - tabindex="-1"> - </wallpaper-grid-item> +<iron-scroll-threshold id="gridScrollThreshold" + on-lower-threshold="onGridScrollThresholdReached_"> + <iron-list id="grid" items="[[photosByRow_]]" as="row" + scroll-target="gridScrollThreshold"> + <template> + <div class="row" rowindex$="[[index]]" tabindex$="[[tabIndex]]" + on-focus="onGridRowFocused_" on-keydown="onGridRowKeyDown_"> + <template is="dom-if" + if="[[isGridRowTitleVisible_(row, photosBySection_)]]"> + <p class="title">[[getGridRowTitle_(row, photosBySection_)]]</p> </template> + <div class="photos"> + <template is="dom-repeat" items="[[row]]" as="photo"> + <wallpaper-grid-item + class="photo" + colindex$="[[index]]" + image-src="[[photo.url.url]]" + on-click="onPhotoSelected_" + on-keypress="onPhotoSelected_" + selected="[[isPhotoSelected_( + photo, currentSelected_, pendingSelected_)]]" + tabindex="-1"> + </wallpaper-grid-item> + </template> + </div> </div> - </div> - </template> -</iron-list> + </template> + </iron-list> +</iron-scroll-threshold>
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_element.ts index b5e3b13..d2492633 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_element.ts
@@ -7,12 +7,14 @@ */ import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; +import 'chrome://resources/polymer/v3_0/iron-scroll-threshold/iron-scroll-threshold.js'; import './styles.js'; import '../../common/styles.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {FilePath} from 'chrome://resources/mojo/mojo/public/mojom/base/file_path.mojom-webui.js'; import {IronListElement} from 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; +import {IronScrollThresholdElement} from 'chrome://resources/polymer/v3_0/iron-scroll-threshold/iron-scroll-threshold.js'; import {afterNextRender, html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getNumberOfGridItemsPerRow, isNonEmptyArray, isSelectionEvent, normalizeKeyForRTL} from '../../common/utils.js'; @@ -20,7 +22,7 @@ import {WithPersonalizationStore} from '../personalization_store.js'; import {isGooglePhotosPhoto} from '../utils.js'; -import {selectWallpaper} from './wallpaper_controller.js'; +import {fetchGooglePhotosPhotos, selectWallpaper} from './wallpaper_controller.js'; import {getWallpaperProvider} from './wallpaper_interface_provider.js'; /** A list of |GooglePhotosPhoto|'s to be rendered in a row. */ @@ -33,7 +35,7 @@ }; export interface GooglePhotosPhotos { - $: {grid: IronListElement;}; + $: {grid: IronListElement; gridScrollThreshold: IronScrollThresholdElement}; } export class GooglePhotosPhotos extends WithPersonalizationStore { @@ -63,16 +65,12 @@ pendingSelected_: Object, photos_: Array, - - photosByRow_: { - type: Array, - computed: 'computePhotosByRow_(photosBySection_)', - }, + photosByRow_: Array, photosBySection_: { type: Array, - computed: - 'computePhotosBySection_(photos_, photosLoading_, photosPerRow_)', + computed: 'computePhotosBySection_(photos_, photosPerRow_)', + observer: 'onPhotosBySectionChanged_', }, photosLoading_: Boolean, @@ -83,6 +81,11 @@ return getNumberOfGridItemsPerRow(); }, }, + + photosResumeToken_: { + type: String, + observer: 'onPhotosResumeTokenChanged_', + }, }; } @@ -119,6 +122,9 @@ /** The number of photos to render per row in a grid. */ private photosPerRow_: number; + /** The resume token needed to fetch the next page of photos. */ + private photosResumeToken_: string|null; + /** The singleton wallpaper provider interface. */ private wallpaperProvider_: WallpaperProviderInterface = getWallpaperProvider(); @@ -136,20 +142,29 @@ 'photos_', state => state.wallpaper.googlePhotos.photos); this.watch<GooglePhotosPhotos['photosLoading_']>( 'photosLoading_', state => state.wallpaper.loading.googlePhotos.photos); + this.watch<GooglePhotosPhotos['photosResumeToken_']>( + 'photosResumeToken_', + state => state.wallpaper.googlePhotos.resumeTokens.photos); this.updateFromStore(); } - /** Invoked on changes to this element's |hidden| state. */ - private onHiddenChanged_(hidden: GooglePhotosPhotos['hidden']) { - if (hidden) { + /** Invoked on grid scroll threshold reached. */ + private onGridScrollThresholdReached_() { + // Ignore this event if fired during initialization. + if (!this.$.gridScrollThreshold.scrollHeight) { + this.$.gridScrollThreshold.clearTriggers(); return; } - // When iron-list items change while their parent element is hidden, the - // iron-list will render incorrectly. Force relayout by invalidating the - // iron-list when this element becomes visible. - afterNextRender(this, () => this.$.grid.fire('iron-resize')); + // Ignore this event if photos are already being loading or if there is no + // resume token (indicating there are no additional photos to load). + if (this.photosLoading_ === true || this.photosResumeToken_ === null) { + return; + } + + // Fetch the next page of photos. + fetchGooglePhotosPhotos(this.wallpaperProvider_, this.getStore()); } /** Invoked on focus of a grid row. */ @@ -202,6 +217,18 @@ } } + /** Invoked on changes to this element's |hidden| state. */ + private onHiddenChanged_(hidden: GooglePhotosPhotos['hidden']) { + if (hidden) { + return; + } + + // When iron-list items change while their parent element is hidden, the + // iron-list will render incorrectly. Force relayout by invalidating the + // iron-list when this element becomes visible. + afterNextRender(this, () => this.$.grid.fire('iron-resize')); + } + /** Invoked on selection of a photo. */ private onPhotoSelected_(e: Event&{model: {photo: GooglePhotosPhoto}}) { assert(e.model.photo); @@ -210,31 +237,55 @@ } } + /** Invoked on changes to |photosBySection_|. */ + private onPhotosBySectionChanged_( + photosBySection: GooglePhotosPhotos['photosBySection_']) { + if (!isNonEmptyArray(photosBySection)) { + this.photosByRow_ = null; + return; + } + + const photosByRow = photosBySection.flatMap(section => section.rows); + + // Case: First batch of photos. + if (this.photosByRow_ === null) { + this.photosByRow_ = photosByRow; + return; + } + + // Case: Subsequent batches of photos. + photosByRow.forEach((row, i) => { + if (i < this.photosByRow_!.length) { + this.set(`photosByRow_.${i}`, row); + } else { + this.push('photosByRow_', row); + } + }); + + while (this.photosByRow_.length > photosByRow.length) { + this.pop('photosByRow_'); + } + } + + /** Invoked on changes to |photosResumeToken_|. */ + private onPhotosResumeTokenChanged_( + photosResumeToken: GooglePhotosPhotos['photosResumeToken_']) { + if (photosResumeToken?.length) { + this.$.gridScrollThreshold.clearTriggers(); + } + } + /** Invoked on resize of this element. */ private onResized_() { this.photosPerRow_ = getNumberOfGridItemsPerRow(); } - /** Invoked to compute |photosByRow_|. */ - private computePhotosByRow_(photosBySection: - GooglePhotosPhotos['photosBySection_']): - GooglePhotosPhotosRow[]|null { - if (!isNonEmptyArray(photosBySection)) { - return null; - } - return photosBySection.flatMap(section => section.rows); - } - /** Invoked to compute |photosBySection_|. */ private computePhotosBySection_( photos: GooglePhotosPhotos['photos_'], - photosLoading: GooglePhotosPhotos['photosLoading_'], photosPerRow: GooglePhotosPhotos['photosPerRow_']): GooglePhotosPhotosSection[]|null { - if (photosLoading || !photosPerRow) { - return null; - } - if (!isNonEmptyArray(photos)) { + if (!isNonEmptyArray(photos) || !photosPerRow) { return null; }
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_actions.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_actions.ts index d74356b5..e8396906 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_actions.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_actions.ts
@@ -14,6 +14,7 @@ */ export enum WallpaperActionName { + APPEND_GOOGLE_PHOTOS_PHOTOS = 'append_google_photos_photos', BEGIN_LOAD_GOOGLE_PHOTOS_ALBUM = 'begin_load_google_photos_album', BEGIN_LOAD_GOOGLE_PHOTOS_ALBUMS = 'begin_load_google_photos_albums', BEGIN_LOAD_GOOGLE_PHOTOS_COUNT = 'begin_load_google_photos_count', @@ -30,7 +31,6 @@ SET_GOOGLE_PHOTOS_ALBUM = 'set_google_photos_album', SET_GOOGLE_PHOTOS_ALBUMS = 'set_google_photos_albums', SET_GOOGLE_PHOTOS_COUNT = 'set_google_photos_count', - SET_GOOGLE_PHOTOS_PHOTOS = 'set_google_photos_photos', SET_IMAGES_FOR_COLLECTION = 'set_images_for_collection', SET_LOCAL_IMAGES = 'set_local_images', SET_LOCAL_IMAGE_DATA = 'set_local_image_data', @@ -40,18 +40,38 @@ } export type WallpaperActions = - BeginLoadGooglePhotosAlbumAction|BeginLoadGooglePhotosAlbumsAction| - BeginLoadGooglePhotosCountAction|BeginLoadGooglePhotosPhotosAction| - BeginLoadImagesForCollectionsAction|BeginLoadLocalImagesAction| - BeginLoadLocalImageDataAction|BeginUpdateDailyRefreshImageAction| - BeginLoadSelectedImageAction|BeginSelectImageAction|EndSelectImageAction| - SetCollectionsAction|SetDailyRefreshCollectionIdAction| - SetGooglePhotosAlbumAction|SetGooglePhotosAlbumsAction| - SetGooglePhotosCountAction|SetGooglePhotosPhotosAction| + AppendGooglePhotosPhotosAction|BeginLoadGooglePhotosAlbumAction| + BeginLoadGooglePhotosAlbumsAction|BeginLoadGooglePhotosCountAction| + BeginLoadGooglePhotosPhotosAction|BeginLoadImagesForCollectionsAction| + BeginLoadLocalImagesAction|BeginLoadLocalImageDataAction| + BeginUpdateDailyRefreshImageAction|BeginLoadSelectedImageAction| + BeginSelectImageAction|EndSelectImageAction|SetCollectionsAction| + SetDailyRefreshCollectionIdAction|SetGooglePhotosAlbumAction| + SetGooglePhotosAlbumsAction|SetGooglePhotosCountAction| SetImagesForCollectionAction|SetLocalImageDataAction|SetLocalImagesAction| SetUpdatedDailyRefreshImageAction|SetSelectedImageAction| SetFullscreenEnabledAction; +export type AppendGooglePhotosPhotosAction = Action&{ + name: WallpaperActionName.APPEND_GOOGLE_PHOTOS_PHOTOS; + photos: GooglePhotosPhoto[]|null; + resumeToken: string|null; +}; + +/** + * Appends to the list of Google Photos photos. May be called with null on + * error. + */ +export function appendGooglePhotosPhotosAction( + photos: GooglePhotosPhoto[]|null, + resumeToken: string|null): AppendGooglePhotosPhotosAction { + return { + photos, + resumeToken, + name: WallpaperActionName.APPEND_GOOGLE_PHOTOS_PHOTOS + }; +} + export type BeginLoadGooglePhotosAlbumAction = Action&{ name: WallpaperActionName.BEGIN_LOAD_GOOGLE_PHOTOS_ALBUM; albumId: string; @@ -265,17 +285,6 @@ return {count, name: WallpaperActionName.SET_GOOGLE_PHOTOS_COUNT}; } -export type SetGooglePhotosPhotosAction = Action&{ - name: WallpaperActionName.SET_GOOGLE_PHOTOS_PHOTOS; - photos: GooglePhotosPhoto[]|null; -}; - -/** Sets the list of Google Photos photos. May be called with null on error. */ -export function setGooglePhotosPhotosAction(photos: GooglePhotosPhoto[]| - null): SetGooglePhotosPhotosAction { - return {photos, name: WallpaperActionName.SET_GOOGLE_PHOTOS_PHOTOS}; -} - export type SetImagesForCollectionAction = Action&{ name: WallpaperActionName.SET_IMAGES_FOR_COLLECTION; collectionId: string;
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_controller.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_controller.ts index 527c0f6c..ce83d0d0 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_controller.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_controller.ts
@@ -140,28 +140,26 @@ } /** Fetches the list of Google Photos photos and saves it to the store. */ -async function fetchGooglePhotosPhotos( +export async function fetchGooglePhotosPhotos( provider: WallpaperProviderInterface, store: PersonalizationStore): Promise<void> { store.dispatch(action.beginLoadGooglePhotosPhotosAction()); let photos: Array<GooglePhotosPhoto>|null = []; - let resumeToken: string|null|undefined = null; + let resumeToken = store.data.wallpaper.googlePhotos.resumeTokens.photos; - // TODO(b/216882690): Support incremental load of photos as the user scrolls - // through their library as opposed to loading them all at once. - do { - const {response} = await provider.fetchGooglePhotosPhotos( - /*itemId=*/ null, /*albumId=*/ null, resumeToken) as - {response: FetchGooglePhotosPhotosResponse}; - if (!Array.isArray(response.photos)) { - console.warn('Failed to fetch Google Photos photos'); - photos = null; - break; - } + const {response} = await provider.fetchGooglePhotosPhotos( + /*itemId=*/ null, /*albumId=*/ null, resumeToken) as + {response: FetchGooglePhotosPhotosResponse}; + if (Array.isArray(response.photos)) { photos.push(...response.photos); - resumeToken = response.resumeToken; - } while (resumeToken); + resumeToken = response.resumeToken ?? null; + } else { + console.warn('Failed to fetch Google Photos photos'); + photos = null; + // NOTE: `resumeToken` is intentionally *not* modified so that the request + // which failed can be reattempted. + } // Impose max resolution. if (photos !== null) { @@ -169,7 +167,7 @@ photo => ({...photo, url: appendMaxResolutionSuffix(photo.url)})); } - store.dispatch(action.setGooglePhotosPhotosAction(photos)); + store.dispatch(action.appendGooglePhotosPhotosAction(photos, resumeToken)); } /** Get list of local images from disk and save it to the store. */ @@ -360,7 +358,7 @@ store.dispatch(action.beginLoadGooglePhotosAlbumsAction()); store.dispatch(action.beginLoadGooglePhotosPhotosAction()); store.dispatch(action.setGooglePhotosAlbumsAction(result)); - store.dispatch(action.setGooglePhotosPhotosAction(result)); + store.dispatch(action.appendGooglePhotosPhotosAction(result, null)); store.endBatchUpdate(); return; }
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_grid_item_element.html b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_grid_item_element.html index b119f9e..47f04d3 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_grid_item_element.html +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_grid_item_element.html
@@ -135,7 +135,7 @@ </style> <div class="item" aria-selected$="[[selected]]"> <template is="dom-if" if="[[isImageVisible_(imageSrc)]]"> - <img is="cr-auto-img" auto-src="[[imageSrc]]" with-cookies></img> + <img is="cr-auto-img" auto-src="[[imageSrc]]" clear-src with-cookies></img> </template> <template is="dom-if" if="[[isTextVisible_(primaryText, secondaryText)]]"> <div class="text">
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_reducers.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_reducers.ts index 9512b333..4bf700df 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_reducers.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_reducers.ts
@@ -192,7 +192,7 @@ photos: true, }, }; - case WallpaperActionName.SET_GOOGLE_PHOTOS_PHOTOS: + case WallpaperActionName.APPEND_GOOGLE_PHOTOS_PHOTOS: assert(state.googlePhotos.photos === true); return { ...state, @@ -363,14 +363,40 @@ count: action.count, }; case WallpaperActionName.BEGIN_LOAD_GOOGLE_PHOTOS_PHOTOS: - // The list of photos should be loaded only once. - assert(state.photos === undefined); + // The list of photos should be loaded only while additional photos exist. + assert(state.photos === undefined || state.resumeTokens.photos); return state; - case WallpaperActionName.SET_GOOGLE_PHOTOS_PHOTOS: + case WallpaperActionName.APPEND_GOOGLE_PHOTOS_PHOTOS: assert(action.photos !== undefined); + // Case: First batch of photos. + if (!Array.isArray(state.photos)) { + return { + ...state, + photos: action.photos, + resumeTokens: { + ...state.resumeTokens, + photos: action.resumeToken, + }, + }; + } + // Case: Subsequent batches of photos. + if (Array.isArray(action.photos)) { + return { + ...state, + photos: [...state.photos, ...action.photos], + resumeTokens: { + ...state.resumeTokens, + photos: action.resumeToken, + }, + }; + } + // Case: Error. return { ...state, - photos: action.photos, + resumeTokens: { + ...state.resumeTokens, + photos: action.resumeToken, + }, }; default: return state;
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_state.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_state.ts index 364854c..6cc4009 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_state.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_state.ts
@@ -31,6 +31,7 @@ albums: GooglePhotosAlbum[]|null|undefined; photos: GooglePhotosPhoto[]|null|undefined; photosByAlbumId: Record<string, GooglePhotosPhoto[]|null|undefined>; + resumeTokens: {photos: string|null}; } /** @@ -115,6 +116,7 @@ albums: undefined, photos: undefined, photosByAlbumId: {}, + resumeTokens: {photos: null}, }, }; }
diff --git a/ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.cc b/ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.cc index a33e662..aed3181 100644 --- a/ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.cc +++ b/ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.cc
@@ -73,6 +73,12 @@ std::move(callback).Run(0); } +void FakePersonalizationAppWallpaperProvider::FetchGooglePhotosEnabled( + FetchGooglePhotosEnabledCallback callback) { + std::move(callback).Run( + ash::personalization_app::mojom::GooglePhotosEnablementState::kEnabled); +} + void FakePersonalizationAppWallpaperProvider::FetchGooglePhotosPhotos( const absl::optional<std::string>& item_id, const absl::optional<std::string>& album_id,
diff --git a/ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.h b/ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.h index 7a4942e5..fd1eb00 100644 --- a/ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.h +++ b/ash/webui/personalization_app/test/fake_personalization_app_wallpaper_provider.h
@@ -50,6 +50,9 @@ void FetchGooglePhotosCount(FetchGooglePhotosCountCallback callback) override; + void FetchGooglePhotosEnabled( + FetchGooglePhotosEnabledCallback callback) override; + void FetchGooglePhotosPhotos( const absl::optional<std::string>& item_id, const absl::optional<std::string>& album_id,
diff --git a/ash/webui/shimless_rma/DEPS b/ash/webui/shimless_rma/DEPS index b8d5aff..c72c12ae 100644 --- a/ash/webui/shimless_rma/DEPS +++ b/ash/webui/shimless_rma/DEPS
@@ -4,8 +4,6 @@ "+chromeos/dbus/rmad", "+chromeos/dbus/update_engine", "+chromeos/dbus/util", - "+chromeos/login/login_state", - "+chromeos/services/network_config", "+ui/resources", "+ui/web_dialogs", "+ui/chromeos/strings",
diff --git a/ash/webui/shimless_rma/backend/BUILD.gn b/ash/webui/shimless_rma/backend/BUILD.gn index b97da59..dfd5a5dc 100644 --- a/ash/webui/shimless_rma/backend/BUILD.gn +++ b/ash/webui/shimless_rma/backend/BUILD.gn
@@ -26,7 +26,6 @@ "//chromeos/dbus/update_engine:proto", "//chromeos/dbus/util", "//chromeos/network:network", - "//chromeos/services/network_config:in_process_instance", "//chromeos/services/network_config/public/mojom:mojom", "//components/qr_code_generator", ] @@ -50,7 +49,6 @@ "//chromeos/dbus/rmad", "//chromeos/dbus/rmad:rmad_proto", "//chromeos/dbus/update_engine:update_engine", - "//chromeos/login/login_state:login_state", "//chromeos/network:network", "//chromeos/network:test_support", "//chromeos/services/network_config/public/cpp:test_support",
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.cc b/ash/webui/shimless_rma/backend/shimless_rma_service.cc index 1369315..0b5bff7 100644 --- a/ash/webui/shimless_rma/backend/shimless_rma_service.cc +++ b/ash/webui/shimless_rma/backend/shimless_rma_service.cc
@@ -15,7 +15,6 @@ #include "ash/webui/shimless_rma/mojom/shimless_rma.mojom.h" #include "ash/webui/shimless_rma/mojom/shimless_rma_mojom_traits.h" #include "base/bind.h" -#include "base/containers/contains.h" #include "base/logging.h" #include "chromeos/dbus/power/power_manager_client.h" #include "chromeos/dbus/rmad/rmad.pb.h" @@ -23,8 +22,6 @@ #include "chromeos/dbus/util/version_loader.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" -#include "chromeos/services/network_config/in_process_instance.h" -#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" #include "components/qr_code_generator/qr_code_generator.h" using chromeos::network_config::mojom::ConnectionStateType; @@ -38,8 +35,6 @@ namespace { -namespace network_mojom = ::chromeos::network_config::mojom; - mojom::State RmadStateToMojo(rmad::RmadState::StateCase rmadState) { return mojo::EnumTraits<ash::shimless_rma::mojom::State, rmad::RmadState::StateCase>::ToMojom(rmadState); @@ -84,23 +79,12 @@ qr_code->data.assign(qr_data->data.begin(), qr_data->data.end()); return qr_code; } - -chromeos::network_config::mojom::NetworkFilterPtr GetNetworkFilter() { - return network_mojom::NetworkFilter::New( - network_mojom::FilterType::kConfigured, network_mojom::NetworkType::kWiFi, - network_mojom::kNoLimit); -} - } // namespace ShimlessRmaService::ShimlessRmaService( std::unique_ptr<ShimlessRmaDelegate> shimless_rma_delegate) : shimless_rma_delegate_(std::move(shimless_rma_delegate)) { chromeos::RmadClient::Get()->AddObserver(this); - - network_config::BindToInProcessInstance( - remote_cros_network_config_.BindNewPipeAndPassReceiver()); - version_updater_.SetOsUpdateStatusCallback( base::BindRepeating(&ShimlessRmaService::OnOsUpdateStatusCallback, weak_ptr_factory_.GetWeakPtr())); @@ -183,59 +167,6 @@ } } -void ShimlessRmaService::TrackConfiguredNetworks() { - // Only populate `existing_saved_network_guids_` once to avoid treating a new - // network like an existing network. TrackConfiguredNetworks() can potentially - // be called twice if the user navigates back to the networking page. - if (!existing_saved_network_guids_.empty()) { - LOG(WARNING) << "Already captured configured networks."; - return; - } - - remote_cros_network_config_->GetNetworkStateList( - GetNetworkFilter(), - base::BindOnce(&ShimlessRmaService::OnTrackConfiguredNetworks, - base::Unretained(this))); -} - -void ShimlessRmaService::OnTrackConfiguredNetworks( - std::vector<network_mojom::NetworkStatePropertiesPtr> networks) { - for (auto& network : networks) { - existing_saved_network_guids_.push_back(std::move(network->guid)); - } -} - -void ShimlessRmaService::ForgetNewNetworkConnections() { - remote_cros_network_config_->GetNetworkStateList( - GetNetworkFilter(), - base::BindOnce(&ShimlessRmaService::OnForgetNewNetworkConnections, - base::Unretained(this))); -} - -void ShimlessRmaService::OnForgetNewNetworkConnections( - std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr> - networks) { - for (auto& network : networks) { - const std::string& guid = network->guid; - const bool found_network_guid = - base::Contains(existing_saved_network_guids_, guid); - - // If `network` did not exist before RMA, attempt to forget it. - if (!found_network_guid) { - remote_cros_network_config_->ForgetNetwork( - guid, base::BindOnce(&ShimlessRmaService::OnForgetNetwork, - base::Unretained(this), guid)); - } - } -} - -void ShimlessRmaService::OnForgetNetwork(const std::string& guid, - bool success) { - if (!success) { - LOG(ERROR) << "Failed to forget saved network configuration GUID: " << guid; - } -} - void ShimlessRmaService::NetworkSelectionComplete( NetworkSelectionCompleteCallback callback) { if (state_proto_.state_case() != rmad::RmadState::kWelcome || @@ -918,9 +849,6 @@ rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } - - ForgetNewNetworkConnections(); - state_proto_.mutable_repair_complete()->set_shutdown( rmad::RepairCompleteState::RMAD_REPAIR_COMPLETE_REBOOT); TransitionNextStateGeneric(std::move(callback)); @@ -935,9 +863,6 @@ rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } - - ForgetNewNetworkConnections(); - state_proto_.mutable_repair_complete()->set_shutdown( rmad::RepairCompleteState::RMAD_REPAIR_COMPLETE_SHUTDOWN); TransitionNextStateGeneric(std::move(callback)); @@ -953,9 +878,6 @@ rmad::RmadErrorCode::RMAD_ERROR_REQUEST_INVALID); return; } - - ForgetNewNetworkConnections(); - state_proto_.mutable_repair_complete()->set_shutdown( rmad::RepairCompleteState::RMAD_REPAIR_COMPLETE_BATTERY_CUTOFF); TransitionNextStateGeneric(std::move(callback)); @@ -1192,7 +1114,6 @@ return; } - ForgetNewNetworkConnections(); // Send status before shutting down or restarting Chrome session. std::move(callback).Run(rmad::RMAD_ERROR_OK);
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service.h b/ash/webui/shimless_rma/backend/shimless_rma_service.h index aa340a5..f909a85 100644 --- a/ash/webui/shimless_rma/backend/shimless_rma_service.h +++ b/ash/webui/shimless_rma/backend/shimless_rma_service.h
@@ -7,14 +7,12 @@ #include <memory> #include <string> -#include <vector> #include "ash/webui/shimless_rma/backend/version_updater.h" #include "ash/webui/shimless_rma/mojom/shimless_rma.mojom.h" #include "chromeos/dbus/rmad/rmad.pb.h" #include "chromeos/dbus/rmad/rmad_client.h" #include "chromeos/dbus/update_engine/update_engine.pb.h" -#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote_set.h" @@ -43,7 +41,6 @@ void BeginFinalization(BeginFinalizationCallback callback) override; - void TrackConfiguredNetworks(); void NetworkSelectionComplete( NetworkSelectionCompleteCallback callback) override; @@ -210,23 +207,6 @@ void OsUpdateOrNextRmadStateCallback(TransitionStateCallback callback, const std::string& version); - // Saves existing configured networks to `existing_saved_networks_`. - void OnTrackConfiguredNetworks( - std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr> - networks); - - // Fetches the list of configured networks on RMA completion/exit. - void ForgetNewNetworkConnections(); - - // Compares the saved and current list of configured networks and attempts to - // drop any new network configurations. - void OnForgetNewNetworkConnections( - std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr> - networks); - - // Confirms if the network was dropped. - void OnForgetNetwork(const std::string& guid, bool success); - rmad::RmadState state_proto_; bool can_abort_ = false; bool can_go_back_ = false; @@ -259,14 +239,6 @@ mojo::Remote<mojom::UpdateRoFirmwareObserver> update_ro_firmware_observer_; mojo::Receiver<mojom::ShimlessRmaService> receiver_{this}; - // Remote for sending requests to the CrosNetworkConfig service. - mojo::Remote<chromeos::network_config::mojom::CrosNetworkConfig> - remote_cros_network_config_; - - // The GUIDs of the saved network configurations prior to starting RMA. Needed - // to track network connections added during RMA. - std::vector<std::string> existing_saved_network_guids_; - VersionUpdater version_updater_; base::OnceCallback<void(const std::string& version)> check_os_callback_;
diff --git a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc index 6a17cd95..4b31679e 100644 --- a/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc +++ b/ash/webui/shimless_rma/backend/shimless_rma_service_unittest.cc
@@ -12,7 +12,6 @@ #include "ash/webui/shimless_rma/backend/shimless_rma_delegate.h" #include "ash/webui/shimless_rma/mojom/shimless_rma.mojom.h" -#include "base/callback_helpers.h" #include "base/strings/stringprintf.h" #include "base/test/bind.h" #include "base/test/task_environment.h" @@ -20,12 +19,8 @@ #include "chromeos/dbus/rmad/fake_rmad_client.h" #include "chromeos/dbus/rmad/rmad_client.h" #include "chromeos/dbus/update_engine/update_engine.pb.h" -#include "chromeos/login/login_state/login_state.h" -#include "chromeos/network/managed_network_configuration_handler.h" #include "chromeos/network/network_configuration_handler.h" -#include "chromeos/network/network_state_handler.h" #include "chromeos/network/network_state_test_helper.h" -#include "chromeos/network/network_type_pattern.h" #include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" #include "testing/gtest/include/gtest/gtest.h" @@ -92,7 +87,11 @@ void SetUp() override { chromeos::DBusThreadManager::Initialize(); - SetupFakeNetwork(); + cros_network_config_test_helper_ = + std::make_unique<network_config::CrosNetworkConfigTestHelper>(false); + cros_network_config_test_helper().Initialize(nullptr); + NetworkHandler::Initialize(); + FakeRmadClientForTest::Initialize(); rmad_client_ = chromeos::RmadClient::Get(); // ShimlessRmaService has to be created after RmadClient or there will be a @@ -112,32 +111,9 @@ chromeos::RmadClient::Shutdown(); NetworkHandler::Shutdown(); cros_network_config_test_helper_.reset(); - chromeos::LoginState::Shutdown(); chromeos::DBusThreadManager::Shutdown(); } - void SetupFakeNetwork() { - chromeos::LoginState::Initialize(); - - cros_network_config_test_helper_ = - std::make_unique<network_config::CrosNetworkConfigTestHelper>(false); - network_configuration_handler_ = - NetworkConfigurationHandler::InitializeForTest( - network_state_helper().network_state_handler(), - cros_network_config_test_helper().network_device_handler()); - managed_network_configuration_handler_ = - ManagedNetworkConfigurationHandler::InitializeForTesting( - /*network_state_handler=*/nullptr, - /*network_profile_handler=*/nullptr, - /*network_device_handler=*/nullptr, - network_configuration_handler_.get(), - /*ui_proxy_config_service=*/nullptr); - cros_network_config_test_helper().Initialize( - managed_network_configuration_handler_.get()); - - NetworkHandler::Initialize(); - } - rmad::RmadState* CreateState(rmad::RmadState::StateCase state_case) { rmad::RmadState* state = new rmad::RmadState(); switch (state_case) { @@ -239,13 +215,6 @@ base::RunLoop().RunUntilIdle(); } - void GetCurrentlyConfiguredWifiNetworks( - NetworkStateHandler::NetworkStateList* list) { - network_state_handler()->GetNetworkListByType( - NetworkTypePattern::WiFi(), /*configured_only=*/true, - /*visible_only=*/true, /*no_limit=*/0, list); - } - protected: network_config::CrosNetworkConfigTestHelper& cros_network_config_test_helper() { @@ -256,19 +225,12 @@ return cros_network_config_test_helper_->network_state_helper(); } - chromeos::NetworkStateHandler* network_state_handler() { - return network_state_helper().network_state_handler(); - } - std::unique_ptr<ShimlessRmaService> shimless_rma_provider_; chromeos::RmadClient* rmad_client_ = nullptr; // Unowned convenience pointer. private: std::unique_ptr<network_config::CrosNetworkConfigTestHelper> cros_network_config_test_helper_; - std::unique_ptr<ManagedNetworkConfigurationHandler> - managed_network_configuration_handler_; - std::unique_ptr<NetworkConfigurationHandler> network_configuration_handler_; base::test::TaskEnvironment task_environment_; }; @@ -457,68 +419,6 @@ run_loop.Run(); } -TEST_F(ShimlessRmaServiceTest, ConfiguredNetworksKeepExistingNetworks) { - const std::vector<rmad::GetStateReply> fake_states = { - CreateStateReply(rmad::RmadState::kRepairComplete, rmad::RMAD_ERROR_OK)}; - fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); - - base::RunLoop run_loop; - shimless_rma_provider_->GetCurrentState(base::DoNothing()); - run_loop.RunUntilIdle(); - - // Simulate 2 saved networks existing before the start of RMA. - SetupWiFiNetwork("WiFi 1"); - SetupWiFiNetwork("WiFi 2"); - NetworkStateHandler::NetworkStateList configured_networks; - GetCurrentlyConfiguredWifiNetworks(&configured_networks); - EXPECT_EQ(2u, configured_networks.size()); - - // Snapshot the saved networks before connecting to a network during RMA. - shimless_rma_provider_->TrackConfiguredNetworks(); - run_loop.RunUntilIdle(); - - // End RMA and expect no networks to be removed from the saved networks. - shimless_rma_provider_->EndRmaAndReboot(base::DoNothing()); - run_loop.RunUntilIdle(); - - GetCurrentlyConfiguredWifiNetworks(&configured_networks); - EXPECT_EQ(2u, configured_networks.size()); -} - -TEST_F(ShimlessRmaServiceTest, ConfiguredNetworksDropNewNetworks) { - const std::vector<rmad::GetStateReply> fake_states = { - CreateStateReply(rmad::RmadState::kRepairComplete, rmad::RMAD_ERROR_OK)}; - fake_rmad_client_()->SetFakeStateReplies(std::move(fake_states)); - - base::RunLoop run_loop; - shimless_rma_provider_->GetCurrentState(base::DoNothing()); - run_loop.RunUntilIdle(); - - // Simulate a saved network existing before the start of RMA. - const std::string saved_network_guid = "WiFi 1"; - SetupWiFiNetwork(saved_network_guid); - NetworkStateHandler::NetworkStateList configured_networks; - GetCurrentlyConfiguredWifiNetworks(&configured_networks); - EXPECT_EQ(1u, configured_networks.size()); - - // Snapshot the saved networks before connecting to a network during RMA. - shimless_rma_provider_->TrackConfiguredNetworks(); - run_loop.RunUntilIdle(); - - // Simulate connecting to a new network on the RMA `kConfigureNetwork` page. - SetupWiFiNetwork("WiFi 2"); - GetCurrentlyConfiguredWifiNetworks(&configured_networks); - EXPECT_EQ(2u, configured_networks.size()); - - // End RMA and expect the new network to be removed from the saved networks. - shimless_rma_provider_->EndRmaAndReboot(base::DoNothing()); - run_loop.RunUntilIdle(); - - GetCurrentlyConfiguredWifiNetworks(&configured_networks); - EXPECT_EQ(1u, configured_networks.size()); - EXPECT_EQ(saved_network_guid, configured_networks[0]->guid()); -} - // TODO(gavindodd): Add tests of transitions back from rmad states through // the mojom chrome update and network selection states when implemented.
diff --git a/base/BUILD.gn b/base/BUILD.gn index 3a64f694..c30006fc 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2837,6 +2837,10 @@ deps += [ "//testing/android/native_test:native_test_native_code" ] shard_timeout = 600 } + if (is_fuchsia) { + # TODO(crbug.com/1306335): Switch to CFv2 once infrastructure supports it. + use_cfv2 = false + } if (!is_official_build) { # The extra data tables required by stack traces are turned off for official
diff --git a/base/allocator/partition_allocator/partition_alloc_perftest.cc b/base/allocator/partition_allocator/partition_alloc_perftest.cc index 5a15b3b60..840d08a 100644 --- a/base/allocator/partition_allocator/partition_alloc_perftest.cc +++ b/base/allocator/partition_allocator/partition_alloc_perftest.cc
@@ -22,8 +22,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/perf/perf_result_reporter.h" -#if BUILDFLAG(IS_ANDROID) || defined(ARCH_CPU_32_BITS) || \ - (BUILDFLAG(IS_FUCHSIA) && defined(ARCH_CPU_ARM64)) +#if BUILDFLAG(IS_ANDROID) || defined(ARCH_CPU_32_BITS) || BUILDFLAG(IS_FUCHSIA) // Some tests allocate many GB of memory, which can cause issues on Android and // address-space exhaustion for any 32-bit process. #define MEMORY_CONSTRAINED
diff --git a/build/config/OWNERS b/build/config/OWNERS index 8766231..580fa2e 100644 --- a/build/config/OWNERS +++ b/build/config/OWNERS
@@ -1,5 +1,3 @@ -scottmg@chromium.org - per-file ozone.gni=file://ui/ozone/OWNERS per-file ozone_extra.gni=file://ui/ozone/OWNERS per-file rust.gni=file://build/rust/OWNERS
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index ca9a807..219fb42 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -7.20220310.2.2 +7.20220315.2.1
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1 index 253e464..219fb42 100644 --- a/build/fuchsia/linux_internal.sdk.sha1 +++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@ -7.20220315.1.1 +7.20220315.2.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index ca9a807..253e464 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -7.20220310.2.2 +7.20220315.1.1
diff --git a/build/toolchain/OWNERS b/build/toolchain/OWNERS index e1b5385..3575950 100644 --- a/build/toolchain/OWNERS +++ b/build/toolchain/OWNERS
@@ -1,4 +1,2 @@ -scottmg@chromium.org - # Code Coverage. per-file *code_coverage*=liaoyuke@chromium.org
diff --git a/build/toolchain/cros/BUILD.gn b/build/toolchain/cros/BUILD.gn index 2dfe045..6d3d94f 100644 --- a/build/toolchain/cros/BUILD.gn +++ b/build/toolchain/cros/BUILD.gn
@@ -211,6 +211,20 @@ toolchain_args = { forward_variables_from(lacros_args, "*") + + # TODO(crbug.com/1298821) Change to a better way to set gn args. + # The following gn args are present in ash config like + # //build/args/chromeos/atlas.gni but not in + # //build/args/chromeos/amd64-generic-crostoolchain.gni. + # So we need to reset them to the default value where Lacros needs. + # Starts from here. + ozone_auto_platforms = true + ozone_platform = "" + ozone_platform_gbm = -1 + ozone_platform_headless = false + + # Ends here. + cros_v8_snapshot_sysroot = lacros_v8_snapshot_sysroot current_os = "chromeos" target_os = "chromeos"
diff --git a/build/toolchain/fuchsia/OWNERS b/build/toolchain/fuchsia/OWNERS index 3f809e82..e7034ea 100644 --- a/build/toolchain/fuchsia/OWNERS +++ b/build/toolchain/fuchsia/OWNERS
@@ -1 +1 @@ -scottmg@chromium.org +file://build/fuchsia/OWNERS
diff --git a/chrome/VERSION b/chrome/VERSION index 6a6053a0..b6b950a 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=101 MINOR=0 -BUILD=4946 +BUILD=4947 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index a8d48a9..30ca73e55 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -246,6 +246,7 @@ "//components/browser_ui/settings/android:java_resources", "//components/browser_ui/strings/android:browser_ui_strings_grd", "//components/browser_ui/styles/android:java_resources", + "//components/browser_ui/theme/android:java_resources", "//components/browser_ui/widget/android:java_resources", "//components/find_in_page/android:java_resources", "//components/javascript_dialogs/android:java_resources",
diff --git a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrCoreInstallUtils.java b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrCoreInstallUtils.java index 2194f66..f285a292a 100644 --- a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrCoreInstallUtils.java +++ b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrCoreInstallUtils.java
@@ -25,6 +25,7 @@ import org.chromium.components.messages.MessageDispatcherProvider; import org.chromium.components.messages.MessageIdentifier; import org.chromium.components.messages.MessageScopeType; +import org.chromium.components.messages.PrimaryActionClickBehavior; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modelutil.PropertyModel; @@ -223,6 +224,7 @@ new Intent(Intent.ACTION_VIEW, Uri.parse(VR_CORE_MARKET_URI)), VR_SERVICES_UPDATE_RESULT); + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; }) .with(MessageBannerProperties.ON_DISMISSED, this::onMessageDismissed) .build();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java index 86e8a8b4..a2c1514 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java
@@ -51,6 +51,7 @@ import org.chromium.components.messages.MessageDispatcherProvider; import org.chromium.components.messages.MessageIdentifier; import org.chromium.components.messages.MessageScopeType; +import org.chromium.components.messages.PrimaryActionClickBehavior; import org.chromium.components.navigation_interception.InterceptNavigationDelegate; import org.chromium.components.user_prefs.UserPrefs; import org.chromium.content_public.browser.LoadCommittedDetails; @@ -555,20 +556,23 @@ // Save url for #onMessageDismissed. mDistillerUrl may have been changed and became // different from the url when message is enqueued. GURL url = mDistillerUrl; - mMessageModel = - new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS) - .with(MessageBannerProperties.MESSAGE_IDENTIFIER, - MessageIdentifier.READER_MODE) - .with(MessageBannerProperties.TITLE, - resources.getString(R.string.reader_mode_message_title)) - .with(MessageBannerProperties.ICON_RESOURCE_ID, - R.drawable.infobar_mobile_friendly) - .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, - resources.getString(R.string.reader_mode_message_button)) - .with(MessageBannerProperties.ON_PRIMARY_ACTION, this::activateReaderMode) - .with(MessageBannerProperties.ON_DISMISSED, - (reason) -> onMessageDismissed(url, reason)) - .build(); + mMessageModel = new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS) + .with(MessageBannerProperties.MESSAGE_IDENTIFIER, + MessageIdentifier.READER_MODE) + .with(MessageBannerProperties.TITLE, + resources.getString(R.string.reader_mode_message_title)) + .with(MessageBannerProperties.ICON_RESOURCE_ID, + R.drawable.infobar_mobile_friendly) + .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, + resources.getString(R.string.reader_mode_message_button)) + .with(MessageBannerProperties.ON_PRIMARY_ACTION, + () -> { + activateReaderMode(); + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; + }) + .with(MessageBannerProperties.ON_DISMISSED, + (reason) -> onMessageDismissed(url, reason)) + .build(); messageDispatcher.enqueueMessage( mMessageModel, mTab.getWebContents(), MessageScopeType.NAVIGATION, false); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadMessageUiControllerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadMessageUiControllerImpl.java index 26e2cee8..fdf9073 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadMessageUiControllerImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadMessageUiControllerImpl.java
@@ -33,6 +33,7 @@ import org.chromium.components.messages.MessageBannerProperties; import org.chromium.components.messages.MessageDispatcher; import org.chromium.components.messages.MessageIdentifier; +import org.chromium.components.messages.PrimaryActionClickBehavior; import org.chromium.components.offline_items_collection.ContentId; import org.chromium.components.offline_items_collection.LegacyHelpers; import org.chromium.components.offline_items_collection.OfflineContentProvider; @@ -887,7 +888,8 @@ mNotificationIds.remove(contentId); } - private void onPrimaryAction(ContentId itemId, final OfflineItemSchedule schedule) { + private @PrimaryActionClickBehavior int onPrimaryAction( + ContentId itemId, final OfflineItemSchedule schedule) { OfflineItem offlineItem = mTrackedItems.remove(itemId); removeNotification(itemId); if (itemId != null && schedule != null) { @@ -905,6 +907,7 @@ getOTRProfileIDForTrackedItems(), DownloadOpenSource.DOWNLOAD_PROGRESS_MESSAGE); recordLinkClicked(false /*openItem*/); } + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; } private OTRProfileID getOTRProfileIDForTrackedItems() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsMessageDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsMessageDelegate.java index ecdf340e..40edaea 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsMessageDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsMessageDelegate.java
@@ -18,6 +18,7 @@ import org.chromium.components.messages.MessageDispatcher; import org.chromium.components.messages.MessageIdentifier; import org.chromium.components.messages.MessageScopeType; +import org.chromium.components.messages.PrimaryActionClickBehavior; import org.chromium.components.webapps.WebappsIconUtils; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.modelutil.PropertyModel; @@ -91,9 +92,10 @@ /** * Open the Instant App when the message primary button is clicked. */ - private void handlePrimaryAction() { + private @PrimaryActionClickBehavior int handlePrimaryAction() { InstantAppsMessageDelegateJni.get().onPrimaryAction(mData.isInstantAppDefault()); InstantAppsHandler.getInstance().launchFromBanner(mData); + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java index 2055f9d..16ff3112 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java
@@ -50,6 +50,7 @@ import org.chromium.components.messages.MessageBannerProperties; import org.chromium.components.messages.MessageDispatcher; import org.chromium.components.messages.MessageIdentifier; +import org.chromium.components.messages.PrimaryActionClickBehavior; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.url.GURL; @@ -279,7 +280,10 @@ .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, resources.getString(R.string.chrome_survey_message_button)) .with(MessageBannerProperties.ON_PRIMARY_ACTION, - () -> showSurvey(siteId)) + () -> { + showSurvey(siteId); + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; + }) .with(MessageBannerProperties.ON_DISMISSED, this::recordSurveyPromptMetrics) .build();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessage.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessage.java index 201d60fe..97109b3a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessage.java
@@ -26,6 +26,7 @@ import org.chromium.components.messages.MessageDispatcher; import org.chromium.components.messages.MessageDispatcherProvider; import org.chromium.components.messages.MessageIdentifier; +import org.chromium.components.messages.PrimaryActionClickBehavior; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modelutil.PropertyModel; @@ -117,9 +118,10 @@ } } - private void onAccepted() { + private @PrimaryActionClickBehavior int onAccepted() { SyncErrorPromptUtils.onUserAccepted(mType); recordHistogram(SyncErrorPromptAction.BUTTON_CLICKED); + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; } private void onDismissed(@DismissReason int reason) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillUpstreamTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillUpstreamTest.java index 3658826c..da774ac 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillUpstreamTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillUpstreamTest.java
@@ -122,7 +122,7 @@ .get(0); PropertyModel model = MessagesTestHelper.getCurrentMessage(handler); TestThreadUtils.runOnUiThreadBlocking(() -> { - model.get(MessageBannerProperties.ON_PRIMARY_ACTION).run(); + model.get(MessageBannerProperties.ON_PRIMARY_ACTION).get(); dispatcher.dismissMessage(model, DismissReason.PRIMARY_ACTION); }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java index 5007afb..ffd7eda 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
@@ -96,6 +96,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Random; @@ -312,6 +313,8 @@ // Choose a fixed, "random" port to create stable screenshots. mTestServerRule.setServerPort(424242); mTestServerRule.setServerUsesHttps(true); + + PageInfoAdPersonalizationController.setTopicsForTesting(Arrays.asList("Testing topic")); } @After @@ -330,6 +333,7 @@ clearPermissions(); HistoryContentManager.setProviderForTests(null); PageInfoHistoryController.setProviderForTests(null); + PageInfoAdPersonalizationController.setTopicsForTesting(null); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java index a6188e2..ee2d759e7 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerIntegrationTest.java
@@ -151,8 +151,8 @@ Assert.assertNotNull("Message should not be null.", message); // Simulate the message primary button click. - Runnable primaryActionCallback = message.get(MessageBannerProperties.ON_PRIMARY_ACTION); - TestThreadUtils.runOnUiThreadBlocking(primaryActionCallback); + TestThreadUtils.runOnUiThreadBlocking( + () -> { message.get(MessageBannerProperties.ON_PRIMARY_ACTION).get(); }); // Simulate message dismissal on primary button click. TestThreadUtils.runOnUiThreadBlocking( () -> mMessageDispatcher.dismissMessage(message, DismissReason.PRIMARY_ACTION));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java index 9fed331..75b7f3f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ManageSyncSettingsTest.java
@@ -55,6 +55,7 @@ import org.chromium.components.sync.ModelType; import org.chromium.content_public.browser.test.util.TestThreadUtils; +import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -605,8 +606,7 @@ public void testAdvancedSyncFlowTopView() throws Exception { mSyncTestRule.setUpAccountAndEnableSyncForTesting(); final ManageSyncSettings fragment = startManageSyncPreferences(); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - mRenderTestRule.render(fragment.getView(), "advanced_sync_flow_top_view"); + render(fragment, "advanced_sync_flow_top_view"); } @Test @@ -622,8 +622,7 @@ recyclerView.setVerticalScrollBarEnabled(false); recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount() - 1); }); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - mRenderTestRule.render(fragment.getView(), "advanced_sync_flow_bottom_view"); + render(fragment, "advanced_sync_flow_bottom_view"); } @Test @@ -632,8 +631,7 @@ public void testAdvancedSyncFlowFromSyncConsentTopView() throws Exception { mSyncTestRule.setUpAccountAndEnableSyncForTesting(); final ManageSyncSettings fragment = startManageSyncPreferencesFromSyncConsentFlow(); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - mRenderTestRule.render(fragment.getView(), "advanced_sync_flow_top_view_from_sync_consent"); + render(fragment, "advanced_sync_flow_top_view_from_sync_consent"); } @Test @@ -649,9 +647,7 @@ recyclerView.setVerticalScrollBarEnabled(false); recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount() - 1); }); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - mRenderTestRule.render( - fragment.getView(), "advanced_sync_flow_bottom_view_from_sync_consent"); + render(fragment, "advanced_sync_flow_bottom_view_from_sync_consent"); } @Test @@ -661,8 +657,7 @@ public void testAdvancedSyncFlowTopViewForChildUser() throws Exception { mSyncTestRule.setUpChildAccountAndEnableSyncForTesting(); final ManageSyncSettings fragment = startManageSyncPreferences(); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - mRenderTestRule.render(fragment.getView(), "advanced_sync_flow_top_view_child"); + render(fragment, "advanced_sync_flow_top_view_child"); } @Test @@ -679,8 +674,7 @@ recyclerView.setVerticalScrollBarEnabled(false); recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount() - 1); }); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - mRenderTestRule.render(fragment.getView(), "advanced_sync_flow_bottom_view_child"); + render(fragment, "advanced_sync_flow_bottom_view_child"); } @Test @@ -690,9 +684,7 @@ public void testAdvancedSyncFlowFromSyncConsentTopViewForChildUser() throws Exception { mSyncTestRule.setUpChildAccountAndEnableSyncForTesting(); final ManageSyncSettings fragment = startManageSyncPreferencesFromSyncConsentFlow(); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - mRenderTestRule.render( - fragment.getView(), "advanced_sync_flow_top_view_from_sync_consent_child"); + render(fragment, "advanced_sync_flow_top_view_from_sync_consent_child"); } @Test @@ -709,9 +701,7 @@ recyclerView.setVerticalScrollBarEnabled(false); recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount() - 1); }); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - mRenderTestRule.render( - fragment.getView(), "advanced_sync_flow_bottom_view_from_sync_consent_child"); + render(fragment, "advanced_sync_flow_bottom_view_from_sync_consent_child"); } private ManageSyncSettings startManageSyncPreferences() { @@ -829,4 +819,12 @@ TestThreadUtils.runOnUiThreadBlocking(() -> textView.setError(null)); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); } + + private void render(ManageSyncSettings fragment, String skiaGoldId) throws IOException { + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + // Sanitize the view, in particular to ensure the presence of scroll bars do not cause + // image diffs. + ChromeRenderTestRule.sanitize(fragment.getView()); + mRenderTestRule.render(fragment.getView(), skiaGoldId); + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/instantapps/InstantAppsMessageDelegateTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/instantapps/InstantAppsMessageDelegateTest.java index d1bab053..cbb64ab 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/instantapps/InstantAppsMessageDelegateTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/instantapps/InstantAppsMessageDelegateTest.java
@@ -124,7 +124,7 @@ mDelegate.showMessage(); PropertyModel message = mDelegate.getMessageForTesting(); - message.get(MessageBannerProperties.ON_PRIMARY_ACTION).run(); + message.get(MessageBannerProperties.ON_PRIMARY_ACTION).get(); Mockito.verify(mNativeMock).onPrimaryAction(mData.isInstantAppDefault()); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerFlowTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerFlowTest.java index 3a36798..b6a99a1 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerFlowTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerFlowTest.java
@@ -68,6 +68,7 @@ import org.chromium.components.messages.MessageBannerProperties; import org.chromium.components.messages.MessageDispatcher; import org.chromium.components.messages.MessageIdentifier; +import org.chromium.components.messages.PrimaryActionClickBehavior; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.modelutil.PropertyModel; @@ -573,7 +574,9 @@ Assert.assertNotNull("Message dismissal action is null.", messageModel.get(MessageBannerProperties.ON_DISMISSED)); - messageModel.get(MessageBannerProperties.ON_PRIMARY_ACTION).run(); + Assert.assertEquals("Message ON_PRIMARY_ACTION should return DISMISS_IMMEDIATELY.", + PrimaryActionClickBehavior.DISMISS_IMMEDIATELY, + messageModel.get(MessageBannerProperties.ON_PRIMARY_ACTION).get().intValue()); Assert.assertEquals("showSurvey should be called.", 1, mTestSurveyController.showSurveyIfAvailableCallback.getCallCount()); }
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 95b8cf3b..bf0af51 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-101.0.4940.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-amd64-101.0.4943.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index acd34d23..60dab288 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -10983,11 +10983,6 @@ Your organization doesn't allow you to share this content. If you need help, contact your administrator. </message> - <!--Printer registration message for local discovery and Print Preview--> - <message name="IDS_CLOUD_PRINT_REGISTER_PRINTER_INFORMATION" desc="Information about registering printers with Google Cloud Print shown to the user before they confirm registration."> - Documents are <ph name="BEGIN_LINK_HELP"><a is="action-link" href="https://support.google.com/cloudprint/answer/2541843" target="_blank"></ph>sent to Google<ph name="END_LINK_HELP"></a></ph> to prepare them for printing. View, edit and manage your printers and printer history on the <ph name="BEGIN_LINK_DASHBOARD"><a is="action-link" href="https://www.google.com/cloudprint#jobs" target="_blank"></ph>Google Cloud Print dashboard<ph name="END_LINK_DASHBOARD"></a></ph>. - </message> - <!--Tab alert tooltip strings--> <message name="IDS_TOOLTIP_TAB_ALERT_STATE_MEDIA_RECORDING" desc="Extra tool tip text, when the tab is recording media."> This tab is using your camera or microphone.
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 41bb31c..3d77b83 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -5012,10 +5012,10 @@ "policy/browser_signin_policy_handler.h", "policy/cloud/user_cloud_policy_manager_builder.cc", "policy/cloud/user_cloud_policy_manager_builder.h", - "policy/cloud/user_policy_signin_service_base.cc", - "policy/cloud/user_policy_signin_service_base.h", "policy/cloud/user_policy_signin_service_factory.cc", "policy/cloud/user_policy_signin_service_factory.h", + "policy/cloud/user_policy_signin_service_util.cc", + "policy/cloud/user_policy_signin_service_util.h", "profiles/gaia_info_update_service.cc", "profiles/gaia_info_update_service.h", "profiles/gaia_info_update_service_factory.cc", @@ -5143,6 +5143,8 @@ "lacros/account_manager/profile_account_manager.h", "lacros/account_manager/profile_account_manager_factory.cc", "lacros/account_manager/profile_account_manager_factory.h", + "lacros/account_manager/web_signin_helper_lacros.cc", + "lacros/account_manager/web_signin_helper_lacros.h", "lacros/app_mode/kiosk_session_service_lacros.cc", "lacros/app_mode/kiosk_session_service_lacros.h", "lacros/arc/arc_icon_cache.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 9ee7487..c1b5de5 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -7255,8 +7255,9 @@ // multiple related features. SINGLE_VALUE_TYPE_AND_VALUE( switches::kEnableFeatures, - "PrivacySandboxSettings3:disable-dialog-for-" - "testing/true,EnableFetchingAccountCapabilities,InterestGroupStorage," + "PrivacySandboxSettings3:" + "disable-dialog-for-testing/true/show-sample-data/true," + "EnableFetchingAccountCapabilities,InterestGroupStorage," "AdInterestGroupAPI,Fledge,FencedFrames")}, {"privacy-sandbox-v3-android", flag_descriptions::kPrivacySandboxV3Name, @@ -7265,8 +7266,9 @@ // multiple related features when they are available. SINGLE_VALUE_TYPE_AND_VALUE( switches::kEnableFeatures, - "PrivacySandboxSettings3:disable-dialog-for-testing/" - "true,EnableFetchingAccountCapabilities")}, + "PrivacySandboxSettings3:" + "disable-dialog-for-testing/true/show-sample-data/true," + "EnableFetchingAccountCapabilities")}, {"animated-image-resume", flag_descriptions::kAnimatedImageResumeName, flag_descriptions::kAnimatedImageResumeDescription, kOsAll,
diff --git a/chrome/browser/ash/crosapi/url_handler_ash.cc b/chrome/browser/ash/crosapi/url_handler_ash.cc index 3efc8463..f686ee6 100644 --- a/chrome/browser/ash/crosapi/url_handler_ash.cc +++ b/chrome/browser/ash/crosapi/url_handler_ash.cc
@@ -86,6 +86,18 @@ GURL target_url = crosapi::gurl_os_handler_utils::SanitizeAshURL(url); GURL short_target_url = crosapi::gurl_os_handler_utils::SanitizeAshURL( url, /*include_path=*/false); + // Change os://settings/* into chrome://os-settings/* which will be the long + // term home for our OS-settings. + if (short_target_url == GURL(chrome::kOsUISettingsURL)) { + // This converts the os (GURL lib unusable) address into a chrome + // (GURL lib usable) address. + target_url = + crosapi::gurl_os_handler_utils::GetChromeUrlFromSystemUrl(target_url); + GURL::Replacements replacements; + replacements.SetHostStr(chrome::kChromeUIOSSettingsHost); + target_url = target_url.ReplaceComponents(replacements); + short_target_url = GURL(chrome::kChromeUIOSSettingsURL); + } // Settings will be handled. if (short_target_url == GURL(chrome::kChromeUIOSSettingsURL)) { chrome::SettingsWindowManager* settings_window_manager =
diff --git a/chrome/browser/ash/login/app_mode/kiosk_browsertest.cc b/chrome/browser/ash/login/app_mode/kiosk_browsertest.cc index 0669a2c..ae4ca5f 100644 --- a/chrome/browser/ash/login/app_mode/kiosk_browsertest.cc +++ b/chrome/browser/ash/login/app_mode/kiosk_browsertest.cc
@@ -15,7 +15,6 @@ #include "ash/public/cpp/login_screen_test_api.h" #include "ash/public/cpp/shelf_config.h" #include "ash/public/cpp/shelf_test_api.h" -#include "ash/public/cpp/wallpaper/wallpaper_controller_observer.h" #include "base/barrier_closure.h" #include "base/bind.h" #include "base/callback_helpers.h" @@ -39,6 +38,7 @@ #include "chrome/browser/ash/app_mode/kiosk_app_manager.h" #include "chrome/browser/ash/file_manager/fake_disk_mount_manager.h" #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h" +#include "chrome/browser/ash/login/login_wizard.h" #include "chrome/browser/ash/login/startup_utils.h" #include "chrome/browser/ash/login/test/device_state_mixin.h" #include "chrome/browser/ash/login/test/fake_gaia_mixin.h" @@ -72,7 +72,6 @@ #include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/speech/extension_api/tts_engine_extension_api.h" -#include "chrome/browser/ui/ash/wallpaper_controller_client_impl.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" @@ -685,11 +684,10 @@ void EnableConsumerKioskMode() { bool locked = false; - scoped_refptr<content::MessageLoopRunner> runner = - new content::MessageLoopRunner; + base::RunLoop loop; KioskAppManager::Get()->EnableConsumerKioskAutoLaunch(base::BindOnce( - &ConsumerKioskModeAutoStartLockCheck, &locked, runner->QuitClosure())); - runner->Run(); + &ConsumerKioskModeAutoStartLockCheck, &locked, loop.QuitClosure())); + loop.Run(); EXPECT_TRUE(locked); } @@ -1147,20 +1145,37 @@ KioskAppLaunchError::Get()); } -IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningCancel) { +class KioskConsumerTest : public KioskTest { + public: + KioskConsumerTest() { login_manager_.AppendRegularUsers(1); } + + // KioskTest: + void SetUpCommandLine(base::CommandLine* command_line) override { + KioskTest::SetUpCommandLine(command_line); + // Postpone login screen creation. + command_line->RemoveSwitch(switches::kForceLoginManagerInTests); + } + void SetUpInProcessBrowserTestFixture() override { + KioskTest::SetUpInProcessBrowserTestFixture(); + // Postpone login screen creation. + base::CommandLine::ForCurrentProcess()->RemoveSwitch( + switches::kForceLoginManagerInTests); + } + + bool ShouldWaitForOobeUI() override { return false; } + + private: + LoginManagerMixin login_manager_{&mixin_host_}; +}; + +IN_PROC_BROWSER_TEST_F(KioskConsumerTest, AutolaunchWarningCancel) { EnableConsumerKioskMode(); - - WizardController::SkipPostLoginScreensForTesting(); - auto* wizard_controller = WizardController::default_controller(); - ASSERT_TRUE(wizard_controller); - - // Start login screen after configuring auto launch app since the warning - // is triggered when switching to login screen. - wizard_controller->AdvanceToScreen(WelcomeView::kScreenId); ReloadAutolaunchKioskApps(); EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty()); EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled()); - wizard_controller->SkipToLoginForTesting(); + + ShowLoginWizard(OobeScreen::SCREEN_UNKNOWN); + OobeScreenWaiter(KioskAutolaunchScreenView::kScreenId).Wait(); // Wait for the auto launch warning come up. WaitForAutoLaunchWarning(/*visibility=*/true); @@ -1172,20 +1187,14 @@ EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled()); } -IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningConfirm) { +IN_PROC_BROWSER_TEST_F(KioskConsumerTest, AutolaunchWarningConfirm) { EnableConsumerKioskMode(); - - WizardController::SkipPostLoginScreensForTesting(); - auto* wizard_controller = WizardController::default_controller(); - ASSERT_TRUE(wizard_controller); - - // Start login screen after configuring auto launch app since the warning - // is triggered when switching to login screen. - wizard_controller->AdvanceToScreen(WelcomeView::kScreenId); ReloadAutolaunchKioskApps(); EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty()); EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled()); - wizard_controller->SkipToLoginForTesting(); + + ShowLoginWizard(OobeScreen::SCREEN_UNKNOWN); + OobeScreenWaiter(KioskAutolaunchScreenView::kScreenId).Wait(); // Wait for the auto launch warning come up. WaitForAutoLaunchWarning(/*visibility=*/true); @@ -1329,16 +1338,12 @@ // Verifies that a consumer device does not auto-launch kiosk mode when cros // settings are untrusted. -IN_PROC_BROWSER_TEST_F(KioskTest, NoConsumerAutoLaunchWhenUntrusted) { +IN_PROC_BROWSER_TEST_F(KioskConsumerTest, NoConsumerAutoLaunchWhenUntrusted) { EnableConsumerKioskMode(); - - // Wait for and confirm the auto-launch warning. - WizardController::SkipPostLoginScreensForTesting(); - auto* wizard_controller = WizardController::default_controller(); - ASSERT_TRUE(wizard_controller); - wizard_controller->AdvanceToScreen(WelcomeView::kScreenId); ReloadAutolaunchKioskApps(); - wizard_controller->SkipToLoginForTesting(); + ShowLoginWizard(OobeScreen::SCREEN_UNKNOWN); + OobeScreenWaiter(KioskAutolaunchScreenView::kScreenId).Wait(); + WaitForAutoLaunchWarning(/*visibility=*/true); // Make cros settings untrusted. @@ -2775,73 +2780,6 @@ EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); } -// Specialized test fixture for testing kiosk mode on the -// hidden WebUI initialization flow for slow hardware. -class KioskHiddenWebUITest : public KioskTest, - public WallpaperControllerObserver { - public: - KioskHiddenWebUITest() = default; - - KioskHiddenWebUITest(const KioskHiddenWebUITest&) = delete; - KioskHiddenWebUITest& operator=(const KioskHiddenWebUITest&) = delete; - - // KioskTest: - void SetUpOnMainThread() override { - LoginDisplayHostWebUI::DisableRestrictiveProxyCheckForTest(); - - KioskTest::SetUpOnMainThread(); - WallpaperControllerClientImpl::Get()->AddObserver(this); - } - void TearDownOnMainThread() override { - WallpaperControllerClientImpl::Get()->RemoveObserver(this); - KioskTest::TearDownOnMainThread(); - } - - void WaitForWallpaper() { - if (!wallpaper_loaded_) { - runner_ = new content::MessageLoopRunner; - runner_->Run(); - } - } - - bool wallpaper_loaded() const { return wallpaper_loaded_; } - - // WallpaperControllerObserver: - void OnWallpaperChanged() override { - wallpaper_loaded_ = true; - if (runner_.get()) - runner_->Quit(); - } - - private: - bool wallpaper_loaded_ = false; - scoped_refptr<content::MessageLoopRunner> runner_; -}; - -IN_PROC_BROWSER_TEST_F(KioskHiddenWebUITest, AutolaunchWarning) { - // Set kiosk app to autolaunch. - EnableConsumerKioskMode(); - WizardController::SkipPostLoginScreensForTesting(); - auto* wizard_controller = WizardController::default_controller(); - ASSERT_TRUE(wizard_controller); - - // Start login screen after configuring auto launch app since the warning - // is triggered when switching to login screen. - wizard_controller->AdvanceToScreen(WelcomeView::kScreenId); - ReloadAutolaunchKioskApps(); - wizard_controller->SkipToLoginForTesting(); - - EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty()); - EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled()); - - // Wait for the auto launch warning come up. - WaitForAutoLaunchWarning(/*visibility=*/true); - - // Wait for the wallpaper to load. - WaitForWallpaper(); - EXPECT_TRUE(wallpaper_loaded()); -} - class KioskAutoLaunchViewsTest : public OobeBaseTest, public LocalStateMixin::Delegate { public:
diff --git a/chrome/browser/ash/login/enrollment/hands_off_enrollment_browsertest.cc b/chrome/browser/ash/login/enrollment/hands_off_enrollment_browsertest.cc index 1255a96..444be8c 100644 --- a/chrome/browser/ash/login/enrollment/hands_off_enrollment_browsertest.cc +++ b/chrome/browser/ash/login/enrollment/hands_off_enrollment_browsertest.cc
@@ -47,6 +47,7 @@ MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line); command_line->AppendSwitchASCII( switches::kEnterpriseEnableZeroTouchEnrollment, "hands-off"); + command_line->AppendSwitch(switches::kLoginManager); } void SetUpOnMainThread() override {
diff --git a/chrome/browser/ash/login/error_screen_browsertest.cc b/chrome/browser/ash/login/error_screen_browsertest.cc index 4b74fb8..6628794 100644 --- a/chrome/browser/ash/login/error_screen_browsertest.cc +++ b/chrome/browser/ash/login/error_screen_browsertest.cc
@@ -77,6 +77,7 @@ void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch( switches::kDisableOOBEChromeVoxHintTimerForTesting); + command_line->AppendSwitch(switches::kLoginManager); } void ShowErrorScreenWithNetworkList() {
diff --git a/chrome/browser/ash/login/existing_user_controller.cc b/chrome/browser/ash/login/existing_user_controller.cc index 02e77c5..67871e0 100644 --- a/chrome/browser/ash/login/existing_user_controller.cc +++ b/chrome/browser/ash/login/existing_user_controller.cc
@@ -686,10 +686,6 @@ weak_factory_.GetWeakPtr())); } -void ExistingUserController::OnStartKioskAutolaunchScreen() { - ShowKioskAutolaunchScreen(); -} - void ExistingUserController::SetDisplayEmail(const std::string& email) { display_email_ = email; } @@ -729,10 +725,6 @@ GetLoginDisplayHost()->StartWizard(KioskEnableScreenView::kScreenId); } -void ExistingUserController::ShowKioskAutolaunchScreen() { - GetLoginDisplayHost()->StartWizard(KioskAutolaunchScreenView::kScreenId); -} - void ExistingUserController::ShowEncryptionMigrationScreen( const UserContext& user_context, EncryptionMigrationMode migration_mode) {
diff --git a/chrome/browser/ash/login/existing_user_controller.h b/chrome/browser/ash/login/existing_user_controller.h index 4f3e2eb0..3607c18 100644 --- a/chrome/browser/ash/login/existing_user_controller.h +++ b/chrome/browser/ash/login/existing_user_controller.h
@@ -99,7 +99,6 @@ void Login(const UserContext& user_context, const SigninSpecifics& specifics) override; void OnStartKioskEnableScreen() override; - void OnStartKioskAutolaunchScreen() override; void ResetAutoLoginTimer() override; void CompleteLogin(const UserContext& user_context); @@ -212,9 +211,6 @@ // Shows kiosk feature enable screen. void ShowKioskEnableScreen(); - // Shows "kiosk auto-launch permission" screen. - void ShowKioskAutolaunchScreen(); - // Shows "filesystem encryption migration" screen. void ShowEncryptionMigrationScreen(const UserContext& user_context, EncryptionMigrationMode migration_mode);
diff --git a/chrome/browser/ash/login/screens/network_screen.cc b/chrome/browser/ash/login/screens/network_screen.cc index 07b3eb1..fc460db 100644 --- a/chrome/browser/ash/login/screens/network_screen.cc +++ b/chrome/browser/ash/login/screens/network_screen.cc
@@ -77,20 +77,9 @@ } bool NetworkScreen::MaybeSkip(WizardContext* context) { - if (!first_time_shown_) - return false; - first_time_shown_ = false; - - if (features::IsOobeNetworkScreenSkipEnabled() && - network_state_helper_->IsConnectedToEthernet()) { - if (chromeos::features::IsOobeConsolidatedConsentEnabled()) - exit_callback_.Run(Result::NOT_APPLICABLE_CONSOLIDATED_CONSENT); - else - exit_callback_.Run(Result::NOT_APPLICABLE); - return true; - } - - return false; + // Skip this screen if the device is connected to Ethernet for the first time + // in this session. + return UpdateStatusIfConnectedToEthernet(); } void NetworkScreen::ShowImpl() { @@ -211,6 +200,11 @@ network_id_ = network_id; + // Automatically continue if the device is connected to Ethernet for the first + // time in this session. + if (UpdateStatusIfConnectedToEthernet()) + return; + // Automatically continue if we are using Zero-Touch Hands-Off Enrollment. if (is_connected && continue_attempts_ == 0 && WizardController::IsZeroTouchHandsOffOobeFlow()) { @@ -252,4 +246,36 @@ continue_pressed_ = true; WaitForConnection(network_id_); } + +bool NetworkScreen::UpdateStatusIfConnectedToEthernet() { + if (!features::IsOobeNetworkScreenSkipEnabled()) + return false; + + if (!first_ethernet_connection_) + return false; + + if (!network_state_helper_->IsConnectedToEthernet()) + return false; + + first_ethernet_connection_ = false; + + if (is_hidden()) { + // Screen not shown yet: skipping it. + if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { + exit_callback_.Run(Result::NOT_APPLICABLE_CONSOLIDATED_CONSENT); + } else { + exit_callback_.Run(Result::NOT_APPLICABLE); + } + } else { + // Screen already shown: automatically continuing. + if (chromeos::features::IsOobeConsolidatedConsentEnabled()) { + exit_callback_.Run(Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + } else { + exit_callback_.Run(Result::CONNECTED_REGULAR); + } + } + + return true; +} + } // namespace ash
diff --git a/chrome/browser/ash/login/screens/network_screen.h b/chrome/browser/ash/login/screens/network_screen.h index 797ac3a..cc59a498 100644 --- a/chrome/browser/ash/login/screens/network_screen.h +++ b/chrome/browser/ash/login/screens/network_screen.h
@@ -69,8 +69,10 @@ friend class DemoSetupTest; FRIEND_TEST_ALL_PREFIXES(NetworkScreenTest, CanConnect); FRIEND_TEST_ALL_PREFIXES(NetworkScreenTest, Timeout); - FRIEND_TEST_ALL_PREFIXES(NetworkScreenTest, HandsOffCanConnect); - FRIEND_TEST_ALL_PREFIXES(NetworkScreenTest, HandsOffTimeout); + FRIEND_TEST_ALL_PREFIXES(NetworkScreenTest, HandsOffCanConnect_Skipped); + FRIEND_TEST_ALL_PREFIXES(NetworkScreenTest, HandsOffTimeout_NotSkipped); + FRIEND_TEST_ALL_PREFIXES(NetworkScreenTest, + DelayedEthernetConnection_Skipped); FRIEND_TEST_ALL_PREFIXES(NetworkScreenUnitTest, ContinuesAutomatically); FRIEND_TEST_ALL_PREFIXES(NetworkScreenUnitTest, ContinuesOnlyOnce); @@ -120,6 +122,10 @@ // Called when continue button is clicked. void OnContinueButtonClicked(); + // Skip this screen or automatically continue if the device is connected to + // Ethernet for the first time in this session. + bool UpdateStatusIfConnectedToEthernet(); + // True if subscribed to network change notification. bool is_network_subscribed_ = false; @@ -136,8 +142,9 @@ // Indicates that we should proceed with OOBE as soon as we are connected. bool continue_pressed_ = false; - // Indicates whether screen has been shown already or not. - bool first_time_shown_ = true; + // Indicates whether the device has already been connected to Ethernet in this + // session or not. + bool first_ethernet_connection_ = true; // Timer for connection timeout. base::OneShotTimer connection_timer_;
diff --git a/chrome/browser/ash/login/screens/network_screen_browsertest.cc b/chrome/browser/ash/login/screens/network_screen_browsertest.cc index c3f580a..8e3b141 100644 --- a/chrome/browser/ash/login/screens/network_screen_browsertest.cc +++ b/chrome/browser/ash/login/screens/network_screen_browsertest.cc
@@ -152,11 +152,8 @@ // EXPECT_FALSE(view_->IsContinueEnabled()); network_screen()->UpdateStatus(); - // Expecting 2 calls: one to decide if the device should - // `StopWaitingForConnection`; and one to decide if it should automatically - // continue (in case of zero-touch hands-off enrollment). EXPECT_CALL(*network_state_helper(), IsConnected()) - .Times(2) + .Times(AnyNumber()) .WillRepeatedly(Return(true)); // TODO(nkostylev): Add integration with WebUI view http://crosbug.com/22570 // EXPECT_FALSE(view_->IsContinueEnabled()); @@ -173,11 +170,8 @@ // EXPECT_FALSE(view_->IsContinueEnabled()); network_screen()->UpdateStatus(); - // Expecting 2 calls: one to decide if the device should automatically - // continue (in case of zero-touch hands-off enrollment); and one to decide if - // it should show the error bubble. EXPECT_CALL(*network_state_helper(), IsConnected()) - .Times(2) + .Times(AnyNumber()) .WillRepeatedly(Return(false)); // TODO(nkostylev): Add integration with WebUI view http://crosbug.com/22570 // EXPECT_FALSE(view_->IsContinueEnabled()); @@ -192,7 +186,7 @@ // The network screen should be skipped if the device can connect and it's using // zero-touch hands-off enrollment. -IN_PROC_BROWSER_TEST_F(NetworkScreenTest, HandsOffCanConnect) { +IN_PROC_BROWSER_TEST_F(NetworkScreenTest, HandsOffCanConnect_Skipped) { // Configure the UI to use Hands-Off Enrollment flow. This cannot be done in // the `SetUpCommandLine` method, because the welcome screen would also be // skipped, causing the network screen to be shown before we could set up this @@ -206,12 +200,8 @@ network_screen()->UpdateStatus(); - // Expecting 3 calls: one to decide if the device should - // `StopWaitingForConnection`; one to decide if it should automatically - // continue (in case of zero-touch hands-off enrollment); and one to decide if - // this screens should `NotifyOnConnection`. EXPECT_CALL(*network_state_helper(), IsConnected()) - .Times(3) + .Times(AnyNumber()) .WillRepeatedly(Return(true)); network_screen()->UpdateStatus(); @@ -222,7 +212,7 @@ // The network screen should NOT be skipped if the connection times out, even if // it's using zero-touch hands-off enrollment. -IN_PROC_BROWSER_TEST_F(NetworkScreenTest, HandsOffTimeout) { +IN_PROC_BROWSER_TEST_F(NetworkScreenTest, HandsOffTimeout_NotSkipped) { // Configure the UI to use Hands-Off Enrollment flow. This cannot be done in // the `SetUpCommandLine` method, because the welcome screen would also be // skipped, causing the network screen to be shown before we could set up this @@ -236,20 +226,21 @@ network_screen()->UpdateStatus(); - // Expecting 2 calls: one to decide if the device should automatically - // continue (in case of zero-touch hands-off enrollment); and one to decide if - // it should show the error bubble. EXPECT_CALL(*network_state_helper(), IsConnected()) - .Times(2) + .Times(AnyNumber()) .WillRepeatedly(Return(false)); network_screen()->OnConnectionTimeout(); } -IN_PROC_BROWSER_TEST_F(NetworkScreenTest, SkippedEthernetConnected) { +IN_PROC_BROWSER_TEST_F(NetworkScreenTest, EthernetConnection_Skipped) { + EXPECT_CALL(*network_state_helper(), IsConnected()) + .Times(AnyNumber()) + .WillRepeatedly(Return(true)); EXPECT_CALL(*network_state_helper(), IsConnectedToEthernet()) .Times(AnyNumber()) .WillRepeatedly((Return(true))); + ShowNetworkScreen(); WaitForScreenExit(); @@ -276,4 +267,31 @@ WaitForScreenShown(); } +IN_PROC_BROWSER_TEST_F(NetworkScreenTest, DelayedEthernetConnection_Skipped) { + ShowNetworkScreen(); + + EXPECT_CALL(*network_state_helper(), IsConnecting()).WillOnce((Return(true))); + + network_screen()->UpdateStatus(); + + EXPECT_CALL(*network_state_helper(), IsConnected()) + .Times(AnyNumber()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*network_state_helper(), IsConnectedToEthernet()) + .Times(AnyNumber()) + .WillRepeatedly((Return(true))); + + network_screen()->UpdateStatus(); + WaitForScreenExit(); + + if (chromeos::features::IsOobeConsolidatedConsentEnabled()) + CheckResult(NetworkScreen::Result::CONNECTED_REGULAR_CONSOLIDATED_CONSENT); + else + CheckResult(NetworkScreen::Result::CONNECTED_REGULAR); + + // Showing screen again to test skip doesn't work now. + ShowNetworkScreen(); + WaitForScreenShown(); +} + } // namespace ash
diff --git a/chrome/browser/ash/login/session/chrome_session_manager.cc b/chrome/browser/ash/login/session/chrome_session_manager.cc index 72da93af..236afde 100644 --- a/chrome/browser/ash/login/session/chrome_session_manager.cc +++ b/chrome/browser/ash/login/session/chrome_session_manager.cc
@@ -286,14 +286,13 @@ return; } - if (parsed_command_line.HasSwitch(switches::kLoginManager) && - (!is_running_test || force_login_screen_in_test)) { - VLOG(1) << "Starting Chrome with login/oobe screen."; + if (parsed_command_line.HasSwitch(switches::kLoginManager)) { oobe_configuration_->CheckConfiguration(); + if (is_running_test && !force_login_screen_in_test) + return; + VLOG(1) << "Starting Chrome with login/oobe screen."; StartLoginOobeSession(); return; - } else if (is_running_test) { - oobe_configuration_->CheckConfiguration(); } VLOG(1) << "Starting Chrome with a user session.";
diff --git a/chrome/browser/ash/login/ui/login_display.h b/chrome/browser/ash/login/ui/login_display.h index 4943d44..fac2797c 100644 --- a/chrome/browser/ash/login/ui/login_display.h +++ b/chrome/browser/ash/login/ui/login_display.h
@@ -35,9 +35,6 @@ // Called when the user requests kiosk enable screen. virtual void OnStartKioskEnableScreen() = 0; - // Called when the owner permission for kiosk app auto launch is requested. - virtual void OnStartKioskAutolaunchScreen() = 0; - // Restarts the auto-login timer if it is running. virtual void ResetAutoLoginTimer() = 0;
diff --git a/chrome/browser/ash/login/ui/login_display_mojo.cc b/chrome/browser/ash/login/ui/login_display_mojo.cc index a420238..2f088f2 100644 --- a/chrome/browser/ash/login/ui/login_display_mojo.cc +++ b/chrome/browser/ash/login/ui/login_display_mojo.cc
@@ -149,10 +149,6 @@ return false; } -void LoginDisplayMojo::ShowKioskAutolaunchScreen() { - NOTIMPLEMENTED(); -} - bool LoginDisplayMojo::IsUserSigninCompleted() const { return is_signin_completed(); }
diff --git a/chrome/browser/ash/login/ui/login_display_mojo.h b/chrome/browser/ash/login/ui/login_display_mojo.h index 9f89161..8844f54 100644 --- a/chrome/browser/ash/login/ui/login_display_mojo.h +++ b/chrome/browser/ash/login/ui/login_display_mojo.h
@@ -40,7 +40,6 @@ void Login(const UserContext& user_context, const SigninSpecifics& specifics) override; bool IsSigninInProgress() const override; - void ShowKioskAutolaunchScreen() override; bool IsUserSigninCompleted() const override; // user_manager::UserManager::Observer:
diff --git a/chrome/browser/ash/login/ui/login_display_webui.cc b/chrome/browser/ash/login/ui/login_display_webui.cc index f88bdd1..c86513a 100644 --- a/chrome/browser/ash/login/ui/login_display_webui.cc +++ b/chrome/browser/ash/login/ui/login_display_webui.cc
@@ -67,11 +67,6 @@ delegate_->Login(user_context, specifics); } -void LoginDisplayWebUI::ShowKioskAutolaunchScreen() { - if (delegate_) - delegate_->OnStartKioskAutolaunchScreen(); -} - bool LoginDisplayWebUI::IsSigninInProgress() const { return delegate_->IsSigninInProgress(); }
diff --git a/chrome/browser/ash/login/ui/login_display_webui.h b/chrome/browser/ash/login/ui/login_display_webui.h index 89183d7..30d72c4 100644 --- a/chrome/browser/ash/login/ui/login_display_webui.h +++ b/chrome/browser/ash/login/ui/login_display_webui.h
@@ -33,7 +33,6 @@ void Login(const UserContext& user_context, const SigninSpecifics& specifics) override; bool IsSigninInProgress() const override; - void ShowKioskAutolaunchScreen() override; bool IsUserSigninCompleted() const override; // ui::UserActivityDetector implementation:
diff --git a/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.cc b/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.cc index cdcaf2c..4e49542 100644 --- a/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.cc +++ b/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.cc
@@ -55,6 +55,25 @@ MockGooglePhotosCountFetcher::~MockGooglePhotosCountFetcher() = default; +MockGooglePhotosEnabledFetcher::MockGooglePhotosEnabledFetcher(Profile* profile) + : GooglePhotosEnabledFetcher(profile) { + ON_CALL(*this, AddRequestAndStartIfNecessary) + .WillByDefault( + [](base::OnceCallback<void(GooglePhotosEnablementState)> callback) { + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(std::move(callback), + GooglePhotosEnablementState::kEnabled)); + }); + + ON_CALL(*this, ParseResponse) + .WillByDefault([this](const base::Value::Dict* response) { + return GooglePhotosEnabledFetcher::ParseResponse(response); + }); +} + +MockGooglePhotosEnabledFetcher::~MockGooglePhotosEnabledFetcher() = default; + MockGooglePhotosPhotosFetcher::MockGooglePhotosPhotosFetcher(Profile* profile) : GooglePhotosPhotosFetcher(profile) { using ash::personalization_app::mojom::FetchGooglePhotosPhotosResponse;
diff --git a/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.h b/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.h index 87e9ffc..c43b6f24 100644 --- a/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.h +++ b/chrome/browser/ash/wallpaper_handlers/mock_wallpaper_handlers.h
@@ -61,6 +61,31 @@ (override)); }; +// Fetcher that claims the user is allowed to access Google Photos data. Used to +// avoid network requests in unit tests. +class MockGooglePhotosEnabledFetcher : public GooglePhotosEnabledFetcher { + public: + explicit MockGooglePhotosEnabledFetcher(Profile* profile); + + MockGooglePhotosEnabledFetcher(const MockGooglePhotosEnabledFetcher&) = + delete; + MockGooglePhotosEnabledFetcher& operator=( + const MockGooglePhotosEnabledFetcher&) = delete; + + ~MockGooglePhotosEnabledFetcher() override; + + // GooglePhotosEnabledFetcher: + MOCK_METHOD(void, + AddRequestAndStartIfNecessary, + (base::OnceCallback<void(GooglePhotosEnablementState)> callback), + (override)); + + MOCK_METHOD(GooglePhotosEnablementState, + ParseResponse, + (const base::Value::Dict* response), + (override)); +}; + // Fetcher that returns an empty photo list and no resume token in response to a // request for photos from the user's Google Photos library. Used to avoid // network requests in unit tests.
diff --git a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc index 178e3c9d..0ffde54 100644 --- a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc +++ b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc
@@ -125,6 +125,32 @@ "Not implemented, considered not necessary." })"); +// The URL to download whether the user is allowed to access Google Photos data. +constexpr char kGooglePhotosEnabledUrl[] = + "https://photosfirstparty-pa.googleapis.com/v1/chromeos/userenabled:read"; + +constexpr net::NetworkTrafficAnnotationTag + kGooglePhotosEnabledTrafficAnnotation = + net::DefineNetworkTrafficAnnotation("wallpaper_google_photos_enabled", + R"( + semantics { + sender: "ChromeOS Wallpaper Picker" + description: + "The ChromeOS Wallpaper Picker displays a tile to view and pick from " + "a user's Google Photos library. This tile should not display any " + "user data if there is an enterprise setting preventing the user " + "from accessing Google Photos." + trigger: "When the user opens the ChromeOS Wallpaper Picker app." + data: "OAuth credentials for the user's Google Photos account." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: NO + setting: "N/A" + policy_exception_justification: + "Not implemented, considered not necessary." + })"); + // The URL to download a photo from a user's Google Photos library. constexpr char kGooglePhotosPhotoUrl[] = "https://photosfirstparty-pa.googleapis.com/v1/chromeos/itemById:read"; @@ -718,6 +744,36 @@ return base::saturated_cast<int>(count); } +GooglePhotosEnabledFetcher::GooglePhotosEnabledFetcher(Profile* profile) + : GooglePhotosFetcher(profile, kGooglePhotosEnabledTrafficAnnotation) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); +} + +GooglePhotosEnabledFetcher::~GooglePhotosEnabledFetcher() = default; + +void GooglePhotosEnabledFetcher::AddRequestAndStartIfNecessary( + base::OnceCallback<void(GooglePhotosEnablementState)> callback) { + GooglePhotosFetcher::AddRequestAndStartIfNecessary( + GURL(kGooglePhotosEnabledUrl), std::move(callback)); +} + +GooglePhotosEnablementState GooglePhotosEnabledFetcher::ParseResponse( + const base::Value::Dict* response) { + if (!response) + return GooglePhotosEnablementState::kError; + + const auto* state = response->FindStringByDottedPath("status.userState"); + + if (!state) + return GooglePhotosEnablementState::kError; + + return *state == "USER_PERMITTED" + ? GooglePhotosEnablementState::kEnabled + : *state == "USER_DASHER_DISABLED" + ? GooglePhotosEnablementState::kDisabled + : GooglePhotosEnablementState::kError; +} + GooglePhotosPhotosFetcher::GooglePhotosPhotosFetcher(Profile* profile) : GooglePhotosFetcher(profile, kGooglePhotosPhotosTrafficAnnotation) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h index 5ebf5cd..f562a51f 100644 --- a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h +++ b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.h
@@ -253,6 +253,28 @@ int ParseResponse(const base::Value::Dict* response) override; }; +using ash::personalization_app::mojom::GooglePhotosEnablementState; +// Downloads whether the user is allowed to access Google Photos data. +class GooglePhotosEnabledFetcher + : public GooglePhotosFetcher<GooglePhotosEnablementState> { + public: + explicit GooglePhotosEnabledFetcher(Profile* profile); + + GooglePhotosEnabledFetcher(const GooglePhotosEnabledFetcher&) = delete; + GooglePhotosEnabledFetcher& operator=(const GooglePhotosEnabledFetcher&) = + delete; + + ~GooglePhotosEnabledFetcher() override; + + virtual void AddRequestAndStartIfNecessary( + base::OnceCallback<void(GooglePhotosEnablementState)> callback); + + protected: + // GooglePhotosFetcher: + GooglePhotosEnablementState ParseResponse( + const base::Value::Dict* response) override; +}; + using GooglePhotosPhotosCbkArgs = ash::personalization_app::mojom::FetchGooglePhotosPhotosResponsePtr; // Downloads visible photos from a user's Google Photos library.
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc index ec92503..cbf6d42 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.cc
@@ -208,6 +208,26 @@ std::move(callback)); } +void PersonalizationAppWallpaperProviderImpl::FetchGooglePhotosEnabled( + FetchGooglePhotosEnabledCallback callback) { + if (!ash::features::IsWallpaperGooglePhotosIntegrationEnabled()) { + mojo::ReportBadMessage( + "Cannot call `FetchGooglePhotosEnabled()` without Google Photos " + "Wallpaper integration enabled."); + std::move(callback).Run( + ash::personalization_app::mojom::GooglePhotosEnablementState::kError); + return; + } + + if (!google_photos_enabled_fetcher_) { + google_photos_enabled_fetcher_ = + std::make_unique<wallpaper_handlers::GooglePhotosEnabledFetcher>( + profile_); + } + google_photos_enabled_fetcher_->AddRequestAndStartIfNecessary( + std::move(callback)); +} + void PersonalizationAppWallpaperProviderImpl::FetchGooglePhotosPhotos( const absl::optional<std::string>& item_id, const absl::optional<std::string>& album_id, @@ -505,6 +525,13 @@ return google_photos_count_fetcher_.get(); } +wallpaper_handlers::GooglePhotosEnabledFetcher* +PersonalizationAppWallpaperProviderImpl::SetGooglePhotosEnabledFetcherForTest( + std::unique_ptr<wallpaper_handlers::GooglePhotosEnabledFetcher> fetcher) { + google_photos_enabled_fetcher_ = std::move(fetcher); + return google_photos_enabled_fetcher_.get(); +} + wallpaper_handlers::GooglePhotosPhotosFetcher* PersonalizationAppWallpaperProviderImpl::SetGooglePhotosPhotosFetcherForTest( std::unique_ptr<wallpaper_handlers::GooglePhotosPhotosFetcher> fetcher) {
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.h b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.h index 35357e50..5c0c7d0 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.h +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl.h
@@ -48,6 +48,7 @@ class BackdropImageInfoFetcher; class GooglePhotosAlbumsFetcher; class GooglePhotosCountFetcher; +class GooglePhotosEnabledFetcher; class GooglePhotosPhotosFetcher; } // namespace wallpaper_handlers @@ -94,6 +95,9 @@ void FetchGooglePhotosCount(FetchGooglePhotosCountCallback callback) override; + void FetchGooglePhotosEnabled( + FetchGooglePhotosEnabledCallback callback) override; + void FetchGooglePhotosPhotos( const absl::optional<std::string>& item_id, const absl::optional<std::string>& album_id, @@ -154,6 +158,10 @@ SetGooglePhotosCountFetcherForTest( std::unique_ptr<wallpaper_handlers::GooglePhotosCountFetcher> fetcher); + wallpaper_handlers::GooglePhotosEnabledFetcher* + SetGooglePhotosEnabledFetcherForTest( + std::unique_ptr<wallpaper_handlers::GooglePhotosEnabledFetcher> fetcher); + wallpaper_handlers::GooglePhotosPhotosFetcher* SetGooglePhotosPhotosFetcherForTest( std::unique_ptr<wallpaper_handlers::GooglePhotosPhotosFetcher> fetcher); @@ -244,6 +252,13 @@ std::unique_ptr<wallpaper_handlers::GooglePhotosCountFetcher> google_photos_count_fetcher_; + // Fetches the state of the user's permission to access Google Photos data. + // Constructed lazily at the time of the first request and then persists for + // the rest of the delegate's lifetime, unless preemptively or subsequently + // replaced by a mock in a test. + std::unique_ptr<wallpaper_handlers::GooglePhotosEnabledFetcher> + google_photos_enabled_fetcher_; + // Fetches visible photos from the user's Google Photos library. Constructed // lazily at the time of the first request and then persists for the rest of // the delegate's lifetime, unless preemptively or subsequently replaced by a
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc index cd7292d..c6979feb 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc
@@ -490,6 +490,32 @@ wallpaper_provider_remote()->FlushForTesting(); } +TEST_P(PersonalizationAppWallpaperProviderImplGooglePhotosTest, FetchEnabled) { + using ash::personalization_app::mojom::GooglePhotosEnablementState; + + // Mock a fetcher for the enablement state query. + auto* const google_photos_enabled_fetcher = static_cast< + ::testing::NiceMock<wallpaper_handlers::MockGooglePhotosEnabledFetcher>*>( + delegate()->SetGooglePhotosEnabledFetcherForTest( + std::make_unique<::testing::NiceMock< + wallpaper_handlers::MockGooglePhotosEnabledFetcher>>(profile()))); + + // Simulate the client making multiple requests for the same information to + // test that all callbacks for that query are called. + EXPECT_CALL(*google_photos_enabled_fetcher, AddRequestAndStartIfNecessary) + .Times(GooglePhotosEnabled() ? kNumFetches : 0); + + for (size_t i = 0; i < kNumFetches; ++i) { + wallpaper_provider_remote()->get()->FetchGooglePhotosEnabled( + base::BindLambdaForTesting([this](GooglePhotosEnablementState state) { + EXPECT_EQ(state, GooglePhotosEnabled() + ? GooglePhotosEnablementState::kEnabled + : GooglePhotosEnablementState::kError); + })); + } + wallpaper_provider_remote()->FlushForTesting(); +} + TEST_P(PersonalizationAppWallpaperProviderImplGooglePhotosTest, FetchPhotos) { // Mock a fetcher for the photos query. auto* const google_photos_photos_fetcher = static_cast< @@ -650,6 +676,41 @@ EXPECT_EQ(1, google_photos_count_fetcher->ParseResponse(&response)); } +TEST_P(PersonalizationAppWallpaperProviderImplGooglePhotosTest, ParseEnabled) { + using ash::personalization_app::mojom::GooglePhotosEnablementState; + + // Mock a fetcher to parse constructed responses. + auto* const google_photos_enabled_fetcher = static_cast< + ::testing::NiceMock<wallpaper_handlers::MockGooglePhotosEnabledFetcher>*>( + delegate()->SetGooglePhotosEnabledFetcherForTest( + std::make_unique<::testing::NiceMock< + wallpaper_handlers::MockGooglePhotosEnabledFetcher>>(profile()))); + + // Parse an absent response (simulating a fetching error). + EXPECT_EQ(GooglePhotosEnablementState::kError, + google_photos_enabled_fetcher->ParseResponse(nullptr)); + + // Parse a response without an enabled state. + base::Value::Dict response; + EXPECT_EQ(GooglePhotosEnablementState::kError, + google_photos_enabled_fetcher->ParseResponse(&response)); + + // Parse a response with an unknown enabled state. + response.SetByDottedPath("status.userState", "UNKNOWN_STATUS_STATE"); + EXPECT_EQ(GooglePhotosEnablementState::kError, + google_photos_enabled_fetcher->ParseResponse(&response)); + + // Parse a response indicating that the user cannot access Google Photos data. + response.SetByDottedPath("status.userState", "USER_DASHER_DISABLED"); + EXPECT_EQ(GooglePhotosEnablementState::kDisabled, + google_photos_enabled_fetcher->ParseResponse(&response)); + + // Parse a response indicating that the user can access Google Photos data. + response.SetByDottedPath("status.userState", "USER_PERMITTED"); + EXPECT_EQ(GooglePhotosEnablementState::kEnabled, + google_photos_enabled_fetcher->ParseResponse(&response)); +} + TEST_P(PersonalizationAppWallpaperProviderImplGooglePhotosTest, ParsePhotosAbsentPhoto) { using ash::personalization_app::mojom::FetchGooglePhotosPhotosResponse;
diff --git a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewModel.java b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewModel.java index 35c31d8..cd34390 100644 --- a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewModel.java +++ b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewModel.java
@@ -23,6 +23,7 @@ import org.chromium.components.messages.DismissReason; import org.chromium.components.messages.MessageBannerProperties; import org.chromium.components.messages.MessageIdentifier; +import org.chromium.components.messages.PrimaryActionClickBehavior; import org.chromium.ui.modelutil.PropertyModel; import java.lang.annotation.Retention; @@ -87,9 +88,11 @@ .with(MessageBannerProperties.ON_DISMISSED, (reason) -> actionsHandler.onMessageDismissed(reason, messageAssociatedUrl)) .with(MessageBannerProperties.ON_PRIMARY_ACTION, - () - -> actionsHandler.onMessagePrimaryAction( - trustSignals, messageAssociatedUrl)) + () -> { + actionsHandler.onMessagePrimaryAction( + trustSignals, messageAssociatedUrl); + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; + }) .build(); } @@ -181,4 +184,4 @@ assert titleUI == MessageTitleUI.VIEW_STORE_INFO : "Invalid title UI"; return R.string.merchant_viewer_message_title; } -} \ No newline at end of file +}
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h index 65b5fc2..0537fe3 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h
@@ -22,6 +22,10 @@ using KeyInfo = std::pair<KeyTrustLevel, std::vector<uint8_t>>; virtual ~KeyPersistenceDelegate() = default; + // Validates that the current context has sufficient permissions to perform a + // key rotation operation. + virtual bool CheckRotationPermissions() = 0; + // Stores the trust level and wrapped key in a platform specific location. // This method requires elevation since it writes to a location that is // shared by all OS users of the device. Returns true on success.
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.cc index f16a233..2de57cb 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.cc +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.cc
@@ -4,15 +4,20 @@ #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.h" +#include <grp.h> +#include <sys/stat.h> + #include <string> #include <vector> #include "base/base64.h" #include "base/files/file.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/notreached.h" +#include "base/syslog_logging.h" #include "base/values.h" #include "build/branding_buildflags.h" #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/shared_command_constants.h" @@ -26,6 +31,12 @@ namespace { +// Mode the signing key file should have. +constexpr int kFileMode = 0664; + +// Group name the signing key file should have. +constexpr char kGroupName[] = "chromemgmt"; + // Path to the signing key file differs based on chrome/chromium build. #if BUILDFLAG(GOOGLE_CHROME_BRANDING) base::FilePath::CharType kDirPolicyPath[] = @@ -35,14 +46,51 @@ FILE_PATH_LITERAL("/etc/chromium/policies"); #endif -// Returns the created signing key file with the specified file `flags`. -base::File OpenSigningKeyFile(uint32_t flags) { +base::FilePath GetSigningKeyFilePath() { base::FilePath path(kDirPolicyPath); - return base::File(path.Append(constants::kSigningKeyFilePath), flags); + return path.Append(constants::kSigningKeyFilePath); +} + +base::File OpenSigningKeyFile(uint32_t flags) { + return base::File(GetSigningKeyFilePath(), flags); } } // namespace +bool LinuxKeyPersistenceDelegate::CheckRotationPermissions() { + auto signing_key_path = GetSigningKeyFilePath(); + auto file = base::File(signing_key_path, + base::File::FLAG_OPEN | base::File::FLAG_WRITE); + + if (!file.IsValid() || + (file.Lock(base::File::LockMode::kExclusive) != base::File::FILE_OK)) { + SYSLOG(ERROR) << "Device trust key rotation failed. Could not acquire a " + "lock on the signing key storage."; + return false; + } + + int mode; + if (!base::GetPosixFilePermissions(signing_key_path, &mode)) { + SYSLOG(ERROR) + << "Device trust key rotation failed. Could not get permissions " + "for the signing key storage."; + return false; + } + + struct stat st; + stat(signing_key_path.value().c_str(), &st); + gid_t signing_key_file_gid = st.st_gid; + struct group* chrome_mgmt_group = getgrnam(kGroupName); + + if (!chrome_mgmt_group || signing_key_file_gid != chrome_mgmt_group->gr_gid || + mode != kFileMode) { + SYSLOG(ERROR) << "Device trust key rotation failed. Incorrect permissions " + "for signing key storage."; + return false; + } + return true; +} + LinuxKeyPersistenceDelegate::~LinuxKeyPersistenceDelegate() = default; const int kMaxBufferSize = 2048; const char kSigningKeyName[] = "signingKey";
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.h index 764d8a6..9e49f09 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.h +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.h
@@ -15,6 +15,7 @@ ~LinuxKeyPersistenceDelegate() override; // KeyPersistenceDelegate: + bool CheckRotationPermissions() override; bool StoreKeyPair(KeyPersistenceDelegate::KeyTrustLevel trust_level, std::vector<uint8_t> wrapped) override; KeyPersistenceDelegate::KeyInfo LoadKeyPair() override;
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.cc index cbb07cef..10abe59e 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.cc +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.cc
@@ -10,6 +10,11 @@ MacKeyPersistenceDelegate::~MacKeyPersistenceDelegate() = default; +bool MacKeyPersistenceDelegate::CheckRotationPermissions() { + NOTIMPLEMENTED(); + return false; +} + bool MacKeyPersistenceDelegate::StoreKeyPair(KeyTrustLevel trust_level, std::vector<uint8_t> wrapped) { NOTIMPLEMENTED();
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.h index cc7b780d..1465e92 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.h +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.h
@@ -15,6 +15,7 @@ ~MacKeyPersistenceDelegate() override; // KeyPersistenceDelegate: + bool CheckRotationPermissions() override; bool StoreKeyPair(KeyPersistenceDelegate::KeyTrustLevel trust_level, std::vector<uint8_t> wrapped) override; KeyPersistenceDelegate::KeyInfo LoadKeyPair() override;
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h index a5fce03..e2e8fe99 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h
@@ -18,6 +18,7 @@ ~MockKeyPersistenceDelegate() override; // KeyPersistenceDelegate: + MOCK_METHOD(bool, CheckRotationPermissions, (), (override)); MOCK_METHOD(bool, StoreKeyPair, (KeyPersistenceDelegate::KeyTrustLevel, std::vector<uint8_t>),
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.cc index ea763ea..0572498 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.cc +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.cc
@@ -14,6 +14,10 @@ WinKeyPersistenceDelegate::~WinKeyPersistenceDelegate() = default; +bool WinKeyPersistenceDelegate::CheckRotationPermissions() { + return true; +} + bool WinKeyPersistenceDelegate::StoreKeyPair( KeyPersistenceDelegate::KeyTrustLevel trust_level, std::vector<uint8_t> wrapped) {
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.h index dc7c0ac..a41361e 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.h +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.h
@@ -15,6 +15,7 @@ ~WinKeyPersistenceDelegate() override; // KeyPersistenceDelegate: + bool CheckRotationPermissions() override; bool StoreKeyPair(KeyPersistenceDelegate::KeyTrustLevel trust_level, std::vector<uint8_t> wrapped) override; KeyPersistenceDelegate::KeyInfo LoadKeyPair() override;
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc index 4645ce8..9f7a677 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc
@@ -68,6 +68,12 @@ return false; } + if (!persistence_delegate_->CheckRotationPermissions()) { + RecordRotationStatus(nonce, + RotationStatus::FAILURE_INCORRECT_FILE_PERMISSIONS); + return false; + } + // Create a new key pair. First try creating a TPM-backed key. If that does // not work, try a less secure type. KeyTrustLevel new_trust_level = BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED;
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc index 07adadb..ec52c369 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc
@@ -96,6 +96,8 @@ // The mocked delegate is already set-up to return a working TPM key and // provider. EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair()); + EXPECT_CALL(*mock_persistence_delegate, CheckRotationPermissions()) + .WillOnce(Return(true)); EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider()).Times(2); EXPECT_CALL( *mock_persistence_delegate, @@ -149,6 +151,8 @@ // provider. Force it to not return a key. EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair()) .WillOnce(Return(CreateEmptyKeyPair())); + EXPECT_CALL(*mock_persistence_delegate, CheckRotationPermissions()) + .WillOnce(Return(true)); EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider()); EXPECT_CALL(*mock_persistence_delegate, StoreKeyPair(BPKUR::CHROME_BROWSER_TPM_KEY, _)) @@ -179,6 +183,8 @@ std::make_unique<MockKeyPersistenceDelegate>(); EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair()) .WillOnce(Return(CreateEmptyKeyPair())); + EXPECT_CALL(*mock_persistence_delegate, CheckRotationPermissions()) + .WillOnce(Return(true)); EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider()); EXPECT_CALL(*mock_persistence_delegate, StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY, _)) @@ -218,6 +224,9 @@ EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair()) .WillOnce(Return(CreateEmptyKeyPair())); + EXPECT_CALL(*mock_persistence_delegate, CheckRotationPermissions()) + .WillOnce(Return(true)); + EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider()); EXPECT_CALL(*mock_persistence_delegate, StoreKeyPair(BPKUR::CHROME_BROWSER_TPM_KEY, _)) @@ -266,6 +275,9 @@ EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair()) .WillOnce(Return(CreateEmptyKeyPair())); + EXPECT_CALL(*mock_persistence_delegate, CheckRotationPermissions()) + .WillOnce(Return(true)); + EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider()); EXPECT_CALL(*mock_persistence_delegate, StoreKeyPair(BPKUR::CHROME_BROWSER_TPM_KEY, _)) @@ -305,6 +317,8 @@ auto mock_persistence_delegate = scoped_factory_.CreateMockedECDelegate(); EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair()); + EXPECT_CALL(*mock_persistence_delegate, CheckRotationPermissions()) + .WillOnce(Return(true)); EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider()); EXPECT_CALL(*mock_persistence_delegate, StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY, _)) @@ -337,6 +351,8 @@ auto original_key_wrapped = scoped_factory_.ec_wrapped_key(); EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair()); + EXPECT_CALL(*mock_persistence_delegate, CheckRotationPermissions()) + .WillOnce(Return(true)); EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider()); EXPECT_CALL( *mock_persistence_delegate, @@ -369,6 +385,8 @@ auto original_key_wrapped = scoped_factory_.ec_wrapped_key(); EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair()); + EXPECT_CALL(*mock_persistence_delegate, CheckRotationPermissions()) + .WillOnce(Return(true)); EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider()); EXPECT_CALL( *mock_persistence_delegate, @@ -410,6 +428,8 @@ InSequence s; EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair()); + EXPECT_CALL(*mock_persistence_delegate, CheckRotationPermissions()) + .WillOnce(Return(true)); EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider()); EXPECT_CALL( *mock_persistence_delegate, @@ -439,6 +459,41 @@ histogram_tester.ExpectTotalCount(opposite_status_histogram_name(), 0); } +// Tests a success key rotation flow when incorrect permissions were set +// on the signing key file. +TEST_P(KeyRotationManagerTest, + RotateWithAdminRights_StoreFailed_InvalidFilePermissions) { + base::HistogramTester histogram_tester; + + auto mock_persistence_delegate = + std::make_unique<MockKeyPersistenceDelegate>(); + EXPECT_CALL(*mock_persistence_delegate, CheckRotationPermissions()) + .WillOnce(Return(false)); + EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair()); + EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider()).Times(0); + EXPECT_CALL(*mock_persistence_delegate, + StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY, _)) + .Times(0); + + GURL dm_server_url(kDmServerUrl); + auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>(); + EXPECT_CALL(*mock_network_delegate, + SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _)) + .Times(0); + + auto manager = KeyRotationManager::CreateForTesting( + std::move(mock_network_delegate), std::move(mock_persistence_delegate)); + + EXPECT_FALSE( + manager->RotateWithAdminRights(dm_server_url, kDmToken, nonce())); + + // Should expect one successful attempt to rotate a key. + histogram_tester.ExpectUniqueSample( + status_histogram_name(), + RotationStatus::FAILURE_INCORRECT_FILE_PERMISSIONS, 1); + histogram_tester.ExpectTotalCount(opposite_status_histogram_name(), 0); +} + INSTANTIATE_TEST_SUITE_P(, KeyRotationManagerTest, testing::Bool()); } // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service/rotate_util_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service/rotate_util_unittest.cc index 07c1df47..31c04eb 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service/rotate_util_unittest.cc +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/management_service/rotate_util_unittest.cc
@@ -87,6 +87,9 @@ // Tests when the chrome management services key rotation was successful. TEST_F(RotateUtilTest, RotateDTKeySuccess) { + EXPECT_CALL(*mock_persistence_delegate_, CheckRotationPermissions()) + .WillOnce(Return(true)); + EXPECT_CALL(*mock_persistence_delegate_, StoreKeyPair(_, _)) .WillOnce(Return(true)); @@ -102,15 +105,6 @@ } // Tests when the chrome management services key rotation failed due to -// incorrect signing key file permissions. -TEST_F(RotateUtilTest, RotateDTKeyFailure_IncorrectPermissions) { - EXPECT_FALSE(RotateDeviceTrustKey( - std::move(key_rotation_manager_), - GetCommandLine(kEncodedFakeDMToken, kEncodedNonce, kFakeDmServerUrl), - version_info::Channel::STABLE)); -} - -// Tests when the chrome management services key rotation failed due to // an invalid dm token. TEST_F(RotateUtilTest, RotateDTKeyFailure_InvalidDmToken) { EXPECT_FALSE(RotateDeviceTrustKey( @@ -147,8 +141,23 @@ } // Tests when the chrome management services key rotation failed due to +// incorrect signing key permissions. +TEST_F(RotateUtilTest, RotateDTKeyFailure_PermissionsFailed) { + EXPECT_CALL(*mock_persistence_delegate_, CheckRotationPermissions()) + .WillOnce(Return(false)); + + EXPECT_FALSE(RotateDeviceTrustKey( + std::move(key_rotation_manager_), + GetCommandLine(kEncodedFakeDMToken, kEncodedNonce, kFakeDmServerUrl), + version_info::Channel::STABLE)); +} + +// Tests when the chrome management services key rotation failed due to // an store key failure. TEST_F(RotateUtilTest, RotateDTKeyFailure_StoreKeyFailed) { + EXPECT_CALL(*mock_persistence_delegate_, CheckRotationPermissions()) + .WillOnce(Return(true)); + EXPECT_CALL(*mock_persistence_delegate_, StoreKeyPair(_, _)) .WillOnce(Return(false)); @@ -161,6 +170,9 @@ // Tests when the chrome management services key rotation failed due to // an upload key failure. TEST_F(RotateUtilTest, RotateDTKeyFailure_UploadKeyFailed) { + EXPECT_CALL(*mock_persistence_delegate_, CheckRotationPermissions()) + .WillOnce(Return(true)); + EXPECT_CALL(*mock_persistence_delegate_, StoreKeyPair(_, _)) .Times(2) .WillRepeatedly(Return(true));
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/metrics_util.h b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/metrics_util.h index 97b82126..deb56f1 100644 --- a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/metrics_util.h +++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/metrics_util.h
@@ -20,7 +20,8 @@ FAILURE_CANNOT_UPLOAD_KEY_TRIES_EXHAUSTED, FAILURE_CANNOT_UPLOAD_KEY_RESTORE_FAILED, FAILURE_CANNOT_UPLOAD_KEY_TRIES_EXHAUSTED_RESTORE_FAILED, - kMaxValue = FAILURE_CANNOT_UPLOAD_KEY_TRIES_EXHAUSTED_RESTORE_FAILED, + FAILURE_INCORRECT_FILE_PERMISSIONS, + kMaxValue = FAILURE_INCORRECT_FILE_PERMISSIONS, }; // Metrics for the RotateWithAdminRights() result. `nonce` is the
diff --git a/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc b/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc index 441237f..0befa520 100644 --- a/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc +++ b/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.cc
@@ -115,13 +115,40 @@ const std::string& extension_id, const PortId& receiver_port_id, content::WebContents* receiver_contents, - int receiver_frame_id) { + int receiver_frame_id, + const std::string& receiver_document_id) { // Frame ID -1 is every frame in the tab. - bool include_child_frames = receiver_frame_id == -1; - content::RenderFrameHost* receiver_rfh = - include_child_frames ? receiver_contents->GetMainFrame() - : ExtensionApiFrameIdMap::GetRenderFrameHostById( - receiver_contents, receiver_frame_id); + bool include_child_frames = + receiver_frame_id == -1 && receiver_document_id.empty(); + + content::RenderFrameHost* receiver_rfh = nullptr; + if (include_child_frames) { + // The target is the active outermost main frame of the WebContents. + receiver_rfh = receiver_contents->GetMainFrame(); + } else if (!receiver_document_id.empty()) { + ExtensionApiFrameIdMap::DocumentId document_id = + ExtensionApiFrameIdMap::DocumentIdFromString(receiver_document_id); + + // Return early for invalid documentIds. + if (!document_id) + return nullptr; + + receiver_rfh = + ExtensionApiFrameIdMap::Get()->GetRenderFrameHostByDocumentId( + document_id); + + // If both |document_id| and |receiver_frame_id| are provided they + // should find the same RenderFrameHost, if not return early. + if (receiver_frame_id != -1 && + ExtensionApiFrameIdMap::GetRenderFrameHostById( + receiver_contents, receiver_frame_id) != receiver_rfh) { + return nullptr; + } + } else { + DCHECK_GT(receiver_frame_id, -1); + receiver_rfh = ExtensionApiFrameIdMap::GetRenderFrameHostById( + receiver_contents, receiver_frame_id); + } if (!receiver_rfh) return nullptr;
diff --git a/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.h b/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.h index b5942ac..58f4fda 100644 --- a/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.h +++ b/chrome/browser/extensions/api/messaging/chrome_messaging_delegate.h
@@ -33,7 +33,8 @@ const std::string& extension_id, const PortId& receiver_port_id, content::WebContents* receiver_contents, - int receiver_frame_id) override; + int receiver_frame_id, + const std::string& receiver_document_id) override; std::unique_ptr<MessagePort> CreateReceiverForNativeApp( content::BrowserContext* browser_context, base::WeakPtr<MessagePort::ChannelDelegate> channel_delegate,
diff --git a/chrome/browser/feed/android/BUILD.gn b/chrome/browser/feed/android/BUILD.gn index 9aeb4da..05032a2 100644 --- a/chrome/browser/feed/android/BUILD.gn +++ b/chrome/browser/feed/android/BUILD.gn
@@ -324,7 +324,7 @@ "//chrome/test/android:chrome_java_test_support", "//components/browser_ui/bottomsheet/android:java", "//components/browser_ui/settings/android:java", - "//components/browser_ui/styles/android:java_resources", + "//components/browser_ui/theme/android:java_resources", "//components/browser_ui/widget/android:java", "//components/embedder_support/android:junit_test_support", "//components/favicon/android:java",
diff --git a/chrome/browser/lacros/account_manager/web_signin_helper_lacros.cc b/chrome/browser/lacros/account_manager/web_signin_helper_lacros.cc new file mode 100644 index 0000000..5a223444 --- /dev/null +++ b/chrome/browser/lacros/account_manager/web_signin_helper_lacros.cc
@@ -0,0 +1,106 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/lacros/account_manager/web_signin_helper_lacros.h" + +#include "base/callback.h" +#include "base/containers/contains.h" +#include "base/feature_list.h" +#include "chrome/browser/lacros/account_manager/account_manager_util.h" +#include "chrome/browser/ui/profile_picker.h" +#include "components/signin/public/base/signin_switches.h" +#include "components/signin/public/identity_manager/account_info.h" + +WebSigninHelperLacros::WebSigninHelperLacros( + const base::FilePath& profile_path, + AccountProfileMapper* account_profile_mapper, + signin::IdentityManager* identity_manager, + signin::ConsistencyCookieManager* consistency_cookie_manager, + base::OnceClosure callback) + : callback_(std::move(callback)), + profile_path_(profile_path), + account_profile_mapper_(account_profile_mapper), + identity_manager_(identity_manager) { + if (base::FeatureList::IsEnabled(switches::kLacrosNonSyncingProfiles)) { + DCHECK(consistency_cookie_manager); + scoped_account_update_ = + std::make_unique<signin::ConsistencyCookieManager::ScopedAccountUpdate>( + consistency_cookie_manager->CreateScopedAccountUpdate()); + } + + GetAccountsAvailableAsSecondary( + account_profile_mapper, profile_path, + base::BindOnce( + &WebSigninHelperLacros::OnAccountsAvailableAsSecondaryFetched, + weak_factory_.GetWeakPtr())); +} + +WebSigninHelperLacros::~WebSigninHelperLacros() { + Finalize(); +} + +void WebSigninHelperLacros::OnAccountsAvailableAsSecondaryFetched( + const std::vector<account_manager::Account>& accounts) { + if (!accounts.empty()) { + // Pass in the current profile to signal that the user wants to select a + // _secondary_ account for this particular profile. + ProfilePicker::Show(ProfilePicker::Params::ForLacrosSelectAvailableAccount( + profile_path_, base::BindOnce(&WebSigninHelperLacros::OnAccountPicked, + weak_factory_.GetWeakPtr()))); + return; + } + + account_profile_mapper_->ShowAddAccountDialog( + profile_path_, + account_manager::AccountManagerFacade::AccountAdditionSource:: + kOgbAddAccount, + base::BindOnce(&WebSigninHelperLacros::OnAccountAdded, + weak_factory_.GetWeakPtr())); +} + +void WebSigninHelperLacros::OnAccountAdded( + const absl::optional<AccountProfileMapper::AddAccountResult>& result) { + std::string gaia_id; + if (result.has_value() && result->account.key.account_type() == + account_manager::AccountType::kGaia) { + gaia_id = result->account.key.id(); + } + OnAccountPicked(gaia_id); +} + +void WebSigninHelperLacros::OnAccountPicked(const std::string& gaia_id) { + if (gaia_id.empty()) { + Finalize(); + return; + } + + std::vector<CoreAccountInfo> accounts_in_tokens = + identity_manager_->GetAccountsWithRefreshTokens(); + if (base::Contains(accounts_in_tokens, gaia_id, + [](const CoreAccountInfo& info) { return info.gaia; })) { + // Account is already in tokens. + Finalize(); + return; + } + + // Wait for account to be in tokens. + account_added_to_mapping_ = gaia_id; + identity_manager_observervation_.Observe(identity_manager_); +} + +void WebSigninHelperLacros::Finalize() { + identity_manager_observervation_.Reset(); + scoped_account_update_.reset(); + if (callback_) + std::move(callback_).Run(); + // `this` may be deleted. +} + +void WebSigninHelperLacros::OnRefreshTokenUpdatedForAccount( + const CoreAccountInfo& account_info) { + if (account_added_to_mapping_ == account_info.gaia) { + Finalize(); + return; + } +}
diff --git a/chrome/browser/lacros/account_manager/web_signin_helper_lacros.h b/chrome/browser/lacros/account_manager/web_signin_helper_lacros.h new file mode 100644 index 0000000..2c5bb755 --- /dev/null +++ b/chrome/browser/lacros/account_manager/web_signin_helper_lacros.h
@@ -0,0 +1,86 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_LACROS_ACCOUNT_MANAGER_WEB_SIGNIN_HELPER_LACROS_H_ +#define CHROME_BROWSER_LACROS_ACCOUNT_MANAGER_WEB_SIGNIN_HELPER_LACROS_H_ + +#include <memory> + +#include "base/callback_forward.h" +#include "base/files/file_path.h" +#include "base/scoped_observation.h" +#include "chrome/browser/lacros/account_manager/account_profile_mapper.h" +#include "components/signin/core/browser/consistency_cookie_manager.h" +#include "components/signin/public/identity_manager/account_info.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +class AccountProfileMapper; + +// Handles the signin flow starting from the web (when receiving the +// `GAIA_SERVICE_TYPE_ADDSESSION` parameter). Maintains a `ScopedAccountUpdate` +// for the whole duration of the flow. The steps are: +// 1) Call `GetAccountsAvailableAsSecondary()` to check whether there are +// available accounts in the OS that the user could pick. +// 2) If there are available accounts in the OS, show the account picker in +// Chrome. If the user picks an existing account then skip to step 4. +// 3) Call `AccountProfileMapper::ShowAddAccountDialog()` to add a new account +// to the OS. +// 4) Once the account is added to the profile, wait until the `Identitymanager` +// picks it up. +class WebSigninHelperLacros : public signin::IdentityManager::Observer { + public: + WebSigninHelperLacros( + const base::FilePath& profile_path, + AccountProfileMapper* account_profile_mapper, + signin::IdentityManager* identity_manager, + signin::ConsistencyCookieManager* consistency_cookie_manager, + base::OnceClosure callback); + + ~WebSigninHelperLacros() override; + + WebSigninHelperLacros(const WebSigninHelperLacros&) = delete; + WebSigninHelperLacros& operator=(const WebSigninHelperLacros&) = delete; + + private: + // Callback for `GetAccountsAvailableAsSecondary()`. + void OnAccountsAvailableAsSecondaryFetched( + const std::vector<account_manager::Account>& accounts); + + // Callback for `AccountProfileMapper::ShowAddAccountDialog()`. + void OnAccountAdded( + const absl::optional<AccountProfileMapper::AddAccountResult>& result); + + // Called once the user has picked an account (either from the picker or by + // adding it to the OS directly). + void OnAccountPicked(const std::string& gaia_id); + + // Unregisters the identity manager observation, releases + // the `ScopedAccountUpdate`, and calls `callback_`. + void Finalize(); + + // signin::IdentityManager::Observer: + void OnRefreshTokenUpdatedForAccount( + const CoreAccountInfo& account_info) override; + + // Sets the consistency cookie to "Updating". + std::unique_ptr<signin::ConsistencyCookieManager::ScopedAccountUpdate> + scoped_account_update_; + + base::OnceClosure callback_; + base::FilePath profile_path_; + AccountProfileMapper* const account_profile_mapper_; + + signin::IdentityManager* const identity_manager_; + base::ScopedObservation<signin::IdentityManager, + signin::IdentityManager::Observer> + identity_manager_observervation_{this}; + + // Gaia ID returned by `AccountProfileMapper::ShowAddAccountDialog()`. + std::string account_added_to_mapping_; + + base::WeakPtrFactory<WebSigninHelperLacros> weak_factory_{this}; +}; + +#endif // CHROME_BROWSER_LACROS_ACCOUNT_MANAGER_WEB_SIGNIN_HELPER_LACROS_H_
diff --git a/chrome/browser/lacros/account_manager/web_signin_helper_lacros_unittest.cc b/chrome/browser/lacros/account_manager/web_signin_helper_lacros_unittest.cc new file mode 100644 index 0000000..a745cf43 --- /dev/null +++ b/chrome/browser/lacros/account_manager/web_signin_helper_lacros_unittest.cc
@@ -0,0 +1,273 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/lacros/account_manager/web_signin_helper_lacros.h" + +#include <memory> +#include <string> + +#include "base/containers/flat_set.h" +#include "base/test/mock_callback.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/task_environment.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/lacros/account_manager/account_profile_mapper.h" +#include "chrome/browser/profiles/profile_attributes_entry.h" +#include "chrome/browser/profiles/profile_attributes_storage.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "components/account_manager_core/account.h" +#include "components/account_manager_core/account_addition_result.h" +#include "components/account_manager_core/account_manager_facade.h" +#include "components/account_manager_core/mock_account_manager_facade.h" +#include "components/signin/core/browser/account_reconcilor.h" +#include "components/signin/core/browser/account_reconcilor_delegate.h" +#include "components/signin/core/browser/consistency_cookie_manager.h" +#include "components/signin/core/browser/mirror_landing_account_reconcilor_delegate.h" +#include "components/signin/public/base/signin_switches.h" +#include "components/signin/public/base/test_signin_client.h" +#include "components/signin/public/identity_manager/identity_test_environment.h" +#include "components/signin/public/identity_manager/identity_test_utils.h" +#include "components/signin/public/identity_manager/set_accounts_in_cookie_result.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "google_apis/gaia/gaia_urls.h" +#include "services/network/test/test_cookie_manager.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class MockCookieManager + : public testing::StrictMock<network::TestCookieManager> { + public: + MOCK_METHOD4(SetCanonicalCookie, + void(const net::CanonicalCookie& cookie, + const GURL& source_url, + const net::CookieOptions& cookie_options, + SetCanonicalCookieCallback callback)); +}; + +class TestAccountReconcilor : public AccountReconcilor { + public: + TestAccountReconcilor(signin::IdentityManager* identity_manager, + SigninClient* client) + : AccountReconcilor( + identity_manager, + client, + std::make_unique< + signin::MirrorLandingAccountReconcilorDelegate>()) {} + + void SimulateSetCookiesFinished() { + OnSetAccountsInCookieCompleted(signin::SetAccountsInCookieResult::kSuccess); + } +}; + +} // namespace + +class WebSigninHelperLacrosTest : public testing::Test { + public: + WebSigninHelperLacrosTest() { + CHECK(testing_profile_manager_.SetUp()); + + profile_path_ = + testing_profile_manager_.profile_manager()->user_data_dir().AppendASCII( + "Default"); + ProfileAttributesInitParams params; + params.profile_path = profile_path(); + params.profile_name = u"ProfileName"; + storage()->AddProfile(std::move(params)); + + // No account in the facade. + EXPECT_CALL(mock_facade_, GetAccounts(testing::_)) + .Times(testing::AtLeast(1)) + .WillRepeatedly( + [](base::OnceCallback<void( + const std::vector<account_manager::Account>&)> callback) { + std::move(callback).Run({}); + }); + + testing_profile_manager_.SetAccountProfileMapper( + std::make_unique<AccountProfileMapper>( + &mock_facade_, storage(), + testing_profile_manager_.local_state()->Get())); + std::unique_ptr<MockCookieManager> mock_cookie_manager = + std::make_unique<MockCookieManager>(); + cookie_manager_ = mock_cookie_manager.get(); + signin_client_.set_cookie_manager(std::move(mock_cookie_manager)); + identity_test_env_.WaitForRefreshTokensLoaded(); + identity_test_env_.SetCookieAccounts({}); + reconcilor_.Initialize(/*start_reconcile_if_tokens_available=*/true); + WaitForConsistentReconcilorState(); + ExpectCookieSet("Consistent"); + consistency_cookie_manager_ = + std::make_unique<signin::ConsistencyCookieManager>(&signin_client_, + &reconcilor_); + } + + ~WebSigninHelperLacrosTest() override { reconcilor_.Shutdown(); } + + // Returns a `WebSigninHelperLacros` instance. The `AccountProfileMapper` and + // the `IdentityManager` are not connected to each other, and must be managed + // separately. + std::unique_ptr<WebSigninHelperLacros> CreateWebSigninHelperLacros( + base::OnceClosure closure) { + return std::make_unique<WebSigninHelperLacros>( + profile_path_, + testing_profile_manager_.profile_manager()->GetAccountProfileMapper(), + identity_test_env_.identity_manager(), + consistency_cookie_manager_.get(), std::move(closure)); + } + + void ExpectCookieSet(const std::string& value) { + EXPECT_CALL( + *cookie_manager_, + SetCanonicalCookie( + testing::AllOf( + testing::Property(&net::CanonicalCookie::Name, + "CHROME_ID_CONSISTENCY_STATE"), + testing::Property(&net::CanonicalCookie::Value, value)), + GaiaUrls::GetInstance()->gaia_url(), testing::_, testing::_)) + .Times(1); + } + + MockCookieManager* cookie_manager() { return cookie_manager_; } + + account_manager::MockAccountManagerFacade* mock_facade() { + return &mock_facade_; + } + + const base::FilePath& profile_path() const { return profile_path_; } + + void WaitForConsistentReconcilorState() { + while (reconcilor_.GetState() != signin_metrics::ACCOUNT_RECONCILOR_OK) + base::RunLoop().RunUntilIdle(); + } + + void SimulateSetCookiesFinished() { + reconcilor_.SimulateSetCookiesFinished(); + } + + ProfileAttributesStorage* storage() { + return &testing_profile_manager_.profile_manager() + ->GetProfileAttributesStorage(); + } + + AccountProfileMapper* mapper() { + return testing_profile_manager_.profile_manager() + ->GetAccountProfileMapper(); + } + + signin::IdentityTestEnvironment* identity_test_env() { + return &identity_test_env_; + } + + private: + base::test::ScopedFeatureList feature_list_{ + switches::kLacrosNonSyncingProfiles}; + + base::test::TaskEnvironment task_environment; + account_manager::MockAccountManagerFacade mock_facade_; + sync_preferences::TestingPrefServiceSyncable prefs_; + base::FilePath profile_path_; + network::TestURLLoaderFactory test_url_loader_factory_; + + TestingProfileManager testing_profile_manager_{ + TestingBrowserProcess::GetGlobal()}; + + TestSigninClient signin_client_{&prefs_, &test_url_loader_factory_}; + + signin::IdentityTestEnvironment identity_test_env_{ + /*test_url_loader_factory=*/nullptr, &prefs_, + signin::AccountConsistencyMethod::kDisabled, &signin_client_}; + + TestAccountReconcilor reconcilor_{identity_test_env_.identity_manager(), + &signin_client_}; + + MockCookieManager* cookie_manager_ = nullptr; // Owned by `signin_client_`. + + std::unique_ptr<signin::ConsistencyCookieManager> consistency_cookie_manager_; +}; + +// Checks that creating a deleting the helper updates the cookie and that the +// destruction callback is run. +TEST_F(WebSigninHelperLacrosTest, DeletionCallback) { + testing::StrictMock<base::MockOnceClosure> helper_deleted; + + // Create the helper. + ExpectCookieSet("Updating"); + std::unique_ptr<WebSigninHelperLacros> web_signin_helper = + CreateWebSigninHelperLacros(helper_deleted.Get()); + + // Delete the helper. + EXPECT_CALL(helper_deleted, Run).Times(1); + ExpectCookieSet("Consistent"); + web_signin_helper.reset(); +} + +// Checks that an account can be added through the OS when there is no available +// account. +TEST_F(WebSigninHelperLacrosTest, NoAccountAvailable) { + testing::StrictMock<base::MockOnceClosure> helper_complete; + + const std::string email("testemail"); + std::string gaia_id = signin::GetTestGaiaIdForEmail(email); + account_manager::Account new_account{ + {gaia_id, account_manager::AccountType::kGaia}, email}; + + // Create the helper, this should trigger a call to `ShowAddAccountDialog()`. + EXPECT_CALL(*mock_facade(), + ShowAddAccountDialog(account_manager::AccountManagerFacade:: + AccountAdditionSource::kOgbAddAccount, + testing::_)) + .Times(1) + .WillRepeatedly( + [new_account]( + account_manager::AccountManagerFacade::AccountAdditionSource, + base::OnceCallback<void( + const account_manager::AccountAdditionResult& result)> + callback) { + std::move(callback).Run( + account_manager::AccountAdditionResult::FromAccount( + new_account)); + }); + ExpectCookieSet("Updating"); + std::unique_ptr<WebSigninHelperLacros> web_signin_helper = + CreateWebSigninHelperLacros(helper_complete.Get()); + testing::Mock::VerifyAndClearExpectations(cookie_manager()); + testing::Mock::VerifyAndClearExpectations(mock_facade()); + + // Simmulate the mapper adding the account to the profile. + identity_test_env()->MakeAccountAvailable(email); + + EXPECT_CALL(helper_complete, Run).Times(1); + + // `AccountProfileMapper` expects a call of `OnAccountUpserted()` before + // completing the account addition. + EXPECT_CALL(*mock_facade(), GetAccounts(testing::_)) + .Times(testing::AtLeast(1)) + .WillRepeatedly( + [new_account]( + base::OnceCallback<void( + const std::vector<account_manager::Account>&)> callback) { + std::move(callback).Run({new_account}); + }); + mapper()->OnAccountUpserted(new_account); + + // Account mapping is complete, check that the account was added to the right + // profile. + EXPECT_EQ( + storage()->GetProfileAttributesWithPath(profile_path())->GetGaiaIds(), + base::flat_set<std::string>{gaia_id}); + + // The `AccountReconcilor` stops running, cookie is reset. + ExpectCookieSet("Consistent"); + SimulateSetCookiesFinished(); + + testing::Mock::VerifyAndClearExpectations(cookie_manager()); + testing::Mock::VerifyAndClearExpectations(&helper_complete); + + // Delete the helper, nothing happens. + web_signin_helper.reset(); +}
diff --git a/chrome/browser/paint_preview/android/javatests/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewAccessibilityTest.java b/chrome/browser/paint_preview/android/javatests/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewAccessibilityTest.java index b1b3010..6205977 100644 --- a/chrome/browser/paint_preview/android/javatests/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewAccessibilityTest.java +++ b/chrome/browser/paint_preview/android/javatests/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewAccessibilityTest.java
@@ -19,7 +19,6 @@ import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.paint_preview.services.PaintPreviewTabService; import org.chromium.chrome.browser.tab.Tab; @@ -60,7 +59,6 @@ */ @Test @MediumTest - @DisabledTest(message = "https://crbug.com/1287526") public void smokeTest() throws ExecutionException, TimeoutException { Tab tab = mActivityTestRule.getActivity().getActivityTab(); TabbedPaintPreview tabbedPaintPreview =
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service.cc b/chrome/browser/policy/cloud/user_policy_signin_service.cc index 6a07536..260637b 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service.cc +++ b/chrome/browser/policy/cloud/user_policy_signin_service.cc
@@ -12,17 +12,24 @@ #include "base/callback_helpers.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/enterprise/util/managed_browser_utils.h" #include "chrome/browser/policy/cloud/user_policy_signin_service_internal.h" +#include "chrome/browser/policy/cloud/user_policy_signin_service_util.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_attributes_entry.h" +#include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/signin/account_id_from_account_info.h" #include "chrome/browser/signin/signin_util.h" +#include "chrome/common/chrome_content_client.h" #include "chrome/common/pref_names.h" +#include "components/policy/core/browser/cloud/user_policy_signin_service_util.h" #include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h" #include "components/policy/core/common/cloud/user_cloud_policy_manager.h" #include "components/prefs/pref_change_registrar.h" #include "components/signin/public/base/consent_level.h" #include "components/signin/public/identity_manager/account_info.h" +#include "components/signin/public/identity_manager/primary_account_change_event.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/storage_partition.h" @@ -34,6 +41,24 @@ bool g_force_prohibit_signout_for_tests = false; } +ProfileManagerObserverBridge::ProfileManagerObserverBridge( + UserPolicySigninService* user_policy_signin_service) + : user_policy_signin_service_(user_policy_signin_service) { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + if (profile_manager) + profile_manager->AddObserver(this); +} + +void ProfileManagerObserverBridge::OnProfileAdded(Profile* profile) { + user_policy_signin_service_->OnProfileReady(profile); +} + +ProfileManagerObserverBridge::~ProfileManagerObserverBridge() { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + if (profile_manager) + profile_manager->RemoveObserver(this); +} + UserPolicySigninService::UserPolicySigninService( Profile* profile, PrefService* local_state, @@ -41,16 +66,16 @@ UserCloudPolicyManager* policy_manager, signin::IdentityManager* identity_manager, scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory) - : UserPolicySigninServiceBase(profile, - local_state, + : UserPolicySigninServiceBase(local_state, device_management_service, policy_manager, identity_manager, - system_url_loader_factory) { + system_url_loader_factory), + profile_(profile) { // IdentityManager should not yet have loaded its tokens since this // happens in the background after PKS initialization - so this service // should always be created before the oauth token is available. - DCHECK(!CanApplyPoliciesForSignedInUser(/*check_for_refresh_token=*/true)); + DCHECK(!CanApplyPolicies(/*check_for_refresh_token=*/true)); // Some tests don't have a profile manager. if (g_browser_process->profile_manager()) { observed_profile_.Observe( @@ -66,9 +91,8 @@ // in the destructor because we want to shutdown the registration helper // before UserCloudPolicyManager shuts down the CloudPolicyClient. registration_helper_.reset(); - if (g_browser_process->profile_manager()) { + if (g_browser_process->profile_manager()) observed_profile_.Reset(); - } UserPolicySigninServiceBase::PrepareForUserCloudPolicyManagerShutdown(); } @@ -116,17 +140,19 @@ void UserPolicySigninService::OnPrimaryAccountChanged( const signin::PrimaryAccountChangeEvent& event) { - UserPolicySigninServiceBase::OnPrimaryAccountChanged(event); - - if (event.GetEventTypeFor(signin::ConsentLevel::kSync) != - signin::PrimaryAccountChangeEvent::Type::kSet && - event.GetEventTypeFor(signin::ConsentLevel::kSignin) != - signin::PrimaryAccountChangeEvent::Type::kSet) { - return; + ProfileManager* profile_manager = g_browser_process->profile_manager(); + if (profile_manager && IsSignoutEvent(event)) { + UpdateProfileAttributesWhenSignout(profile_, profile_manager); + ShutdownUserCloudPolicyManager(); + } else if (IsTurnOffSyncEvent(event)) { + ShutdownUserCloudPolicyManager(); } + if (!IsAnySigninEvent(event)) + return; + DCHECK(identity_manager()->HasPrimaryAccount(consent_level())); - if (!CanApplyPoliciesForSignedInUser(/*check_for_refresh_token=*/true)) + if (!CanApplyPolicies(/*check_for_refresh_token=*/true)) return; // IdentityManager has a refresh token for the primary account, so initialize @@ -139,7 +165,7 @@ // Ignore OAuth tokens or those for any account but the primary one. if (account_info.account_id != identity_manager()->GetPrimaryAccountId(consent_level()) || - !CanApplyPoliciesForSignedInUser(/*check_for_refresh_token=*/true)) { + !CanApplyPolicies(/*check_for_refresh_token=*/true)) { return; } @@ -149,7 +175,7 @@ } void UserPolicySigninService::TryInitializeForSignedInUser() { - DCHECK(CanApplyPoliciesForSignedInUser(/*check_for_refresh_token=*/true)); + DCHECK(CanApplyPolicies(/*check_for_refresh_token=*/true)); // If using a TestingProfile with no UserCloudPolicyManager, skip // initialization. @@ -163,8 +189,7 @@ InitializeForSignedInUser( AccountIdFromAccountInfo( identity_manager()->GetPrimaryAccountInfo(consent_level())), - profile() - ->GetDefaultStoragePartition() + profile_->GetDefaultStoragePartition() ->GetURLLoaderFactoryForBrowserProcess()); } @@ -176,18 +201,24 @@ ProhibitSignoutIfNeeded(); } +void UserPolicySigninService::Shutdown() { + if (identity_manager()) + identity_manager()->RemoveObserver(this); + UserPolicySigninServiceBase::Shutdown(); +} + void UserPolicySigninService::ShutdownUserCloudPolicyManager() { UserCloudPolicyManager* manager = policy_manager(); // Allow the user to signout again. if (manager) - signin_util::SetUserSignoutAllowedForProfile(profile(), true); + signin_util::SetUserSignoutAllowedForProfile(profile_, true); UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager(); } void UserPolicySigninService::OnProfileUserManagementAcceptanceChanged( const base::FilePath& profile_path) { - if (CanApplyPoliciesForSignedInUser(/*check_for_refresh_token=*/true)) + if (CanApplyPolicies(/*check_for_refresh_token=*/true)) TryInitializeForSignedInUser(); } @@ -200,7 +231,7 @@ DVLOG_IF(1, manager->IsClientRegistered()) << "Client already registered - not fetching DMToken"; if (!manager->IsClientRegistered()) { - if (!CanApplyPoliciesForSignedInUser(/*check_for_refresh_token=*/true)) { + if (!CanApplyPolicies(/*check_for_refresh_token=*/true)) { // No token yet - this class listens for OnRefreshTokenUpdatedForAccount() // and will re-attempt registration once the token is available. DLOG(WARNING) << "No OAuth Refresh Token - delaying policy download"; @@ -240,8 +271,50 @@ if (policy_manager()->IsClientRegistered() || internal::g_force_prohibit_signout_for_tests) { DVLOG(1) << "User is registered for policy - prohibiting signout"; - signin_util::SetUserSignoutAllowedForProfile(profile(), false); + signin_util::SetUserSignoutAllowedForProfile(profile_, false); } } +void UserPolicySigninService::OnProfileReady(Profile* profile) { + if (profile && profile == profile_) + InitializeOnProfileReady(profile); +} + +void UserPolicySigninService::InitializeOnProfileReady(Profile* profile) { + DCHECK_EQ(profile, profile_); + + // If using a TestingProfile with no IdentityManager or + // UserCloudPolicyManager, skip initialization. + if (!policy_manager() || !identity_manager()) { + DVLOG(1) << "Skipping initialization for tests due to missing components."; + return; + } + + // Shutdown the UserCloudPolicyManager when the user signs out. We start + // observing the IdentityManager here because we don't want to get signout + // notifications until after the profile has started initializing + // (http://crbug.com/316229). + identity_manager()->AddObserver(this); + + AccountId account_id = AccountIdFromAccountInfo( + identity_manager()->GetPrimaryAccountInfo(consent_level())); + if (!CanApplyPolicies(/*check_for_refresh_token=*/false)) { + ShutdownUserCloudPolicyManager(); + } else { + InitializeForSignedInUser(account_id, + profile->GetDefaultStoragePartition() + ->GetURLLoaderFactoryForBrowserProcess()); + } +} + +bool UserPolicySigninService::CanApplyPolicies(bool check_for_refresh_token) { + if (!CanApplyPoliciesForSignedInUser(check_for_refresh_token, + identity_manager())) { + return false; + } + + return (profile_can_be_managed_for_testing_ || + chrome::enterprise_util::ProfileCanBeManaged(profile_)); +} + } // namespace policy
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service.h b/chrome/browser/policy/cloud/user_policy_signin_service.h index 08f96d1..2ef08e6 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service.h +++ b/chrome/browser/policy/cloud/user_policy_signin_service.h
@@ -10,8 +10,9 @@ #include "base/memory/ref_counted.h" #include "base/scoped_observation.h" -#include "chrome/browser/policy/cloud/user_policy_signin_service_base.h" #include "chrome/browser/profiles/profile_attributes_storage.h" +#include "chrome/browser/profiles/profile_manager_observer.h" +#include "components/policy/core/browser/cloud/user_policy_signin_service_base.h" #include "components/prefs/pref_change_registrar.h" #include "components/signin/public/identity_manager/identity_manager.h" @@ -26,10 +27,31 @@ class CloudPolicyClientRegistrationHelper; +class UserPolicySigninService; + +// Observer bridge for UserPolicySigninService to observe profile manager +// events. +class ProfileManagerObserverBridge : public ProfileManagerObserver { + public: + explicit ProfileManagerObserverBridge( + UserPolicySigninService* user_policy_signin_service); + ProfileManagerObserverBridge(const ProfileManagerObserverBridge&) = delete; + ProfileManagerObserverBridge& operator=(const ProfileManagerObserverBridge&) = + delete; + ~ProfileManagerObserverBridge() override; + + // ProfileManagerObserver implementation: + void OnProfileAdded(Profile* profile) override; + + private: + UserPolicySigninService* user_policy_signin_service_; +}; + // A specialization of the UserPolicySigninServiceBase for the desktop // platforms (Windows, Mac and Linux). class UserPolicySigninService : public UserPolicySigninServiceBase, - public ProfileAttributesStorage::Observer { + public ProfileAttributesStorage::Observer, + public signin::IdentityManager::Observer { public: // Creates a UserPolicySigninService associated with the passed // |policy_manager| and |identity_manager|. @@ -54,7 +76,6 @@ PolicyRegistrationCallback callback); // signin::IdentityManager::Observer implementation: - // UserPolicySigninServiceBase is already an observer of IdentityManager. void OnPrimaryAccountChanged( const signin::PrimaryAccountChangeEvent& event_details) override; void OnRefreshTokenUpdatedForAccount( @@ -71,6 +92,13 @@ void OnProfileUserManagementAcceptanceChanged( const base::FilePath& profile_path) override; + // Handler for when the profile is ready. + void OnProfileReady(Profile* profile); + + void set_profile_can_be_managed_for_testing(bool can_be_managed) { + profile_can_be_managed_for_testing_ = can_be_managed; + } + protected: // UserPolicySigninServiceBase implementation: void InitializeUserCloudPolicyManager( @@ -80,6 +108,9 @@ void PrepareForUserCloudPolicyManagerShutdown() override; private: + // KeyedService implementation: + void Shutdown() override; + // Fetches an OAuth token to allow the cloud policy service to register with // the cloud policy server. |oauth_login_token| should contain an OAuth login // refresh token that can be downscoped to get an access token for the @@ -102,7 +133,29 @@ void CallPolicyRegistrationCallback(std::unique_ptr<CloudPolicyClient> client, PolicyRegistrationCallback callback); + // Initializes the UserPolicySigninService once its owning Profile becomes + // ready. If the Profile has a signed-in account associated with it at startup + // then this initializes the cloud policy manager by calling + // InitializeForSignedInUser(); otherwise it clears any stored policies. + void InitializeOnProfileReady(Profile* profile); + + // Returns true when policies can be applied for the profile. The profile has + // to be at least tied to an account. + bool CanApplyPolicies(bool check_for_refresh_token); + + // True when the profile can be managed for testing purpose. Has to be set + // from the test fixture. This is used to bypass the check on the profile + // attributes entry. + bool profile_can_be_managed_for_testing_ = false; + std::unique_ptr<CloudPolicyClientRegistrationHelper> registration_helper_; + + // Parent profile for this service. + raw_ptr<Profile> profile_; + + // Observer bridge for profile added events. + ProfileManagerObserverBridge profile_manager_observer_bridge_{this}; + base::ScopedObservation<ProfileAttributesStorage, ProfileAttributesStorage::Observer> observed_profile_{this};
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_mobile.cc b/chrome/browser/policy/cloud/user_policy_signin_service_mobile.cc index bf04a68..6193a21 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service_mobile.cc +++ b/chrome/browser/policy/cloud/user_policy_signin_service_mobile.cc
@@ -15,14 +15,26 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "build/build_config.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/enterprise/util/managed_browser_utils.h" +#include "chrome/browser/policy/cloud/user_policy_signin_service_util.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_attributes_entry.h" +#include "chrome/browser/profiles/profile_attributes_storage.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/signin/account_id_from_account_info.h" +#include "chrome/common/chrome_content_client.h" #include "chrome/common/pref_names.h" +#include "components/policy/core/browser/cloud/user_policy_signin_service_util.h" #include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h" #include "components/policy/core/common/cloud/user_cloud_policy_manager.h" #include "components/policy/core/common/policy_switches.h" #include "components/policy/proto/device_management_backend.pb.h" #include "components/prefs/pref_service.h" +#include "components/signin/public/base/consent_level.h" #include "components/signin/public/identity_manager/identity_manager.h" +#include "components/signin/public/identity_manager/primary_account_change_event.h" +#include "content/public/browser/storage_partition.h" #include "net/base/network_change_notifier.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -48,13 +60,16 @@ UserCloudPolicyManager* policy_manager, signin::IdentityManager* identity_manager, scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory) - : UserPolicySigninServiceBase(profile, - local_state, + : UserPolicySigninServiceBase(local_state, device_management_service, policy_manager, identity_manager, system_url_loader_factory), - profile_prefs_(profile->GetPrefs()) {} + profile_prefs_(profile->GetPrefs()), + profile_(profile) { + if (g_browser_process->profile_manager()) + g_browser_process->profile_manager()->AddObserver(this); +} UserPolicySigninService::~UserPolicySigninService() {} @@ -99,6 +114,11 @@ } void UserPolicySigninService::Shutdown() { + // Don't handle ProfileManager when testing because it is null. + if (g_browser_process->profile_manager()) + g_browser_process->profile_manager()->RemoveObserver(this); + if (identity_manager()) + identity_manager()->RemoveObserver(this); CancelPendingRegistration(); UserPolicySigninServiceBase::Shutdown(); } @@ -171,4 +191,57 @@ registration_helper_.reset(); } +void UserPolicySigninService::OnPrimaryAccountChanged( + const signin::PrimaryAccountChangeEvent& event) { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + if (profile_manager && IsSignoutEvent(event)) { + UpdateProfileAttributesWhenSignout(profile_, profile_manager); + ShutdownUserCloudPolicyManager(); + } else if (IsTurnOffSyncEvent(event)) { + ShutdownUserCloudPolicyManager(); + } +} + +void UserPolicySigninService::OnProfileAdded(Profile* profile) { + if (profile && profile == profile_) + InitializeOnProfileReady(profile); +} + +void UserPolicySigninService::InitializeOnProfileReady(Profile* profile) { + DCHECK_EQ(profile, profile_); + + // If using a TestingProfile with no IdentityManager or + // UserCloudPolicyManager, skip initialization. + if (!policy_manager() || !identity_manager()) { + DVLOG(1) << "Skipping initialization for tests due to missing components."; + return; + } + + // Shutdown the UserCloudPolicyManager when the user signs out. We start + // observing the IdentityManager here because we don't want to get signout + // notifications until after the profile has started initializing + // (http://crbug.com/316229). + identity_manager()->AddObserver(this); + + AccountId account_id = AccountIdFromAccountInfo( + identity_manager()->GetPrimaryAccountInfo(consent_level())); + if (!CanApplyPolicies(/*check_for_refresh_token=*/false)) { + ShutdownUserCloudPolicyManager(); + } else { + InitializeForSignedInUser(account_id, + profile->GetDefaultStoragePartition() + ->GetURLLoaderFactoryForBrowserProcess()); + } +} + +bool UserPolicySigninService::CanApplyPolicies(bool check_for_refresh_token) { + if (!CanApplyPoliciesForSignedInUser(check_for_refresh_token, + identity_manager())) { + return false; + } + + return (profile_can_be_managed_for_testing_ || + chrome::enterprise_util::ProfileCanBeManaged(profile_)); +} + } // namespace policy
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_mobile.h b/chrome/browser/policy/cloud/user_policy_signin_service_mobile.h index 7c7f162..796c303 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service_mobile.h +++ b/chrome/browser/policy/cloud/user_policy_signin_service_mobile.h
@@ -13,7 +13,9 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "build/build_config.h" -#include "chrome/browser/policy/cloud/user_policy_signin_service_base.h" +#include "chrome/browser/profiles/profile_manager_observer.h" +#include "components/policy/core/browser/cloud/user_policy_signin_service_base.h" +#include "components/signin/public/identity_manager/identity_manager.h" class Profile; @@ -29,8 +31,10 @@ class CloudPolicyClientRegistrationHelper; -// A specialization of UserPolicySigninServiceBase for the Android. -class UserPolicySigninService : public UserPolicySigninServiceBase { +// A specialization of UserPolicySigninServiceBase for Android. +class UserPolicySigninService : public UserPolicySigninServiceBase, + public ProfileManagerObserver, + public signin::IdentityManager::Observer { public: // Creates a UserPolicySigninService associated with the passed |profile|. UserPolicySigninService( @@ -55,10 +59,21 @@ const CoreAccountId& account_id, PolicyRegistrationCallback callback); - // Overridden from UserPolicySigninServiceBase to cancel the pending delayed - // registration. + // Overridden from UserPolicySigninServiceForProfile to cancel the pending + // delayed registration. void ShutdownUserCloudPolicyManager() override; + // signin::IdentityManager::Observer implementation: + void OnPrimaryAccountChanged( + const signin::PrimaryAccountChangeEvent& event) override; + + // ProfileManagerObserver implementation. + void OnProfileAdded(Profile* profile) override; + + void set_profile_can_be_managed_for_testing(bool can_be_managed) { + profile_can_be_managed_for_testing_ = can_be_managed; + } + private: void CallPolicyRegistrationCallback(std::unique_ptr<CloudPolicyClient> client, PolicyRegistrationCallback callback); @@ -77,11 +92,29 @@ void OnRegistrationDone(); + // Initializes the UserPolicySigninService once its owning Profile becomes + // ready. If the Profile has a signed-in account associated with it at startup + // then this initializes the cloud policy manager by calling + // InitializeForSignedInUser(); otherwise it clears any stored policies. + void InitializeOnProfileReady(Profile* profile); + + // Returns true when policies can be applied for the profile. The profile has + // to be at least tied to an account. + bool CanApplyPolicies(bool check_for_refresh_token); + + // True when the profile can be managed for testing purpose. Has to be set + // from the test fixture. This is used to bypass the check on the profile + // attributes entry. + bool profile_can_be_managed_for_testing_ = false; + std::unique_ptr<CloudPolicyClientRegistrationHelper> registration_helper_; // The PrefService associated with the profile. raw_ptr<PrefService> profile_prefs_; + // Parent profile for this service. + raw_ptr<Profile> profile_; + base::WeakPtrFactory<UserPolicySigninService> weak_factory_{this}; };
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc index 30f4816..b9cda1a 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc +++ b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
@@ -195,10 +195,13 @@ EXPECT_CALL(*mock_store_, Clear()); // Let the SigninService know that the profile has been created. - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PROFILE_ADDED, - content::Source<Profile>(profile_.get()), - content::NotificationService::NoDetails()); +#if BUILDFLAG(IS_ANDROID) + UserPolicySigninServiceFactory::GetForProfile(profile_.get()) + ->OnProfileAdded(profile_.get()); +#else + UserPolicySigninServiceFactory::GetForProfile(profile_.get()) + ->OnProfileReady(profile_.get()); +#endif // BUILDFLAG(IS_ANDROID) } bool IsRequestActive() { @@ -322,10 +325,13 @@ signin::ConsentLevel::kSync); // Let the SigninService know that the profile has been created. - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PROFILE_ADDED, - content::Source<Profile>(profile_.get()), - content::NotificationService::NoDetails()); +#if BUILDFLAG(IS_ANDROID) + UserPolicySigninServiceFactory::GetForProfile(profile_.get()) + ->OnProfileAdded(profile_.get()); +#else + UserPolicySigninServiceFactory::GetForProfile(profile_.get()) + ->OnProfileReady(profile_.get()); +#endif // BUILDFLAG(IS_ANDROID) } };
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_util.cc b/chrome/browser/policy/cloud/user_policy_signin_service_util.cc new file mode 100644 index 0000000..42e0546c --- /dev/null +++ b/chrome/browser/policy/cloud/user_policy_signin_service_util.cc
@@ -0,0 +1,29 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/policy/cloud/user_policy_signin_service_util.h" + +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_attributes_entry.h" +#include "chrome/browser/profiles/profile_attributes_storage.h" +#include "chrome/browser/profiles/profile_manager.h" + +namespace policy { + +void UpdateProfileAttributesWhenSignout(Profile* profile, + ProfileManager* profile_manager) { + if (!profile_manager) { + // Skip the update there isn't a profile manager which can happen when + // testing. + return; + } + + ProfileAttributesEntry* entry = + profile_manager->GetProfileAttributesStorage() + .GetProfileAttributesWithPath(profile->GetPath()); + if (entry) + entry->SetUserAcceptedAccountManagement(false); +} + +} // namespace policy
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_util.h b/chrome/browser/policy/cloud/user_policy_signin_service_util.h new file mode 100644 index 0000000..180ee095 --- /dev/null +++ b/chrome/browser/policy/cloud/user_policy_signin_service_util.h
@@ -0,0 +1,19 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_UTIL_H_ +#define CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_UTIL_H_ + +class Profile; +class ProfileManager; + +namespace policy { + +// Update the Profile attributes for when the account is signed out. +void UpdateProfileAttributesWhenSignout(Profile* profile, + ProfileManager* profile_manager); + +} // namespace policy + +#endif // CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_UTIL_H_
diff --git a/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc b/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc index 16c4f76..2c075d92 100644 --- a/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc +++ b/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc
@@ -324,7 +324,12 @@ auto test_records = BuildTestRecordsVector(kNumTestRecords, kGenerationId); const auto force_confirm_by_server = force_confirm(); - EXPECT_CALL(*client_, UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) + EXPECT_CALL( + *client_, + UploadEncryptedReport( + IsDataUploadRequestValid(DataUploadRequestValidityMatcher::Settings() + .SetCheckRecordDetails(false)), + _, _)) .WillOnce(WithArgs<0, 2>( Invoke([&force_confirm_by_server]( base::Value::Dict request, @@ -399,8 +404,8 @@ FailedResponseFromRequest(request, response); std::move(callback).Run(std::move(response)); }))); - EXPECT_CALL(*client_, - UploadEncryptedReport(IsDataUploadRequestValid(), _, _)) + // TODO(b/214040998: Add a matcher for the gap upload) + EXPECT_CALL(*client_, UploadEncryptedReport(_, _, _)) .WillOnce(WithArgs<0, 2>( Invoke([&force_confirm_by_server]( base::Value::Dict request,
diff --git a/chrome/browser/policy/messaging_layer/util/test.cc b/chrome/browser/policy/messaging_layer/util/test.cc index f5e81fca..76a8ca1 100644 --- a/chrome/browser/policy/messaging_layer/util/test.cc +++ b/chrome/browser/policy/messaging_layer/util/test.cc
@@ -9,12 +9,85 @@ namespace reporting { +// Return true if s a properly formatted positive integer, i.e., is not empty, +// contains digits only and does not start with 0. +static bool IsPositiveInteger(base::StringPiece s) { + if (s.empty()) { + return false; + } else if (s.size() == 1) { + return std::isdigit(s[0]); + } else { + return s[0] != '0' && + s.find_first_not_of("0123456789") == std::string::npos; + } +} + +DataUploadRequestValidityMatcher::Settings& +DataUploadRequestValidityMatcher::Settings::SetCheckRecordDetails(bool flag) { + check_record_details_ = flag; + return *this; +} + DataUploadRequestValidityMatcher::Settings& DataUploadRequestValidityMatcher::Settings::SetCheckEncryptedRecord(bool flag) { check_encrypted_record_ = flag; return *this; } +bool DataUploadRequestValidityMatcher::CheckRecord( + const base::Value& record, + MatchResultListener* listener) const { + const auto* record_dict = record.GetIfDict(); + if (record_dict == nullptr) { + *listener << "Record " << record << " is not a dict."; + return false; + } + + if (record_dict->FindString("encryptedWrappedRecord") == nullptr) { + *listener << "No key named \"encryptedWrappedRecord\" or the value " + "is not a string in record " + << record << '.'; + return false; + } + + { // sequence information + const auto* sequence_information = + record_dict->FindDict("sequenceInformation"); + if (sequence_information == nullptr) { + *listener << "No key named \"sequenceInformation\" or the value is " + "not a dict in record " + << record << '.'; + return false; + } + + if (!sequence_information->FindInt("priority").has_value()) { + *listener << "No key named \"sequenceInformation/priority\" or the " + "value is not an integer in record " + << record << '.'; + return false; + } + + for (const char* id : {"sequencingId", "generationId"}) { + const auto* id_val = sequence_information->FindString(id); + if (id_val == nullptr) { + *listener << "No key named \"sequenceInformation/" << id + << "\" or the value is not a string in record " << record + << '.'; + return false; + } + if (!IsPositiveInteger(*id_val)) { + *listener + << "The value of \"sequenceInformation/" << id + << "\" is not a properly formatted positive integer in record " + << record << '.'; + return false; + } + } + } + + return true; +} + DataUploadRequestValidityMatcher::DataUploadRequestValidityMatcher( const Settings& settings) : settings_(settings) {} @@ -22,21 +95,29 @@ bool DataUploadRequestValidityMatcher::MatchAndExplain( const base::Value::Dict& arg, MatchResultListener* listener) const { - if (settings_.check_encrypted_record_ && - arg.FindList("encryptedRecord") == nullptr) { - *listener - << "No key named \"encryptedRecord\" in the argument or the value is " - "not a list."; - return false; + if (settings_.check_encrypted_record_) { + const auto* record_list = arg.FindList("encryptedRecord"); + if (record_list == nullptr) { + *listener + << "No key named \"encryptedRecord\" in the argument or the value is " + "not a list."; + return false; + } + + // examine each record + if (settings_.check_record_details_) { + for (const auto& record : *record_list) { + if (!CheckRecord(record, listener)) { + return false; + } + } + } } - // TODO: Check the validity of each record based on whether they have required - // fields and types. const auto* request_id = arg.FindString("requestId"); if (request_id == nullptr) { - *listener - << "No key named \"requestId\" in the argument or the value is not a " - "string."; + *listener << "No key named \"requestId\" in the argument or the value " + "is not a string."; return false; } if (request_id->empty()) { @@ -81,9 +162,8 @@ MatchResultListener* listener) const { const auto* record_list = arg.FindList("encryptedRecord"); if (record_list == nullptr) { - *listener - << "No key named \"encryptedRecord\" in the argument or the value is " - "not a list."; + *listener << "No key named \"encryptedRecord\" in the argument or the " + "value is not a list."; return false; } @@ -107,8 +187,8 @@ } // Match each key and value of matched_record with those of the iterated - // record_dict. In this way, users can specify part of a record instead of - // the full record. + // record_dict. In this way, users can specify part of a record instead + // of the full record. if (IsSubDict(*matched_record_dict, *record_dict)) { return true; }
diff --git a/chrome/browser/policy/messaging_layer/util/test.h b/chrome/browser/policy/messaging_layer/util/test.h index a9bbbcd..5153998f 100644 --- a/chrome/browser/policy/messaging_layer/util/test.h +++ b/chrome/browser/policy/messaging_layer/util/test.h
@@ -28,12 +28,17 @@ Settings(const Settings& other) = default; Settings(Settings&& other) = default; // Enable or disable checking the existence of key "encryptedRecord" and - // that the value is a list. + // that the value is a list. If disabled, implies the effect of + // SetCheckRecordDetails(false). Settings& SetCheckEncryptedRecord(bool flag); + // Enable or disable checking the details of each record. Useful to disable + // if the test case includes intentionally malformed records. + Settings& SetCheckRecordDetails(bool flag); private: friend DataUploadRequestValidityMatcher; bool check_encrypted_record_ = true; + bool check_record_details_ = true; }; DataUploadRequestValidityMatcher() = default; @@ -45,6 +50,10 @@ private: const Settings settings_{}; + // Check the validity of the specified record. Return true if the record is + // valid. + bool CheckRecord(const base::Value& record, + MatchResultListener* listener) const; }; class RequestContainingRecordMatcher {
diff --git a/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBridgeTest.java b/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBridgeTest.java index 5dd29797..0b1bb3b 100644 --- a/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBridgeTest.java +++ b/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxBridgeTest.java
@@ -28,7 +28,8 @@ * Tests for PrivacySandboxBridge. */ @RunWith(ChromeJUnit4ClassRunner.class) -@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, + "enable-features=PrivacySandboxSettings3:show-sample-data/true"}) @Batch(Batch.PER_CLASS) public class PrivacySandboxBridgeTest { @ClassRule
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc index b60c918..652c62d6 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc
@@ -725,27 +725,31 @@ std::vector<privacy_sandbox::CanonicalTopic> PrivacySandboxService::GetCurrentTopTopics() const { // TODO(crbug.com/1286276): Add proper Topics implementation. - return std::vector<privacy_sandbox::CanonicalTopic>( - fake_current_topics_.begin(), fake_current_topics_.end()); + if (privacy_sandbox::kPrivacySandboxSettings3ShowSampleDataForTesting.Get()) + return {fake_current_topics_.begin(), fake_current_topics_.end()}; + return {}; } std::vector<privacy_sandbox::CanonicalTopic> PrivacySandboxService::GetBlockedTopics() const { // TODO(crbug.com/1286276): Add proper Topics implementation. - return std::vector<privacy_sandbox::CanonicalTopic>( - fake_blocked_topics_.begin(), fake_blocked_topics_.end()); + if (privacy_sandbox::kPrivacySandboxSettings3ShowSampleDataForTesting.Get()) + return {fake_blocked_topics_.begin(), fake_blocked_topics_.end()}; + return {}; } void PrivacySandboxService::SetTopicAllowed( privacy_sandbox::CanonicalTopic topic, bool allowed) { // TODO(crbug.com/1286276): Update preferences. - if (allowed) { - fake_current_topics_.insert(topic); - fake_blocked_topics_.erase(topic); - } else { - fake_current_topics_.erase(topic); - fake_blocked_topics_.insert(topic); + if (privacy_sandbox::kPrivacySandboxSettings3ShowSampleDataForTesting.Get()) { + if (allowed) { + fake_current_topics_.insert(topic); + fake_blocked_topics_.erase(topic); + } else { + fake_current_topics_.erase(topic); + fake_blocked_topics_.insert(topic); + } } }
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service_unittest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_service_unittest.cc index 2e70cf9..e6ff02f 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_service_unittest.cc +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service_unittest.cc
@@ -1416,6 +1416,36 @@ EXPECT_FALSE(prefs()->GetBoolean(prefs::kPrivacySandboxApisEnabledV2)); } +TEST_F(PrivacySandboxServiceTest, TestNoFakeTopics) { + auto* service = privacy_sandbox_service(); + EXPECT_THAT(service->GetCurrentTopTopics(), testing::IsEmpty()); + EXPECT_THAT(service->GetBlockedTopics(), testing::IsEmpty()); +} + +TEST_F(PrivacySandboxServiceTest, TestFakeTopics) { + feature_list()->Reset(); + feature_list()->InitAndEnableFeatureWithParameters( + privacy_sandbox::kPrivacySandboxSettings3, + {{privacy_sandbox::kPrivacySandboxSettings3ShowSampleDataForTesting.name, + "true"}}); + CanonicalTopic topic1(Topic(1), CanonicalTopic::AVAILABLE_TAXONOMY); + CanonicalTopic topic2(Topic(2), CanonicalTopic::AVAILABLE_TAXONOMY); + CanonicalTopic topic3(Topic(3), CanonicalTopic::AVAILABLE_TAXONOMY); + CanonicalTopic topic4(Topic(4), CanonicalTopic::AVAILABLE_TAXONOMY); + + auto* service = privacy_sandbox_service(); + EXPECT_THAT(service->GetCurrentTopTopics(), ElementsAre(topic1, topic2)); + EXPECT_THAT(service->GetBlockedTopics(), ElementsAre(topic3, topic4)); + + service->SetTopicAllowed(topic1, false); + EXPECT_THAT(service->GetCurrentTopTopics(), ElementsAre(topic2)); + EXPECT_THAT(service->GetBlockedTopics(), ElementsAre(topic1, topic3, topic4)); + + service->SetTopicAllowed(topic4, true); + EXPECT_THAT(service->GetCurrentTopTopics(), ElementsAre(topic2, topic4)); + EXPECT_THAT(service->GetBlockedTopics(), ElementsAre(topic1, topic3)); +} + class PrivacySandboxServiceTestReconciliationBlocked : public PrivacySandboxServiceTest { public: @@ -2117,25 +2147,6 @@ histograms.ExpectTotalCount(histogram_name, 0); } -TEST_F(PrivacySandboxServiceTestNonRegularProfile, TestFakeTopics) { - CanonicalTopic topic1(Topic(1), CanonicalTopic::AVAILABLE_TAXONOMY); - CanonicalTopic topic2(Topic(2), CanonicalTopic::AVAILABLE_TAXONOMY); - CanonicalTopic topic3(Topic(3), CanonicalTopic::AVAILABLE_TAXONOMY); - CanonicalTopic topic4(Topic(4), CanonicalTopic::AVAILABLE_TAXONOMY); - - auto* service = privacy_sandbox_service(); - EXPECT_THAT(service->GetCurrentTopTopics(), ElementsAre(topic1, topic2)); - EXPECT_THAT(service->GetBlockedTopics(), ElementsAre(topic3, topic4)); - - service->SetTopicAllowed(topic1, false); - EXPECT_THAT(service->GetCurrentTopTopics(), ElementsAre(topic2)); - EXPECT_THAT(service->GetBlockedTopics(), ElementsAre(topic1, topic3, topic4)); - - service->SetTopicAllowed(topic4, true); - EXPECT_THAT(service->GetCurrentTopTopics(), ElementsAre(topic2, topic4)); - EXPECT_THAT(service->GetBlockedTopics(), ElementsAre(topic1, topic3)); -} - TEST_F(PrivacySandboxServiceTestNonRegularProfile, NoDialogRequired) { // Non-regular profiles should never have a dialog shown. SetupDialogTestState(feature_list(), prefs(),
diff --git a/chrome/browser/resources/chromeos/login/screens/common/gaia_signin.js b/chrome/browser/resources/chromeos/login/screens/common/gaia_signin.js index b50798a8..88d5aa8b 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/gaia_signin.js +++ b/chrome/browser/resources/chromeos/login/screens/common/gaia_signin.js
@@ -537,8 +537,6 @@ * @param {Object} data Screen init payload */ onBeforeShow(data) { - chrome.send('loginUIStateChanged', ['gaia-signin', true]); - // Re-enable navigation in case it was disabled before refresh. this.navigationEnabled_ = true; @@ -586,7 +584,6 @@ * Event handler that is invoked just before the screen is hidden. */ onBeforeHide() { - chrome.send('loginUIStateChanged', ['gaia-signin', false]); this.isShown_ = false; }
diff --git a/chrome/browser/resources/feedback_webui/feedback_resources.grd b/chrome/browser/resources/feedback_webui/feedback_resources.grd index e9f4bca..4c2b035d 100644 --- a/chrome/browser/resources/feedback_webui/feedback_resources.grd +++ b/chrome/browser/resources/feedback_webui/feedback_resources.grd
@@ -32,7 +32,7 @@ file="images/2x/button_butter_bar_close_hover.png" type="BINDATA" /> <include name="IDR_FEEDBACK_BUTTON_BUTTER_BAR_CLOSE_PRESSED_2X_PNG" file="images/2x/button_butter_bar_close_pressed.png" type="BINDATA" /> - <include name="IDR_FEEDBACK_SYSINFO_HTML" file="html/sys_info.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_FEEDBACK_SYSINFO_HTML" file="html/sys_info.html" type="BINDATA" /> <include name="IDR_FEEDBACK_SYSINFO_JS" file="js/sys_info.js" type="BINDATA" /> <include name="IDR_FEEDBACK_SYSINFO_CSS" file="css/sys_info.css" type="BINDATA" /> <if expr="chromeos">
diff --git a/chrome/browser/resources/feedback_webui/html/sys_info.html b/chrome/browser/resources/feedback_webui/html/sys_info.html index 1517e3ce..e2289b5 100644 --- a/chrome/browser/resources/feedback_webui/html/sys_info.html +++ b/chrome/browser/resources/feedback_webui/html/sys_info.html
@@ -6,7 +6,7 @@ <title>$i18n{sysinfoPageTitle}</title> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> <link rel="stylesheet" href="chrome://resources/css/spinner.css"> - <link rel="stylesheet" href="../../about_sys/about_sys.css"> + <link rel="stylesheet" href="../css/about_sys.css"> <link rel="stylesheet" href="../css/sys_info.css"> <link rel="stylesheet" href="../css/feedback_shared_styles.css">
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index db7e5e1..9636d5a 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -279,6 +279,9 @@ "chromeos/internet_page/cellular_setup_settings_delegate.js", "chromeos/internet_page/internet_page_browser_proxy.js", "chromeos/kerberos_page/kerberos_accounts_browser_proxy.js", + "chromeos/multidevice_page/multidevice_browser_proxy.js", + "chromeos/multidevice_page/multidevice_constants.js", + "chromeos/multidevice_page/multidevice_feature_behavior.js", "chromeos/nearby_share_page/nearby_account_manager_browser_proxy.js", "chromeos/nearby_share_page/nearby_share_receive_manager.js", "chromeos/nearby_share_page/types.js", @@ -475,25 +478,22 @@ "chromeos/kerberos_page/kerberos_add_account_dialog.js", "chromeos/kerberos_page/kerberos_page.js", "chromeos/keyboard_shortcut_banner/keyboard_shortcut_banner.js", - "chromeos/multidevice_page/multidevice_browser_proxy.m.js", - "chromeos/multidevice_page/multidevice_combined_setup_item.m.js", - "chromeos/multidevice_page/multidevice_constants.m.js", - "chromeos/multidevice_page/multidevice_feature_behavior.m.js", - "chromeos/multidevice_page/multidevice_feature_item.m.js", - "chromeos/multidevice_page/multidevice_feature_toggle.m.js", - "chromeos/multidevice_page/multidevice_notification_access_setup_dialog.m.js", - "chromeos/multidevice_page/multidevice_page.m.js", - "chromeos/multidevice_page/multidevice_permissions_setup_dialog.m.js", - "chromeos/multidevice_page/multidevice_radio_button.m.js", - "chromeos/multidevice_page/multidevice_screen_lock_subpage.m.js", - "chromeos/multidevice_page/multidevice_smartlock_subpage.m.js", - "chromeos/multidevice_page/multidevice_subpage.m.js", - "chromeos/multidevice_page/multidevice_tether_item.m.js", - "chromeos/multidevice_page/multidevice_task_continuation_disabled_link.m.js", - "chromeos/multidevice_page/multidevice_task_continuation_item.m.js", - "chromeos/multidevice_page/multidevice_wifi_sync_disabled_link.m.js", - "chromeos/multidevice_page/multidevice_wifi_sync_item.m.js", - "chromeos/multidevice_page/multidevice_smartlock_item.m.js", + "chromeos/multidevice_page/multidevice_combined_setup_item.js", + "chromeos/multidevice_page/multidevice_feature_item.js", + "chromeos/multidevice_page/multidevice_feature_toggle.js", + "chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js", + "chromeos/multidevice_page/multidevice_page.js", + "chromeos/multidevice_page/multidevice_permissions_setup_dialog.js", + "chromeos/multidevice_page/multidevice_radio_button.js", + "chromeos/multidevice_page/multidevice_screen_lock_subpage.js", + "chromeos/multidevice_page/multidevice_smartlock_subpage.js", + "chromeos/multidevice_page/multidevice_subpage.js", + "chromeos/multidevice_page/multidevice_tether_item.js", + "chromeos/multidevice_page/multidevice_task_continuation_disabled_link.js", + "chromeos/multidevice_page/multidevice_task_continuation_item.js", + "chromeos/multidevice_page/multidevice_wifi_sync_disabled_link.js", + "chromeos/multidevice_page/multidevice_wifi_sync_item.js", + "chromeos/multidevice_page/multidevice_smartlock_item.js", "chromeos/nearby_share_page/nearby_share_confirm_page.js", "chromeos/nearby_share_page/nearby_share_contact_visibility_dialog.js", "chromeos/nearby_share_page/nearby_share_data_usage_dialog.js", @@ -796,7 +796,7 @@ "internet_page:web_components", "kerberos_page:web_components", "keyboard_shortcut_banner:web_components", - "multidevice_page:polymer3_elements", + "multidevice_page:web_components", "nearby_share_page:web_components", "os_a11y_page:web_components", "os_about_page:web_components",
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn index 686b0dd..629664cc 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
@@ -292,8 +292,8 @@ js_library("cellular_networks_list") { deps = [ ":esim_install_error_dialog", - "../multidevice_page:multidevice_browser_proxy.m", - "../multidevice_page:multidevice_constants.m", + "../multidevice_page:multidevice_browser_proxy", + "../multidevice_page:multidevice_constants", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_components/chromeos/cellular_setup:cellular_types.m", "//ui/webui/resources/cr_components/chromeos/cellular_setup:esim_manager_listener_behavior.m",
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.js b/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.js index 69d5f063..f675c4f 100644 --- a/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.js +++ b/chrome/browser/resources/settings/chromeos/internet_page/cellular_networks_list.js
@@ -31,8 +31,8 @@ import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js'; import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from '../multidevice_page/multidevice_browser_proxy.m.js'; -import {MultiDeviceFeature, MultiDeviceFeatureState, MultiDevicePageContentData, MultiDeviceSettingsMode, PhoneHubFeatureAccessProhibitedReason, PhoneHubFeatureAccessStatus, SmartLockSignInEnabledState} from '../multidevice_page/multidevice_constants.m.js'; +import {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from '../multidevice_page/multidevice_browser_proxy.js'; +import {MultiDeviceFeature, MultiDeviceFeatureState, MultiDevicePageContentData, MultiDeviceSettingsMode, PhoneHubFeatureAccessProhibitedReason, PhoneHubFeatureAccessStatus, SmartLockSignInEnabledState} from '../multidevice_page/multidevice_constants.js'; Polymer({ _template: html`{__html_template__}`,
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn index 0ec056a..161506b 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/BUILD.gn
@@ -3,8 +3,7 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") -import("//tools/polymer/polymer.gni") -import("//ui/webui/resources/tools/js_modulizer.gni") +import("//tools/polymer/html_to_js.gni") import("../../../nearby_share/shared/nearby_shared.gni") import("../os_settings.gni") @@ -12,58 +11,51 @@ closure_flags = os_settings_closure_flags is_polymer3 = true deps = [ - ":multidevice_browser_proxy.m", - ":multidevice_combined_setup_item.m", - ":multidevice_constants.m", - ":multidevice_feature_behavior.m", - ":multidevice_feature_item.m", - ":multidevice_feature_toggle.m", - ":multidevice_notification_access_setup_dialog.m", - ":multidevice_page.m", - ":multidevice_permissions_setup_dialog.m", - ":multidevice_radio_button.m", - ":multidevice_screen_lock_subpage.m", - ":multidevice_smartlock_subpage.m", - ":multidevice_subpage.m", - ":multidevice_task_continuation_disabled_link.m", - ":multidevice_task_continuation_item.m", - ":multidevice_tether_item.m", - ":multidevice_wifi_sync_disabled_link.m", - ":multidevice_wifi_sync_item.m", + ":multidevice_browser_proxy", + ":multidevice_combined_setup_item", + ":multidevice_constants", + ":multidevice_feature_behavior", + ":multidevice_feature_item", + ":multidevice_feature_toggle", + ":multidevice_notification_access_setup_dialog", + ":multidevice_page", + ":multidevice_permissions_setup_dialog", + ":multidevice_radio_button", + ":multidevice_screen_lock_subpage", + ":multidevice_smartlock_subpage", + ":multidevice_subpage", + ":multidevice_task_continuation_disabled_link", + ":multidevice_task_continuation_item", + ":multidevice_tether_item", + ":multidevice_wifi_sync_disabled_link", + ":multidevice_wifi_sync_item", ] } -js_library("multidevice_browser_proxy.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.m.js" ] +js_library("multidevice_browser_proxy") { deps = [ - ":multidevice_constants.m", + ":multidevice_constants", "//ui/webui/resources/js:cr.m", ] - extra_deps = [ ":modulize" ] } -js_library("multidevice_constants.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.m.js" ] +js_library("multidevice_constants") { deps = [] - extra_deps = [ ":modulize" ] } -js_library("multidevice_feature_behavior.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.m.js" ] +js_library("multidevice_feature_behavior") { deps = [ - ":multidevice_constants.m", + ":multidevice_constants", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:i18n_behavior.m", ] - extra_deps = [ ":modulize" ] } -js_library("multidevice_feature_item.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.m.js" ] +js_library("multidevice_feature_item") { deps = [ - ":multidevice_constants.m", - ":multidevice_feature_behavior.m", - ":multidevice_feature_toggle.m", + ":multidevice_constants", + ":multidevice_feature_behavior", + ":multidevice_feature_toggle", "..:os_route", "..:route_origin_behavior", "../..:router", @@ -71,27 +63,23 @@ "//ui/webui/resources/cr_components/localized_link:localized_link", "//ui/webui/resources/js:assert.m", ] - extra_deps = [ ":multidevice_feature_item_module" ] } -js_library("multidevice_feature_toggle.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.m.js" ] +js_library("multidevice_feature_toggle") { deps = [ - ":multidevice_constants.m", - ":multidevice_feature_behavior.m", + ":multidevice_constants", + ":multidevice_feature_behavior", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] - extra_deps = [ ":multidevice_feature_toggle_module" ] } -js_library("multidevice_page.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.m.js" ] +js_library("multidevice_page") { deps = [ - ":multidevice_browser_proxy.m", - ":multidevice_constants.m", - ":multidevice_feature_behavior.m", - ":multidevice_notification_access_setup_dialog.m", - ":multidevice_permissions_setup_dialog.m", + ":multidevice_browser_proxy", + ":multidevice_constants", + ":multidevice_feature_behavior", + ":multidevice_notification_access_setup_dialog", + ":multidevice_permissions_setup_dialog", "..:deep_linking_behavior", "..:metrics_recorder", "..:os_route", @@ -104,45 +92,37 @@ "//ui/webui/resources/js:assert.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] - extra_deps = [ ":multidevice_page_module" ] } -js_library("multidevice_notification_access_setup_dialog.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.m.js" ] +js_library("multidevice_notification_access_setup_dialog") { deps = [ - ":multidevice_constants.m", + ":multidevice_constants", "//ui/webui/resources/js:i18n_behavior.m", "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] - extra_deps = [ ":multidevice_notification_access_setup_dialog_module" ] } -js_library("multidevice_permissions_setup_dialog.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.m.js" ] +js_library("multidevice_permissions_setup_dialog") { deps = [ - ":multidevice_constants.m", + ":multidevice_constants", "//ui/webui/resources/js:i18n_behavior.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] - extra_deps = [ ":multidevice_permissions_setup_dialog_module" ] } -js_library("multidevice_radio_button.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.m.js" ] +js_library("multidevice_radio_button") { deps = [ "//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted", "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button_behavior.m", "//ui/webui/resources/cr_elements/policy:cr_policy_indicator.m", ] - extra_deps = [ ":multidevice_radio_button_module" ] } -js_library("multidevice_smartlock_subpage.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.m.js" ] +js_library("multidevice_smartlock_subpage") { deps = [ - ":multidevice_constants.m", - ":multidevice_feature_behavior.m", + ":multidevice_constants", + ":multidevice_feature_behavior", "..:deep_linking_behavior", "..:metrics_recorder", "..:os_route", @@ -154,18 +134,16 @@ "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] - extra_deps = [ ":multidevice_smartlock_subpage_module" ] externs_list = [ "$externs_path/quick_unlock_private.js" ] } -js_library("multidevice_subpage.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.m.js" ] +js_library("multidevice_subpage") { deps = [ - ":multidevice_browser_proxy.m", - ":multidevice_combined_setup_item.m", - ":multidevice_constants.m", - ":multidevice_task_continuation_item.m", - ":multidevice_wifi_sync_item.m", + ":multidevice_browser_proxy", + ":multidevice_combined_setup_item", + ":multidevice_constants", + ":multidevice_task_continuation_item", + ":multidevice_wifi_sync_item", "..:deep_linking_behavior", "..:os_route", "..:os_settings_routes", @@ -174,26 +152,22 @@ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior.m", ] - extra_deps = [ ":multidevice_subpage_module" ] } -js_library("multidevice_combined_setup_item.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_combined_setup_item.m.js" ] +js_library("multidevice_combined_setup_item") { deps = [ - ":multidevice_constants.m", - ":multidevice_feature_behavior.m", - ":multidevice_feature_item.m", + ":multidevice_constants", + ":multidevice_feature_behavior", + ":multidevice_feature_item", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] - extra_deps = [ ":multidevice_combined_setup_item_module" ] externs_list = [ "../settings_controls_types.js" ] } -js_library("multidevice_tether_item.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_tether_item.m.js" ] +js_library("multidevice_tether_item") { deps = [ - ":multidevice_feature_behavior.m", + ":multidevice_feature_behavior", "..:os_route", "..:os_settings_routes", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", @@ -201,29 +175,25 @@ "//ui/webui/resources/cr_components/chromeos/network:network_listener_behavior.m", "//ui/webui/resources/cr_components/chromeos/network:onc_mojo.m", ] - extra_deps = [ ":multidevice_tether_item_module" ] } -js_library("multidevice_task_continuation_item.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_item.m.js" ] +js_library("multidevice_task_continuation_item") { deps = [ - ":multidevice_constants.m", - ":multidevice_feature_behavior.m", - ":multidevice_feature_item.m", - ":multidevice_task_continuation_disabled_link.m", + ":multidevice_constants", + ":multidevice_feature_behavior", + ":multidevice_feature_item", + ":multidevice_task_continuation_disabled_link", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] - extra_deps = [ ":multidevice_task_continuation_item_module" ] externs_list = [ "../settings_controls_types.js" ] } -js_library("multidevice_wifi_sync_item.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_item.m.js" ] +js_library("multidevice_wifi_sync_item") { deps = [ - ":multidevice_feature_behavior.m", - ":multidevice_feature_item.m", - ":multidevice_wifi_sync_disabled_link.m", + ":multidevice_feature_behavior", + ":multidevice_feature_item", + ":multidevice_wifi_sync_disabled_link", "..:os_route", "..:route_origin_behavior", "../..:router", @@ -233,12 +203,10 @@ "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] - extra_deps = [ ":multidevice_wifi_sync_item_module" ] externs_list = [ "../settings_controls_types.js" ] } -js_library("multidevice_task_continuation_disabled_link.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_disabled_link.m.js" ] +js_library("multidevice_task_continuation_disabled_link") { deps = [ "..:os_route", "../..:router", @@ -246,13 +214,11 @@ "//ui/webui/resources/js:i18n_behavior.m", "//ui/webui/resources/js:load_time_data.m", ] - extra_deps = [ ":multidevice_task_continuation_disabled_link_module" ] } -js_library("multidevice_wifi_sync_disabled_link.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_disabled_link.m.js" ] +js_library("multidevice_wifi_sync_disabled_link") { deps = [ - ":multidevice_feature_behavior.m", + ":multidevice_feature_behavior", "..:os_route", "..:route_origin_behavior", "../..:router", @@ -260,11 +226,9 @@ "//ui/webui/resources/js:i18n_behavior.m", "//ui/webui/resources/js:load_time_data.m", ] - extra_deps = [ ":multidevice_wifi_sync_disabled_link_module" ] } -js_library("multidevice_screen_lock_subpage.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.m.js" ] +js_library("multidevice_screen_lock_subpage") { deps = [ "../os_people_page:lock_screen_password_prompt_dialog", "../os_people_page:lock_state_behavior.m", @@ -275,214 +239,38 @@ "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js/cr/ui:focus_without_ink.m", ] - extra_deps = [ ":multidevice_screen_lock_subpage_module" ] externs_list = [ "$externs_path/chrome_extensions.js" ] } -js_library("multidevice_smartlock_item.m") { - sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_item.m.js" ] +js_library("multidevice_smartlock_item") { deps = [ - ":multidevice_browser_proxy.m", - ":multidevice_constants.m", - ":multidevice_feature_behavior.m", - ":multidevice_feature_item.m", + ":multidevice_browser_proxy", + ":multidevice_constants", + ":multidevice_feature_behavior", + ":multidevice_feature_item", "..:metrics_recorder", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] - extra_deps = [ ":multidevice_smartlock_item_module" ] } -group("polymer3_elements") { - public_deps = [ - ":modulize", - ":multidevice_combined_setup_item_module", - ":multidevice_feature_item_module", - ":multidevice_feature_toggle_module", - ":multidevice_notification_access_setup_dialog_module", - ":multidevice_page_module", - ":multidevice_permissions_setup_dialog_module", - ":multidevice_radio_button_module", - ":multidevice_screen_lock_subpage_module", - ":multidevice_smartlock_item_module", - ":multidevice_smartlock_subpage_module", - ":multidevice_subpage_module", - ":multidevice_task_continuation_disabled_link_module", - ":multidevice_task_continuation_item_module", - ":multidevice_tether_item_module", - ":multidevice_wifi_sync_disabled_link_module", - ":multidevice_wifi_sync_item_module", +html_to_js("web_components") { + js_files = [ + "multidevice_combined_setup_item.js", + "multidevice_feature_item.js", + "multidevice_feature_toggle.js", + "multidevice_notification_access_setup_dialog.js", + "multidevice_page.js", + "multidevice_permissions_setup_dialog.js", + "multidevice_radio_button.js", + "multidevice_screen_lock_subpage.js", + "multidevice_smartlock_item.js", + "multidevice_smartlock_subpage.js", + "multidevice_subpage.js", + "multidevice_task_continuation_disabled_link.js", + "multidevice_task_continuation_item.js", + "multidevice_tether_item.js", + "multidevice_wifi_sync_disabled_link.js", + "multidevice_wifi_sync_item.js", ] } - -nearby_shared_auto_imports_closure_fix = [ - # TODO(crbug.com/1121865): polymer.py normalizes the relative paths to shared - # nearby resources like ../../shared/* against - # c/b/r/settings/chromeos/nearby_share_page - # generating paths with the prefix c/b/r/settings/shared/*. It uses the - # normalized path to look up relative references for auto import. In order to - # get the auto import to match, we need to use this path prefix even though it - # does not exist on disk there. The actual resources are in - # c/b/r/nearby_share/shared and are re-hosted in the chrome://os-settings - # webui at the chrome://os-settings/shared/* prefix. - "chrome/browser/resources/settings/shared/nearby_contact_manager.html|getContactManager", - "chrome/browser/resources/settings/shared/nearby_share_settings.html|getNearbyShareSettings", - "chrome/browser/resources/settings/shared/nearby_share_settings_behavior.html|NearbyShareSettingsBehavior,NearbySettings", -] - -polymer_modulizer("multidevice_feature_item") { - js_file = "multidevice_feature_item.js" - html_file = "multidevice_feature_item.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports + - [ "ui/webui/resources/html/assert.html|assert" ] -} - -polymer_modulizer("multidevice_feature_toggle") { - js_file = "multidevice_feature_toggle.js" - html_file = "multidevice_feature_toggle.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_page") { - js_file = "multidevice_page.js" - html_file = "multidevice_page.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = - os_settings_namespace_rewrites + nearby_shared_namespace_rewrites - auto_imports = - os_settings_auto_imports + nearby_shared_auto_imports_closure_fix + - [ "ui/webui/resources/html/polymer.html|Polymer,html,beforeNextRender" ] -} - -polymer_modulizer("multidevice_notification_access_setup_dialog") { - js_file = "multidevice_notification_access_setup_dialog.js" - html_file = "multidevice_notification_access_setup_dialog.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_permissions_setup_dialog") { - js_file = "multidevice_permissions_setup_dialog.js" - html_file = "multidevice_permissions_setup_dialog.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_radio_button") { - js_file = "multidevice_radio_button.js" - html_file = "multidevice_radio_button.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_smartlock_subpage") { - js_file = "multidevice_smartlock_subpage.js" - html_file = "multidevice_smartlock_subpage.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_subpage") { - js_file = "multidevice_subpage.js" - html_file = "multidevice_subpage.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_combined_setup_item") { - js_file = "multidevice_combined_setup_item.js" - html_file = "multidevice_combined_setup_item.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_tether_item") { - js_file = "multidevice_tether_item.js" - html_file = "multidevice_tether_item.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_task_continuation_item") { - js_file = "multidevice_task_continuation_item.js" - html_file = "multidevice_task_continuation_item.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_wifi_sync_item") { - js_file = "multidevice_wifi_sync_item.js" - html_file = "multidevice_wifi_sync_item.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_task_continuation_disabled_link") { - js_file = "multidevice_task_continuation_disabled_link.js" - html_file = "multidevice_task_continuation_disabled_link.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_wifi_sync_disabled_link") { - js_file = "multidevice_wifi_sync_disabled_link.js" - html_file = "multidevice_wifi_sync_disabled_link.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_screen_lock_subpage") { - js_file = "multidevice_screen_lock_subpage.js" - html_file = "multidevice_screen_lock_subpage.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -polymer_modulizer("multidevice_smartlock_item") { - js_file = "multidevice_smartlock_item.js" - html_file = "multidevice_smartlock_item.html" - html_type = "dom-module" - migrated_imports = os_settings_migrated_imports - namespace_rewrites = os_settings_namespace_rewrites - auto_imports = os_settings_auto_imports -} - -js_modulizer("modulize") { - input_files = [ - "multidevice_browser_proxy.js", - "multidevice_feature_behavior.js", - "multidevice_constants.js", - ] - namespace_rewrites = os_settings_namespace_rewrites -}
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.js index a3dd04f..03ce440 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.js
@@ -2,182 +2,172 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; -// #import {MultiDevicePageContentData, MultiDeviceFeature} from './multidevice_constants.m.js'; -// clang-format on +import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; -cr.define('settings', function() { - /** - * An object containing messages for web permissisions origin - * and the messages multidevice feature state. - * - * @typedef {{origin: string, - * enabled: boolean}} - */ - /* #export */ let AndroidSmsInfo; +import {MultiDeviceFeature, MultiDevicePageContentData} from './multidevice_constants.js'; - /** @interface */ - /* #export */ class MultiDeviceBrowserProxy { - showMultiDeviceSetupDialog() {} +/** + * An object containing messages for web permissisions origin + * and the messages multidevice feature state. + * + * @typedef {{origin: string, + * enabled: boolean}} + */ +export let AndroidSmsInfo; - /** @return {!Promise<!settings.MultiDevicePageContentData>} */ - getPageContentData() {} +/** @interface */ +export class MultiDeviceBrowserProxy { + showMultiDeviceSetupDialog() {} - /** - * @param {!settings.MultiDeviceFeature} feature The feature whose state - * should be set. - * @param {boolean} enabled Whether the feature should be turned off or on. - * @param {string=} opt_authToken Proof that the user is authenticated. - * Needed to enable Smart Lock, and Better Together Suite if the Smart - * Lock user pref is enabled. - * @return {!Promise<boolean>} Whether the operation was successful. - */ - setFeatureEnabledState(feature, enabled, opt_authToken) {} - - removeHostDevice() {} - - retryPendingHostSetup() {} - - /** - * Called when the "Set Up" button is clicked to open the Android Messages - * PWA. - */ - setUpAndroidSms() {} - - /** - * Returns the value of the preference controlling whether Smart Lock may be - * used to sign-in the user (as opposed to unlocking the screen). - * @return {!Promise<boolean>} - */ - getSmartLockSignInEnabled() {} - - /** - * Sets the value of the preference controlling whether Smart Lock may be - * used to sign-in the user (as opposed to unlocking the screen). - * @param {boolean} enabled - * @param {string=} opt_authToken Authentication token used to restrict - * edit access to the Smart Lock sign-in pref. - */ - setSmartLockSignInEnabled(enabled, opt_authToken) {} - - /** - * Returns the value of the preference controlling whether Smart Lock - * sign-in is allowed. - * @return {!Promise<boolean>} - */ - getSmartLockSignInAllowed() {} - - /** - * Returns android messages info with messages feature state - * and messages for web permissions origin. - * @return {!Promise<!settings.AndroidSmsInfo>} Android SMS Info - */ - getAndroidSmsInfo() {} - - /** - * Attempts the phone hub notification access setup flow. - */ - attemptNotificationSetup() {} - - /** - * Cancels the phone hub notification access setup flow. - */ - cancelNotificationSetup() {} - - /** - * Attempts the phone hub apps access setup flow. - */ - attemptAppsSetup() {} - - /** - * Cancels the phone hub apps access setup flow. - */ - cancelAppsSetup() {} - } + /** @return {!Promise<!MultiDevicePageContentData>} */ + getPageContentData() {} /** - * @implements {settings.MultiDeviceBrowserProxy} + * @param {!MultiDeviceFeature} feature The feature whose state + * should be set. + * @param {boolean} enabled Whether the feature should be turned off or on. + * @param {string=} opt_authToken Proof that the user is authenticated. + * Needed to enable Smart Lock, and Better Together Suite if the Smart + * Lock user pref is enabled. + * @return {!Promise<boolean>} Whether the operation was successful. */ - /* #export */ class MultiDeviceBrowserProxyImpl { - /** @override */ - showMultiDeviceSetupDialog() { - chrome.send('showMultiDeviceSetupDialog'); - } + setFeatureEnabledState(feature, enabled, opt_authToken) {} - /** @override */ - getPageContentData() { - return cr.sendWithPromise('getPageContentData'); - } + removeHostDevice() {} - /** @override */ - setFeatureEnabledState(feature, enabled, opt_authToken) { - return cr.sendWithPromise( - 'setFeatureEnabledState', feature, enabled, opt_authToken); - } + retryPendingHostSetup() {} - /** @override */ - removeHostDevice() { - chrome.send('removeHostDevice'); - } + /** + * Called when the "Set Up" button is clicked to open the Android Messages + * PWA. + */ + setUpAndroidSms() {} - /** @override */ - retryPendingHostSetup() { - chrome.send('retryPendingHostSetup'); - } + /** + * Returns the value of the preference controlling whether Smart Lock may be + * used to sign-in the user (as opposed to unlocking the screen). + * @return {!Promise<boolean>} + */ + getSmartLockSignInEnabled() {} - /** @override */ - setUpAndroidSms() { - chrome.send('setUpAndroidSms'); - } + /** + * Sets the value of the preference controlling whether Smart Lock may be + * used to sign-in the user (as opposed to unlocking the screen). + * @param {boolean} enabled + * @param {string=} opt_authToken Authentication token used to restrict + * edit access to the Smart Lock sign-in pref. + */ + setSmartLockSignInEnabled(enabled, opt_authToken) {} - /** @override */ - getSmartLockSignInEnabled() { - return cr.sendWithPromise('getSmartLockSignInEnabled'); - } + /** + * Returns the value of the preference controlling whether Smart Lock + * sign-in is allowed. + * @return {!Promise<boolean>} + */ + getSmartLockSignInAllowed() {} - /** @override */ - setSmartLockSignInEnabled(enabled, opt_authToken) { - chrome.send('setSmartLockSignInEnabled', [enabled, opt_authToken]); - } + /** + * Returns android messages info with messages feature state + * and messages for web permissions origin. + * @return {!Promise<!AndroidSmsInfo>} Android SMS Info + */ + getAndroidSmsInfo() {} - /** @override */ - getSmartLockSignInAllowed() { - return cr.sendWithPromise('getSmartLockSignInAllowed'); - } + /** + * Attempts the phone hub notification access setup flow. + */ + attemptNotificationSetup() {} - /** @override */ - getAndroidSmsInfo() { - return cr.sendWithPromise('getAndroidSmsInfo'); - } + /** + * Cancels the phone hub notification access setup flow. + */ + cancelNotificationSetup() {} - /** @override */ - attemptNotificationSetup() { - chrome.send('attemptNotificationSetup'); - } + /** + * Attempts the phone hub apps access setup flow. + */ + attemptAppsSetup() {} - /** @override */ - cancelNotificationSetup() { - chrome.send('cancelNotificationSetup'); - } + /** + * Cancels the phone hub apps access setup flow. + */ + cancelAppsSetup() {} +} - /** @override */ - attemptAppsSetup() { - chrome.send('attemptAppsSetup'); - } - - /** @override */ - cancelAppsSetup() { - chrome.send('cancelAppsSetup'); - } +/** + * @implements {MultiDeviceBrowserProxy} + */ +export class MultiDeviceBrowserProxyImpl { + /** @override */ + showMultiDeviceSetupDialog() { + chrome.send('showMultiDeviceSetupDialog'); } - cr.addSingletonGetter(MultiDeviceBrowserProxyImpl); + /** @override */ + getPageContentData() { + return sendWithPromise('getPageContentData'); + } - // #cr_define_end - return { - AndroidSmsInfo, - MultiDeviceBrowserProxy, - MultiDeviceBrowserProxyImpl, - }; -}); + /** @override */ + setFeatureEnabledState(feature, enabled, opt_authToken) { + return sendWithPromise( + 'setFeatureEnabledState', feature, enabled, opt_authToken); + } + + /** @override */ + removeHostDevice() { + chrome.send('removeHostDevice'); + } + + /** @override */ + retryPendingHostSetup() { + chrome.send('retryPendingHostSetup'); + } + + /** @override */ + setUpAndroidSms() { + chrome.send('setUpAndroidSms'); + } + + /** @override */ + getSmartLockSignInEnabled() { + return sendWithPromise('getSmartLockSignInEnabled'); + } + + /** @override */ + setSmartLockSignInEnabled(enabled, opt_authToken) { + chrome.send('setSmartLockSignInEnabled', [enabled, opt_authToken]); + } + + /** @override */ + getSmartLockSignInAllowed() { + return sendWithPromise('getSmartLockSignInAllowed'); + } + + /** @override */ + getAndroidSmsInfo() { + return sendWithPromise('getAndroidSmsInfo'); + } + + /** @override */ + attemptNotificationSetup() { + chrome.send('attemptNotificationSetup'); + } + + /** @override */ + cancelNotificationSetup() { + chrome.send('cancelNotificationSetup'); + } + + /** @override */ + attemptAppsSetup() { + chrome.send('attemptAppsSetup'); + } + + /** @override */ + cancelAppsSetup() { + chrome.send('cancelAppsSetup'); + } +} + +addSingletonGetter(MultiDeviceBrowserProxyImpl);
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_combined_setup_item.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_combined_setup_item.html index 0cb3ae9..3a97f3a 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_combined_setup_item.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_combined_setup_item.html
@@ -1,38 +1,25 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_components/localized_link/localized_link.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> -<link rel="import" href="multidevice_constants.html"> -<link rel="import" href="multidevice_feature_behavior.html"> -<link rel="import" href="multidevice_feature_item.html"> - -<dom-module id="settings-multidevice-combined-setup-item"> - <template> - <style include="settings-shared"> - cr-button { - white-space: nowrap; - } - </style> - <settings-multidevice-feature-item id="phoneHubCombinedSetupItem" - page-content-data="[[pageContentData]]" is-sub-feature> - <div id="featureName" slot="feature-name"> - [[setupName_]] - </div> - <localized-link - class="secondary" - id="featureSecondary" - slot="feature-summary" - localized-string="[[setupSummary_]]"> - </localized-link> - <cr-button - slot="feature-controller" - on-click="handlePhoneHubSetupClick_" - aria-labelledby="featureName" - aria-describedby="featureSecondary" - disabled="[[getButtonDisabledState_(pageContentData)]]"> - $i18n{multideviceSetupButton} - </cr-button> - </settings-multidevice-feature-item> - </template> - <script src="multidevice_combined_setup_item.js"></script> -</dom-module> +<style include="settings-shared"> + cr-button { + white-space: nowrap; + } +</style> +<settings-multidevice-feature-item id="phoneHubCombinedSetupItem" + page-content-data="[[pageContentData]]" is-sub-feature> + <div id="featureName" slot="feature-name"> + [[setupName_]] + </div> + <localized-link + class="secondary" + id="featureSecondary" + slot="feature-summary" + localized-string="[[setupSummary_]]"> + </localized-link> + <cr-button + slot="feature-controller" + on-click="handlePhoneHubSetupClick_" + aria-labelledby="featureName" + aria-describedby="featureSecondary" + disabled="[[getButtonDisabledState_(pageContentData)]]"> + $i18n{multideviceSetupButton} + </cr-button> +</settings-multidevice-feature-item>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_combined_setup_item.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_combined_setup_item.js index 0e235f4..b218631 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_combined_setup_item.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_combined_setup_item.js
@@ -2,11 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '//resources/cr_components/localized_link/localized_link.js'; +import '//resources/cr_elements/cr_button/cr_button.m.js'; +import './multidevice_feature_item.js'; + +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {MultiDeviceFeatureBehavior} from './multidevice_feature_behavior.js'; + /** * @fileoverview 'settings-multidevice-combined-setup-item' encapsulates * special logic for setting up multiple features from one click. */ Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-combined-setup-item', behaviors: [MultiDeviceFeatureBehavior],
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.js index 80829f3..625e6ac 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.js
@@ -2,161 +2,146 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -cr.define('settings', function() { +/** + * The state of the preference controlling Smart Lock's ability to sign-in the + * user. + * @enum {string} + */ +export const SmartLockSignInEnabledState = { + ENABLED: 'enabled', + DISABLED: 'disabled', +}; - /** - * The state of the preference controlling Smart Lock's ability to sign-in the - * user. - * @enum {string} - */ - /* #export */ const SmartLockSignInEnabledState = { - ENABLED: 'enabled', - DISABLED: 'disabled', - }; +/** + * The possible statuses of hosts on the logged in account that determine the + * page content. Note that this is based on (and must include an analog of + * all values in) the HostStatus enum in + * services/multidevice_setup/public/mojom/multidevice_setup.mojom. + * @enum {number} + */ +export const MultiDeviceSettingsMode = { + NO_ELIGIBLE_HOSTS: 0, + NO_HOST_SET: 1, + HOST_SET_WAITING_FOR_SERVER: 2, + HOST_SET_WAITING_FOR_VERIFICATION: 3, + HOST_SET_VERIFIED: 4, +}; - /** - * The possible statuses of hosts on the logged in account that determine the - * page content. Note that this is based on (and must include an analog of - * all values in) the HostStatus enum in - * services/multidevice_setup/public/mojom/multidevice_setup.mojom. - * @enum {number} - */ - /* #export */ const MultiDeviceSettingsMode = { - NO_ELIGIBLE_HOSTS: 0, - NO_HOST_SET: 1, - HOST_SET_WAITING_FOR_SERVER: 2, - HOST_SET_WAITING_FOR_VERIFICATION: 3, - HOST_SET_VERIFIED: 4, - }; +/** + * Enum of MultiDevice features. Note that this is copied from (and must + * include an analog of all values in) the Feature enum in + * //ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom. + * @enum {number} + */ +export const MultiDeviceFeature = { + BETTER_TOGETHER_SUITE: 0, + INSTANT_TETHERING: 1, + MESSAGES: 2, + SMART_LOCK: 3, + PHONE_HUB: 4, + PHONE_HUB_NOTIFICATIONS: 5, + PHONE_HUB_TASK_CONTINUATION: 6, + WIFI_SYNC: 7, + ECHE: 8, + PHONE_HUB_CAMERA_ROLL: 9, +}; - /** - * Enum of MultiDevice features. Note that this is copied from (and must - * include an analog of all values in) the Feature enum in - * //ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom. - * @enum {number} - */ - /* #export */ const MultiDeviceFeature = { - BETTER_TOGETHER_SUITE: 0, - INSTANT_TETHERING: 1, - MESSAGES: 2, - SMART_LOCK: 3, - PHONE_HUB: 4, - PHONE_HUB_NOTIFICATIONS: 5, - PHONE_HUB_TASK_CONTINUATION: 6, - WIFI_SYNC: 7, - ECHE: 8, - PHONE_HUB_CAMERA_ROLL: 9, - }; +/** + * Possible states of MultiDevice features. Note that this is copied from (and + * must include an analog of all values in) the FeatureState enum in + * //ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom. + * @enum {number} + */ +export const MultiDeviceFeatureState = { + PROHIBITED_BY_POLICY: 0, + DISABLED_BY_USER: 1, + ENABLED_BY_USER: 2, + NOT_SUPPORTED_BY_CHROMEBOOK: 3, + NOT_SUPPORTED_BY_PHONE: 4, + UNAVAILABLE_NO_VERIFIED_HOST: 5, + UNAVAILABLE_INSUFFICIENT_SECURITY: 6, + UNAVAILABLE_SUITE_DISABLED: 7, + FURTHER_SETUP_REQUIRED: 8, + UNAVAILABLE_TOP_LEVEL_FEATURE_DISABLED: 9, + UNAVAILABLE_NO_VERIFIED_HOST_CLIENT_NOT_READY: 10, +}; - /** - * Possible states of MultiDevice features. Note that this is copied from (and - * must include an analog of all values in) the FeatureState enum in - * //ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom. - * @enum {number} - */ - /* #export */ const MultiDeviceFeatureState = { - PROHIBITED_BY_POLICY: 0, - DISABLED_BY_USER: 1, - ENABLED_BY_USER: 2, - NOT_SUPPORTED_BY_CHROMEBOOK: 3, - NOT_SUPPORTED_BY_PHONE: 4, - UNAVAILABLE_NO_VERIFIED_HOST: 5, - UNAVAILABLE_INSUFFICIENT_SECURITY: 6, - UNAVAILABLE_SUITE_DISABLED: 7, - FURTHER_SETUP_REQUIRED: 8, - UNAVAILABLE_TOP_LEVEL_FEATURE_DISABLED: 9, - UNAVAILABLE_NO_VERIFIED_HOST_CLIENT_NOT_READY: 10, - }; +/** + * Possible states of Phone Hub's feature access. Access can be + * prohibited if the user is using a work profile on their phone on Android + * version <N, or if the policy managing the phone disables access. + * @enum {number} + */ +export const PhoneHubFeatureAccessStatus = { + PROHIBITED: 0, + AVAILABLE_BUT_NOT_GRANTED: 1, + ACCESS_GRANTED: 2, +}; - /** - * Possible states of Phone Hub's feature access. Access can be - * prohibited if the user is using a work profile on their phone on Android - * version <N, or if the policy managing the phone disables access. - * @enum {number} - */ - /* #export */ const PhoneHubFeatureAccessStatus = { - PROHIBITED: 0, - AVAILABLE_BUT_NOT_GRANTED: 1, - ACCESS_GRANTED: 2, - }; +/** + * Possible reasons for Phone Hub's feature access being prohibited. + * Users should ensure feature access is actually prohibited before + * comparing against these reasons. + * @enum {number} + */ +export const PhoneHubFeatureAccessProhibitedReason = { + UNKNOWN: 0, + WORK_PROFILE: 1, + DISABLED_BY_PHONE_POLICY: 2, +}; - /** - * Possible reasons for Phone Hub's feature access being prohibited. - * Users should ensure feature access is actually prohibited before - * comparing against these reasons. - * @enum {number} - */ - /* #export */ const PhoneHubFeatureAccessProhibitedReason = { - UNKNOWN: 0, - WORK_PROFILE: 1, - DISABLED_BY_PHONE_POLICY: 2, - }; +/** + * Possible of Phone Hub's permissions setup mode.The value will be assigned + * when the user clicks on the settings UI. Basically, INIT_MODE will be + * default value, which means it has not been set yet. + * ALL_PERMISSIONS_SETUP_MODE means that we will process notifications and + * apps streaming onboarding flow in order. + * + * @enum {number} + */ +export const PhoneHubPermissionsSetupMode = { + INIT_MODE: 0, + NOTIFICATION_SETUP_MODE: 1, + APPS_SETUP_MODE: 2, + CAMERA_ROLL_SETUP_MODE: 3, + ALL_PERMISSIONS_SETUP_MODE: 4, +}; - /** - * Possible of Phone Hub's permissions setup mode.The value will be assigned - * when the user clicks on the settings UI. Basically, INIT_MODE will be - * default value, which means it has not been set yet. - * ALL_PERMISSIONS_SETUP_MODE means that we will process notifications and - * apps streaming onboarding flow in order. - * - * @enum {number} - */ - /* #export */ const PhoneHubPermissionsSetupMode = { - INIT_MODE: 0, - NOTIFICATION_SETUP_MODE: 1, - APPS_SETUP_MODE: 2, - CAMERA_ROLL_SETUP_MODE: 3, - ALL_PERMISSIONS_SETUP_MODE: 4, - }; - - /** - * Container for the initial data that the page requires in order to display - * the correct content. It is also used for receiving status updates during - * use. Note that the host device may be verified (enabled or disabled), - * awaiting verification, or it may have failed setup because it was not able - * to connect to the server. - * - * For each MultiDevice feature (including the "suite" feature, which acts as - * a gatekeeper for the others), the corresponding *State property is an enum - * containing the data necessary to display it. Note that hostDeviceName - * should be undefined if and only if no host has been set up, regardless of - * whether there are potential hosts on the account. - * - * @typedef {{ - * mode: !settings.MultiDeviceSettingsMode, - * hostDeviceName: (string|undefined), - * betterTogetherState: !settings.MultiDeviceFeatureState, - * instantTetheringState: !settings.MultiDeviceFeatureState, - * messagesState: !settings.MultiDeviceFeatureState, - * smartLockState: !settings.MultiDeviceFeatureState, - * phoneHubState: !settings.MultiDeviceFeatureState, - * phoneHubCameraRollState: !settings.MultiDeviceFeatureState, - * phoneHubNotificationsState: !settings.MultiDeviceFeatureState, - * phoneHubTaskContinuationState: !settings.MultiDeviceFeatureState, - * phoneHubAppsState: !settings.MultiDeviceFeatureState, - * wifiSyncState: !settings.MultiDeviceFeatureState, - * isAndroidSmsPairingComplete: boolean, - * cameraRollAccessStatus: !settings.PhoneHubFeatureAccessStatus, - * notificationAccessStatus: !settings.PhoneHubFeatureAccessStatus, - * notificationAccessProhibitedReason: - * !settings.PhoneHubFeatureAccessProhibitedReason, - * isNearbyShareDisallowedByPolicy: boolean, - * isPhoneHubAppsAccessGranted: boolean, - * isPhoneHubPermissionsDialogSupported: boolean, - * isCameraRollFilePermissionGranted: boolean - * }} - */ - /* #export */ let MultiDevicePageContentData; - - // #cr_define_end - return { - MultiDeviceSettingsMode, - MultiDeviceFeature, - MultiDeviceFeatureState, - MultiDevicePageContentData, - PhoneHubFeatureAccessStatus, - PhoneHubFeatureAccessProhibitedReason, - PhoneHubPermissionsSetupMode, - SmartLockSignInEnabledState - }; -}); +/** + * Container for the initial data that the page requires in order to display + * the correct content. It is also used for receiving status updates during + * use. Note that the host device may be verified (enabled or disabled), + * awaiting verification, or it may have failed setup because it was not able + * to connect to the server. + * + * For each MultiDevice feature (including the "suite" feature, which acts as + * a gatekeeper for the others), the corresponding *State property is an enum + * containing the data necessary to display it. Note that hostDeviceName + * should be undefined if and only if no host has been set up, regardless of + * whether there are potential hosts on the account. + * + * @typedef {{ + * mode: !MultiDeviceSettingsMode, + * hostDeviceName: (string|undefined), + * betterTogetherState: !MultiDeviceFeatureState, + * instantTetheringState: !MultiDeviceFeatureState, + * messagesState: !MultiDeviceFeatureState, + * smartLockState: !MultiDeviceFeatureState, + * phoneHubState: !MultiDeviceFeatureState, + * phoneHubCameraRollState: !MultiDeviceFeatureState, + * phoneHubNotificationsState: !MultiDeviceFeatureState, + * phoneHubTaskContinuationState: !MultiDeviceFeatureState, + * phoneHubAppsState: !MultiDeviceFeatureState, + * wifiSyncState: !MultiDeviceFeatureState, + * isAndroidSmsPairingComplete: boolean, + * cameraRollAccessStatus: !PhoneHubFeatureAccessStatus, + * notificationAccessStatus: !PhoneHubFeatureAccessStatus, + * notificationAccessProhibitedReason: + * !PhoneHubFeatureAccessProhibitedReason, + * isNearbyShareDisallowedByPolicy: boolean, + * isPhoneHubAppsAccessGranted: boolean, + * isPhoneHubPermissionsDialogSupported: boolean, + * isCameraRollFilePermissionGranted: boolean + * }} + */ +export let MultiDevicePageContentData;
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.js index abeadba..1ab63ab 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.js
@@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// clang-format off -// #import {MultiDeviceSettingsMode, MultiDeviceFeature, MultiDeviceFeatureState, MultiDevicePageContentData, PhoneHubFeatureAccessStatus, PhoneHubFeatureAccessProhibitedReason} from './multidevice_constants.m.js'; -// #import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; -// clang-format on +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; + +import {MultiDeviceFeature, MultiDeviceFeatureState, MultiDevicePageContentData, MultiDeviceSettingsMode, PhoneHubFeatureAccessStatus} from './multidevice_constants.js'; /** * @fileoverview Polymer behavior for dealing with MultiDevice features. It is @@ -16,7 +15,7 @@ /** @polymerBehavior */ const MultiDeviceFeatureBehaviorImpl = { properties: { - /** @type {!settings.MultiDevicePageContentData} */ + /** @type {!MultiDevicePageContentData} */ pageContentData: Object, /** @@ -25,7 +24,7 @@ */ MultiDeviceFeature: { type: Object, - value: settings.MultiDeviceFeature, + value: MultiDeviceFeature, }, }, @@ -37,7 +36,7 @@ isSuiteOn() { return !!this.pageContentData && this.pageContentData.betterTogetherState === - settings.MultiDeviceFeatureState.ENABLED_BY_USER; + MultiDeviceFeatureState.ENABLED_BY_USER; }, /** @@ -48,26 +47,26 @@ isSuiteAllowedByPolicy() { return !!this.pageContentData && this.pageContentData.betterTogetherState !== - settings.MultiDeviceFeatureState.PROHIBITED_BY_POLICY; + MultiDeviceFeatureState.PROHIBITED_BY_POLICY; }, /** * Whether an individual feature is allowed by policy. - * @param {!settings.MultiDeviceFeature} feature + * @param {!MultiDeviceFeature} feature * @return {boolean} */ isFeatureAllowedByPolicy(feature) { return this.getFeatureState(feature) !== - settings.MultiDeviceFeatureState.PROHIBITED_BY_POLICY; + MultiDeviceFeatureState.PROHIBITED_BY_POLICY; }, /** - * @param {!settings.MultiDeviceFeature} feature + * @param {!MultiDeviceFeature} feature * @return {boolean} */ isFeatureSupported(feature) { - return ![settings.MultiDeviceFeatureState.NOT_SUPPORTED_BY_CHROMEBOOK, - settings.MultiDeviceFeatureState.NOT_SUPPORTED_BY_PHONE, + return ![MultiDeviceFeatureState.NOT_SUPPORTED_BY_CHROMEBOOK, + MultiDeviceFeatureState.NOT_SUPPORTED_BY_PHONE, ].includes(this.getFeatureState(feature)); }, @@ -76,20 +75,19 @@ * @return {boolean} */ isPhoneHubOn() { - return this.getFeatureState(settings.MultiDeviceFeature.PHONE_HUB) === - settings.MultiDeviceFeatureState.ENABLED_BY_USER; + return this.getFeatureState(MultiDeviceFeature.PHONE_HUB) === + MultiDeviceFeatureState.ENABLED_BY_USER; }, /** - * @param {!settings.MultiDeviceFeature} feature + * @param {!MultiDeviceFeature} feature * @return {boolean} */ isPhoneHubSubFeature(feature) { return [ - settings.MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL, - settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, - settings.MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION, - settings.MultiDeviceFeature.ECHE + MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL, + MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, + MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION, MultiDeviceFeature.ECHE ].includes(feature); }, @@ -100,7 +98,7 @@ isPhoneHubNotificationAccessProhibited() { return this.pageContentData && this.pageContentData.notificationAccessStatus === - settings.PhoneHubFeatureAccessStatus.PROHIBITED; + PhoneHubFeatureAccessStatus.PROHIBITED; }, /** @@ -108,10 +106,9 @@ * @return {boolean} */ isPhoneHubCameraRollSetupRequired() { - return this.isFeatureSupported( - settings.MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL) && + return this.isFeatureSupported(MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL) && this.pageContentData.cameraRollAccessStatus === - settings.PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED; + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED; }, /** @@ -119,7 +116,7 @@ * @return {boolean} */ isPhoneHubAppsSetupRequired() { - return this.isFeatureSupported(settings.MultiDeviceFeature.ECHE) && + return this.isFeatureSupported(MultiDeviceFeature.ECHE) && this.pageContentData.isPhoneHubPermissionsDialogSupported && !this.pageContentData.isPhoneHubAppsAccessGranted; }, @@ -130,19 +127,19 @@ */ isPhoneHubNotificationsSetupRequired() { return this.pageContentData.notificationAccessStatus === - settings.PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED; + PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED; }, /** * Whether the user is prevented from attempted to change a given feature. In * the UI this corresponds to a disabled toggle. - * @param {!settings.MultiDeviceFeature} feature + * @param {!MultiDeviceFeature} feature * @return {boolean} */ isFeatureStateEditable(feature) { // The suite is off and the toggle corresponds to an individual feature // (as opposed to the full suite). - if (feature !== settings.MultiDeviceFeature.BETTER_TOGETHER_SUITE && + if (feature !== MultiDeviceFeature.BETTER_TOGETHER_SUITE && !this.isSuiteOn()) { return false; } @@ -155,43 +152,43 @@ // Cannot edit the Phone Hub notification toggle if notification access is // prohibited. - if (feature === settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS && + if (feature === MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS && this.isPhoneHubNotificationAccessProhibited()) { return false; } return [ - settings.MultiDeviceFeatureState.DISABLED_BY_USER, - settings.MultiDeviceFeatureState.ENABLED_BY_USER + MultiDeviceFeatureState.DISABLED_BY_USER, + MultiDeviceFeatureState.ENABLED_BY_USER ].includes(this.getFeatureState(feature)); }, /** * The localized string representing the name of the feature. - * @param {!settings.MultiDeviceFeature} feature + * @param {!MultiDeviceFeature} feature * @return {string} */ getFeatureName(feature) { switch (feature) { - case settings.MultiDeviceFeature.BETTER_TOGETHER_SUITE: + case MultiDeviceFeature.BETTER_TOGETHER_SUITE: return this.i18n('multideviceSetupItemHeading'); - case settings.MultiDeviceFeature.INSTANT_TETHERING: + case MultiDeviceFeature.INSTANT_TETHERING: return this.i18n('multideviceInstantTetheringItemTitle'); - case settings.MultiDeviceFeature.MESSAGES: + case MultiDeviceFeature.MESSAGES: return this.i18n('multideviceAndroidMessagesItemTitle'); - case settings.MultiDeviceFeature.SMART_LOCK: + case MultiDeviceFeature.SMART_LOCK: return this.i18n('multideviceSmartLockItemTitle'); - case settings.MultiDeviceFeature.PHONE_HUB: + case MultiDeviceFeature.PHONE_HUB: return this.i18n('multidevicePhoneHubItemTitle'); - case settings.MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL: + case MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL: return this.i18n('multidevicePhoneHubCameraRollItemTitle'); - case settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS: + case MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS: return this.i18n('multidevicePhoneHubNotificationsItemTitle'); - case settings.MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION: + case MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION: return this.i18n('multidevicePhoneHubTaskContinuationItemTitle'); - case settings.MultiDeviceFeature.WIFI_SYNC: + case MultiDeviceFeature.WIFI_SYNC: return this.i18n('multideviceWifiSyncItemTitle'); - case settings.MultiDeviceFeature.ECHE: + case MultiDeviceFeature.ECHE: return this.i18n('multidevicePhoneHubAppsItemTitle'); default: return ''; @@ -201,24 +198,24 @@ /** * The full icon name used provided by the containing iron-iconset-svg * (i.e. [iron-iconset-svg name]:[SVG <g> tag id]) for a given feature. - * @param {!settings.MultiDeviceFeature} feature + * @param {!MultiDeviceFeature} feature * @return {string} */ getIconName(feature) { switch (feature) { - case settings.MultiDeviceFeature.BETTER_TOGETHER_SUITE: + case MultiDeviceFeature.BETTER_TOGETHER_SUITE: return 'os-settings:multidevice-better-together-suite'; - case settings.MultiDeviceFeature.MESSAGES: + case MultiDeviceFeature.MESSAGES: return 'os-settings:multidevice-messages'; - case settings.MultiDeviceFeature.SMART_LOCK: + case MultiDeviceFeature.SMART_LOCK: return 'os-settings:multidevice-smart-lock'; - case settings.MultiDeviceFeature.PHONE_HUB: - case settings.MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL: - case settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS: - case settings.MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION: - case settings.MultiDeviceFeature.ECHE: + case MultiDeviceFeature.PHONE_HUB: + case MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL: + case MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS: + case MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION: + case MultiDeviceFeature.ECHE: return 'os-settings:multidevice-better-together-suite'; - case settings.MultiDeviceFeature.WIFI_SYNC: + case MultiDeviceFeature.WIFI_SYNC: return 'os-settings:multidevice-wifi-sync'; default: return ''; @@ -228,29 +225,29 @@ /** * The localized string providing a description or useful status information * concerning a given feature. - * @param {!settings.MultiDeviceFeature} feature + * @param {!MultiDeviceFeature} feature * @return {string} */ getFeatureSummaryHtml(feature) { switch (feature) { - case settings.MultiDeviceFeature.SMART_LOCK: + case MultiDeviceFeature.SMART_LOCK: return this.i18nAdvanced('multideviceSmartLockItemSummary'); - case settings.MultiDeviceFeature.INSTANT_TETHERING: + case MultiDeviceFeature.INSTANT_TETHERING: return this.i18nAdvanced('multideviceInstantTetheringItemSummary'); - case settings.MultiDeviceFeature.MESSAGES: + case MultiDeviceFeature.MESSAGES: return this.i18nAdvanced('multideviceAndroidMessagesItemSummary'); - case settings.MultiDeviceFeature.PHONE_HUB: + case MultiDeviceFeature.PHONE_HUB: return this.i18nAdvanced('multidevicePhoneHubItemSummary'); - case settings.MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL: + case MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL: return this.i18nAdvanced('multidevicePhoneHubCameraRollItemSummary'); - case settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS: + case MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS: return this.i18nAdvanced('multidevicePhoneHubNotificationsItemSummary'); - case settings.MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION: + case MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION: return this.i18nAdvanced( 'multidevicePhoneHubTaskContinuationItemSummary'); - case settings.MultiDeviceFeature.WIFI_SYNC: + case MultiDeviceFeature.WIFI_SYNC: return this.i18nAdvanced('multideviceWifiSyncItemSummary'); - case settings.MultiDeviceFeature.ECHE: + case MultiDeviceFeature.ECHE: return this.i18nAdvanced('multidevicePhoneHubAppsItemSummary'); default: return ''; @@ -261,8 +258,8 @@ * Extracts the MultiDeviceFeatureState enum value describing the given * feature from this.pageContentData. Returns null if the feature is not * an accepted value (e.g. testing fake). - * @param {!settings.MultiDeviceFeature} feature - * @return {?settings.MultiDeviceFeatureState} + * @param {!MultiDeviceFeature} feature + * @return {?MultiDeviceFeatureState} */ getFeatureState(feature) { if (!this.pageContentData) { @@ -270,25 +267,25 @@ } switch (feature) { - case settings.MultiDeviceFeature.BETTER_TOGETHER_SUITE: + case MultiDeviceFeature.BETTER_TOGETHER_SUITE: return this.pageContentData.betterTogetherState; - case settings.MultiDeviceFeature.INSTANT_TETHERING: + case MultiDeviceFeature.INSTANT_TETHERING: return this.pageContentData.instantTetheringState; - case settings.MultiDeviceFeature.MESSAGES: + case MultiDeviceFeature.MESSAGES: return this.pageContentData.messagesState; - case settings.MultiDeviceFeature.SMART_LOCK: + case MultiDeviceFeature.SMART_LOCK: return this.pageContentData.smartLockState; - case settings.MultiDeviceFeature.PHONE_HUB: + case MultiDeviceFeature.PHONE_HUB: return this.pageContentData.phoneHubState; - case settings.MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL: + case MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL: return this.pageContentData.phoneHubCameraRollState; - case settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS: + case MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS: return this.pageContentData.phoneHubNotificationsState; - case settings.MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION: + case MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION: return this.pageContentData.phoneHubTaskContinuationState; - case settings.MultiDeviceFeature.WIFI_SYNC: + case MultiDeviceFeature.WIFI_SYNC: return this.pageContentData.wifiSyncState; - case settings.MultiDeviceFeature.ECHE: + case MultiDeviceFeature.ECHE: return this.pageContentData.phoneHubAppsState; default: return null; @@ -301,15 +298,15 @@ */ isHostSet() { return [ - settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER, - settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION, - settings.MultiDeviceSettingsMode.HOST_SET_VERIFIED, + MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER, + MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION, + MultiDeviceSettingsMode.HOST_SET_VERIFIED, ].includes(this.pageContentData.mode); }, }; /** @polymerBehavior */ -/* #export */ const MultiDeviceFeatureBehavior = [ +export const MultiDeviceFeatureBehavior = [ I18nBehavior, MultiDeviceFeatureBehaviorImpl, ];
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.html index f34c8f5..9dcc043 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.html
@@ -1,125 +1,104 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> +<style include="settings-shared"> + :host([is-sub-feature]) #feature-icon { + display: none; + } -<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> -<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> -<link rel="import" href="chrome://resources/html/assert.html"> -<link rel="import" href="chrome://resources/html/cr.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="../os_route.html"> -<link rel="import" href="../../router.html"> -<link rel="import" href="../../settings_shared_css.html"> -<link rel="import" href="chrome://resources/cr_components/localized_link/localized_link.html"> -<link rel="import" href="../route_origin_behavior.html"> -<link rel="import" href="multidevice_constants.html"> -<link rel="import" href="multidevice_feature_behavior.html"> -<link rel="import" href="multidevice_feature_toggle.html"> + :host([is-sub-feature]) .settings-box .middle { + padding-inline-start: 64px; + } -<dom-module id="settings-multidevice-feature-item"> - <template> - <style include="settings-shared"> - :host([is-sub-feature]) #feature-icon { - display: none; - } + #card { + border-top: var(--cr-separator-line); + border-top-style: var(--feature-item-border-top-style, solid); + padding: var(--feature-item-row-padding); + } - :host([is-sub-feature]) .settings-box .middle { - padding-inline-start: 64px; - } + #feature-icon { + padding: 2px; + } - #card { - border-top: var(--cr-separator-line); - border-top-style: var(--feature-item-border-top-style, solid); - padding: var(--feature-item-row-padding); - } + cr-policy-indicator { + padding: 0 var(--cr-controlled-by-spacing); + } - #feature-icon { - padding: 2px; - } - - cr-policy-indicator { - padding: 0 var(--cr-controlled-by-spacing); - } - - #help-icon:active { - /* Still reveal tooltip on click. */ - pointer-events: none; - } - </style> - <div id="card" class="settings-box two-line no-padding"> - <div id="linkWrapper" class="link-wrapper" - actionable$="[[isRowClickable_( - feature, pageContentData, subpageRoute)]]" - on-click="handleItemClick_"> - <template is="dom-if" if="[[!isFeatureIconHidden]]"> - <slot name="icon"> - <iron-icon id="feature-icon" icon="[[getIconName(feature)]]" - aria-hidden="true"> - </iron-icon> - </slot> - </template> - <div id="item-text-container" - class$="[[getItemTextContainerClassName_(isFeatureIconHidden)]]" - aria-hidden="true"> - <slot name="feature-name"> - <div id="featureName">[[getFeatureName(feature)]]</div> - </slot> - <slot name="feature-summary"> - <localized-link - class="secondary" - id="featureSecondary" - localized-string="[[getFeatureSummaryHtml(feature)]]"> - </localized-link> - </slot> - </div> - <template is="dom-if" - if="[[hasSubpageClickHandler_(feature, pageContentData, - subpageRoute)]]" - restamp> - <cr-icon-button id="subpageButton" class="subpage-arrow" - aria-labelledby="featureName" aria-describedby="featureSecondary" - aria-roledescription="$i18n{subpageArrowRoleDescription}"> - </cr-icon-button> - </template> - <template is="dom-if" if="[[iconTooltip]]" restamp> - <iron-icon id="help-icon" tabindex="0" icon="[[icon]]" - aria-labelledby="tooltip"> - </iron-icon> - <paper-tooltip id="tooltip" for="help-icon" position="top" - aria-hidden="true" fit-to-visible-bounds> - [[iconTooltip]] - </paper-tooltip> - </template> - </div> - <template is="dom-if" - if="[[shouldShowSeparator_( - feature, pageContentData, subpageRoute)]]" - restamp> - <div class="separator"></div> - </template> - - <template is="dom-if" - if="[[!isFeatureAllowedByPolicy(feature, pageContentData)]]" - restamp> - <cr-policy-indicator indicator-type="userPolicy"></cr-policy-indicator> - </template> - <div class="margin-matches-padding" aria-labelledby="featureName" - aria-describedby="featureSecondary"> - <!-- The aria-labelledby and aria-describedby are used by custom slotted - content, without which ChromeVox will not announce the #featureName - or #featureSummary. Note that the default slotted content still needs - their own aria-labelledby and aria-describedby attributes. --> - <slot name="feature-controller"> - <!-- This settings-multidevice-feature-toggle is the default - controller. If an element with slot="feature-controller" is attached, - it will replace this one. --> - <settings-multidevice-feature-toggle - aria-labelledby="featureName" - aria-describedby="featureSecondary" - feature="[[feature]]" - page-content-data="[[pageContentData]]"> - </settings-multidevice-feature-toggle> - </slot> - </div> + #help-icon:active { + /* Still reveal tooltip on click. */ + pointer-events: none; + } +</style> +<div id="card" class="settings-box two-line no-padding"> + <div id="linkWrapper" class="link-wrapper" + actionable$="[[isRowClickable_( + feature, pageContentData, subpageRoute)]]" + on-click="handleItemClick_"> + <template is="dom-if" if="[[!isFeatureIconHidden]]"> + <slot name="icon"> + <iron-icon id="feature-icon" icon="[[getIconName(feature)]]" + aria-hidden="true"> + </iron-icon> + </slot> + </template> + <div id="item-text-container" + class$="[[getItemTextContainerClassName_(isFeatureIconHidden)]]" + aria-hidden="true"> + <slot name="feature-name"> + <div id="featureName">[[getFeatureName(feature)]]</div> + </slot> + <slot name="feature-summary"> + <localized-link + class="secondary" + id="featureSecondary" + localized-string="[[getFeatureSummaryHtml(feature)]]"> + </localized-link> + </slot> </div> + <template is="dom-if" + if="[[hasSubpageClickHandler_(feature, pageContentData, + subpageRoute)]]" + restamp> + <cr-icon-button id="subpageButton" class="subpage-arrow" + aria-labelledby="featureName" aria-describedby="featureSecondary" + aria-roledescription="$i18n{subpageArrowRoleDescription}"> + </cr-icon-button> + </template> + <template is="dom-if" if="[[iconTooltip]]" restamp> + <iron-icon id="help-icon" tabindex="0" icon="[[icon]]" + aria-labelledby="tooltip"> + </iron-icon> + <paper-tooltip id="tooltip" for="help-icon" position="top" + aria-hidden="true" fit-to-visible-bounds> + [[iconTooltip]] + </paper-tooltip> + </template> + </div> + <template is="dom-if" + if="[[shouldShowSeparator_( + feature, pageContentData, subpageRoute)]]" + restamp> + <div class="separator"></div> </template> - <script src="multidevice_feature_item.js"></script> -</dom-module> + + <template is="dom-if" + if="[[!isFeatureAllowedByPolicy(feature, pageContentData)]]" + restamp> + <cr-policy-indicator indicator-type="userPolicy"></cr-policy-indicator> + </template> + <div class="margin-matches-padding" aria-labelledby="featureName" + aria-describedby="featureSecondary"> + <!-- The aria-labelledby and aria-describedby are used by custom slotted + content, without which ChromeVox will not announce the #featureName + or #featureSummary. Note that the default slotted content still needs + their own aria-labelledby and aria-describedby attributes. --> + <slot name="feature-controller"> + <!-- This settings-multidevice-feature-toggle is the default + controller. If an element with slot="feature-controller" is attached, + it will replace this one. --> + <settings-multidevice-feature-toggle + aria-labelledby="featureName" + aria-describedby="featureSecondary" + feature="[[feature]]" + page-content-data="[[pageContentData]]"> + </settings-multidevice-feature-toggle> + </slot> + </div> +</div>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.js index 1bf9d9b..cf2e9faf 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.js
@@ -2,6 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; +import '//resources/cr_elements/shared_vars_css.m.js'; +import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; +import '../../settings_shared_css.js'; +import '//resources/cr_components/localized_link/localized_link.js'; +import './multidevice_feature_toggle.js'; + +import {assert} from '//resources/js/assert.m.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {Route, Router} from '../../router.js'; +import {routes} from '../os_route.m.js'; +import {RouteOriginBehavior} from '../route_origin_behavior.m.js'; + +import {MultiDeviceFeature} from './multidevice_constants.js'; +import {MultiDeviceFeatureBehavior} from './multidevice_feature_behavior.js'; + /** * @fileoverview * Item for an individual multidevice feature. These features appear in the @@ -11,19 +28,20 @@ * feature's autonomous page if there is one. */ Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-feature-item', - behaviors: [MultiDeviceFeatureBehavior, settings.RouteOriginBehavior], + behaviors: [MultiDeviceFeatureBehavior, RouteOriginBehavior], properties: { - /** @type {!settings.MultiDeviceFeature} */ + /** @type {!MultiDeviceFeature} */ feature: Number, /** * If it is truthy, the item should be actionable and clicking on it should * navigate to the provided route. Otherwise, the item is simply not * actionable. - * @type {!settings.Route|undefined} + * @type {!Route|undefined} */ subpageRoute: Object, @@ -62,8 +80,8 @@ } }, - /** settings.RouteOriginBehavior override */ - route_: settings.routes.MULTIDEVICE_FEATURES, + /** RouteOriginBehavior override */ + route_: routes.MULTIDEVICE_FEATURES, ready() { this.addFocusConfig(this.subpageRoute, '#subpageButton'); @@ -128,8 +146,8 @@ // Remove the search term when navigating to avoid potentially having any // visible search term reappear at a later time. See // https://crbug.com/989119. - settings.Router.getInstance().navigateTo( - /** @type {!settings.Route} */ (this.subpageRoute), + Router.getInstance().navigateTo( + /** @type {!Route} */ (this.subpageRoute), this.subpageRouteUrlSearchParams, true /* opt_removeSearch */); },
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.html index ff3bacf1..37eace30 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.html
@@ -1,18 +1,6 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> -<link rel="import" href="multidevice_browser_proxy.html"> -<link rel="import" href="multidevice_constants.html"> -<link rel="import" href="multidevice_feature_behavior.html"> - -<dom-module id="settings-multidevice-feature-toggle"> - <template> - <cr-toggle id="toggle" - aria-label$="[[getToggleA11yLabel_(feature)]]" - checked="{{checked_}}" - disabled="[[!isFeatureStateEditable(feature, pageContentData)]]" - on-change="toggleFeature"> - </cr-toggle> - </template> - <script src="multidevice_feature_toggle.js"></script> -</dom-module> +<cr-toggle id="toggle" + aria-label$="[[getToggleA11yLabel_(feature)]]" + checked="{{checked_}}" + disabled="[[!isFeatureStateEditable(feature, pageContentData)]]" + on-change="toggleFeature"> +</cr-toggle>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.js index 3fbcfb7..5fd229f 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.js
@@ -2,6 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '//resources/cr_elements/cr_toggle/cr_toggle.m.js'; + +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {MultiDeviceFeature, MultiDeviceFeatureState} from './multidevice_constants.js'; +import {MultiDeviceFeatureBehavior} from './multidevice_feature_behavior.js'; + /** * @fileoverview * A toggle button specially suited for the MultiDevice Settings UI use-case. @@ -11,12 +18,13 @@ * reflects them in the toggle status. */ Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-feature-toggle', behaviors: [MultiDeviceFeatureBehavior], properties: { - /** @type {!settings.MultiDeviceFeature} */ + /** @type {!MultiDeviceFeature} */ feature: Number, toggleAriaLabel: String, @@ -63,14 +71,14 @@ */ resetChecked_() { // If Phone Hub notification access is prohibited, the toggle is always off. - if (this.feature === settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS && + if (this.feature === MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS && this.isPhoneHubNotificationAccessProhibited()) { this.checked_ = false; return; } this.checked_ = this.getFeatureState(this.feature) === - settings.MultiDeviceFeatureState.ENABLED_BY_USER; + MultiDeviceFeatureState.ENABLED_BY_USER; }, /**
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html index 4d3240f..17ed8019 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html
@@ -1,172 +1,152 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> +<style include="cr-shared-style settings-shared"> + :host { + --cr-dialog-font-family: 'Google Sans'; + --cr-dialog-title-font-size: 16px; + } -<link rel="import" href="chrome://resources/html/assert.html"> -<link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="multidevice_browser_proxy.html"> -<link rel="import" href="multidevice_constants.html"> -<link rel="import" href="chrome://resources/cr_components/localized_link/localized_link.html"> -<link rel="import" href="../os_icons.html"> -<link rel="import" href="../../settings_shared_css.html"> + cr-dialog::part(dialog) { + width: 512px; + } -<dom-module id="settings-multidevice-notification-access-setup-dialog"> - <template> - <style include="cr-shared-style settings-shared"> - :host { - --cr-dialog-font-family: 'Google Sans'; - --cr-dialog-title-font-size: 16px; - } + div[slot='title'] { + flex-direction: column; + height: auto; + } - cr-dialog::part(dialog) { - width: 512px; - } + div[slot='body'] { + align-items: center; + display: flex; + flex-direction: column; + height: auto; + justify-content: center; + width: 464px; + } - div[slot='title'] { - flex-direction: column; - height: auto; - } + iron-icon { + --iron-icon-fill-color: var(--cros-icon-color-alert); + padding-bottom: 13px; + } - div[slot='body'] { - align-items: center; - display: flex; - flex-direction: column; - height: auto; - justify-content: center; - width: 464px; - } + #description { + display: flex; + flex-direction: column; + gap: 12px; + } - iron-icon { - --iron-icon-fill-color: var(--cros-icon-color-alert); - padding-bottom: 13px; - } + :host(:not([did-setup-attempt-fail_])) #description { + /* Larger height to account for the lack of #failureIcon */ + height: 93px; + } - #description { - display: flex; - flex-direction: column; - gap: 12px; - } + :host([did-setup-attempt-fail_]) #description { + /* Smaller height to account for the presence of #failureIcon */ + height: 60px; + } - :host(:not([did-setup-attempt-fail_])) #description { - /* Larger height to account for the lack of #failureIcon */ - height: 93px; - } + #illustration { + background-position: center center; + background-repeat: no-repeat; + background-size: contain; + height: 200px; + margin-bottom: 24px; + margin-top: 24px; + width: 100%; + } - :host([did-setup-attempt-fail_]) #description { - /* Smaller height to account for the presence of #failureIcon */ - height: 60px; - } + :host([has-not-started-setup-attempt_]) #illustration { + background-image: + url(chrome://os-settings/images/notification_access_setup.svg); + } - #illustration { - background-position: center center; - background-repeat: no-repeat; - background-size: contain; - height: 200px; - margin-bottom: 24px; - margin-top: 24px; - width: 100%; - } + :host([is-setup-attempt-in-progress_]) #illustration { + background-image: + url(chrome://os-settings/images/notification_access_connecting.svg); + } - :host([has-not-started-setup-attempt_]) #illustration { - background-image: - url(chrome://os-settings/images/notification_access_setup.svg); - } + :host([did-setup-attempt-fail_]) #illustration { + background-image: + url(chrome://os-settings/images/notification_access_error.svg); + } - :host([is-setup-attempt-in-progress_]) #illustration { - background-image: - url(chrome://os-settings/images/notification_access_connecting.svg); - } + :host([has-completed-setup-successfully_]) #illustration { + background-image: + url(chrome://os-settings/images/notification_access_finished.svg); + } - :host([did-setup-attempt-fail_]) #illustration { - background-image: - url(chrome://os-settings/images/notification_access_error.svg); - } + @media(prefers-color-scheme: dark) { + :host([has-not-started-setup-attempt_]) #illustration { + background-image: url( + chrome://os-settings/images/notification_access_setup_dark.svg); + } - :host([has-completed-setup-successfully_]) #illustration { - background-image: - url(chrome://os-settings/images/notification_access_finished.svg); - } + :host([is-setup-attempt-in-progress_]) #illustration { + background-image: url( + chrome://os-settings/images/notification_access_connecting_dark.svg); + } - @media(prefers-color-scheme: dark) { - :host([has-not-started-setup-attempt_]) #illustration { - background-image: url( - chrome://os-settings/images/notification_access_setup_dark.svg); - } + :host([did-setup-attempt-fail_]) #illustration { + background-image: url( + chrome://os-settings/images/notification_access_error_dark.svg); + } - :host([is-setup-attempt-in-progress_]) #illustration { - background-image: url( - chrome://os-settings/images/notification_access_connecting_dark.svg); - } - - :host([did-setup-attempt-fail_]) #illustration { - background-image: url( - chrome://os-settings/images/notification_access_error_dark.svg); - } - - :host([has-completed-setup-successfully_]) #illustration { - background-image: url( - chrome://os-settings/images/notification_access_finished_dark.svg); - } - } - </style> - <cr-dialog id="dialog" close-text="$i18n{close}"> - <div id="dialogTitle" slot="title"> - <template is="dom-if" if="[[didSetupAttemptFail_]]" restamp> - <iron-icon id="failureIcon" icon="os-settings:failure-alert"> - </iron-icon> - </template> - <div id="title">[[title_]]</div> + :host([has-completed-setup-successfully_]) #illustration { + background-image: url( + chrome://os-settings/images/notification_access_finished_dark.svg); + } + } +</style> +<cr-dialog id="dialog" close-text="$i18n{close}"> + <div id="dialogTitle" slot="title"> + <template is="dom-if" if="[[didSetupAttemptFail_]]" restamp> + <iron-icon id="failureIcon" icon="os-settings:failure-alert"> + </iron-icon> + </template> + <div id="title">[[title_]]</div> + </div> + <div id="dialogBody" slot="body"> + <div id="illustration"></div> + <div id="description"> + <template is="dom-if" if="[[description_]]" restamp> + <localized-link localized-string="[[description_]]"> + </localized-link> + </template> + <div hidden="[[!shouldShowSetupInstructionsSeparately_]]"> + $i18n{multideviceNotificationAccessSetupInstructions} </div> - <div id="dialogBody" slot="body"> - <div id="illustration"></div> - <div id="description"> - <template is="dom-if" if="[[description_]]" restamp> - <localized-link localized-string="[[description_]]"> - </localized-link> - </template> - <div hidden="[[!shouldShowSetupInstructionsSeparately_]]"> - $i18n{multideviceNotificationAccessSetupInstructions} - </div> - </div> - </div> - <div id="buttonContainer" slot="button-container"> - <template is="dom-if" if="[[shouldShowCancelButton_(setupState_)]]" - restamp> - <cr-button id="cancelButton" class="cancel-button" - on-click="onCancelClicked_"> - $i18n{cancel} - </cr-button> - </template> - <template is="dom-if" if="[[hasCompletedSetupSuccessfully_]]" restamp> - <cr-button id="doneButton" class="action-button" - on-click="onDoneOrCloseButtonClicked_"> - $i18n{done} - </cr-button> - </template> - <template is="dom-if" if="[[isNotificationAccessProhibited_]]" restamp> - <cr-button id="closeButton" class="action-button" - on-click="onDoneOrCloseButtonClicked_"> - $i18n{close} - </cr-button> - </template> - <template is="dom-if" if="[[hasNotStartedSetupAttempt_]]" restamp> - <cr-button id="getStartedButton" class="action-button" - on-click="attemptNotificationSetup_"> - $i18n{multideviceNotificationAccessSetupGetStarted} - </cr-button> - </template> - <template is="dom-if" if="[[shouldShowTryAgainButton_(setupState_)]]" - restamp> - <cr-button id="tryAgainButton" class="action-button" - on-click="attemptNotificationSetup_"> - $i18n{multideviceNotificationAccessSetupTryAgain} - </cr-button> - </template> - </div> - </cr-dialog> - </template> - <script src="multidevice_notification_access_setup_dialog.js"></script> -</dom-module> + </div> + </div> + <div id="buttonContainer" slot="button-container"> + <template is="dom-if" if="[[shouldShowCancelButton_(setupState_)]]" + restamp> + <cr-button id="cancelButton" class="cancel-button" + on-click="onCancelClicked_"> + $i18n{cancel} + </cr-button> + </template> + <template is="dom-if" if="[[hasCompletedSetupSuccessfully_]]" restamp> + <cr-button id="doneButton" class="action-button" + on-click="onDoneOrCloseButtonClicked_"> + $i18n{done} + </cr-button> + </template> + <template is="dom-if" if="[[isNotificationAccessProhibited_]]" restamp> + <cr-button id="closeButton" class="action-button" + on-click="onDoneOrCloseButtonClicked_"> + $i18n{close} + </cr-button> + </template> + <template is="dom-if" if="[[hasNotStartedSetupAttempt_]]" restamp> + <cr-button id="getStartedButton" class="action-button" + on-click="attemptNotificationSetup_"> + $i18n{multideviceNotificationAccessSetupGetStarted} + </cr-button> + </template> + <template is="dom-if" if="[[shouldShowTryAgainButton_(setupState_)]]" + restamp> + <cr-button id="tryAgainButton" class="action-button" + on-click="attemptNotificationSetup_"> + $i18n{multideviceNotificationAccessSetupTryAgain} + </cr-button> + </template> + </div> +</cr-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js index df54590..f7fb6992 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.js
@@ -2,6 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '//resources/cr_elements/cr_button/cr_button.m.js'; +import '//resources/cr_elements/cr_dialog/cr_dialog.m.js'; +import '//resources/cr_elements/shared_style_css.m.js'; +import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; +import '//resources/cr_components/localized_link/localized_link.js'; +import '../os_icons.js'; +import '../../settings_shared_css.js'; + +import {I18nBehavior} from '//resources/js/i18n_behavior.m.js'; +import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from './multidevice_browser_proxy.js'; +import {MultiDeviceFeature} from './multidevice_constants.js'; + /** * @fileoverview * This element provides the Phone Hub notification access setup flow that, when @@ -15,7 +30,7 @@ * CONNECTION_REQUESTED. * @enum{number} */ -/* #export */ const NotificationAccessSetupOperationStatus = { +export const NotificationAccessSetupOperationStatus = { CONNECTION_REQUESTED: 0, CONNECTING: 1, TIMED_OUT_CONNECTING: 2, @@ -26,6 +41,7 @@ }; Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-notification-access-setup-dialog', behaviors: [ @@ -98,12 +114,12 @@ }, }, - /** @private {?settings.MultiDeviceBrowserProxy} */ + /** @private {?MultiDeviceBrowserProxy} */ browserProxy_: null, /** @override */ ready() { - this.browserProxy_ = settings.MultiDeviceBrowserProxyImpl.getInstance(); + this.browserProxy_ = MultiDeviceBrowserProxyImpl.getInstance(); }, /** @override */ @@ -123,7 +139,7 @@ if (this.setupState_ === NotificationAccessSetupOperationStatus.COMPLETED_SUCCESSFULLY) { this.browserProxy_.setFeatureEnabledState( - settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, true); + MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, true); } },
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html index 077d679..96c37f5 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html
@@ -1,253 +1,215 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> -<link rel="import" href="chrome://resources/html/assert.html"> -<link rel="import" href="chrome://resources/html/cr.html"> -<link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="../../i18n_setup.html"> -<link rel="import" href="../deep_linking_behavior.html"> -<link rel="import" href="../os_route.html"> -<link rel="import" href="../../router.html"> -<link rel="import" href="../route_observer_behavior.html"> -<link rel="import" href="../../controls/password_prompt_dialog.html"> -<link rel="import" href="../../settings_page/settings_animated_pages.html"> -<link rel="import" href="../../settings_page/settings_subpage.html"> -<link rel="import" href="../prefs_behavior.html"> -<link rel="import" href="../../settings_shared_css.html"> -<link rel="import" href="../nearby_share_page/nearby_share_subpage.html"> -<link rel="import" href="../../shared/nearby_share_settings_behavior.html"> -<link rel="import" href="chrome://resources/cr_components/localized_link/localized_link.html"> -<link rel="import" href="../metrics_recorder.html"> -<link rel="import" href="multidevice_browser_proxy.html"> -<link rel="import" href="multidevice_constants.html"> -<link rel="import" href="multidevice_feature_behavior.html"> -<link rel="import" href="multidevice_feature_toggle.html"> -<link rel="import" href="multidevice_notification_access_setup_dialog.html"> -<link rel="import" href="multidevice_permissions_setup_dialog.html"> -<link rel="import" href="multidevice_smartlock_subpage.html"> -<link rel="import" href="multidevice_subpage.html"> - -<dom-module id="settings-multidevice-page"> - <template> - <style include="settings-shared"> - cr-policy-indicator { - padding: 0 var(--cr-controlled-by-spacing); - } - </style> - <settings-animated-pages id="pages" section="multidevice" - focus-config="[[focusConfig_]]"> - <div route-path="default"> - <div id="multidevice-item" - class="settings-box first two-line no-padding"> - <div class="link-wrapper" id="suiteLinkWrapper" - actionable$="[[doesClickOpenSubpage_(pageContentData)]]" - on-click="handleItemClick_"> - <iron-icon icon= - "[[getIconName(MultiDeviceFeature.BETTER_TOGETHER_SUITE)]]" - id="betterTogetherSuiteIcon"> - </iron-icon> - <div class="middle settings-box-text" - aria-hidden$="[[getTextAriaHidden_(pageContentData)]]"> - <div id="multidevice-label"> - [[getLabelText_(pageContentData)]] - </div> - <localized-link id="multideviceSubLabel" - class="secondary" - localized-string="[[getSubLabelInnerHtml_(pageContentData)]]"> - </localized-link> - </div> - <template is="dom-if" - if="[[doesClickOpenSubpage_(pageContentData)]]" - restamp> - <cr-icon-button class="subpage-arrow" - aria-labelledby="multidevice-label" - aria-describedby="multideviceSubLabel" - aria-roledescription="$i18n{subpageArrowRoleDescription}"> - </cr-icon-button> - </template> +<style include="settings-shared"> + cr-policy-indicator { + padding: 0 var(--cr-controlled-by-spacing); + } +</style> +<settings-animated-pages id="pages" section="multidevice" + focus-config="[[focusConfig_]]"> + <div route-path="default"> + <div id="multidevice-item" + class="settings-box first two-line no-padding"> + <div class="link-wrapper" id="suiteLinkWrapper" + actionable$="[[doesClickOpenSubpage_(pageContentData)]]" + on-click="handleItemClick_"> + <iron-icon icon= + "[[getIconName(MultiDeviceFeature.BETTER_TOGETHER_SUITE)]]" + id="betterTogetherSuiteIcon"> + </iron-icon> + <div class="middle settings-box-text" + aria-hidden$="[[getTextAriaHidden_(pageContentData)]]"> + <div id="multidevice-label"> + [[getLabelText_(pageContentData)]] </div> - <template is="dom-if" - if="[[!isSuiteAllowedByPolicy(pageContentData)]]" - restamp> - <cr-policy-indicator id="suitePolicyIndicator" - indicator-type="userPolicy"> - </cr-policy-indicator> - <settings-multidevice-feature-toggle - class="margin-matches-padding" - toggle-aria-label="$i18n{multideviceSuiteToggleA11yLabel}" - feature="[[MultiDeviceFeature.BETTER_TOGETHER_SUITE]]" - page-content-data="[[pageContentData]]" - deep-link-focus-id$="[[Setting.kMultiDeviceOnOff]]"> - </settings-multidevice-feature-toggle> - </template> - <template is="dom-if" - if="[[shouldShowSeparatorAndSubpageArrow_(pageContentData)]]" - restamp> - <div class="separator"></div> - </template> - <template is="dom-if" - if="[[shouldShowButton_(pageContentData)]]" - restamp> - <cr-button class="margin-matches-padding" - on-click="handleButtonClick_" - aria-describedby="multideviceSubLabel" - deep-link-focus-id$="[[Setting.kSetUpMultiDevice]] - [[Setting.kVerifyMultiDeviceSetup]]"> - [[getButtonText_(pageContentData)]] - </cr-button> - </template> - <template is="dom-if" - if="[[shouldShowToggle_(pageContentData)]]" - restamp> - <settings-multidevice-feature-toggle - class="margin-matches-padding" - toggle-aria-label="$i18n{multideviceSuiteToggleA11yLabel}" - feature="[[MultiDeviceFeature.BETTER_TOGETHER_SUITE]]" - page-content-data="[[pageContentData]]" - deep-link-focus-id$="[[Setting.kMultiDeviceOnOff]]"> - </settings-multidevice-feature-toggle> - </template> + <localized-link id="multideviceSubLabel" + class="secondary" + localized-string="[[getSubLabelInnerHtml_(pageContentData)]]"> + </localized-link> </div> - <template is="dom-if" if="[[isNearbyShareSupported_]]" restamp> - <div id="nearbyshare-item" class="settings-box two-line no-padding"> - <div class="link-wrapper" id="nearbyLinkWrapper" - actionable$= - "[[!isNearbyShareDisallowedByPolicy_(pageContentData)]]" - on-click="nearbyShareClick_"> - <iron-icon icon="os-settings:nearby-share"> - </iron-icon> - <div id="nearbyShareLabel" class="middle settings-box-text"> - <div aria-hidden="true"> - $i18n{nearbyShareTitle} - </div> - <template is="dom-if" if="[[showNearbyShareOnOffString_( - prefs.nearby_sharing.onboarding_complete.value, - pageContentData)]]" restamp> - <div class="secondary" id="nearbyShareSecondary"> - [[getOnOffString_(prefs.nearby_sharing.enabled.value, - '$i18nPolymer{deviceOn}', '$i18nPolymer{deviceOff}')]] - </div> - </template> - <template is="dom-if" if="[[showNearbyShareDescription_( - prefs.nearby_sharing.onboarding_complete.value, - pageContentData)]]" restamp> - <div class="secondary" id="nearbyShareSecondary"> - <localized-link - localized-string="$i18n{nearbyShareDescription}" - link-url="$i18n{nearbyShareLearnMoreLink}"> - </localized-link> - </div> - </template> - </div> - <template is="dom-if" if="[[shouldShowNearbyShareSubpageArrow_( - prefs.nearby_sharing.enabled.value, - shouldEnableNearbyShareBackgroundScanningRevamp_, - pageContentData)]]" restamp> - <cr-icon-button id="nearbyShareSubpageArrow" - class="subpage-arrow" - aria-labelledby="nearbyShareLabel" - aria-describedby="nearbyShareSecondary" - aria-roledescription="$i18n{subpageArrowRoleDescription}"> - </cr-icon-button> - </template> - </div> - <template is="dom-if" - if="[[isNearbyShareDisallowedByPolicy_(pageContentData)]]" - restamp> - <cr-policy-indicator id="nearbyPolicyIndicator" - indicator-type="userPolicy"> - </cr-policy-indicator> - </template> - <template is="dom-if" - if="[[!isNearbyShareDisallowedByPolicy_(pageContentData)]]" - restamp> - <div class="separator"></div> - </template> - <template is="dom-if" if="[[showNearbyShareToggle_( - prefs.nearby_sharing.onboarding_complete.value, - pageContentData)]]" restamp> - <cr-toggle id="nearbySharingToggleButton" - class="margin-matches-padding" - aria-label="$i18n{nearbyShareTitle}" - checked="{{prefs.nearby_sharing.enabled.value}}" - disabled= - "[[isNearbyShareDisallowedByPolicy_(pageContentData)]]" - deep-link-focus-id$="[[Setting.kNearbyShareOnOff]]"> - </cr-toggle> - </template> - <template is="dom-if" if="[[showNearbyShareSetupButton_( - prefs.nearby_sharing.onboarding_complete.value, - pageContentData)]]" restamp> - <cr-button class="margin-matches-padding" - id="nearbySetUp" - on-click="handleNearbySetUpClick_" - disabled= - "[[isNearbyShareDisallowedByPolicy_(pageContentData)]]"> - $i18n{nearbyShareSetUpButtonTitle} - </cr-button> - </template> - </div> + <template is="dom-if" + if="[[doesClickOpenSubpage_(pageContentData)]]" + restamp> + <cr-icon-button class="subpage-arrow" + aria-labelledby="multidevice-label" + aria-describedby="multideviceSubLabel" + aria-roledescription="$i18n{subpageArrowRoleDescription}"> + </cr-icon-button> </template> </div> - <template is="dom-if" route-path="/multidevice/features" restamp> - <settings-subpage page-title="[[getLabelText_(pageContentData)]]"> - <settings-multidevice-subpage - page-content-data="[[pageContentData]]"> - </settings-multidevice-subpage> - </settings-subpage> + <template is="dom-if" + if="[[!isSuiteAllowedByPolicy(pageContentData)]]" + restamp> + <cr-policy-indicator id="suitePolicyIndicator" + indicator-type="userPolicy"> + </cr-policy-indicator> + <settings-multidevice-feature-toggle + class="margin-matches-padding" + toggle-aria-label="$i18n{multideviceSuiteToggleA11yLabel}" + feature="[[MultiDeviceFeature.BETTER_TOGETHER_SUITE]]" + page-content-data="[[pageContentData]]" + deep-link-focus-id$="[[Setting.kMultiDeviceOnOff]]"> + </settings-multidevice-feature-toggle> </template> - <template is="dom-if" route-path="/multidevice/features/smartLock" + <template is="dom-if" + if="[[shouldShowSeparatorAndSubpageArrow_(pageContentData)]]" restamp> - <settings-subpage page-title="$i18n{easyUnlockSectionTitle}"> - <settings-multidevice-smartlock-subpage - prefs="{{prefs}}" - page-content-data="[[pageContentData]]"> - </settings-multidevice-smartlock-subpage> - </settings-subpage> + <div class="separator"></div> </template> - <template is="dom-if" if="[[isNearbyShareSupported_]]" restamp> - <template is="dom-if" route-path="/multidevice/nearbyshare" restamp> - <settings-subpage page-title="$i18n{nearbyShareTitle}"> - <settings-nearby-share-subpage settings="{{settings}}" - prefs="{{prefs}}" - is-settings-retreived="[[isSettingsRetreived]]"> - </settings-nearby-share-subpage> - </settings-subpage> + <template is="dom-if" + if="[[shouldShowButton_(pageContentData)]]" + restamp> + <cr-button class="margin-matches-padding" + on-click="handleButtonClick_" + aria-describedby="multideviceSubLabel" + deep-link-focus-id$="[[Setting.kSetUpMultiDevice]] + [[Setting.kVerifyMultiDeviceSetup]]"> + [[getButtonText_(pageContentData)]] + </cr-button> + </template> + <template is="dom-if" + if="[[shouldShowToggle_(pageContentData)]]" + restamp> + <settings-multidevice-feature-toggle + class="margin-matches-padding" + toggle-aria-label="$i18n{multideviceSuiteToggleA11yLabel}" + feature="[[MultiDeviceFeature.BETTER_TOGETHER_SUITE]]" + page-content-data="[[pageContentData]]" + deep-link-focus-id$="[[Setting.kMultiDeviceOnOff]]"> + </settings-multidevice-feature-toggle> + </template> + </div> + <template is="dom-if" if="[[isNearbyShareSupported_]]" restamp> + <div id="nearbyshare-item" class="settings-box two-line no-padding"> + <div class="link-wrapper" id="nearbyLinkWrapper" + actionable$= + "[[!isNearbyShareDisallowedByPolicy_(pageContentData)]]" + on-click="nearbyShareClick_"> + <iron-icon icon="os-settings:nearby-share"> + </iron-icon> + <div id="nearbyShareLabel" class="middle settings-box-text"> + <div aria-hidden="true"> + $i18n{nearbyShareTitle} + </div> + <template is="dom-if" if="[[showNearbyShareOnOffString_( + prefs.nearby_sharing.onboarding_complete.value, + pageContentData)]]" restamp> + <div class="secondary" id="nearbyShareSecondary"> + [[getOnOffString_(prefs.nearby_sharing.enabled.value, + '$i18nPolymer{deviceOn}', '$i18nPolymer{deviceOff}')]] + </div> + </template> + <template is="dom-if" if="[[showNearbyShareDescription_( + prefs.nearby_sharing.onboarding_complete.value, + pageContentData)]]" restamp> + <div class="secondary" id="nearbyShareSecondary"> + <localized-link + localized-string="$i18n{nearbyShareDescription}" + link-url="$i18n{nearbyShareLearnMoreLink}"> + </localized-link> + </div> + </template> + </div> + <template is="dom-if" if="[[shouldShowNearbyShareSubpageArrow_( + prefs.nearby_sharing.enabled.value, + shouldEnableNearbyShareBackgroundScanningRevamp_, + pageContentData)]]" restamp> + <cr-icon-button id="nearbyShareSubpageArrow" + class="subpage-arrow" + aria-labelledby="nearbyShareLabel" + aria-describedby="nearbyShareSecondary" + aria-roledescription="$i18n{subpageArrowRoleDescription}"> + </cr-icon-button> + </template> + </div> + <template is="dom-if" + if="[[isNearbyShareDisallowedByPolicy_(pageContentData)]]" + restamp> + <cr-policy-indicator id="nearbyPolicyIndicator" + indicator-type="userPolicy"> + </cr-policy-indicator> </template> - </template> - </settings-animated-pages> - <template is="dom-if" if="[[showPasswordPromptDialog_]]" restamp> - <settings-password-prompt-dialog id="multidevicePasswordPrompt" - on-token-obtained="onTokenObtained_"> - </settings-password-prompt-dialog> + <template is="dom-if" + if="[[!isNearbyShareDisallowedByPolicy_(pageContentData)]]" + restamp> + <div class="separator"></div> + </template> + <template is="dom-if" if="[[showNearbyShareToggle_( + prefs.nearby_sharing.onboarding_complete.value, + pageContentData)]]" restamp> + <cr-toggle id="nearbySharingToggleButton" + class="margin-matches-padding" + aria-label="$i18n{nearbyShareTitle}" + checked="{{prefs.nearby_sharing.enabled.value}}" + disabled= + "[[isNearbyShareDisallowedByPolicy_(pageContentData)]]" + deep-link-focus-id$="[[Setting.kNearbyShareOnOff]]"> + </cr-toggle> + </template> + <template is="dom-if" if="[[showNearbyShareSetupButton_( + prefs.nearby_sharing.onboarding_complete.value, + pageContentData)]]" restamp> + <cr-button class="margin-matches-padding" + id="nearbySetUp" + on-click="handleNearbySetUpClick_" + disabled= + "[[isNearbyShareDisallowedByPolicy_(pageContentData)]]"> + $i18n{nearbyShareSetUpButtonTitle} + </cr-button> + </template> + </div> </template> - <template is="dom-if" if="[[showPermissionsSetupDialog_( - showPhonePermissionSetupDialog_)]]" - restamp> - <settings-multidevice-notification-access-setup-dialog - is-password-dialog-showing="{{isPasswordDialogShowing_}}" - on-close="onHidePhonePermissionsSetupDialog_"> - </settings-multidevice-notification-access-setup-dialog> - </template> - <template is="dom-if" - if="[[showNewPermissionsSetupDialog_( - showPhonePermissionSetupDialog_)]]" - restamp> - <settings-multidevice-permissions-setup-dialog - is-password-dialog-showing="{{isPasswordDialogShowing_}}" - show-camera-roll="[[isPhoneHubCameraRollSetupRequired( - pageContentData)]]" - show-notifications="[[isPhoneHubNotificationsSetupRequired( - pageContentData)]]" - show-app-streaming="[[isPhoneHubAppsSetupRequired( - pageContentData)]]" - on-close="onHidePhonePermissionsSetupDialog_"> - </settings-multidevice-permissions-setup-dialog> + </div> + <template is="dom-if" route-path="/multidevice/features" restamp> + <settings-subpage page-title="[[getLabelText_(pageContentData)]]"> + <settings-multidevice-subpage + page-content-data="[[pageContentData]]"> + </settings-multidevice-subpage> + </settings-subpage> + </template> + <template is="dom-if" route-path="/multidevice/features/smartLock" + restamp> + <settings-subpage page-title="$i18n{easyUnlockSectionTitle}"> + <settings-multidevice-smartlock-subpage + prefs="{{prefs}}" + page-content-data="[[pageContentData]]"> + </settings-multidevice-smartlock-subpage> + </settings-subpage> + </template> + <template is="dom-if" if="[[isNearbyShareSupported_]]" restamp> + <template is="dom-if" route-path="/multidevice/nearbyshare" restamp> + <settings-subpage page-title="$i18n{nearbyShareTitle}"> + <settings-nearby-share-subpage settings="{{settings}}" + prefs="{{prefs}}" + is-settings-retreived="[[isSettingsRetreived]]"> + </settings-nearby-share-subpage> + </settings-subpage> </template> </template> - <script src="multidevice_page.js"></script> -</dom-module> +</settings-animated-pages> +<template is="dom-if" if="[[showPasswordPromptDialog_]]" restamp> + <settings-password-prompt-dialog id="multidevicePasswordPrompt" + on-token-obtained="onTokenObtained_"> + </settings-password-prompt-dialog> +</template> +<template is="dom-if" if="[[showPermissionsSetupDialog_( + showPhonePermissionSetupDialog_)]]" + restamp> + <settings-multidevice-notification-access-setup-dialog + is-password-dialog-showing="{{isPasswordDialogShowing_}}" + on-close="onHidePhonePermissionsSetupDialog_"> + </settings-multidevice-notification-access-setup-dialog> +</template> +<template is="dom-if" + if="[[showNewPermissionsSetupDialog_( + showPhonePermissionSetupDialog_)]]" + restamp> + <settings-multidevice-permissions-setup-dialog + is-password-dialog-showing="{{isPasswordDialogShowing_}}" + show-camera-roll="[[isPhoneHubCameraRollSetupRequired( + pageContentData)]]" + show-notifications="[[isPhoneHubNotificationsSetupRequired( + pageContentData)]]" + show-app-streaming="[[isPhoneHubAppsSetupRequired( + pageContentData)]]" + on-close="onHidePhonePermissionsSetupDialog_"> + </settings-multidevice-permissions-setup-dialog> +</template>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js index 003d8e2..6660c982 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.js
@@ -2,13 +2,46 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '//resources/cr_elements/cr_button/cr_button.m.js'; +import '//resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; +import '//resources/cr_elements/cr_toggle/cr_toggle.m.js'; +import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; +import '../../controls/password_prompt_dialog.js'; +import '../../settings_page/settings_animated_pages.js'; +import '../../settings_page/settings_subpage.js'; +import '../../settings_shared_css.js'; +import '../nearby_share_page/nearby_share_subpage.js'; +import '//resources/cr_components/localized_link/localized_link.js'; +import './multidevice_feature_toggle.js'; +import './multidevice_notification_access_setup_dialog.js'; +import './multidevice_permissions_setup_dialog.js'; +import './multidevice_smartlock_subpage.js'; +import './multidevice_subpage.js'; + +import {assert, assertNotReached} from '//resources/js/assert.m.js'; +import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js'; +import {beforeNextRender, html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {loadTimeData} from '../../i18n_setup.js'; +import {Route, Router} from '../../router.js'; +import {NearbyShareSettingsBehavior} from '../../shared/nearby_share_settings_behavior.m.js'; +import {DeepLinkingBehavior} from '../deep_linking_behavior.js'; +import {recordSettingChange} from '../metrics_recorder.m.js'; +import {routes} from '../os_route.m.js'; +import {PrefsBehavior} from '../prefs_behavior.js'; +import {RouteObserverBehavior} from '../route_observer_behavior.js'; + +import {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from './multidevice_browser_proxy.js'; +import {MultiDeviceFeature, MultiDeviceFeatureState, MultiDevicePageContentData, MultiDeviceSettingsMode, PhoneHubFeatureAccessStatus} from './multidevice_constants.js'; +import {MultiDeviceFeatureBehavior} from './multidevice_feature_behavior.js'; + Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-page', behaviors: [ - DeepLinkingBehavior, settings.RouteObserverBehavior, - MultiDeviceFeatureBehavior, WebUIListenerBehavior, PrefsBehavior, - nearby_share.NearbyShareSettingsBehavior + DeepLinkingBehavior, RouteObserverBehavior, MultiDeviceFeatureBehavior, + WebUIListenerBehavior, PrefsBehavior, NearbyShareSettingsBehavior ], properties: { @@ -17,7 +50,7 @@ /** * A Map specifying which element should be focused when exiting a subpage. - * The key of the map holds a settings.Route path, and the value holds a + * The key of the map holds a Route path, and the value holds a * query selector that identifies the desired element. * @private {!Map<string, string>} */ @@ -25,9 +58,9 @@ type: Object, value() { const map = new Map(); - if (settings.routes.MULTIDEVICE_FEATURES) { + if (routes.MULTIDEVICE_FEATURES) { map.set( - settings.routes.MULTIDEVICE_FEATURES.path, + routes.MULTIDEVICE_FEATURES.path, '#multidevice-item .subpage-arrow'); } return map; @@ -48,7 +81,7 @@ * required. This value is initialized to null, is set when the password * dialog is opened, and is reset to null again once the password dialog is * closed. - * @private {?settings.MultiDeviceFeature} + * @private {?MultiDeviceFeature} */ featureToBeEnabledOnceAuthenticated_: { type: Number, @@ -123,12 +156,12 @@ 'permission-setup-requested': 'onPermissionSetupRequested_', }, - /** @private {?settings.MultiDeviceBrowserProxy} */ + /** @private {?MultiDeviceBrowserProxy} */ browserProxy_: null, /** @override */ ready() { - this.browserProxy_ = settings.MultiDeviceBrowserProxyImpl.getInstance(); + this.browserProxy_ = MultiDeviceBrowserProxyImpl.getInstance(); this.addWebUIListener( 'settings.updateMultidevicePageContentData', @@ -139,23 +172,23 @@ }, /** - * Overridden from nearby_share.NearbyShareSettingsBehavior. + * Overridden from NearbyShareSettingsBehavior. */ onSettingsRetrieved() { this.isSettingsRetreived = true; }, /** - * Overridden from settings.RouteObserverBehavior. - * @param {!settings.Route} route - * @param {!settings.Route} oldRoute + * Overridden from RouteObserverBehavior. + * @param {!Route} route + * @param {!Route} oldRoute * @protected */ currentRouteChanged(route, oldRoute) { this.leaveNestedPageIfNoHostIsSet_(); // Does not apply to this page. - if (route !== settings.routes.MULTIDEVICE) { + if (route !== routes.MULTIDEVICE) { return; } @@ -180,13 +213,13 @@ return this.i18nAdvanced('multideviceSetupSummary'); } switch (this.pageContentData.mode) { - case settings.MultiDeviceSettingsMode.NO_ELIGIBLE_HOSTS: + case MultiDeviceSettingsMode.NO_ELIGIBLE_HOSTS: return this.i18nAdvanced('multideviceNoHostText'); - case settings.MultiDeviceSettingsMode.NO_HOST_SET: + case MultiDeviceSettingsMode.NO_HOST_SET: return this.i18nAdvanced('multideviceSetupSummary'); - case settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER: + case MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER: // Intentional fall-through. - case settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION: + case MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION: return this.i18nAdvanced('multideviceVerificationText'); default: return this.isSuiteOn() ? this.i18n('multideviceEnabled') : @@ -200,11 +233,11 @@ */ getButtonText_() { switch (this.pageContentData.mode) { - case settings.MultiDeviceSettingsMode.NO_HOST_SET: + case MultiDeviceSettingsMode.NO_HOST_SET: return this.i18n('multideviceSetupButton'); - case settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER: + case MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER: // Intentional fall-through. - case settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION: + case MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION: return this.i18n('multideviceVerifyButton'); default: return ''; @@ -223,7 +256,7 @@ // so the text is still available to assistive tools. return String( this.pageContentData.mode === - settings.MultiDeviceSettingsMode.HOST_SET_VERIFIED); + MultiDeviceSettingsMode.HOST_SET_VERIFIED); }, /** @@ -232,9 +265,9 @@ */ shouldShowButton_() { return [ - settings.MultiDeviceSettingsMode.NO_HOST_SET, - settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER, - settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION, + MultiDeviceSettingsMode.NO_HOST_SET, + MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER, + MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION, ].includes(this.pageContentData.mode); }, @@ -244,7 +277,7 @@ */ shouldShowToggle_() { return this.pageContentData.mode === - settings.MultiDeviceSettingsMode.HOST_SET_VERIFIED; + MultiDeviceSettingsMode.HOST_SET_VERIFIED; }, /** @@ -255,7 +288,7 @@ */ shouldShowSeparatorAndSubpageArrow_() { return this.pageContentData.mode !== - settings.MultiDeviceSettingsMode.NO_ELIGIBLE_HOSTS; + MultiDeviceSettingsMode.NO_ELIGIBLE_HOSTS; }, /** @@ -278,20 +311,19 @@ return; } - settings.Router.getInstance().navigateTo( - settings.routes.MULTIDEVICE_FEATURES); + Router.getInstance().navigateTo(routes.MULTIDEVICE_FEATURES); }, /** @private */ handleButtonClick_(event) { event.stopPropagation(); switch (this.pageContentData.mode) { - case settings.MultiDeviceSettingsMode.NO_HOST_SET: + case MultiDeviceSettingsMode.NO_HOST_SET: this.browserProxy_.showMultiDeviceSetupDialog(); return; - case settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER: + case MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER: // Intentional fall-through. - case settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION: + case MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION: // If this device is waiting for action on the server or the host // device, clicking the button should trigger this action. this.browserProxy_.retryPendingHostSetup(); @@ -324,7 +356,7 @@ this.browserProxy_.setFeatureEnabledState( this.featureToBeEnabledOnceAuthenticated_, true /* enabled */, this.authToken_.token); - settings.recordSettingChange(); + recordSettingChange(); // Reset |this.authToken_| now that it has been used. This ensures that // users cannot keep an old auth token and reuse it on an subsequent @@ -347,7 +379,7 @@ * authentication process. * * @param {!CustomEvent<!{ - * feature: !settings.MultiDeviceFeature, + * feature: !MultiDeviceFeature, * enabled: boolean * }>} event * @private @@ -367,13 +399,12 @@ // If the feature to enable is Phone Hub Notifications, notification access // must have been granted before the feature can be enabled. - if (feature === settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS && - enabled) { + if (feature === MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS && enabled) { switch (this.pageContentData.notificationAccessStatus) { - case settings.PhoneHubFeatureAccessStatus.PROHIBITED: + case PhoneHubFeatureAccessStatus.PROHIBITED: assertNotReached('Cannot enable notification access; prohibited'); return; - case settings.PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED: + case PhoneHubFeatureAccessStatus.AVAILABLE_BUT_NOT_GRANTED: this.showPhonePermissionSetupDialog_ = true; return; default: @@ -385,28 +416,27 @@ // Disabling any feature does not require authentication, and enable some // features does not require authentication. this.browserProxy_.setFeatureEnabledState(feature, enabled); - settings.recordSettingChange(); + recordSettingChange(); }, /** - * @param {!settings.MultiDeviceFeature} feature The feature to enable. + * @param {!MultiDeviceFeature} feature The feature to enable. * @return {boolean} Whether authentication is required to enable the feature. * @private */ isAuthenticationRequiredToEnable_(feature) { // Enabling SmartLock always requires authentication. - if (feature === settings.MultiDeviceFeature.SMART_LOCK) { + if (feature === MultiDeviceFeature.SMART_LOCK) { return true; } // Enabling any feature besides SmartLock and the Better Together suite does // not require authentication. - if (feature !== settings.MultiDeviceFeature.BETTER_TOGETHER_SUITE) { + if (feature !== MultiDeviceFeature.BETTER_TOGETHER_SUITE) { return false; } - const smartLockState = - this.getFeatureState(settings.MultiDeviceFeature.SMART_LOCK); + const smartLockState = this.getFeatureState(MultiDeviceFeature.SMART_LOCK); // If the user is enabling the Better Together suite and this change would // result in SmartLock being implicitly enabled, authentication is required. @@ -414,16 +444,16 @@ // to the suite being disabled or due to the SmartLock host device not // having a lock screen set. return smartLockState === - settings.MultiDeviceFeatureState.UNAVAILABLE_SUITE_DISABLED || + MultiDeviceFeatureState.UNAVAILABLE_SUITE_DISABLED || smartLockState === - settings.MultiDeviceFeatureState.UNAVAILABLE_INSUFFICIENT_SECURITY; + MultiDeviceFeatureState.UNAVAILABLE_INSUFFICIENT_SECURITY; }, /** @private */ onForgetDeviceRequested_() { this.browserProxy_.removeHostDevice(); - settings.recordSettingChange(); - settings.Router.getInstance().navigateTo(settings.routes.MULTIDEVICE); + recordSettingChange(); + Router.getInstance().navigateTo(routes.MULTIDEVICE); }, /** @private */ @@ -444,28 +474,25 @@ // Host status doesn't matter if we are navigating to Nearby Share // settings. - if (settings.routes.NEARBY_SHARE === - settings.Router.getInstance().getCurrentRoute()) { + if (routes.NEARBY_SHARE === Router.getInstance().getCurrentRoute()) { return; } // If the user gets to the a nested page without a host (e.g. by clicking a // stale 'existing user' notifications after forgetting their host) we // direct them back to the main settings page. - if (settings.routes.MULTIDEVICE !== - settings.Router.getInstance().getCurrentRoute() && - settings.routes.MULTIDEVICE.contains( - settings.Router.getInstance().getCurrentRoute()) && + if (routes.MULTIDEVICE !== Router.getInstance().getCurrentRoute() && + routes.MULTIDEVICE.contains(Router.getInstance().getCurrentRoute()) && !this.isHostSet()) { // Render MULTIDEVICE page before the MULTIDEVICE_FEATURES has a chance. - Polymer.RenderStatus.beforeNextRender(this, () => { - settings.Router.getInstance().navigateTo(settings.routes.MULTIDEVICE); + beforeNextRender(this, () => { + Router.getInstance().navigateTo(routes.MULTIDEVICE); }); } }, /** - * @param {!settings.MultiDevicePageContentData} newData + * @param {!MultiDevicePageContentData} newData * @private */ onInitialPageContentDataFetched_(newData) { @@ -474,14 +501,14 @@ // Show the notification access dialog if the url contains the correct // param. // Show combined access dialog with URL having param and features. - const urlParams = settings.Router.getInstance().getQueryParameters(); + const urlParams = Router.getInstance().getQueryParameters(); if (urlParams.get('showPhonePermissionSetupDialog') !== null) { this.showPhonePermissionSetupDialog_ = true; } }, /** - * @param {!settings.MultiDevicePageContentData} newData + * @param {!MultiDevicePageContentData} newData * @private */ onPageContentDataChanged_(newData) { @@ -573,7 +600,7 @@ // whether Nearby Share is on or off so that users can enable/disable the // "Nearby device is trying to share" notification. if (this.shouldEnableNearbyShareBackgroundScanningRevamp_) { - settings.Router.getInstance().navigateTo(settings.routes.NEARBY_SHARE); + Router.getInstance().navigateTo(routes.NEARBY_SHARE); return; } @@ -594,8 +621,7 @@ params.set('entrypoint', 'settings'); params.set('onboarding', ''); } - settings.Router.getInstance().navigateTo( - settings.routes.NEARBY_SHARE, params); + Router.getInstance().navigateTo(routes.NEARBY_SHARE, params); }, @@ -636,8 +662,7 @@ params.set('onboarding', ''); // Set by metrics to determine entrypoint for onboarding params.set('entrypoint', 'settings'); - settings.Router.getInstance().navigateTo( - settings.routes.NEARBY_SHARE, params); + Router.getInstance().navigateTo(routes.NEARBY_SHARE, params); }, /**
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.html index adf5fdfb..9c4d569 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.html
@@ -1,367 +1,344 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> +<style include="cr-shared-style settings-shared"> + cr-dialog::part(dialog) { + width: 512px; + } -<link rel="import" href="chrome://resources/cr_components/localized_link/localized_link.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> -<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> -<link rel="import" href="chrome://resources/html/assert.html"> -<link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="chrome://resources/html/load_time_data.html"> -<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="multidevice_browser_proxy.html"> -<link rel="import" href="multidevice_constants.html"> -<link rel="import" href="multidevice_screen_lock_subpage.html"> -<link rel="import" href="../os_icons.html"> -<link rel="import" href="../../settings_shared_css.html"> + #dialogTitle { + --cr-dialog-title-slot-padding-bottom: 24px; + --cr-dialog-title-slot-padding-end: 24px; + --cr-dialog-title-slot-padding-start: 24px; + --cr-dialog-title-slot-padding-top: 24px; + } -<dom-module id="settings-multidevice-permissions-setup-dialog"> - <template> - <style include="cr-shared-style settings-shared"> - cr-dialog::part(dialog) { - width: 512px; - } + :host(:not([has-started-setup-attempt_])) #dialogTitle { + --cr-dialog-title-slot-padding-bottom: 20px; + } - #dialogTitle { - --cr-dialog-title-slot-padding-bottom: 24px; - --cr-dialog-title-slot-padding-end: 24px; - --cr-dialog-title-slot-padding-start: 24px; - --cr-dialog-title-slot-padding-top: 24px; - } + #title { + align-items: center; + color: var(--cros-text-color-primary); + display: flex; + flex-direction: row; + font-family: 'Google Sans Medium'; + font-size: 16px; + gap: 8px; + justify-content: flex-start; + line-height: 24px; + } - :host(:not([has-started-setup-attempt_])) #dialogTitle { - --cr-dialog-title-slot-padding-bottom: 20px; - } + #subtitle { + color: var(--cros-text-color-secondary); + font-family: 'Roboto'; + font-size: 14px; + line-height: 20px; + } - #title { - align-items: center; - color: var(--cros-text-color-primary); - display: flex; - flex-direction: row; - font-family: 'Google Sans Medium'; - font-size: 16px; - gap: 8px; - justify-content: flex-start; - line-height: 24px; - } + #dialogBody { + display: flex; + flex-direction: column; + padding-inline-end: 24px; + padding-inline-start: 24px; + } - #subtitle { - color: var(--cros-text-color-secondary); - font-family: 'Roboto'; - font-size: 14px; - line-height: 20px; - } + :host([has-started-setup-attempt_]) #dialogBody { + /* Fixed height after intro state */ + height: 296px; + } - #dialogBody { - display: flex; - flex-direction: column; - padding-inline-end: 24px; - padding-inline-start: 24px; - } + :host([did-setup-attempt-fail_]) #dialogBody { + /* Smaller fixed height to account for the presence of #failureIcon */ + height: 288px; + } - :host([has-started-setup-attempt_]) #dialogBody { - /* Fixed height after intro state */ - height: 296px; - } + :host([should-show-setup-instructions-separately_]) #dialogBody { + /* Add space to force setup instructions to bottom of body */ + justify-content: space-between; + } - :host([did-setup-attempt-fail_]) #dialogBody { - /* Smaller fixed height to account for the presence of #failureIcon */ - height: 288px; - } + #buttonContainer { + align-items: center; + display: flex; + flex-direction: row; + justify-content: space-between; + padding-bottom: 20px; + padding-inline-end: 24px; + padding-inline-start: 24px; + padding-top: 0; + } - :host([should-show-setup-instructions-separately_]) #dialogBody { - /* Add space to force setup instructions to bottom of body */ - justify-content: space-between; - } + #failure-icon { + --iron-icon-fill-color: var(--cros-icon-color-warning); + height: 32px; + width: 32px; + } - #buttonContainer { - align-items: center; - display: flex; - flex-direction: row; - justify-content: space-between; - padding-bottom: 20px; - padding-inline-end: 24px; - padding-inline-start: 24px; - padding-top: 0; - } + #feature-icon { + --iron-icon-fill-color: var(--cros-icon-color-prominent); + height: 20px; + width: 20px; + } - #failure-icon { - --iron-icon-fill-color: var(--cros-icon-color-warning); - height: 32px; - width: 32px; - } + #instruction-icon { + --iron-icon-fill-color: var(--cros-icon-color-secondary); + height: 16px; + width: 16px; + } - #feature-icon { - --iron-icon-fill-color: var(--cros-icon-color-prominent); - height: 20px; - width: 20px; - } + #button-detail { + align-items: flex-end; + display: flex; + flex-direction: row; + gap: 8px; + justify-content: right; + } - #instruction-icon { - --iron-icon-fill-color: var(--cros-icon-color-secondary); - height: 16px; - width: 16px; - } + #description { + color: var(--cros-text-color-secondary); + font-family: 'Roboto'; + font-size: 13px; + line-height: 20px; + padding-top: 24px; + } - #button-detail { - align-items: flex-end; - display: flex; - flex-direction: row; - gap: 8px; - justify-content: right; - } + #feature-description { + align-items: flex-start; + display: flex; + flex-direction: column; + width: 252px; + } - #description { - color: var(--cros-text-color-secondary); - font-family: 'Roboto'; - font-size: 13px; - line-height: 20px; - padding-top: 24px; - } + #start-setup-description { + align-items: flex-start; + display: flex; + flex-direction: row; + height: auto; + justify-content: center; + } - #feature-description { - align-items: flex-start; - display: flex; - flex-direction: column; - width: 252px; - } + #feature-details-container { + align-items: flex-start; + color: var(--cros-text-color-secondary); + display: flex; + flex-direction: row; + font-family: 'Roboto'; + font-size: 13px; + gap: 20px; + justify-content: start; + line-height: 20px; + padding-bottom: 16px; + } - #start-setup-description { - align-items: flex-start; - display: flex; - flex-direction: row; - height: auto; - justify-content: center; - } + #half-container { + flex: 1; + } - #feature-details-container { - align-items: flex-start; - color: var(--cros-text-color-secondary); - display: flex; - flex-direction: row; - font-family: 'Roboto'; - font-size: 13px; - gap: 20px; - justify-content: start; - line-height: 20px; - padding-bottom: 16px; - } + /* + * Text size specified as 11-16. + * Aligned to flex-end and height reduced to 14px to shift text down 2px. + */ + #instruction { + align-items: flex-end; + color: var(--cros-text-color-secondary); + display: flex; + flex-direction: row; + font-family: 'Roboto'; + font-size: 11px; + gap: 6px; + justify-content: start; + line-height: 14px; + padding-bottom: 24px; + } - #half-container { - flex: 1; - } + #illustration { + background-position: center center; + background-repeat: no-repeat; + background-size: contain; + height: 200px; + width: 100%; + } - /* - * Text size specified as 11-16. - * Aligned to flex-end and height reduced to 14px to shift text down 2px. - */ - #instruction { - align-items: flex-end; - color: var(--cros-text-color-secondary); - display: flex; - flex-direction: row; - font-family: 'Roboto'; - font-size: 11px; - gap: 6px; - justify-content: start; - line-height: 14px; - padding-bottom: 24px; - } + :host(:not([has-started-setup-attempt_])) #illustration { + background-image: + url(chrome://os-settings/images/notification_access_setup.svg); + padding-bottom: 8px; + padding-top: 8px; + width: 200px; + } - #illustration { - background-position: center center; - background-repeat: no-repeat; - background-size: contain; - height: 200px; - width: 100%; - } + :host([is-setup-attempt-in-progress_]) #illustration { + background-image: + url(chrome://os-settings/images/notification_access_connecting.svg); + } - :host(:not([has-started-setup-attempt_])) #illustration { - background-image: - url(chrome://os-settings/images/notification_access_setup.svg); - padding-bottom: 8px; - padding-top: 8px; - width: 200px; - } + :host([did-setup-attempt-fail_]) #illustration { + background-image: + url(chrome://os-settings/images/notification_access_error.svg); + } - :host([is-setup-attempt-in-progress_]) #illustration { - background-image: - url(chrome://os-settings/images/notification_access_connecting.svg); - } + :host([has-completed-setup-successfully_]) #illustration { + background-image: + url(chrome://os-settings/images/notification_access_finished.svg); + } - :host([did-setup-attempt-fail_]) #illustration { - background-image: - url(chrome://os-settings/images/notification_access_error.svg); - } + @media(prefers-color-scheme: dark) { + :host(:not([has-started-setup-attempt_])) #illustration { + background-image: url( + chrome://os-settings/images/notification_access_setup_dark.svg); + } - :host([has-completed-setup-successfully_]) #illustration { - background-image: - url(chrome://os-settings/images/notification_access_finished.svg); - } + :host([is-setup-attempt-in-progress_]) #illustration { + background-image: url( + chrome://os-settings/images/notification_access_connecting_dark.svg); + } - @media(prefers-color-scheme: dark) { - :host(:not([has-started-setup-attempt_])) #illustration { - background-image: url( - chrome://os-settings/images/notification_access_setup_dark.svg); - } + :host([did-setup-attempt-fail_]) #illustration { + background-image: url( + chrome://os-settings/images/notification_access_error_dark.svg); + } - :host([is-setup-attempt-in-progress_]) #illustration { - background-image: url( - chrome://os-settings/images/notification_access_connecting_dark.svg); - } - - :host([did-setup-attempt-fail_]) #illustration { - background-image: url( - chrome://os-settings/images/notification_access_error_dark.svg); - } - - :host([has-completed-setup-successfully_]) #illustration { - background-image: url( - chrome://os-settings/images/notification_access_finished_dark.svg); - } - } - </style> - <cr-dialog id="dialog" close-text="$i18n{close}"> - <div id="dialogTitle" slot="title"> - <div id="title"> - <template is="dom-if" if="[[didSetupAttemptFail_]]" restamp> - <iron-icon id="failure-icon" icon="os-settings:multidevice-error"> - </iron-icon> - </template> - [[title_]] + :host([has-completed-setup-successfully_]) #illustration { + background-image: url( + chrome://os-settings/images/notification_access_finished_dark.svg); + } + } +</style> +<cr-dialog id="dialog" close-text="$i18n{close}"> + <div id="dialogTitle" slot="title"> + <div id="title"> + <template is="dom-if" if="[[didSetupAttemptFail_]]" restamp> + <iron-icon id="failure-icon" icon="os-settings:multidevice-error"> + </iron-icon> + </template> + [[title_]] + </div> + <template is="dom-if" if="[[hasStartedSetupAttempt_]]" restamp> + <template is="dom-if" if="[[shouldShowScreenLockInstructions_(flowState_)]]" restamp> + <div id="subtitle"> + $i18n{multideviceNotificationAccessSetupScreenLockSubtitle} </div> - <template is="dom-if" if="[[hasStartedSetupAttempt_]]" restamp> - <template is="dom-if" if="[[shouldShowScreenLockInstructions_(flowState_)]]" restamp> - <div id="subtitle"> - $i18n{multideviceNotificationAccessSetupScreenLockSubtitle} - </div> - </template> - </template> - <template is="dom-if" if="[[!hasStartedSetupAttempt_]]" restamp> - <div id="subtitle"> - $i18n{multidevicePermissionsSetupAckSubtitle} - </div> - </template> + </template> + </template> + <template is="dom-if" if="[[!hasStartedSetupAttempt_]]" restamp> + <div id="subtitle"> + $i18n{multidevicePermissionsSetupAckSubtitle} </div> - <div id="dialogBody" slot="body"> - <template is="dom-if" if="[[!hasStartedSetupAttempt_]]" restamp> - <div id="start-setup-description"> - <div id="half-container"> - <div id="illustration"></div> - </div> - <div id="half-container"> - <div id="feature-description"> - <template is="dom-if" if="[[showCameraRoll]]" - restamp> - <div id="feature-details-container"> - <iron-icon id="feature-icon" - icon="os-settings:multidevice-recent-photos"> - </iron-icon> - $i18n{multidevicePermissionsSetupCameraRollSummary} - </div> - </template> - <template is="dom-if" if="[[showNotifications]]" - restamp> - <div id="feature-details-container"> - <iron-icon id="feature-icon" - icon="os-settings:multidevice-notifications"> - </iron-icon> - $i18n{multidevicePermissionsSetupNotificationsSummary} - </div> - </template> - <template is="dom-if" if="[[showAppStreaming]]" restamp> - <div id="feature-details-container"> - <iron-icon id="feature-icon" - icon="os-settings:multidevice-app-streaming"> - </iron-icon> - $i18n{multidevicePermissionsSetupAppsSummary} - </div> - </template> - </div> - </div> - </div> - <div id="instruction"> - <iron-icon id="instruction-icon" icon="os-settings:failure-alert"> - </iron-icon> - $i18n{multideviceNotificationAccessSetupInstructions} - </div> - </template> - <template is="dom-if" if="[[hasStartedSetupAttempt_]]" restamp> - <template is="dom-if" if="[[shouldShowScreenLockInstructions_(flowState_)]]" restamp> - <settings-multidevice-screen-lock-subpage - is-screen-lock-enabled="{{isScreenLockEnabled_}}" - is-password-dialog-showing="{{isPasswordDialogShowing}}"> - </settings-multidevice-screen-lock-subpage> - </template> - <template is="dom-if" if="[[!shouldShowScreenLockInstructions_(flowState_)]]" restamp> - <div id="illustration"></div> - <template is="dom-if" if="[[description_]]" restamp> - <div id="description"> - <localized-link localized-string="[[description_]]"> - </localized-link> - </div> - </template> - </template> - </template> - </div> - <div id="buttonContainer" slot="button-container"> + </template> + </div> + <div id="dialogBody" slot="body"> + <template is="dom-if" if="[[!hasStartedSetupAttempt_]]" restamp> + <div id="start-setup-description"> <div id="half-container"> - <template is="dom-if" if="[[shouldShowLearnMoreButton_]]" restamp> - <cr-button id="learnMore" on-click="onLearnMoreClicked_"> - $i18n{multideviceLearnMoreWithoutURL} - </cr-button> - </template> + <div id="illustration"></div> </div> - <div id="button-detail"> - <template is="dom-if" if="[[shouldShowCancelButton_(setupState_)]]" - restamp> - <cr-button id="cancelButton" on-click="onCancelClicked_"> - $i18n{cancel} - </cr-button> - </template> - <template is="dom-if" if="[[shouldShowDisabledDoneButton_]]" restamp> - <cr-button id="doneButton" class="action-button" disabled> - $i18n{done} - </cr-button> - </template> - <template is="dom-if" if="[[hasCompletedSetupSuccessfully_]]" restamp> - <cr-button id="doneButton" class="action-button" - on-click="onDoneOrCloseButtonClicked_"> - $i18n{done} - </cr-button> - </template> - <template is="dom-if" if="[[isNotificationAccessProhibited_]]" - restamp> - <cr-button id="closeButton" class="action-button" - on-click="onDoneOrCloseButtonClicked_"> - $i18n{close} - </cr-button> - </template> - <template is="dom-if" if="[[!hasStartedSetupAttempt_]]" restamp> - <cr-button id="getStartedButton" class="action-button" - on-click="nextPage_"> - $i18n{next} - </cr-button> - </template> - <template is="dom-if" if="[[hasStartedSetupAttempt_]]" restamp> - <template is="dom-if" if="[[shouldShowScreenLockInstructions_(flowState_)]]" restamp> - <cr-button id="getStartedButton" class="action-button" - on-click="nextPage_"> - $i18n{next} - </cr-button> + <div id="half-container"> + <div id="feature-description"> + <template is="dom-if" if="[[showCameraRoll]]" + restamp> + <div id="feature-details-container"> + <iron-icon id="feature-icon" + icon="os-settings:multidevice-recent-photos"> + </iron-icon> + $i18n{multidevicePermissionsSetupCameraRollSummary} + </div> </template> - </template> - <template is="dom-if" if="[[shouldShowTryAgainButton_(setupState_)]]" - restamp> - <cr-button id="tryAgainButton" class="action-button" - on-click="nextPage_"> - $i18n{multideviceNotificationAccessSetupTryAgain} - </cr-button> - </template> + <template is="dom-if" if="[[showNotifications]]" + restamp> + <div id="feature-details-container"> + <iron-icon id="feature-icon" + icon="os-settings:multidevice-notifications"> + </iron-icon> + $i18n{multidevicePermissionsSetupNotificationsSummary} + </div> + </template> + <template is="dom-if" if="[[showAppStreaming]]" restamp> + <div id="feature-details-container"> + <iron-icon id="feature-icon" + icon="os-settings:multidevice-app-streaming"> + </iron-icon> + $i18n{multidevicePermissionsSetupAppsSummary} + </div> + </template> + </div> </div> </div> - </cr-dialog> - </template> - <script src="multidevice_permissions_setup_dialog.js"></script> -</dom-module> + <div id="instruction"> + <iron-icon id="instruction-icon" icon="os-settings:failure-alert"> + </iron-icon> + $i18n{multideviceNotificationAccessSetupInstructions} + </div> + </template> + <template is="dom-if" if="[[hasStartedSetupAttempt_]]" restamp> + <template is="dom-if" if="[[shouldShowScreenLockInstructions_(flowState_)]]" restamp> + <settings-multidevice-screen-lock-subpage + is-screen-lock-enabled="{{isScreenLockEnabled_}}" + is-password-dialog-showing="{{isPasswordDialogShowing}}"> + </settings-multidevice-screen-lock-subpage> + </template> + <template is="dom-if" if="[[!shouldShowScreenLockInstructions_(flowState_)]]" restamp> + <div id="illustration"></div> + <template is="dom-if" if="[[description_]]" restamp> + <div id="description"> + <localized-link localized-string="[[description_]]"> + </localized-link> + </div> + </template> + </template> + </template> + </div> + <div id="buttonContainer" slot="button-container"> + <div id="half-container"> + <template is="dom-if" if="[[shouldShowLearnMoreButton_]]" restamp> + <cr-button id="learnMore" on-click="onLearnMoreClicked_"> + $i18n{multideviceLearnMoreWithoutURL} + </cr-button> + </template> + </div> + <div id="button-detail"> + <template is="dom-if" if="[[shouldShowCancelButton_(setupState_)]]" + restamp> + <cr-button id="cancelButton" on-click="onCancelClicked_"> + $i18n{cancel} + </cr-button> + </template> + <template is="dom-if" if="[[shouldShowDisabledDoneButton_]]" restamp> + <cr-button id="doneButton" class="action-button" disabled> + $i18n{done} + </cr-button> + </template> + <template is="dom-if" if="[[hasCompletedSetupSuccessfully_]]" restamp> + <cr-button id="doneButton" class="action-button" + on-click="onDoneOrCloseButtonClicked_"> + $i18n{done} + </cr-button> + </template> + <template is="dom-if" if="[[isNotificationAccessProhibited_]]" + restamp> + <cr-button id="closeButton" class="action-button" + on-click="onDoneOrCloseButtonClicked_"> + $i18n{close} + </cr-button> + </template> + <template is="dom-if" if="[[!hasStartedSetupAttempt_]]" restamp> + <cr-button id="getStartedButton" class="action-button" + on-click="nextPage_"> + $i18n{next} + </cr-button> + </template> + <template is="dom-if" if="[[hasStartedSetupAttempt_]]" restamp> + <template is="dom-if" if="[[shouldShowScreenLockInstructions_(flowState_)]]" restamp> + <cr-button id="getStartedButton" class="action-button" + on-click="nextPage_"> + $i18n{next} + </cr-button> + </template> + </template> + <template is="dom-if" if="[[shouldShowTryAgainButton_(setupState_)]]" + restamp> + <cr-button id="tryAgainButton" class="action-button" + on-click="nextPage_"> + $i18n{multideviceNotificationAccessSetupTryAgain} + </cr-button> + </template> + </div> + </div> +</cr-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.js index 6446c04..01ab2f93 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.js
@@ -2,6 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '//resources/cr_components/localized_link/localized_link.js'; +import '//resources/cr_elements/cr_button/cr_button.m.js'; +import '//resources/cr_elements/cr_dialog/cr_dialog.m.js'; +import '//resources/cr_elements/shared_style_css.m.js'; +import '//resources/cr_elements/shared_vars_css.m.js'; +import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; +import './multidevice_screen_lock_subpage.js'; +import '../os_icons.js'; +import '../../settings_shared_css.js'; + +import {I18nBehavior} from '//resources/js/i18n_behavior.m.js'; +import {loadTimeData} from '//resources/js/load_time_data.m.js'; +import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from './multidevice_browser_proxy.js'; +import {MultiDeviceFeature} from './multidevice_constants.js'; + /** * @fileoverview * This element provides the Phone Hub notification and apps access setup flow @@ -15,7 +33,7 @@ * with the exception of CONNECTION_REQUESTED. * @enum {number} */ -/* #export */ const PermissionsSetupStatus = { +export const PermissionsSetupStatus = { CONNECTION_REQUESTED: 0, CONNECTING: 1, TIMED_OUT_CONNECTING: 2, @@ -29,7 +47,7 @@ * Numerical values the flow of dialog set up progress. * @enum {number} */ -/* #export */ const SetupFlowStatus = { +export const SetupFlowStatus = { INTRO: 0, SET_LOCKSCREEN: 1, WAIT_FOR_PHONE_NOTIFICATION: 2, @@ -37,6 +55,7 @@ }; Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-permissions-setup-dialog', behaviors: [ @@ -154,12 +173,12 @@ }, }, - /** @private {?settings.MultiDeviceBrowserProxy} */ + /** @private {?MultiDeviceBrowserProxy} */ browserProxy_: null, /** @override */ ready() { - this.browserProxy_ = settings.MultiDeviceBrowserProxyImpl.getInstance(); + this.browserProxy_ = MultiDeviceBrowserProxyImpl.getInstance(); }, /** @override */ @@ -188,7 +207,7 @@ } this.browserProxy_.setFeatureEnabledState( - settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, true); + MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, true); if (this.showAppStreaming) { this.browserProxy_.attemptAppsSetup(); @@ -209,8 +228,7 @@ this.setupState_ = setupState; if (this.setupState_ === PermissionsSetupStatus.COMPLETED_SUCCESSFULLY) { - this.browserProxy_.setFeatureEnabledState( - settings.MultiDeviceFeature.ECHE, true); + this.browserProxy_.setFeatureEnabledState(MultiDeviceFeature.ECHE, true); } },
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.html index 7caddc3..848001d 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.html
@@ -1,57 +1,41 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> +<style include="settings-shared cr-radio-button-style"> + :host([disabled]) { + opacity: 1; + } -<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button_behavior.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button_style_css.html"> -<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> -<link rel="import" href="../../settings_shared_css.html"> + /* Disc and label should be transluscent, but not the policy indicator. */ + :host([disabled]) .disc-wrapper, + :host([disabled]) #labelWrapper { + opacity: var(--cr-disabled-opacity); + } -<!-- TODO(jhawkins): This is copy/pasted from controlled_radio_button. Figure - out how to refactor such that a common UI/behavior may be shared. The only - difference is how the controlling preference is read. --> -<dom-module id="multidevice-radio-button"> - <template> - <style include="settings-shared cr-radio-button-style"> - :host([disabled]) { - opacity: 1; - } + cr-policy-pref-indicator { + margin-inline-start: var(--settings-controlled-by-spacing); + /* Enable pointer events for the indicator so :hover works. Disable + * clicks/taps via onIndicatorTap_ so outer on-tap doesn't trigger. */ + pointer-events: all; + } +</style> - /* Disc and label should be transluscent, but not the policy indicator. */ - :host([disabled]) .disc-wrapper, - :host([disabled]) #labelWrapper { - opacity: var(--cr-disabled-opacity); - } +<div + role="presentation" + class="disc-wrapper" + id="button" + tabindex$="[[buttonTabIndex_]]" + on-keydown="onInputKeydown_"> + <div class="disc-border"></div> + <div class="disc"></div> +</div> - cr-policy-pref-indicator { - margin-inline-start: var(--settings-controlled-by-spacing); - /* Enable pointer events for the indicator so :hover works. Disable - * clicks/taps via onIndicatorTap_ so outer on-tap doesn't trigger. */ - pointer-events: all; - } - </style> +<div id="labelWrapper" role="presentation"> + <span>[[label]]</span> +</div> - <div - role="presentation" - class="disc-wrapper" - id="button" - tabindex$="[[buttonTabIndex_]]" - on-keydown="onInputKeydown_"> - <div class="disc-border"></div> - <div class="disc"></div> - </div> +<template is="dom-if" if="[[disabled]]" restamp> + <cr-policy-indicator + indicator-type="userPolicy" + icon-aria-label="[[label]]" + on-click="onIndicatorTap_"> + </cr-policy-indicator> +</template> - <div id="labelWrapper" role="presentation"> - <span>[[label]]</span> - </div> - - <template is="dom-if" if="[[disabled]]" restamp> - <cr-policy-indicator - indicator-type="userPolicy" - icon-aria-label="[[label]]" - on-click="onIndicatorTap_"> - </cr-policy-indicator> - </template> - - </template> - <script src="multidevice_radio_button.js"></script> -</dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.js index c6bc408..10a1484 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.js
@@ -2,7 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '//resources/cr_elements/cr_radio_button/cr_radio_button_style_css.m.js'; +import '//resources/cr_elements/policy/cr_policy_indicator.m.js'; +import '//resources/polymer/v3_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js'; +import '../../settings_shared_css.js'; + +import {CrRadioButtonBehavior} from '//resources/cr_elements/cr_radio_button/cr_radio_button_behavior.m.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + Polymer({ + _template: html`{__html_template__}`, is: 'multidevice-radio-button', behaviors: [
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.html index caeb345c..844d9ba 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.html
@@ -1,141 +1,123 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> +<style include="cr-shared-style settings-shared"> -<link rel="import" href="chrome://resources/cr_components/chromeos/quick_unlock/lock_screen_constants.html"> -<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> -<link rel="import" href="chrome://resources/html/assert.html"> -<link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> -<link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="chrome://resources/html/load_time_data.html"> -<link rel="import" href="../os_people_page/lock_screen_password_prompt_dialog.html"> -<link rel="import" href="../os_people_page/lock_state_behavior.html"> -<link rel="import" href="../os_people_page/setup_pin_dialog.html"> -<link rel="import" href="../os_people_page/pin_autosubmit_dialog.html"> + #screen-lock-description { + align-items: center; + display: flex; + flex-direction: row; + height: auto; + justify-content: center; + } -<dom-module id="settings-multidevice-screen-lock-subpage"> - <template> - <style include="cr-shared-style settings-shared"> + #half-container { + flex: 1; + height: 216px; + } - #screen-lock-description { - align-items: center; - display: flex; - flex-direction: row; - height: auto; - justify-content: center; - } + #illustration { + background-image: + url(chrome://os-settings/images/notification_access_connecting.svg); + background-position: center center; + background-repeat: no-repeat; + background-size: contain; + height: 200px; + margin-bottom: 8px; + margin-top: 8px; + width: 100%; + } - #half-container { - flex: 1; - height: 216px; - } + @media(prefers-color-scheme: dark) { + #illustration { + background-image: url( + chrome://os-settings/images/notification_access_connecting_dark.svg); + } + } - #illustration { - background-image: - url(chrome://os-settings/images/notification_access_connecting.svg); - background-position: center center; - background-repeat: no-repeat; - background-size: contain; - height: 200px; - margin-bottom: 8px; - margin-top: 8px; - width: 100%; - } + #radio-button-container { + padding-top: 20px; + } - @media(prefers-color-scheme: dark) { - #illustration { - background-image: url( - chrome://os-settings/images/notification_access_connecting_dark.svg); - } - } + #passwordRadioButton { + --cr-radio-button-label-spacing: 20px; + --cr-radio-button-size: 20px; + color: var(--cr-primary-text-color); + font-family: 'Roboto'; + font-size: 13px; + font-weight: medium; + line-height: 20px; + min-height: 20px; + padding-inline-start: 8px; + padding-top: 24px; + } - #radio-button-container { - padding-top: 20px; - } + #pinRadioButton { + --cr-radio-button-label-spacing: 20px; + --cr-radio-button-size: 20px; + color: var(--cr-primary-text-color); + font-family: 'Roboto'; + font-size: 13px; + font-weight: medium; + line-height: 20px; + min-height: 20px; + padding-inline-start: 8px; + padding-top: 44px; + } - #passwordRadioButton { - --cr-radio-button-label-spacing: 20px; - --cr-radio-button-size: 20px; - color: var(--cr-primary-text-color); - font-family: 'Roboto'; - font-size: 13px; - font-weight: medium; - line-height: 20px; - min-height: 20px; - padding-inline-start: 8px; - padding-top: 24px; - } - - #pinRadioButton { - --cr-radio-button-label-spacing: 20px; - --cr-radio-button-size: 20px; - color: var(--cr-primary-text-color); - font-family: 'Roboto'; - font-size: 13px; - font-weight: medium; - line-height: 20px; - min-height: 20px; - padding-inline-start: 8px; - padding-top: 44px; - } - - #subtext { - color: var(--cr-secondary-text-color); - font-family: 'Roboto'; - font-size: 13px; - font-weight: medium; - line-height: 20px; - padding-inline-start: 48px; - } - </style> - <div id="screen-lock-description"> - <div id="half-container"> - <div id="illustration"></div> - </div> - <div id="half-container"> - <template is="dom-if" if="[[authToken_]]"> - <cr-radio-group id=radio-button-container - disabled$="[[quickUnlockDisabledByPolicy_]]" - selected="{{selectedUnlockType}}" - deep-link-focus-id$="[[Setting.kChangeAuthPinV2]]"> - <cr-radio-button id="passwordRadioButton" name="password" - label=$i18n{lockScreenPasswordOnly}> - </cr-radio-button> - <cr-radio-button id="pinRadioButton" name="pin+password" - label=$i18n{lockScreenPinOrPassword}> - </cr-radio-button> - <div id="subtext"> - $i18n{multideviceNotificationAccessSetupScreenLockInstruction} + #subtext { + color: var(--cr-secondary-text-color); + font-family: 'Roboto'; + font-size: 13px; + font-weight: medium; + line-height: 20px; + padding-inline-start: 48px; + } +</style> +<div id="screen-lock-description"> + <div id="half-container"> + <div id="illustration"></div> + </div> + <div id="half-container"> + <template is="dom-if" if="[[authToken_]]"> + <cr-radio-group id=radio-button-container + disabled$="[[quickUnlockDisabledByPolicy_]]" + selected="{{selectedUnlockType}}" + deep-link-focus-id$="[[Setting.kChangeAuthPinV2]]"> + <cr-radio-button id="passwordRadioButton" name="password" + label=$i18n{lockScreenPasswordOnly}> + </cr-radio-button> + <cr-radio-button id="pinRadioButton" name="pin+password" + label=$i18n{lockScreenPinOrPassword}> + </cr-radio-button> + <div id="subtext"> + $i18n{multideviceNotificationAccessSetupScreenLockInstruction} + </div> + <template is="dom-if" + if="[[showConfigurePinButton_(selectedUnlockType)]]"> + <div class="list-item-end"> + <div id="pinPasswordSecondaryActionDiv" + class="secondary-action"> + <!-- Use stop-keyboard-event-propagation to prevent + triggering this when focused after closing the + dialog. --> + <cr-button id="setupPinButton" on-click="onConfigurePin_" + stop-keyboard-event-propagation> + [[getSetupPinText_(hasPin)]] + </cr-button> </div> - <template is="dom-if" - if="[[showConfigurePinButton_(selectedUnlockType)]]"> - <div class="list-item-end"> - <div id="pinPasswordSecondaryActionDiv" - class="secondary-action"> - <!-- Use stop-keyboard-event-propagation to prevent - triggering this when focused after closing the - dialog. --> - <cr-button id="setupPinButton" on-click="onConfigurePin_" - stop-keyboard-event-propagation> - [[getSetupPinText_(hasPin)]] - </cr-button> - </div> - </div> - </template> - </cr-radio-group> + </div> </template> - </div> - </div> - <template is="dom-if" if="[[shouldPromptPasswordDialog_]]" restamp> - <settings-lock-screen-password-prompt-dialog id="passwordDialog" - on-close="onPasswordPromptDialogClose_" - on-auth-token-obtained="onAuthTokenObtained_"> - </settings-lock-screen-password-prompt-dialog> + </cr-radio-group> </template> - <template is="dom-if" if="[[showSetupPinDialog_]]" restamp> - <settings-setup-pin-dialog id="setupPin" - set-modes="[[setModes_]]" - on-close="onSetupPinDialogClose_"> - </settings-setup-pin-dialog> - </template> - </template> - <script src="multidevice_screen-lock_subpage.js"></script> -</dom-module> + </div> +</div> +<template is="dom-if" if="[[shouldPromptPasswordDialog_]]" restamp> + <settings-lock-screen-password-prompt-dialog id="passwordDialog" + on-close="onPasswordPromptDialogClose_" + on-auth-token-obtained="onAuthTokenObtained_"> + </settings-lock-screen-password-prompt-dialog> +</template> +<template is="dom-if" if="[[showSetupPinDialog_]]" restamp> + <settings-setup-pin-dialog id="setupPin" + set-modes="[[setModes_]]" + on-close="onSetupPinDialogClose_"> + </settings-setup-pin-dialog> +</template>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.js index 7330db0..0d3d88b 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.js
@@ -2,12 +2,27 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '//resources/cr_elements/shared_vars_css.m.js'; +import '../os_people_page/lock_screen_password_prompt_dialog.js'; +import '../os_people_page/setup_pin_dialog.js'; +import '../os_people_page/pin_autosubmit_dialog.js'; + +import {LockScreenProgress, recordLockScreenProgress} from '//resources/cr_components/chromeos/quick_unlock/lock_screen_constants.m.js'; +import {assert} from '//resources/js/assert.m.js'; +import {focusWithoutInk} from '//resources/js/cr/ui/focus_without_ink.m.js'; +import {I18nBehavior} from '//resources/js/i18n_behavior.m.js'; +import {loadTimeData} from '//resources/js/load_time_data.m.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {LockScreenUnlockType, LockStateBehavior} from '../os_people_page/lock_state_behavior.m.js'; + /** * @fileoverview * Subpage of settings-multidevice-notification-access-setup-dialog for setting * up screen lock. */ Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-screen-lock-subpage', behaviors: [ @@ -47,7 +62,7 @@ writeUma_: { type: Object, value() { - return settings.recordLockScreenProgress; + return recordLockScreenProgress; }, }, @@ -190,14 +205,14 @@ */ onConfigurePin_(e) { e.preventDefault(); - this.writeUma_(settings.LockScreenProgress.CHOOSE_PIN_OR_PASSWORD); + this.writeUma_(LockScreenProgress.CHOOSE_PIN_OR_PASSWORD); this.showSetupPinDialog_ = true; }, /** @private */ onSetupPinDialogClose_() { this.showSetupPinDialog_ = false; - cr.ui.focusWithoutInk(assert(this.$$('#setupPinButton'))); + focusWithoutInk(assert(this.$$('#setupPinButton'))); }, /**
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_item.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_item.html index fb3d952..e69801a 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_item.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_item.html
@@ -1,28 +1,10 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="../metrics_recorder.html"> -<link rel="import" href="../os_route.html"> -<link rel="import" href="../os_settings_routes.html"> -<link rel="import" href="../../i18n_setup.html"> -<link rel="import" href="../../router.html"> -<link rel="import" href="multidevice_constants.html"> -<link rel="import" href="multidevice_browser_proxy.html"> -<link rel="import" href="multidevice_feature_behavior.html"> -<link rel="import" href="multidevice_feature_item.html"> - -<dom-module id="settings-multidevice-smartlock-item"> - <template> - <template is="dom-if" - if="[[shouldShowFeature_(pageContentData)]]" - restamp> - <settings-multidevice-feature-item id="smartLockItem" - feature="[[MultiDeviceFeature.SMART_LOCK]]" - page-content-data="[[pageContentData]]" - subpage-route="[[routes.SMART_LOCK]]" - is-feature-icon-hidden> - </settings-multidevice-feature-item> - </template> - </template> - <script src="multidevice_smartlock_item.js"></script> -</dom-module> +<template is="dom-if" + if="[[shouldShowFeature_(pageContentData)]]" + restamp> + <settings-multidevice-feature-item id="smartLockItem" + feature="[[MultiDeviceFeature.SMART_LOCK]]" + page-content-data="[[pageContentData]]" + subpage-route="[[routes.SMART_LOCK]]" + is-feature-icon-hidden> + </settings-multidevice-feature-item> +</template>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_item.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_item.js index f094fe7b..cdd0296 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_item.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_item.js
@@ -2,6 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import './multidevice_feature_item.js'; + +import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {recordSettingChange} from '../metrics_recorder.m.js'; +import {routes} from '../os_route.m.js'; +import {OsSettingsRoutes} from '../os_settings_routes.m.js'; + +import {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from './multidevice_browser_proxy.js'; +import {MultiDeviceFeature, MultiDevicePageContentData, MultiDeviceSettingsMode} from './multidevice_constants.js'; +import {MultiDeviceFeatureBehavior} from './multidevice_feature_behavior.js'; + /** * @fileoverview * Wrapper for multidevice-feature-item that allows displaying the Smart Lock @@ -10,6 +23,7 @@ * in an auth token. */ Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-smartlock-item', behaviors: [ @@ -19,12 +33,12 @@ properties: { /** - * Alias for allowing Polymer bindings to settings.routes. + * Alias for allowing Polymer bindings to routes. * @type {?OsSettingsRoutes} */ routes: { type: Object, - value: settings.routes, + value: routes, }, /** @@ -40,12 +54,12 @@ 'feature-toggle-clicked': 'onFeatureToggleClicked_', }, - /** @private {?settings.MultiDeviceBrowserProxy} */ + /** @private {?MultiDeviceBrowserProxy} */ browserProxy_: null, /** @override */ ready() { - this.browserProxy_ = settings.MultiDeviceBrowserProxyImpl.getInstance(); + this.browserProxy_ = MultiDeviceBrowserProxyImpl.getInstance(); this.addWebUIListener( 'settings.updateMultidevicePageContentData', @@ -61,7 +75,7 @@ }, /** - * @param {!settings.MultiDevicePageContentData} newData + * @param {!MultiDevicePageContentData} newData * @private */ onPageContentDataChanged_(newData) { @@ -75,10 +89,10 @@ shouldShowFeature_() { // We only show the feature when it is editable, because a disabled toggle // is confusing for the user without greater context. - return this.isFeatureSupported(settings.MultiDeviceFeature.SMART_LOCK) && + return this.isFeatureSupported(MultiDeviceFeature.SMART_LOCK) && this.pageContentData.mode === - settings.MultiDeviceSettingsMode.HOST_SET_VERIFIED && - this.isFeatureStateEditable(settings.MultiDeviceFeature.SMART_LOCK); + MultiDeviceSettingsMode.HOST_SET_VERIFIED && + this.isFeatureStateEditable(MultiDeviceFeature.SMART_LOCK); }, /** @@ -88,7 +102,7 @@ * multidevice page * * @param {!CustomEvent<!{ - * feature: !settings.MultiDeviceFeature, + * feature: !MultiDeviceFeature, * enabled: boolean * }>} event * @private @@ -99,6 +113,6 @@ this.browserProxy_.setFeatureEnabledState( feature, enabled, this.authToken.token); - settings.recordSettingChange(); + recordSettingChange(); }, });
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.html index 76e0725..56cf92e 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.html
@@ -1,74 +1,50 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html"> -<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="multidevice_browser_proxy.html"> -<link rel="import" href="multidevice_constants.html"> -<link rel="import" href="multidevice_feature_behavior.html"> -<link rel="import" href="multidevice_feature_toggle.html"> -<link rel="import" href="multidevice_radio_button.html"> -<link rel="import" href="../deep_linking_behavior.html"> -<link rel="import" href="../os_route.html"> -<link rel="import" href="../os_settings_routes.html"> -<link rel="import" href="../../router.html"> -<link rel="import" href="../route_observer_behavior.html"> -<link rel="import" href="../../i18n_setup.html"> -<link rel="import" href="../../settings_shared_css.html"> -<link rel="import" href="../metrics_recorder.html"> - -<dom-module id="settings-multidevice-smartlock-subpage"> - <template> - <style include="settings-shared"></style> - <div class="settings-box first"> - <!-- TODO(jhawkins): Remove this status text and move the toggle into - the subpage header section. --> - <div class="start"> - <template is="dom-if" if="[[smartLockEnabled_]]" restamp> - $i18n{multideviceEnabled} - </template> - <template is="dom-if" if="[[!smartLockEnabled_]]" restamp> - $i18n{multideviceDisabled} - </template> - </div> - <settings-multidevice-feature-toggle - feature="[[MultiDeviceFeature.SMART_LOCK]]" - page-content-data="[[pageContentData]]" - deep-link-focus-id$="[[Setting.kSmartLockOnOff]]"> - </settings-multidevice-feature-toggle> - </div> - <iron-collapse opened="[[smartLockEnabled_]]"> - <div class="settings-box first line-only"> - <h2 class="start first"> - $i18n{multideviceSmartLockOptions} - </h2> - </div> - <div class="list-frame"> - <cr-radio-group - selected="[[smartLockSignInEnabled_]]" - selectable-elements="multidevice-radio-button" - disabled="[[!smartLockSignInAllowed_]]" - on-selected-changed="onSmartLockSignInEnabledChanged_" - deep-link-focus-id$="[[Setting.kSmartLockUnlockOrSignIn]]"> - <multidevice-radio-button - name="disabled" - class="list-item underbar" - label="$i18n{easyUnlockUnlockDeviceOnly}"> - </multidevice-radio-button> - <multidevice-radio-button - name="enabled" - class="list-item" - label="$i18n{easyUnlockUnlockDeviceAndAllowSignin}"> - </multidevice-radio-button> - </cr-radio-group> - </div> - </iron-collapse> - <template is="dom-if" if="[[showPasswordPromptDialog_]]" restamp> - <settings-password-prompt-dialog id="smartLockSignInPasswordPrompt" - on-close="onEnableSignInDialogClose_" - on-token-obtained="onTokenObtained_"> - </settings-password-prompt-dialog> +<style include="settings-shared"></style> +<div class="settings-box first"> + <!-- TODO(jhawkins): Remove this status text and move the toggle into + the subpage header section. --> + <div class="start"> + <template is="dom-if" if="[[smartLockEnabled_]]" restamp> + $i18n{multideviceEnabled} </template> - </template> - <script src="multidevice_smartlock_subpage.js"></script> -</dom-module> + <template is="dom-if" if="[[!smartLockEnabled_]]" restamp> + $i18n{multideviceDisabled} + </template> + </div> + <settings-multidevice-feature-toggle + feature="[[MultiDeviceFeature.SMART_LOCK]]" + page-content-data="[[pageContentData]]" + deep-link-focus-id$="[[Setting.kSmartLockOnOff]]"> + </settings-multidevice-feature-toggle> +</div> +<iron-collapse opened="[[smartLockEnabled_]]"> + <div class="settings-box first line-only"> + <h2 class="start first"> + $i18n{multideviceSmartLockOptions} + </h2> + </div> + <div class="list-frame"> + <cr-radio-group + selected="[[smartLockSignInEnabled_]]" + selectable-elements="multidevice-radio-button" + disabled="[[!smartLockSignInAllowed_]]" + on-selected-changed="onSmartLockSignInEnabledChanged_" + deep-link-focus-id$="[[Setting.kSmartLockUnlockOrSignIn]]"> + <multidevice-radio-button + name="disabled" + class="list-item underbar" + label="$i18n{easyUnlockUnlockDeviceOnly}"> + </multidevice-radio-button> + <multidevice-radio-button + name="enabled" + class="list-item" + label="$i18n{easyUnlockUnlockDeviceAndAllowSignin}"> + </multidevice-radio-button> + </cr-radio-group> + </div> +</iron-collapse> +<template is="dom-if" if="[[showPasswordPromptDialog_]]" restamp> + <settings-password-prompt-dialog id="smartLockSignInPasswordPrompt" + on-close="onEnableSignInDialogClose_" + on-token-obtained="onTokenObtained_"> + </settings-password-prompt-dialog> +</template>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.js index f0345c7..595bf22 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.js
@@ -2,13 +2,34 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '//resources/cr_elements/cr_radio_button/cr_radio_button.m.js'; +import '//resources/cr_elements/cr_radio_group/cr_radio_group.m.js'; +import './multidevice_feature_toggle.js'; +import './multidevice_radio_button.js'; +import '../../settings_shared_css.js'; + +import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {Route} from '../../router.js'; +import {DeepLinkingBehavior} from '../deep_linking_behavior.js'; +import {recordSettingChange} from '../metrics_recorder.m.js'; +import {routes} from '../os_route.m.js'; +import {OsSettingsRoutes} from '../os_settings_routes.m.js'; +import {RouteObserverBehavior} from '../route_observer_behavior.js'; + +import {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from './multidevice_browser_proxy.js'; +import {MultiDeviceFeature, MultiDeviceFeatureState, SmartLockSignInEnabledState} from './multidevice_constants.js'; +import {MultiDeviceFeatureBehavior} from './multidevice_feature_behavior.js'; + Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-smartlock-subpage', behaviors: [ DeepLinkingBehavior, MultiDeviceFeatureBehavior, - settings.RouteObserverBehavior, + RouteObserverBehavior, WebUIListenerBehavior, ], @@ -16,7 +37,7 @@ /** @type {?OsSettingsRoutes} */ routes: { type: Object, - value: settings.routes, + value: routes, }, /** @@ -31,11 +52,11 @@ /** * Whether Smart Lock may be used to sign-in the user (as opposed to only * being able to unlock the user's screen). - * @private {!settings.SmartLockSignInEnabledState} + * @private {!SmartLockSignInEnabledState} */ smartLockSignInEnabled_: { type: Object, - value: settings.SmartLockSignInEnabledState.DISABLED, + value: SmartLockSignInEnabledState.DISABLED, }, /** @@ -74,12 +95,12 @@ }, }, - /** @private {?settings.MultiDeviceBrowserProxy} */ + /** @private {?MultiDeviceBrowserProxy} */ browserProxy_: null, /** @override */ ready() { - this.browserProxy_ = settings.MultiDeviceBrowserProxyImpl.getInstance(); + this.browserProxy_ = MultiDeviceBrowserProxyImpl.getInstance(); this.addWebUIListener( 'smart-lock-signin-enabled-changed', @@ -99,12 +120,12 @@ }, /** - * @param {!settings.Route} route - * @param {!settings.Route} oldRoute + * @param {!Route} route + * @param {!Route} oldRoute */ currentRouteChanged(route, oldRoute) { // Does not apply to this page. - if (route !== settings.routes.SMART_LOCK) { + if (route !== routes.SMART_LOCK) { return; } @@ -118,8 +139,8 @@ */ computeIsSmartLockEnabled_() { return !!this.pageContentData && - this.getFeatureState(settings.MultiDeviceFeature.SMART_LOCK) === - settings.MultiDeviceFeatureState.ENABLED_BY_USER; + this.getFeatureState(MultiDeviceFeature.SMART_LOCK) === + MultiDeviceFeatureState.ENABLED_BY_USER; }, /** @@ -127,9 +148,9 @@ * @private */ updateSmartLockSignInEnabled_(enabled) { - this.smartLockSignInEnabled_ = - enabled ? settings.SmartLockSignInEnabledState.ENABLED : - settings.SmartLockSignInEnabledState.DISABLED; + this.smartLockSignInEnabled_ = enabled ? + SmartLockSignInEnabledState.ENABLED : + SmartLockSignInEnabledState.DISABLED; }, /** @@ -153,19 +174,18 @@ */ onSmartLockSignInEnabledChanged_() { const radioGroup = this.$$('cr-radio-group'); - const enabled = - radioGroup.selected === settings.SmartLockSignInEnabledState.ENABLED; + const enabled = radioGroup.selected === SmartLockSignInEnabledState.ENABLED; if (!enabled) { // No authentication check is required to disable. this.browserProxy_.setSmartLockSignInEnabled(false /* enabled */); - settings.recordSettingChange(); + recordSettingChange(); return; } // Toggle the enabled state back to disabled, as authentication may not // succeed. The toggle state updates automatically by the pref listener. - radioGroup.selected = settings.SmartLockSignInEnabledState.DISABLED; + radioGroup.selected = SmartLockSignInEnabledState.DISABLED; this.openPasswordPromptDialog_(); }, @@ -183,7 +203,7 @@ if (this.authToken_) { this.browserProxy_.setSmartLockSignInEnabled( true /* enabled */, this.authToken_.token); - settings.recordSettingChange(); + recordSettingChange(); } // Always require password entry if re-enabling SignIn with Smart Lock.
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.html index ca335893..05d11c9 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.html
@@ -1,251 +1,220 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> +<style include="settings-shared iron-flex"> + settings-multidevice-feature-item, + settings-multidevice-tether-item { + --feature-item-row-padding: 0; + } -<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_listener_behavior.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_link_row/cr_link_row.html"> -<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> -<link rel="import" href="chrome://resources/html/cr.html"> -<link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="../../i18n_setup.html"> -<link rel="import" href="../deep_linking_behavior.html"> -<link rel="import" href="../os_route.html"> -<link rel="import" href="../os_settings_routes.html"> -<link rel="import" href="../../router.html"> -<link rel="import" href="../route_observer_behavior.html"> -<link rel="import" href="../../settings_shared_css.html"> -<link rel="import" href="../../settings_vars_css.html"> -<link rel="import" href="multidevice_combined_setup_item.html"> -<link rel="import" href="multidevice_constants.html"> -<link rel="import" href="multidevice_browser_proxy.html"> -<link rel="import" href="multidevice_feature_behavior.html"> -<link rel="import" href="multidevice_feature_item.html"> -<link rel="import" href="multidevice_feature_toggle.html"> -<link rel="import" href="multidevice_task_continuation_item.html"> -<link rel="import" href="multidevice_tether_item.html"> -<link rel="import" href="multidevice_wifi_sync_item.html"> + settings-multidevice-feature-item:first-of-type { + --feature-item-border-top-style: none; + } -<dom-module id="settings-multidevice-subpage"> - <template> - <style include="settings-shared iron-flex"> - settings-multidevice-feature-item, - settings-multidevice-tether-item { - --feature-item-row-padding: 0; - } + cr-button { + white-space: nowrap; + } - settings-multidevice-feature-item:first-of-type { - --feature-item-border-top-style: none; - } - - cr-button { - white-space: nowrap; - } - - #feature-items-container { - padding-inline-start: var(--cr-section-indent-padding); - } - </style> - <div class="settings-box first"> - <div id="status-text-container" - class="start" - enabled$="[[isSuiteOn(pageContentData)]]" - inner-h-t-m-l="[[getStatusInnerHtml_(pageContentData)]]"> - </div> - <template is="dom-if" if="[[shouldShowVerifyButton_(pageContentData)]]" + #feature-items-container { + padding-inline-start: var(--cr-section-indent-padding); + } +</style> +<div class="settings-box first"> + <div id="status-text-container" + class="start" + enabled$="[[isSuiteOn(pageContentData)]]" + inner-h-t-m-l="[[getStatusInnerHtml_(pageContentData)]]"> + </div> + <template is="dom-if" if="[[shouldShowVerifyButton_(pageContentData)]]" + restamp> + <cr-button on-click="handleVerifyButtonClick_"> + $i18n{multideviceVerifyButton} + </cr-button> + </template> + <template is="dom-if" if="[[shouldShowSuiteToggle_(pageContentData)]]" + restamp> + <settings-multidevice-feature-toggle + toggle-aria-label="$i18n{multideviceSuiteToggleA11yLabel}" + feature="[[MultiDeviceFeature.BETTER_TOGETHER_SUITE]]" + page-content-data="[[pageContentData]]" + deep-link-focus-id$="[[Setting.kMultiDeviceOnOff]]"> + </settings-multidevice-feature-toggle> + </template> +</div> +<template is="dom-if" + if="[[shouldShowIndividualFeatures_(pageContentData)]]" + restamp> + <div id="feature-items-container"> + <template is="dom-if" + if="[[isFeatureSupported( + MultiDeviceFeature.SMART_LOCK, pageContentData)]]" + restamp> + <settings-multidevice-feature-item id="smartLockItem" + feature="[[MultiDeviceFeature.SMART_LOCK]]" + page-content-data="[[pageContentData]]" + subpage-route="[[routes.SMART_LOCK]]" + deep-link-focus-id$="[[Setting.kSmartLockOnOff]]"> + </settings-multidevice-feature-item> + </template> + <template is="dom-if" + if="[[isFeatureSupported( + MultiDeviceFeature.INSTANT_TETHERING, pageContentData)]]" + restamp> + <settings-multidevice-tether-item id="instantTetheringItem" + page-content-data="[[pageContentData]]" + deep-link-focus-id$="[[Setting.kInstantTetheringOnOff]]"> + </settings-multidevice-tether-item> + </template> + <template is="dom-if" + if="[[isFeatureSupported( + MultiDeviceFeature.MESSAGES, pageContentData)]]" + restamp> + <settings-multidevice-feature-item id="messagesItem" + feature="[[MultiDeviceFeature.MESSAGES]]" + page-content-data="[[pageContentData]]" + deep-link-focus-id$="[[Setting.kMessagesOnOff]] + [[Setting.kMessagesSetUp]]"> + <template is="dom-if" + if="[[doesAndroidMessagesRequireSetUp_(pageContentData)]]" restamp> - <cr-button on-click="handleVerifyButtonClick_"> - $i18n{multideviceVerifyButton} + <cr-button disabled$="[[isAndroidMessagesSetupButtonDisabled_( + pageContentData)]]" + on-click="handleAndroidMessagesButtonClick_" + slot="feature-controller"> + $i18n{multideviceSetupButton} </cr-button> </template> - <template is="dom-if" if="[[shouldShowSuiteToggle_(pageContentData)]]" - restamp> - <settings-multidevice-feature-toggle - toggle-aria-label="$i18n{multideviceSuiteToggleA11yLabel}" - feature="[[MultiDeviceFeature.BETTER_TOGETHER_SUITE]]" - page-content-data="[[pageContentData]]" - deep-link-focus-id$="[[Setting.kMultiDeviceOnOff]]"> - </settings-multidevice-feature-toggle> - </template> - </div> - <template is="dom-if" - if="[[shouldShowIndividualFeatures_(pageContentData)]]" - restamp> - <div id="feature-items-container"> - <template is="dom-if" - if="[[isFeatureSupported( - MultiDeviceFeature.SMART_LOCK, pageContentData)]]" - restamp> - <settings-multidevice-feature-item id="smartLockItem" - feature="[[MultiDeviceFeature.SMART_LOCK]]" - page-content-data="[[pageContentData]]" - subpage-route="[[routes.SMART_LOCK]]" - deep-link-focus-id$="[[Setting.kSmartLockOnOff]]"> - </settings-multidevice-feature-item> - </template> - <template is="dom-if" - if="[[isFeatureSupported( - MultiDeviceFeature.INSTANT_TETHERING, pageContentData)]]" - restamp> - <settings-multidevice-tether-item id="instantTetheringItem" - page-content-data="[[pageContentData]]" - deep-link-focus-id$="[[Setting.kInstantTetheringOnOff]]"> - </settings-multidevice-tether-item> - </template> - <template is="dom-if" - if="[[isFeatureSupported( - MultiDeviceFeature.MESSAGES, pageContentData)]]" - restamp> - <settings-multidevice-feature-item id="messagesItem" - feature="[[MultiDeviceFeature.MESSAGES]]" - page-content-data="[[pageContentData]]" - deep-link-focus-id$="[[Setting.kMessagesOnOff]] - [[Setting.kMessagesSetUp]]"> - <template is="dom-if" - if="[[doesAndroidMessagesRequireSetUp_(pageContentData)]]" - restamp> - <cr-button disabled$="[[isAndroidMessagesSetupButtonDisabled_( - pageContentData)]]" - on-click="handleAndroidMessagesButtonClick_" - slot="feature-controller"> - $i18n{multideviceSetupButton} - </cr-button> - </template> - </settings-multidevice-feature-item> - </template> - <template is="dom-if" - if="[[isFeatureSupported( - MultiDeviceFeature.PHONE_HUB, pageContentData)]]" - restamp> - <settings-multidevice-feature-item id="phoneHubItem" - feature="[[MultiDeviceFeature.PHONE_HUB]]" - page-content-data="[[pageContentData]]" - deep-link-focus-id$="[[Setting.kPhoneHubOnOff]]"> - </settings-multidevice-feature-item> - </template> - <template is="dom-if" - if="[[isFeatureSupported( - MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION, - pageContentData)]]" - restamp> - <settings-multidevice-task-continuation-item - id="phoneHubTaskContinuationItem" - page-content-data="[[pageContentData]]" - deep-link-focus-id$="[[Setting.kPhoneHubTaskContinuationOnOff]]"> - </settings-multidevice-task-continuation-item> - </template> - <template is="dom-if" - if="[[shouldShowPhoneHubCameraRollItem_(pageContentData)]]" - restamp> - <settings-multidevice-feature-item id="phoneHubCameraRollItem" - feature="[[MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL]]" - page-content-data="[[pageContentData]]" is-sub-feature - deep-link-focus-id$="[[Setting.kPhoneHubCameraRollOnOff]]"> - <template is="dom-if" - if="[[isPhoneHubCameraRollSetupRequired(pageContentData)]]" - restamp> - <cr-button on-click="handlePhoneHubSetupClick_" - slot="feature-controller" - disabled="[[isPhoneHubDisabled_(pageContentData)]]"> - $i18n{multideviceSetupButton} - </cr-button> - </template> - </settings-multidevice-feature-item> - </template> - <template is="dom-if" - if="[[shouldShowPhoneHubNotificationsItem_(pageContentData)]]" - restamp> - <settings-multidevice-feature-item id="phoneHubNotificationsItem" - feature="[[MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS]]" - icon-tooltip="[[getPhoneHubNotificationsTooltip_( - pageContentData)]]" - icon="cr:domain" - page-content-data="[[pageContentData]]" is-sub-feature - deep-link-focus-id$="[[Setting.kPhoneHubNotificationsOnOff]]"> - <template is="dom-if" - if="[[isPhoneHubNotificationsSetupRequired(pageContentData)]]" - restamp> - <cr-button on-click="handlePhoneHubSetupClick_" - slot="feature-controller" - disabled="[[isPhoneHubDisabled_(pageContentData)]]"> - $i18n{multideviceSetupButton} - </cr-button> - </template> - </settings-multidevice-feature-item> - </template> - <template is="dom-if" - if="[[shouldShowPhoneHubAppsItem_(pageContentData)]]" - restamp> - <settings-multidevice-feature-item id="phoneHubAppsItem" - feature="[[MultiDeviceFeature.ECHE]]" - page-content-data="[[pageContentData]]" is-sub-feature - deep-link-focus-id$="[[Setting.kPhoneHubAppsOnOff]]"> - <template is="dom-if" - if="[[isPhoneHubAppsSetupRequired(pageContentData)]]" - restamp> - <cr-button on-click="handlePhoneHubSetupClick_" - slot="feature-controller" - disabled="[[isPhoneHubDisabled_(pageContentData)]]"> - $i18n{multideviceSetupButton} - </cr-button> - </template> - </settings-multidevice-feature-item> - </template> - <template is="dom-if" - if="[[shouldShowPhoneHubCombinedSetupItem_(pageContentData)]]" - restamp> - <settings-multidevice-combined-setup-item - id="phoneHubCombinedSetupItem" - camera-roll="[[isPhoneHubCameraRollSetupRequired( - pageContentData)]]" - notifications="[[isPhoneHubNotificationsSetupRequired( - pageContentData)]]" - app-streaming="[[isPhoneHubAppsSetupRequired(pageContentData)]]" - page-content-data="[[pageContentData]]"> - </settings-multidevice-combined-setup-item> - </template> - <template is="dom-if" - if="[[isFeatureSupported( - MultiDeviceFeature.WIFI_SYNC, pageContentData)]]" - restamp> - <settings-multidevice-wifi-sync-item id="wifiSyncItem" - page-content-data="[[pageContentData]]" - deep-link-focus-id$="[[Setting.kWifiSyncOnOff]]"> - </settings-multidevice-wifi-sync-item> - </template> - </div> + </settings-multidevice-feature-item> </template> - <div class="settings-box two-line"> - <div id="forgetDeviceLabel" class="start" aria-hidden="true"> - $i18n{multideviceForgetDevice} - <div id="forgetDeviceSummary" class="secondary" aria-hidden="true"> - $i18n{multideviceForgetDeviceSummary} - </div> - </div> - <cr-button on-click="handleForgetDeviceClick_" - aria-labelledby="forgetDeviceLabel" - aria-describedby="forgetDeviceSummary" - deep-link-focus-id$="[[Setting.kForgetPhone]]"> - $i18n{multideviceForgetDeviceDisconnect} - </cr-button> + <template is="dom-if" + if="[[isFeatureSupported( + MultiDeviceFeature.PHONE_HUB, pageContentData)]]" + restamp> + <settings-multidevice-feature-item id="phoneHubItem" + feature="[[MultiDeviceFeature.PHONE_HUB]]" + page-content-data="[[pageContentData]]" + deep-link-focus-id$="[[Setting.kPhoneHubOnOff]]"> + </settings-multidevice-feature-item> + </template> + <template is="dom-if" + if="[[isFeatureSupported( + MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION, + pageContentData)]]" + restamp> + <settings-multidevice-task-continuation-item + id="phoneHubTaskContinuationItem" + page-content-data="[[pageContentData]]" + deep-link-focus-id$="[[Setting.kPhoneHubTaskContinuationOnOff]]"> + </settings-multidevice-task-continuation-item> + </template> + <template is="dom-if" + if="[[shouldShowPhoneHubCameraRollItem_(pageContentData)]]" + restamp> + <settings-multidevice-feature-item id="phoneHubCameraRollItem" + feature="[[MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL]]" + page-content-data="[[pageContentData]]" is-sub-feature + deep-link-focus-id$="[[Setting.kPhoneHubCameraRollOnOff]]"> + <template is="dom-if" + if="[[isPhoneHubCameraRollSetupRequired(pageContentData)]]" + restamp> + <cr-button on-click="handlePhoneHubSetupClick_" + slot="feature-controller" + disabled="[[isPhoneHubDisabled_(pageContentData)]]"> + $i18n{multideviceSetupButton} + </cr-button> + </template> + </settings-multidevice-feature-item> + </template> + <template is="dom-if" + if="[[shouldShowPhoneHubNotificationsItem_(pageContentData)]]" + restamp> + <settings-multidevice-feature-item id="phoneHubNotificationsItem" + feature="[[MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS]]" + icon-tooltip="[[getPhoneHubNotificationsTooltip_( + pageContentData)]]" + icon="cr:domain" + page-content-data="[[pageContentData]]" is-sub-feature + deep-link-focus-id$="[[Setting.kPhoneHubNotificationsOnOff]]"> + <template is="dom-if" + if="[[isPhoneHubNotificationsSetupRequired(pageContentData)]]" + restamp> + <cr-button on-click="handlePhoneHubSetupClick_" + slot="feature-controller" + disabled="[[isPhoneHubDisabled_(pageContentData)]]"> + $i18n{multideviceSetupButton} + </cr-button> + </template> + </settings-multidevice-feature-item> + </template> + <template is="dom-if" + if="[[shouldShowPhoneHubAppsItem_(pageContentData)]]" + restamp> + <settings-multidevice-feature-item id="phoneHubAppsItem" + feature="[[MultiDeviceFeature.ECHE]]" + page-content-data="[[pageContentData]]" is-sub-feature + deep-link-focus-id$="[[Setting.kPhoneHubAppsOnOff]]"> + <template is="dom-if" + if="[[isPhoneHubAppsSetupRequired(pageContentData)]]" + restamp> + <cr-button on-click="handlePhoneHubSetupClick_" + slot="feature-controller" + disabled="[[isPhoneHubDisabled_(pageContentData)]]"> + $i18n{multideviceSetupButton} + </cr-button> + </template> + </settings-multidevice-feature-item> + </template> + <template is="dom-if" + if="[[shouldShowPhoneHubCombinedSetupItem_(pageContentData)]]" + restamp> + <settings-multidevice-combined-setup-item + id="phoneHubCombinedSetupItem" + camera-roll="[[isPhoneHubCameraRollSetupRequired( + pageContentData)]]" + notifications="[[isPhoneHubNotificationsSetupRequired( + pageContentData)]]" + app-streaming="[[isPhoneHubAppsSetupRequired(pageContentData)]]" + page-content-data="[[pageContentData]]"> + </settings-multidevice-combined-setup-item> + </template> + <template is="dom-if" + if="[[isFeatureSupported( + MultiDeviceFeature.WIFI_SYNC, pageContentData)]]" + restamp> + <settings-multidevice-wifi-sync-item id="wifiSyncItem" + page-content-data="[[pageContentData]]" + deep-link-focus-id$="[[Setting.kWifiSyncOnOff]]"> + </settings-multidevice-wifi-sync-item> + </template> + </div> +</template> +<div class="settings-box two-line"> + <div id="forgetDeviceLabel" class="start" aria-hidden="true"> + $i18n{multideviceForgetDevice} + <div id="forgetDeviceSummary" class="secondary" aria-hidden="true"> + $i18n{multideviceForgetDeviceSummary} </div> - <cr-dialog id="forgetDeviceDialog"> - <div slot="title">$i18n{multideviceForgetDevice}</div> - <div slot="body"> - <div class="first"> - $i18n{multideviceForgetDeviceDialogMessage} - </div> - </div> - <div slot="button-container"> - <cr-button class="cancel-button" - on-click="onForgetDeviceDialogCancelClick_"> - $i18n{cancel} - </cr-button> - <cr-button id="confirmButton" - class="action-button" - on-click="onForgetDeviceDialogConfirmClick_"> - $i18n{multideviceForgetDeviceDisconnect} - </cr-button> - </div> - </cr-dialog> - </template> - <script src="multidevice_subpage.js"></script> -</dom-module> + </div> + <cr-button on-click="handleForgetDeviceClick_" + aria-labelledby="forgetDeviceLabel" + aria-describedby="forgetDeviceSummary" + deep-link-focus-id$="[[Setting.kForgetPhone]]"> + $i18n{multideviceForgetDeviceDisconnect} + </cr-button> +</div> +<cr-dialog id="forgetDeviceDialog"> + <div slot="title">$i18n{multideviceForgetDevice}</div> + <div slot="body"> + <div class="first"> + $i18n{multideviceForgetDeviceDialogMessage} + </div> + </div> + <div slot="button-container"> + <cr-button class="cancel-button" + on-click="onForgetDeviceDialogCancelClick_"> + $i18n{cancel} + </cr-button> + <cr-button id="confirmButton" + class="action-button" + on-click="onForgetDeviceDialogConfirmClick_"> + $i18n{multideviceForgetDeviceDisconnect} + </cr-button> + </div> +</cr-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.js index 47cfdef..e4a0a28 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.js
@@ -2,28 +2,53 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '//resources/cr_elements/cr_button/cr_button.m.js'; +import '//resources/cr_elements/cr_link_row/cr_link_row.js'; +import '//resources/cr_elements/shared_vars_css.m.js'; +import '../../settings_shared_css.js'; +import '../../settings_vars_css.js'; +import './multidevice_combined_setup_item.js'; +import './multidevice_feature_item.js'; +import './multidevice_feature_toggle.js'; +import './multidevice_task_continuation_item.js'; +import './multidevice_tether_item.js'; +import './multidevice_wifi_sync_item.js'; + +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {Route} from '../../router.js'; +import {DeepLinkingBehavior} from '../deep_linking_behavior.js'; +import {routes} from '../os_route.m.js'; +import {OsSettingsRoutes} from '../os_settings_routes.m.js'; +import {RouteObserverBehavior} from '../route_observer_behavior.js'; + +import {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from './multidevice_browser_proxy.js'; +import {MultiDeviceFeature, MultiDeviceFeatureState, MultiDeviceSettingsMode, PhoneHubFeatureAccessProhibitedReason} from './multidevice_constants.js'; +import {MultiDeviceFeatureBehavior} from './multidevice_feature_behavior.js'; + /** * @fileoverview * Subpage of settings-multidevice-page for managing multidevice features * individually and for forgetting a host. */ Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-subpage', behaviors: [ DeepLinkingBehavior, MultiDeviceFeatureBehavior, - settings.RouteObserverBehavior, + RouteObserverBehavior, ], properties: { /** - * Alias for allowing Polymer bindings to settings.routes. + * Alias for allowing Polymer bindings to routes. * @type {?OsSettingsRoutes} */ routes: { type: Object, - value: settings.routes, + value: routes, }, /** @@ -49,21 +74,21 @@ }, }, - /** @private {?settings.MultiDeviceBrowserProxy} */ + /** @private {?MultiDeviceBrowserProxy} */ browserProxy_: null, /** @override */ created() { - this.browserProxy_ = settings.MultiDeviceBrowserProxyImpl.getInstance(); + this.browserProxy_ = MultiDeviceBrowserProxyImpl.getInstance(); }, /** - * @param {!settings.Route} route - * @param {!settings.Route} oldRoute + * @param {!Route} route + * @param {!Route} oldRoute */ currentRouteChanged(route, oldRoute) { // Does not apply to this page. - if (route !== settings.routes.MULTIDEVICE_FEATURES) { + if (route !== routes.MULTIDEVICE_FEATURES) { return; } @@ -86,7 +111,7 @@ */ shouldShowIndividualFeatures_() { return this.pageContentData.mode === - settings.MultiDeviceSettingsMode.HOST_SET_VERIFIED; + MultiDeviceSettingsMode.HOST_SET_VERIFIED; }, /** @@ -95,8 +120,8 @@ */ shouldShowVerifyButton_() { return [ - settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER, - settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION, + MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER, + MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION, ].includes(this.pageContentData.mode); }, @@ -106,7 +131,7 @@ */ shouldShowSuiteToggle_() { return this.pageContentData.mode === - settings.MultiDeviceSettingsMode.HOST_SET_VERIFIED; + MultiDeviceSettingsMode.HOST_SET_VERIFIED; }, /** @private */ @@ -131,8 +156,8 @@ */ getStatusInnerHtml_() { if ([ - settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER, - settings.MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION, + MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER, + MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION, ].includes(this.pageContentData.mode)) { return this.i18nAdvanced('multideviceVerificationText'); } @@ -145,8 +170,8 @@ * @private */ doesAndroidMessagesRequireSetUp_() { - return this.getFeatureState(settings.MultiDeviceFeature.MESSAGES) === - settings.MultiDeviceFeatureState.FURTHER_SETUP_REQUIRED; + return this.getFeatureState(MultiDeviceFeature.MESSAGES) === + MultiDeviceFeatureState.FURTHER_SETUP_REQUIRED; }, /** @@ -155,10 +180,9 @@ */ isAndroidMessagesSetupButtonDisabled_() { const messagesFeatureState = - this.getFeatureState(settings.MultiDeviceFeature.MESSAGES); + this.getFeatureState(MultiDeviceFeature.MESSAGES); return !this.isSuiteOn() || - messagesFeatureState === - settings.MultiDeviceFeatureState.PROHIBITED_BY_POLICY; + messagesFeatureState === MultiDeviceFeatureState.PROHIBITED_BY_POLICY; }, getPhoneHubNotificationsTooltip_() { @@ -167,12 +191,11 @@ } switch (this.pageContentData.notificationAccessProhibitedReason) { - case settings.PhoneHubFeatureAccessProhibitedReason.UNKNOWN: + case PhoneHubFeatureAccessProhibitedReason.UNKNOWN: return this.i18n('multideviceNotificationAccessProhibitedTooltip'); - case settings.PhoneHubFeatureAccessProhibitedReason.WORK_PROFILE: + case PhoneHubFeatureAccessProhibitedReason.WORK_PROFILE: return this.i18n('multideviceNotificationAccessProhibitedTooltip'); - case settings.PhoneHubFeatureAccessProhibitedReason - .DISABLED_BY_PHONE_POLICY: + case PhoneHubFeatureAccessProhibitedReason.DISABLED_BY_PHONE_POLICY: return this.i18n( 'multideviceNotificationAccessProhibitedDisabledByAdminTooltip'); default: @@ -185,8 +208,7 @@ * @private */ shouldShowPhoneHubCameraRollItem_() { - return this.isFeatureSupported( - settings.MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL) && + return this.isFeatureSupported(MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL) && (!this.isPhoneHubCameraRollSetupRequired() || !this.shouldShowPhoneHubCombinedSetupItem_()); }, @@ -197,7 +219,7 @@ */ shouldShowPhoneHubNotificationsItem_() { return this.isFeatureSupported( - settings.MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS) && + MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS) && (!this.isPhoneHubNotificationsSetupRequired() || !this.shouldShowPhoneHubCombinedSetupItem_()); }, @@ -207,7 +229,7 @@ * @private */ shouldShowPhoneHubAppsItem_() { - return this.isFeatureSupported(settings.MultiDeviceFeature.ECHE) && + return this.isFeatureSupported(MultiDeviceFeature.ECHE) && (!this.isPhoneHubAppsSetupRequired() || !this.shouldShowPhoneHubCombinedSetupItem_()); },
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_disabled_link.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_disabled_link.html index 4cb47ce..8a81899 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_disabled_link.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_disabled_link.html
@@ -1,22 +1,8 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="chrome://resources/html/load_time_data.html"> -<link rel="import" href="../os_route.html"> -<link rel="import" href="../os_settings_routes.html"> -<link rel="import" href="../../router.html"> -<link rel="import" href="../../settings_shared_css.html"> - -<dom-module id="settings-multidevice-task-continuation-disabled-link"> - <template> - <style include="settings-shared"> - :host { - --cr-subsequent-anchors-of-span-margin: 0; - } - </style> - <div id="container" - inner-h-t-m-l="[[getAriaLabelledContent_()]]"> - </div> - </template> - <script src="multidevice_task_continuation_disabled_link.js"></script> -</dom-module> \ No newline at end of file +<style include="settings-shared"> + :host { + --cr-subsequent-anchors-of-span-margin: 0; + } +</style> +<div id="container" + inner-h-t-m-l="[[getAriaLabelledContent_()]]"> +</div>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_disabled_link.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_disabled_link.js index b64a8338..33a9e27 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_disabled_link.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_disabled_link.js
@@ -2,6 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '../../settings_shared_css.js'; + +import {I18nBehavior} from '//resources/js/i18n_behavior.m.js'; +import {loadTimeData} from '//resources/js/load_time_data.m.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {Router} from '../../router.js'; +import {routes} from '../os_route.m.js'; + /** * @fileoverview 'settings-multidevice-task-continuation-disabled-link' * creates a localized string with accessibility labels for the Phone Hub Task @@ -13,6 +22,7 @@ * and the other to a Learn More page for Phone Hub. */ Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-task-continuation-disabled-link', behaviors: [I18nBehavior], @@ -73,7 +83,7 @@ window.open('chrome://settings/syncSetup/advanced'); this.fire('opened-browser-advanced-sync-settings'); } else { - settings.Router.getInstance().navigateTo(settings.routes.SYNC_ADVANCED); + Router.getInstance().navigateTo(routes.SYNC_ADVANCED); } }, });
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_item.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_item.html index b3b1d251..e65fb6c7 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_item.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_item.html
@@ -1,35 +1,17 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="multidevice_feature_behavior.html"> -<link rel="import" href="multidevice_feature_item.html"> -<link rel="import" href="multidevice_task_continuation_disabled_link.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> -<link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="chrome://resources/html/load_time_data.html"> -<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="multidevice_constants.html"> -<link rel="import" href="../../settings_shared_css.html"> -<link rel="import" href="../../people_page/sync_browser_proxy.html"> - -<dom-module id="settings-multidevice-task-continuation-item"> - <template> - <style include="settings-shared"></style> - <settings-multidevice-feature-item id="phoneHubTaskContinuationItem" - feature="[[MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION]]" - page-content-data="[[pageContentData]]" is-sub-feature> - <template is="dom-if" if="[[!isChromeTabsSyncEnabled_]]" restamp> - <settings-multidevice-task-continuation-disabled-link - class="secondary" - id="featureSecondary" - slot="feature-summary"> - </settings-multidevice-task-continuation-disabled-link> - <!-- Replace the standard feature-controller with an always disabled and - off cr-toggle when Chrome Sync Open Tabs is disabled. When Chrome Sync - is enabled the standard feature-controller is used. --> - <cr-toggle disabled slot="feature-controller"> - </cr-toggle> - </template> - </settings-multidevice-feature-item> +<style include="settings-shared"></style> +<settings-multidevice-feature-item id="phoneHubTaskContinuationItem" + feature="[[MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION]]" + page-content-data="[[pageContentData]]" is-sub-feature> + <template is="dom-if" if="[[!isChromeTabsSyncEnabled_]]" restamp> + <settings-multidevice-task-continuation-disabled-link + class="secondary" + id="featureSecondary" + slot="feature-summary"> + </settings-multidevice-task-continuation-disabled-link> + <!-- Replace the standard feature-controller with an always disabled and + off cr-toggle when Chrome Sync Open Tabs is disabled. When Chrome Sync + is enabled the standard feature-controller is used. --> + <cr-toggle disabled slot="feature-controller"> + </cr-toggle> </template> - <script src="multidevice_task_continuation_item.js"></script> -</dom-module> +</settings-multidevice-feature-item>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_item.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_item.js index 6785c80a..6f3cded0 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_item.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_item.js
@@ -2,6 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import './multidevice_feature_item.js'; +import './multidevice_task_continuation_disabled_link.js'; +import '//resources/cr_elements/cr_toggle/cr_toggle.m.js'; +import '../../settings_shared_css.js'; + +import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {SyncBrowserProxyImpl} from '../../people_page/sync_browser_proxy.js'; + +import {MultiDeviceFeatureBehavior} from './multidevice_feature_behavior.js'; + /** * @fileoverview 'settings-multidevice-task-continuation-item' encapsulates * special logic for the phonehub task continuation item used in the multidevice @@ -17,6 +29,7 @@ * is a special case containing two links. */ Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-task-continuation-item', behaviors: [ @@ -32,12 +45,12 @@ }, }, - /** @private {?settings.SyncBrowserProxy} */ + /** @private {?SyncBrowserProxy} */ syncBrowserProxy_: null, /** @override */ created() { - this.syncBrowserProxy_ = settings.SyncBrowserProxyImpl.getInstance(); + this.syncBrowserProxy_ = SyncBrowserProxyImpl.getInstance(); }, /** @override */ @@ -61,7 +74,7 @@ /** * Handler for when the sync preferences are updated. - * @param {!settings.SyncPrefs} syncPrefs + * @param {!SyncPrefs} syncPrefs * @private */ handleSyncPrefsChanged_(syncPrefs) {
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_tether_item.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_tether_item.html index fec27f66..c5f1e4a 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_tether_item.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_tether_item.html
@@ -1,32 +1,13 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_listener_behavior.html"> -<link rel="import" href="chrome://resources/cr_components/chromeos/network/mojo_interface_provider.html"> -<link rel="import" href="chrome://resources/cr_components/chromeos/network/network_icon.html"> -<link rel="import" href="chrome://resources/cr_components/chromeos/network/onc_mojo.html"> -<link rel="import" href="../../i18n_setup.html"> -<link rel="import" href="../os_route.html"> -<link rel="import" href="../os_settings_routes.html"> -<link rel="import" href="../../settings_shared_css.html"> -<link rel="import" href="../../settings_vars_css.html"> -<link rel="import" href="multidevice_feature_behavior.html"> -<link rel="import" href="multidevice_feature_item.html"> - -<dom-module id="settings-multidevice-tether-item"> - <template> - <style include="settings-shared"></style> - <settings-multidevice-feature-item page-content-data="[[pageContentData]]" - feature="[[MultiDeviceFeature.INSTANT_TETHERING]]" - subpage-route="[[routes.INTERNET_NETWORKS]]" - subpage-route-url-search-params= - "[[getTetherNetworkUrlSearchParams_()]]"> - <network-icon slot="icon" - aria-hidden="true" - show-technology-badge="[[showTechnologyBadge_]]" - network-state="[[activeNetworkState_]]" - device-state="[[deviceState_]]"> - </network-icon> - </settings-multidevice-feature-item> - </template> - <script src="multidevice_tether_item.js"></script> -</dom-module> +<style include="settings-shared"></style> +<settings-multidevice-feature-item page-content-data="[[pageContentData]]" + feature="[[MultiDeviceFeature.INSTANT_TETHERING]]" + subpage-route="[[routes.INTERNET_NETWORKS]]" + subpage-route-url-search-params= + "[[getTetherNetworkUrlSearchParams_()]]"> + <network-icon slot="icon" + aria-hidden="true" + show-technology-badge="[[showTechnologyBadge_]]" + network-state="[[activeNetworkState_]]" + device-state="[[deviceState_]]"> + </network-icon> +</settings-multidevice-feature-item>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_tether_item.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_tether_item.js index 6b0cabcb..b6eef7a8 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_tether_item.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_tether_item.js
@@ -2,6 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '//resources/cr_components/chromeos/network/network_icon.m.js'; +import '../../settings_shared_css.js'; +import '../../settings_vars_css.js'; +import './multidevice_feature_item.js'; + +import {MojoInterfaceProviderImpl} from '//resources/cr_components/chromeos/network/mojo_interface_provider.m.js'; +import {NetworkListenerBehavior} from '//resources/cr_components/chromeos/network/network_listener_behavior.m.js'; +import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {loadTimeData} from '../../i18n_setup.js'; +import {routes} from '../os_route.m.js'; +import {OsSettingsRoutes} from '../os_settings_routes.m.js'; + +import {MultiDeviceFeatureBehavior} from './multidevice_feature_behavior.js'; + /** * @fileoverview * This element provides a layer between the settings-multidevice-subpage @@ -10,8 +26,8 @@ * networkConfig mojo API as well as updating the data in real time. It * serves a role comparable to the internet_page's network-summary element. */ - Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-tether-item', behaviors: [ @@ -35,12 +51,12 @@ activeNetworkState_: Object, /** - * Alias for allowing Polymer bindings to settings.routes. + * Alias for allowing Polymer bindings to routes. * @type {?OsSettingsRoutes} */ routes: { type: Object, - value: settings.routes, + value: routes, }, /** @@ -61,8 +77,8 @@ /** @override */ created() { - this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance() - .getMojoServiceRemote(); + this.networkConfig_ = + MojoInterfaceProviderImpl.getInstance().getMojoServiceRemote(); }, /** @override */
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_disabled_link.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_disabled_link.html index ec8fa62..8a81899 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_disabled_link.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_disabled_link.html
@@ -1,23 +1,8 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="multidevice_feature_behavior.html"> -<link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="chrome://resources/html/load_time_data.html"> -<link rel="import" href="../os_route.html"> -<link rel="import" href="../os_settings_routes.html"> -<link rel="import" href="../../router.html"> -<link rel="import" href="../../settings_shared_css.html"> - -<dom-module id="settings-multidevice-wifi-sync-disabled-link"> - <template> - <style include="settings-shared"> - :host { - --cr-subsequent-anchors-of-span-margin: 0; - } - </style> - <div id="container" - inner-h-t-m-l="[[getAriaLabelledContent_()]]"> - </div> - </template> - <script src="multidevice_wifi_sync_disabled_link.js"></script> -</dom-module> \ No newline at end of file +<style include="settings-shared"> + :host { + --cr-subsequent-anchors-of-span-margin: 0; + } +</style> +<div id="container" + inner-h-t-m-l="[[getAriaLabelledContent_()]]"> +</div>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_disabled_link.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_disabled_link.js index f5f7cb98..800e560 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_disabled_link.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_disabled_link.js
@@ -2,6 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '../../settings_shared_css.js'; + +import {loadTimeData} from '//resources/js/load_time_data.m.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {Router} from '../../router.js'; +import {routes} from '../os_route.m.js'; + +import {MultiDeviceFeatureBehavior} from './multidevice_feature_behavior.js'; + /** * @fileoverview 'settings-multidevice-wifi-sync-disabled-link' creates a * localized string with accessibility labels for the Wifi Sync feature when @@ -12,6 +22,7 @@ * and the other to a Learn More page for Wifi Sync. */ Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-wifi-sync-disabled-link', behaviors: [ @@ -65,9 +76,9 @@ if (loadTimeData.getBoolean('syncSettingsCategorizationEnabled')) { // If syncSettingsCategorization is enabled, then WiFi sync is controlled // by the OS sync settings, not the browser sync settings. - settings.Router.getInstance().navigateTo(settings.routes.OS_SYNC); + Router.getInstance().navigateTo(routes.OS_SYNC); } else { - settings.Router.getInstance().navigateTo(settings.routes.SYNC_ADVANCED); + Router.getInstance().navigateTo(routes.SYNC_ADVANCED); } }, });
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_item.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_item.html index c67f1f5..461b050 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_item.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_item.html
@@ -1,39 +1,21 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="multidevice_feature_behavior.html"> -<link rel="import" href="multidevice_feature_item.html"> -<link rel="import" href="multidevice_wifi_sync_disabled_link.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> -<link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="chrome://resources/html/load_time_data.html"> -<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="../../settings_shared_css.html"> -<link rel="import" href="../os_people_page/os_sync_browser_proxy.html"> -<link rel="import" href="../../people_page/sync_browser_proxy.html"> - -<dom-module id="settings-multidevice-wifi-sync-item"> - <template> - <style include="settings-shared"></style> - <settings-multidevice-feature-item id="wifiSyncItem" - feature="[[MultiDeviceFeature.WIFI_SYNC]]" - page-content-data="[[pageContentData]]"> - <template is="dom-if" if="[[!isWifiSyncV1Enabled_]]" restamp> - <settings-multidevice-wifi-sync-disabled-link - class="secondary" - id="featureSecondary" - slot="feature-summary"> - </settings-multidevice-wifi-sync-disabled-link> - <!-- Replace the standard feature-controller with an always disabled - cr-toggle when Chrome Sync is disabled. When Chrome Sync is enabled - the standard feature-controller is used. This is done to avoid adding - extra logic in the standard feature-controller to keep the toggle - unchecked when Chrome Sync is on but Wifi Sync host is enabled on the - backend --> - <cr-toggle disabled="true" - slot="feature-controller"> - </cr-toggle> - </template> - </settings-multidevice-feature-item> +<style include="settings-shared"></style> +<settings-multidevice-feature-item id="wifiSyncItem" + feature="[[MultiDeviceFeature.WIFI_SYNC]]" + page-content-data="[[pageContentData]]"> + <template is="dom-if" if="[[!isWifiSyncV1Enabled_]]" restamp> + <settings-multidevice-wifi-sync-disabled-link + class="secondary" + id="featureSecondary" + slot="feature-summary"> + </settings-multidevice-wifi-sync-disabled-link> + <!-- Replace the standard feature-controller with an always disabled + cr-toggle when Chrome Sync is disabled. When Chrome Sync is enabled + the standard feature-controller is used. This is done to avoid adding + extra logic in the standard feature-controller to keep the toggle + unchecked when Chrome Sync is on but Wifi Sync host is enabled on the + backend --> + <cr-toggle disabled="true" + slot="feature-controller"> + </cr-toggle> </template> - <script src="multidevice_wifi_sync_item.js"></script> -</dom-module> +</settings-multidevice-feature-item>
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_item.js b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_item.js index 9cec310..92efa01 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_item.js +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_item.js
@@ -2,6 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import './multidevice_feature_item.js'; +import './multidevice_wifi_sync_disabled_link.js'; +import '//resources/cr_elements/cr_toggle/cr_toggle.m.js'; +import '../../settings_shared_css.js'; + +import {loadTimeData} from '//resources/js/load_time_data.m.js'; +import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js'; +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {SyncBrowserProxyImpl} from '../../people_page/sync_browser_proxy.js'; +import {OsSyncBrowserProxy, OsSyncBrowserProxyImpl, OsSyncPrefs} from '../os_people_page/os_sync_browser_proxy.m.js'; + +import {MultiDeviceFeatureBehavior} from './multidevice_feature_behavior.js'; + /** * @fileoverview 'settings-multidevice-wifi-sync-item' encapsulates special * logic for the wifi sync item used in the multidevice subpage. @@ -15,6 +29,7 @@ * special case containing two links. */ Polymer({ + _template: html`{__html_template__}`, is: 'settings-multidevice-wifi-sync-item', behaviors: [ @@ -27,10 +42,10 @@ isWifiSyncV1Enabled_: Boolean, }, - /** @private {?settings.OsSyncBrowserProxy} */ + /** @private {?OsSyncBrowserProxy} */ osSyncBrowserProxy_: null, - /** @private {?settings.SyncBrowserProxy} */ + /** @private {?SyncBrowserProxy} */ syncBrowserProxy_: null, /** @override */ @@ -49,15 +64,15 @@ /** @override */ created() { if (loadTimeData.getBoolean('syncSettingsCategorizationEnabled')) { - this.osSyncBrowserProxy_ = settings.OsSyncBrowserProxyImpl.getInstance(); + this.osSyncBrowserProxy_ = OsSyncBrowserProxyImpl.getInstance(); } else { - this.syncBrowserProxy_ = settings.SyncBrowserProxyImpl.getInstance(); + this.syncBrowserProxy_ = SyncBrowserProxyImpl.getInstance(); } }, /** * Handler for when the sync preferences are updated. - * @param {!settings.SyncPrefs} syncPrefs + * @param {!SyncPrefs} syncPrefs * @private */ handleSyncPrefsChanged_(syncPrefs) { @@ -67,7 +82,7 @@ /** * Handler for when os sync preferences are updated. - * @param {!settings.OsSyncPrefs} osSyncPrefs + * @param {!OsSyncPrefs} osSyncPrefs * @private */ handleOsSyncPrefsChanged_(osSyncPrefs) {
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn index bfddc1d..ce75d7f 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_people_page/BUILD.gn
@@ -87,7 +87,7 @@ "..:os_route", "..:route_observer_behavior", "../..:router", - "../multidevice_page:multidevice_smartlock_item.m", + "../multidevice_page:multidevice_smartlock_item", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_components/chromeos/quick_unlock:lock_screen_constants.m", "//ui/webui/resources/js:assert.m",
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/lock_screen.js b/chrome/browser/resources/settings/chromeos/os_people_page/lock_screen.js index 44965bd2..edcffb6 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/lock_screen.js +++ b/chrome/browser/resources/settings/chromeos/os_people_page/lock_screen.js
@@ -25,7 +25,7 @@ import '../../prefs/prefs.js'; import '../../settings_shared_css.js'; import '../../settings_vars_css.js'; -import '../multidevice_page/multidevice_smartlock_item.m.js'; +import '../multidevice_page/multidevice_smartlock_item.js'; import {LockScreenProgress, recordLockScreenProgress} from '//resources/cr_components/chromeos/quick_unlock/lock_screen_constants.m.js'; import {assert, assertNotReached} from '//resources/js/assert.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index 6c3d02f..ca62473 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -382,6 +382,25 @@ "chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_add_account_dialog.html", "chrome/browser/resources/settings/chromeos/kerberos_page/kerberos_page.html", "chrome/browser/resources/settings/chromeos/keyboard_shortcut_banner/keyboard_shortcut_banner.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_browser_proxy.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_combined_setup_item.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_constants.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_behavior.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_item.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_notification_access_setup_dialog.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_page.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_radio_button.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_subpage.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_tether_item.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_disabled_link.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_task_continuation_item.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_disabled_link.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_wifi_sync_item.html", + "chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_smartlock_item.html", "chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_confirm_page.html", "chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_contact_visibility_dialog.html", "chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_data_usage_dialog.html",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.js b/chrome/browser/resources/settings/chromeos/os_settings.js index dfa6a8a..9775c87 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.js +++ b/chrome/browser/resources/settings/chromeos/os_settings.js
@@ -35,7 +35,7 @@ import './internet_page/tether_connection_dialog.js'; import './kerberos_page/kerberos_accounts.js'; import './kerberos_page/kerberos_page.js'; -import './multidevice_page/multidevice_page.m.js'; +import './multidevice_page/multidevice_page.js'; import './nearby_share_page/nearby_share_receive_dialog.js'; import './nearby_share_page/nearby_share_subpage.js'; import './personalization_page/change_picture.js'; @@ -121,10 +121,10 @@ export {InternetPageBrowserProxy, InternetPageBrowserProxyImpl} from './internet_page/internet_page_browser_proxy.js'; export {KerberosAccountsBrowserProxyImpl, KerberosConfigErrorCode, KerberosErrorType} from './kerberos_page/kerberos_accounts_browser_proxy.js'; export {recordClick, recordNavigation, recordPageBlur, recordPageFocus, recordSearch, recordSettingChange, setUserActionRecorderForTesting} from './metrics_recorder.m.js'; -export {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from './multidevice_page/multidevice_browser_proxy.m.js'; -export {MultiDeviceFeature, MultiDeviceFeatureState, MultiDevicePageContentData, MultiDeviceSettingsMode, PhoneHubFeatureAccessProhibitedReason, PhoneHubFeatureAccessStatus, PhoneHubPermissionsSetupMode, SmartLockSignInEnabledState} from './multidevice_page/multidevice_constants.m.js'; -export {NotificationAccessSetupOperationStatus} from './multidevice_page/multidevice_notification_access_setup_dialog.m.js'; -export {PermissionsSetupStatus, SetupFlowStatus} from './multidevice_page/multidevice_permissions_setup_dialog.m.js'; +export {MultiDeviceBrowserProxy, MultiDeviceBrowserProxyImpl} from './multidevice_page/multidevice_browser_proxy.js'; +export {MultiDeviceFeature, MultiDeviceFeatureState, MultiDevicePageContentData, MultiDeviceSettingsMode, PhoneHubFeatureAccessProhibitedReason, PhoneHubFeatureAccessStatus, PhoneHubPermissionsSetupMode, SmartLockSignInEnabledState} from './multidevice_page/multidevice_constants.js'; +export {NotificationAccessSetupOperationStatus} from './multidevice_page/multidevice_notification_access_setup_dialog.js'; +export {PermissionsSetupStatus, SetupFlowStatus} from './multidevice_page/multidevice_permissions_setup_dialog.js'; export {Account, NearbyAccountManagerBrowserProxy, NearbyAccountManagerBrowserProxyImpl} from './nearby_share_page/nearby_account_manager_browser_proxy.js'; export {getReceiveManager, observeReceiveManager, setReceiveManagerForTesting} from './nearby_share_page/nearby_share_receive_manager.js'; export {dataUsageStringToEnum, NearbyShareDataUsage} from './nearby_share_page/types.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_settings_page/BUILD.gn index 8ba15b43..e19229a2 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_settings_page/BUILD.gn
@@ -28,7 +28,7 @@ "../crostini_page:crostini_page", "../device_page:device_page", "../kerberos_page:kerberos_page", - "../multidevice_page:multidevice_page.m", + "../multidevice_page:multidevice_page", "../os_a11y_page:os_a11y_page", "../os_apps_page:android_apps_browser_proxy", "../os_apps_page:os_apps_page",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.js b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.js index 0ce06668..91bdd27 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.js +++ b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.js
@@ -25,7 +25,7 @@ import '../device_page/device_page.js'; import '../internet_page/internet_page.js'; import '../kerberos_page/kerberos_page.js'; -import '../multidevice_page/multidevice_page.m.js'; +import '../multidevice_page/multidevice_page.js'; import '../os_bluetooth_page/os_bluetooth_page.js'; import '../os_icons.js';
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn index 7c4e46ec..9dcd2757 100644 --- a/chrome/browser/safe_browsing/BUILD.gn +++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -1,5 +1,6 @@ # 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. import("//components/safe_browsing/buildflags.gni") import("//extensions/buildflags/buildflags.gni")
diff --git a/chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.cc b/chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.cc index 3b1886a1..b30452b 100644 --- a/chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.cc +++ b/chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.cc
@@ -27,17 +27,40 @@ const int kThresholdForInFlowNotificationMinutes = 5; -bool CanQueryTailoredSecurity(GURL url) { +bool CanQueryTailoredSecurityForUrl(GURL url) { return url.DomainIs("google.com") || url.DomainIs("youtube.com"); } +bool CanQueryTailoredSecurity(Profile* profile) { + if (IsEnhancedProtectionEnabled(*profile->GetPrefs())) + return false; + + // We should only trigger the unconsented UX if the user is not consented to + // sync. Syncing users have different UX, handled by the + // `ChromeTailoredSecurityService`. + signin::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile); + if (!identity_manager || + identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync)) { + return false; + } + + if (profile->GetPrefs()->GetBoolean( + prefs::kAccountTailoredSecurityShownNotification)) { + return false; + } + + return true; +} + } // namespace TailoredSecurityUrlObserver::~TailoredSecurityUrlObserver() { if (service_) { service_->RemoveObserver(this); - if (focused_ && CanQueryTailoredSecurity(last_url_)) { + if (has_query_request_) { service_->RemoveQueryRequest(); + has_query_request_ = false; } } } @@ -135,13 +158,24 @@ void TailoredSecurityUrlObserver::UpdateFocusAndURL(bool focused, const GURL& url) { + Profile* profile = + Profile::FromBrowserContext(web_contents()->GetBrowserContext()); + if (!CanQueryTailoredSecurity(profile)) { + return; + } + if (service_) { - bool should_query = focused && CanQueryTailoredSecurity(url); - bool old_should_query = focused_ && CanQueryTailoredSecurity(last_url_); - if (should_query && !old_should_query) + bool should_query = focused && CanQueryTailoredSecurityForUrl(url); + bool old_should_query = + focused_ && CanQueryTailoredSecurityForUrl(last_url_); + if (should_query && !old_should_query) { service_->AddQueryRequest(); - if (!should_query && old_should_query) + has_query_request_ = true; + } + if (!should_query && old_should_query) { service_->RemoveQueryRequest(); + has_query_request_ = false; + } } focused_ = focused;
diff --git a/chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.h b/chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.h index 2331aa9f..e612aa3 100644 --- a/chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.h +++ b/chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.h
@@ -71,6 +71,9 @@ // The most recent URL the WebContents navigated to. GURL last_url_; + // Whether we currently have a query request. + bool has_query_request_ = false; + WEB_CONTENTS_USER_DATA_KEY_DECL(); };
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextIPHController.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextIPHController.java index b40968c..4ee0121 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextIPHController.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextIPHController.java
@@ -23,6 +23,7 @@ import org.chromium.components.messages.MessageDispatcherProvider; import org.chromium.components.messages.MessageIdentifier; import org.chromium.components.messages.MessageScopeType; +import org.chromium.components.messages.PrimaryActionClickBehavior; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.url.GURL; @@ -95,9 +96,10 @@ model, tab.getWebContents(), MessageScopeType.NAVIGATION, false); } - private void onMessageButtonClicked() { + private @PrimaryActionClickBehavior int onMessageButtonClicked() { onOpenInChrome(LinkToTextHelper.SHARED_HIGHLIGHTING_SUPPORT_URL); mTracker.dismissed(FEATURE_NAME); + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; } private void onMessageDismissed(Integer dismissReason) {
diff --git a/chrome/browser/signin/chrome_signin_helper.cc b/chrome/browser/signin/chrome_signin_helper.cc index 01e8d788..87020f9 100644 --- a/chrome/browser/signin/chrome_signin_helper.cc +++ b/chrome/browser/signin/chrome_signin_helper.cc
@@ -33,8 +33,9 @@ #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/process_dice_header_delegate_impl.h" #include "chrome/browser/signin/signin_features.h" +#include "chrome/browser/signin/signin_manager.h" +#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/tab_contents/tab_util.h" -#include "chrome/browser/ui/profile_picker.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/browser/ui/webui/signin/signin_ui_error.h" @@ -70,11 +71,6 @@ #include "chrome/browser/supervised_user/supervised_user_service_factory.h" #endif // BUILDFLAG(IS_CHROMEOS_ASH) -#if BUILDFLAG(IS_CHROMEOS_LACROS) -#include "chrome/browser/lacros/account_manager/account_manager_util.h" -#include "chrome/browser/lacros/account_manager/account_profile_mapper.h" -#endif // BUILDFLAG(IS_CHROMEOS_LACROS) - #if BUILDFLAG(ENABLE_DICE_SUPPORT) #include "chrome/browser/ui/webui/signin/turn_sync_on_helper.h" #endif @@ -165,25 +161,6 @@ #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) -#if BUILDFLAG(IS_CHROMEOS_LACROS) -void OnLacrosAccountsAvailableAsSecondaryFetched( - AccountProfileMapper* mapper, - const base::FilePath& profile_path, - const std::vector<account_manager::Account>& accounts) { - if (!accounts.empty()) { - // Pass in the current profile to signal that the user wants to select a - // _secondary_ account for this particular profile. - ProfilePicker::Show(ProfilePicker::Params::ForLacrosSelectAvailableAccount( - profile_path, base::OnceCallback<void(const std::string&)>())); - return; - } - mapper->ShowAddAccountDialog(profile_path, - account_manager::AccountManagerFacade:: - AccountAdditionSource::kOgbAddAccount, - AccountProfileMapper::AddAccountCallback()); -} -#endif // BUILDFLAG(IS_CHROMEOS_LACROS) - class RequestDestructionObserverUserData : public base::SupportsUserData::Data { public: explicit RequestDestructionObserverUserData(base::OnceClosure closure) @@ -346,12 +323,9 @@ AccountProfileMapper* mapper = g_browser_process->profile_manager()->GetAccountProfileMapper(); - GetAccountsAvailableAsSecondary( - mapper, profile->GetPath(), - // It's safe to bind raw `mapper`, the callback gets called iff - // `mapper` is still valid. - base::BindOnce(&OnLacrosAccountsAvailableAsSecondaryFetched, mapper, - profile->GetPath())); + SigninManagerFactory::GetForProfile(profile)->StartWebSigninFlow( + profile->GetPath(), mapper, + account_reconcilor->GetConsistencyCookieManager()); #else ::GetAccountManagerFacade(profile->GetPath().value()) ->ShowAddAccountDialog(account_manager::AccountManagerFacade::
diff --git a/chrome/browser/signin/signin_manager.cc b/chrome/browser/signin/signin_manager.cc index 2e7736b6..8fa2b188 100644 --- a/chrome/browser/signin/signin_manager.cc +++ b/chrome/browser/signin/signin_manager.cc
@@ -4,14 +4,17 @@ #include "chrome/browser/signin/signin_manager.h" -#include "build/build_config.h" -#include "build/chromeos_buildflags.h" +#include "base/bind.h" #include "components/prefs/pref_service.h" #include "components/signin/public/base/signin_pref_names.h" #include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "components/signin/public/identity_manager/primary_account_mutator.h" +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/lacros/account_manager/web_signin_helper_lacros.h" +#endif + SigninManager::SigninManager(PrefService* prefs, signin::IdentityManager* identity_manager) : prefs_(prefs), identity_manager_(identity_manager) { @@ -26,6 +29,27 @@ SigninManager::~SigninManager() = default; +#if BUILDFLAG(IS_CHROMEOS_LACROS) +void SigninManager::StartWebSigninFlow( + const base::FilePath& profile_path, + AccountProfileMapper* account_profile_mapper, + signin::ConsistencyCookieManager* consistency_cookie_manager) { + if (web_signin_helper_lacros_) { + // There is already a signin flow in progress. + // TODO(https://crbug.com/1260291): Activate the profile picker if it's + // already open. + return; + } + + web_signin_helper_lacros_ = std::make_unique<WebSigninHelperLacros>( + profile_path, account_profile_mapper, identity_manager_, + consistency_cookie_manager, + // Using `base::Unretained()` is fine because this owns the helper. + base::BindOnce(&SigninManager::OnWebSigninHelperLacrosComplete, + base::Unretained(this))); +} +#endif + void SigninManager::UpdateUnconsentedPrimaryAccount() { // Only update the unconsented primary account only after accounts are loaded. if (!identity_manager_->AreRefreshTokensLoaded()) { @@ -218,3 +242,9 @@ void SigninManager::OnSigninAllowedPrefChanged() { UpdateUnconsentedPrimaryAccount(); } + +#if BUILDFLAG(IS_CHROMEOS_LACROS) +void SigninManager::OnWebSigninHelperLacrosComplete() { + web_signin_helper_lacros_.reset(); +} +#endif
diff --git a/chrome/browser/signin/signin_manager.h b/chrome/browser/signin/signin_manager.h index 633e48a0..d992bad0 100644 --- a/chrome/browser/signin/signin_manager.h +++ b/chrome/browser/signin/signin_manager.h
@@ -5,23 +5,47 @@ #ifndef CHROME_BROWSER_SIGNIN_SIGNIN_MANAGER_H_ #define CHROME_BROWSER_SIGNIN_SIGNIN_MANAGER_H_ +#include <memory> + #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_member.h" #include "components/signin/public/identity_manager/identity_manager.h" +namespace base { +class FilePath; +} + +#if BUILDFLAG(IS_CHROMEOS_LACROS) +namespace signin { +class ConsistencyCookieManager; +} + +class AccountProfileMapper; +class WebSigninHelperLacros; +#endif + class PrefService; class SigninManager : public KeyedService, public signin::IdentityManager::Observer { public: SigninManager(PrefService* prefs, signin::IdentityManager* identity_manger); + ~SigninManager() override; + SigninManager(const SigninManager&) = delete; SigninManager& operator=(const SigninManager&) = delete; - ~SigninManager() override; +#if BUILDFLAG(IS_CHROMEOS_LACROS) + void StartWebSigninFlow( + const base::FilePath& profile_path, + AccountProfileMapper* account_profile_mapper, + signin::ConsistencyCookieManager* consistency_cookie_manager); +#endif private: // Updates the cached version of unconsented primary account and notifies the @@ -63,6 +87,10 @@ void OnSigninAllowedPrefChanged(); +#if BUILDFLAG(IS_CHROMEOS_LACROS) + void OnWebSigninHelperLacrosComplete(); +#endif + raw_ptr<PrefService> prefs_; raw_ptr<signin::IdentityManager> identity_manager_; base::ScopedObservation<signin::IdentityManager, @@ -72,6 +100,10 @@ // Helper object to listen for changes to the signin allowed preference. BooleanPrefMember signin_allowed_; +#if BUILDFLAG(IS_CHROMEOS_LACROS) + std::unique_ptr<WebSigninHelperLacros> web_signin_helper_lacros_; +#endif + base::WeakPtrFactory<SigninManager> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/themes/theme_service_unittest.cc b/chrome/browser/themes/theme_service_unittest.cc index 5a9db26c..db5611e 100644 --- a/chrome/browser/themes/theme_service_unittest.cc +++ b/chrome/browser/themes/theme_service_unittest.cc
@@ -807,8 +807,8 @@ EXPECT_TRUE(registry_->GetInstalledExtension(scoper.extension_id())); } -// TODO(crbug.com/1056953): Enable on Fuchsia, and Linux GTK. -#if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(USE_GTK) +// TODO(crbug.com/1056953): Enable on Linux GTK. +#if BUILDFLAG(USE_GTK) #define MAYBE_GetColor DISABLED_GetColor #else #define MAYBE_GetColor GetColor
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 1d6d643a..69b4edd5 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2935,6 +2935,8 @@ "webui/signin/inline_login_handler_modal_delegate.h", "webui/signin/signin_helper_chromeos.cc", "webui/signin/signin_helper_chromeos.h", + "webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos.cc", + "webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos.h", "window_sizer/window_sizer_chromeos.cc", "window_sizer/window_sizer_chromeos.h", ]
diff --git a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeMessageController.java b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeMessageController.java index e92bc2b2..b5cb256 100644 --- a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeMessageController.java +++ b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeMessageController.java
@@ -30,6 +30,7 @@ import org.chromium.components.messages.MessageBannerProperties; import org.chromium.components.messages.MessageDispatcher; import org.chromium.components.messages.MessageIdentifier; +import org.chromium.components.messages.PrimaryActionClickBehavior; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; @@ -134,7 +135,10 @@ .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, resources.getString(R.string.auto_dark_message_button)) .with(MessageBannerProperties.ON_PRIMARY_ACTION, - () -> { onOptOutPrimaryAction(activity, settingsLauncher); }) + () -> { + onOptOutPrimaryAction(activity, settingsLauncher); + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; + }) .with(MessageBannerProperties.ON_DISMISSED, (dismissReason) -> { onOptOutMessageDismissed(profile, dismissReason); @@ -162,7 +166,10 @@ .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, resources.getString(R.string.auto_dark_message_opt_in_button)) .with(MessageBannerProperties.ON_PRIMARY_ACTION, - () -> { onOptInPrimaryAction(profile, webContents); }) + () -> { + onOptInPrimaryAction(profile, webContents); + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; + }) .with(MessageBannerProperties.ON_DISMISSED, (dismissReason) -> { onOptInMessageDismissed(activity, profile, webContents,
diff --git a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeMessageControllerUnitTest.java b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeMessageControllerUnitTest.java index 539d5617..97dc5562 100644 --- a/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeMessageControllerUnitTest.java +++ b/chrome/browser/ui/android/night_mode/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeMessageControllerUnitTest.java
@@ -106,7 +106,7 @@ } private void clickButton() { - mShownMessageModel.get(MessageBannerProperties.ON_PRIMARY_ACTION).run(); + mShownMessageModel.get(MessageBannerProperties.ON_PRIMARY_ACTION).get(); } }
diff --git a/chrome/browser/ui/android/omnibox/BUILD.gn b/chrome/browser/ui/android/omnibox/BUILD.gn index fb7c9bf1..6e7ea29 100644 --- a/chrome/browser/ui/android/omnibox/BUILD.gn +++ b/chrome/browser/ui/android/omnibox/BUILD.gn
@@ -398,7 +398,7 @@ "//chrome/test/android:chrome_java_test_support", "//components/browser_ui/site_settings/android:java", "//components/browser_ui/styles/android:java", - "//components/browser_ui/styles/android:java_resources", + "//components/browser_ui/theme/android:java_resources", "//components/browser_ui/widget/android:java", "//components/content_settings/android:content_settings_enums_java", "//components/embedder_support/android:util_java",
diff --git a/chrome/browser/ui/color/chrome_color_mixer.cc b/chrome/browser/ui/color/chrome_color_mixer.cc index 6405b97ed..0417dea 100644 --- a/chrome/browser/ui/color/chrome_color_mixer.cc +++ b/chrome/browser/ui/color/chrome_color_mixer.cc
@@ -226,7 +226,7 @@ kColorToolbarButtonIcon, kColorDownloadShelfBackground, 0x3A); mixer[kColorDownloadShelfForeground] = {kColorToolbarText}; mixer[kColorDownloadToolbarButtonActive] = {ui::kColorThrobber}; - mixer[kColorDownloadToolbarButtonInactive] = {ui::kColorMidground}; + mixer[kColorDownloadToolbarButtonInactive] = {kColorToolbarButtonIcon}; mixer[kColorDownloadToolbarButtonRingBackground] = { SkColorSetA(kColorDownloadToolbarButtonInactive, 0x33)}; mixer[kColorEyedropperBoundary] = {SK_ColorDKGRAY};
diff --git a/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc b/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc index 02fdd9b..d6a70da7 100644 --- a/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc +++ b/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc
@@ -172,15 +172,27 @@ net::DefineNetworkTrafficAnnotation("side_search_availability_test", R"( semantics { sender: "Side Search Tab Helper" - description: "Pings for the Side Search Google SRP page to check if " - "the page is available." + description: + "After the user has successfully navigated to a search results " + "page (SRP) belonging to their set default search provider, a HEAD " + "request is made to the side search SRP URL.\n" + "The side search SRP URL is generated by taking the original SRP " + "URL and appending the side search param specified in the search " + "engine's prepopulated_engines.json entry.\n" + "This is only done once per session for the currently set default " + "search engine to check the availability of the side search SRP " + "before enabling the feature. This is also gated on the current " + "default search engine signalling participation in the feature " + "with appropriate updates to its prepopulated_engines.json entry." trigger: - "After the user has successfully committed a navigation to a Google" - "SRP in a tab contents." + "After the user has successfully committed a navigation to a " + "default search engine SRP in a tab contents and the availability " + "bit for the default search engine has not already been set for " + "this session." data: - "No data sent except for the additional sidesearch URL parameter. " - "Data does not contain PII." - destination: GOOGLE_OWNED_SERVICE + "The HEAD request includes the original search URL with the " + "addition of the side search header but no PII data / cookies." + destination: WEBSITE } policy { cookies_allowed: NO @@ -197,6 +209,8 @@ ->GetDefaultStoragePartition() ->GetURLLoaderFactoryForBrowserProcess(); auto request = std::make_unique<network::ResourceRequest>(); + // Ensure cookies are not propagated with the request. + request->credentials_mode = network::mojom::CredentialsMode::kOmit; request->url = last_search_url_.value(); // Make a HEAD request to avoid generating an actual SRP page when checking // for availability of the side panel SRP.
diff --git a/chrome/browser/ui/user_education/feature_promo_controller.h b/chrome/browser/ui/user_education/feature_promo_controller.h index 18b296c..9c549f2 100644 --- a/chrome/browser/ui/user_education/feature_promo_controller.h +++ b/chrome/browser/ui/user_education/feature_promo_controller.h
@@ -254,7 +254,7 @@ // accelerator to focus the help bubble. virtual std::u16string GetFocusHelpBubbleScreenReaderHint( FeaturePromoSpecification::PromoType promo_type, - const ui::TrackedElement* anchor_element, + ui::TrackedElement* anchor_element, bool is_critical_promo) const = 0; FeaturePromoRegistry* registry() { return registry_; }
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc index 67ffdd0..ad543ba 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
@@ -481,7 +481,6 @@ prompt_->GetUserCount(), CONTEXT_DIALOG_BODY_TEXT_SMALL, views::style::STYLE_SECONDARY); user_count->SetAutoColorReadabilityEnabled(false); - user_count->SetEnabledColor(SK_ColorGRAY); user_count->SetHorizontalAlignment(gfx::ALIGN_LEFT); webstore_data_container->AddChildView(std::move(user_count)); @@ -601,16 +600,27 @@ SetLayoutManager(std::make_unique<views::FillLayout>()); const ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); - auto extension_info_container = std::make_unique<CustomScrollableView>(this); + auto extension_info_and_justification_container = + std::make_unique<CustomScrollableView>(this); const gfx::Insets content_insets = provider->GetDialogInsetsForContentType( views::DialogContentType::kControl, views::DialogContentType::kControl); - extension_info_container->SetBorder(views::CreateEmptyBorder( - 0, content_insets.left(), 0, content_insets.right())); + extension_info_and_justification_container->SetBorder( + views::CreateEmptyBorder(0, content_insets.left(), 0, + content_insets.right())); + extension_info_and_justification_container->SetLayoutManager( + std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical, gfx::Insets(), + provider->GetDistanceMetric( + views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); + const int content_width = + GetPreferredSize().width() - + extension_info_and_justification_container->GetInsets().width(); + auto* extension_info_container = + extension_info_and_justification_container->AddChildView( + std::make_unique<views::View>()); extension_info_container->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical, gfx::Insets(), provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); - const int content_width = GetPreferredSize().width() - - extension_info_container->GetInsets().width(); std::vector<ExtensionInfoSection> sections; if (prompt_->ShouldShowPermissions()) { @@ -675,19 +685,16 @@ // the |sections| vector since it is later referenced to extract the textfield // string. if (is_justification_field_enabled) { - std::unique_ptr<views::Separator> separator = - std::make_unique<views::Separator>(); - separator->SetColor(SK_ColorTRANSPARENT); - extension_info_container->AddChildView(std::move(separator)); - - justification_view_ = extension_info_container->AddChildView( - std::make_unique<ExtensionJustificationView>(this)); + justification_view_ = + extension_info_and_justification_container->AddChildView( + std::make_unique<ExtensionJustificationView>(this)); } scroll_view_ = new views::ScrollView(); scroll_view_->SetHorizontalScrollBarMode( views::ScrollView::ScrollBarMode::kDisabled); - scroll_view_->SetContents(std::move(extension_info_container)); + scroll_view_->SetContents( + std::move(extension_info_and_justification_container)); scroll_view_->ClipHeightTo( 0, provider->GetDistanceMetric( views::DISTANCE_DIALOG_SCROLLABLE_AREA_MAX_HEIGHT));
diff --git a/chrome/browser/ui/views/safe_browsing/tailored_security_unconsented_modal.cc b/chrome/browser/ui/views/safe_browsing/tailored_security_unconsented_modal.cc index 0178c82..51a1ed26 100644 --- a/chrome/browser/ui/views/safe_browsing/tailored_security_unconsented_modal.cc +++ b/chrome/browser/ui/views/safe_browsing/tailored_security_unconsented_modal.cc
@@ -54,29 +54,6 @@ chrome::FindBrowserWithWebContents(web_contents)); } -class CircleImageSource : public gfx::CanvasImageSource { - public: - CircleImageSource(int size, SkColor color) - : gfx::CanvasImageSource(gfx::Size(size, size)), color_(color) {} - - CircleImageSource(const CircleImageSource&) = delete; - CircleImageSource& operator=(const CircleImageSource&) = delete; - - ~CircleImageSource() override = default; - - void Draw(gfx::Canvas* canvas) override { - float radius = size().width() / 2.0f; - cc::PaintFlags flags; - flags.setStyle(cc::PaintFlags::kFill_Style); - flags.setAntiAlias(true); - flags.setColor(color_); - canvas->DrawCircle(gfx::PointF(radius, radius), radius, flags); - } - - private: - SkColor color_; -}; - class SuperimposedOffsetImageSource : public gfx::CanvasImageSource { public: SuperimposedOffsetImageSource(const gfx::ImageSkia& first, @@ -168,11 +145,14 @@ gfx::ImageSkiaOperations::CreateResizedImage( avatar_image, skia::ImageOperations::RESIZE_BEST, gfx::Size(kAvatarSize, kAvatarSize)); + // The color used in `circle_mask` is irrelevant as long as it's opaque; only + // the alpha channel matters. + gfx::ImageSkia circle_mask = + gfx::ImageSkiaOperations::CreateImageWithCircleBackground( + kAvatarSize / 2, SK_ColorWHITE, gfx::ImageSkia()); gfx::ImageSkia cropped_avatar_image = - gfx::ImageSkiaOperations::CreateMaskedImage( - sized_avatar_image, - gfx::CanvasImageSource::MakeImageSkia<CircleImageSource>( - sized_avatar_image.width(), SK_ColorWHITE)); + gfx::ImageSkiaOperations::CreateMaskedImage(sized_avatar_image, + circle_mask); ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); gfx::ImageSkia header_image = *bundle.GetImageSkiaNamed(IDR_TAILORED_SECURITY_UNCONSENTED);
diff --git a/chrome/browser/ui/views/side_panel/side_panel_combobox_model.cc b/chrome/browser/ui/views/side_panel/side_panel_combobox_model.cc index 902eb2da..624d896 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_combobox_model.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_combobox_model.cc
@@ -33,6 +33,27 @@ [](const auto& a, const auto& b) { return a.id < b.id; }); } +void SidePanelComboboxModel::AddItems( + const std::vector<std::unique_ptr<SidePanelEntry>>& entries) { + for (auto const& entry : entries) { + entries_.emplace_back(SidePanelComboboxModel::Item( + entry->id(), entry->name(), entry->icon())); + } + std::sort(entries_.begin(), entries_.end(), + [](const auto& a, const auto& b) { return a.id < b.id; }); +} + +void SidePanelComboboxModel::RemoveItems( + const std::vector<std::unique_ptr<SidePanelEntry>>& entries) { + for (auto const& current_entry : entries) { + SidePanelEntry::Id id = current_entry.get()->id(); + auto position = std::find_if(entries_.begin(), entries_.end(), + [id](auto entry) { return entry.id == id; }); + if (position != entries_.end()) + entries_.erase(position); + } +} + SidePanelEntry::Id SidePanelComboboxModel::GetIdAt(int index) const { return entries_[index].id; }
diff --git a/chrome/browser/ui/views/side_panel/side_panel_combobox_model.h b/chrome/browser/ui/views/side_panel/side_panel_combobox_model.h index 7891a86..ff59cba 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_combobox_model.h +++ b/chrome/browser/ui/views/side_panel/side_panel_combobox_model.h
@@ -5,7 +5,9 @@ #ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_COMBOBOX_MODEL_H_ #define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_COMBOBOX_MODEL_H_ +#include <memory> #include <string> +#include <vector> #include "chrome/browser/ui/views/side_panel/side_panel_entry.h" #include "ui/base/models/combobox_model.h" @@ -36,6 +38,8 @@ ~SidePanelComboboxModel() override; void AddItem(SidePanelEntry* entry); + void AddItems(const std::vector<std::unique_ptr<SidePanelEntry>>& entries); + void RemoveItems(const std::vector<std::unique_ptr<SidePanelEntry>>& entries); SidePanelEntry::Id GetIdAt(int index) const; // Returns the index for the given side panel entry id, if the id doesn't
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc index fb94884..3d9837a9 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
@@ -46,6 +46,8 @@ constexpr int kSidePanelContentViewId = 42; constexpr int kSidePanelContentWrapperViewId = 43; +constexpr SidePanelEntry::Id kDefaultEntry = SidePanelEntry::Id::kReadingList; + std::unique_ptr<views::ImageButton> CreateControlButton( views::View* host, base::RepeatingClosure pressed_callback, @@ -84,6 +86,7 @@ : browser_view_(browser_view), global_registry_(global_registry) { combobox_model_ = std::make_unique<SidePanelComboboxModel>(); global_registry->AddObserver(this); + browser_view_->browser()->tab_strip_model()->AddObserver(this); // TODO(pbos): Consider moving creation of SidePanelEntry into other functions // that can easily be unit tested. global_registry->Register(std::make_unique<SidePanelEntry>( @@ -114,18 +117,19 @@ } } -SidePanelCoordinator::~SidePanelCoordinator() = default; +SidePanelCoordinator::~SidePanelCoordinator() { + browser_view_->browser()->tab_strip_model()->RemoveObserver(this); +} void SidePanelCoordinator::Show(absl::optional<SidePanelEntry::Id> entry_id) { - if (!entry_id.has_value()) { - // TODO(corising): Handle choosing between last active entries when there - // are multiple registries. - entry_id = GetLastActiveEntry(); - } + if (!entry_id.has_value()) + entry_id = GetLastActiveEntryId().value_or(kDefaultEntry); SidePanelEntry* entry = GetEntryForId(entry_id.value()); - if (!entry) + if (!entry || (GetContentView() && GetLastActiveEntryId().has_value() && + GetLastActiveEntryId().value() == entry->id())) { return; + } if (GetContentView() == nullptr) { InitializeSidePanel(); @@ -148,6 +152,17 @@ if (!content_view) return; + if (global_registry_->active_entry().has_value()) { + last_active_global_entry_id_ = + global_registry_->active_entry().value()->id(); + } + // Reset active entry values for all registries since existence of an + // active_entry for a tab in any registry will trigger the side panel to be + // shown. + global_registry_->ResetActiveEntry(); + if (auto* contextual_registry = GetActiveContextualRegistry()) + contextual_registry->ResetActiveEntry(); + // TODO(pbos): Make this button observe panel-visibility state instead. browser_view_->toolbar()->side_panel_button()->SetTooltipText( l10n_util::GetStringUTF16(IDS_TOOLTIP_SIDE_PANEL_SHOW)); @@ -171,9 +186,11 @@ SidePanelEntry* SidePanelCoordinator::GetEntryForId( SidePanelEntry::Id entry_id) { - for (auto const& entry : global_registry_->entries()) { - if (entry.get()->id() == entry_id) - return entry.get(); + if (auto* entry = global_registry_->GetEntryForId(entry_id)) + return entry; + if (auto* contextual_registry = GetActiveContextualRegistry()) { + if (auto* entry = contextual_registry->GetEntryForId(entry_id)) + return entry; } return nullptr; } @@ -212,13 +229,35 @@ DCHECK(content_wrapper); content_wrapper->RemoveAllChildViews(); content_wrapper->AddChildView(entry->CreateContent()); + if (auto* contextual_registry = GetActiveContextualRegistry()) + contextual_registry->ResetActiveEntry(); entry->OnEntryShown(); } -SidePanelEntry::Id SidePanelCoordinator::GetLastActiveEntry() const { - return global_registry_->last_active_entry().has_value() - ? global_registry_->last_active_entry().value() - : SidePanelEntry::Id::kReadingList; +absl::optional<SidePanelEntry::Id> SidePanelCoordinator::GetLastActiveEntryId() + const { + // If a contextual entry is active, return that. If not, return the last + // active global entry. If neither exist, fall back to kReadingList. + if (GetActiveContextualRegistry() && + GetActiveContextualRegistry()->active_entry().has_value()) { + return GetActiveContextualRegistry()->active_entry().value()->id(); + } + + if (global_registry_->active_entry().has_value()) + return global_registry_->active_entry().value()->id(); + + if (last_active_global_entry_id_.has_value()) + return last_active_global_entry_id_.value(); + + return absl::nullopt; +} + +SidePanelRegistry* SidePanelCoordinator::GetActiveContextualRegistry() const { + if (auto* web_contents = + browser_view_->browser()->tab_strip_model()->GetActiveWebContents()) { + return SidePanelRegistry::Get(web_contents); + } + return nullptr; } std::unique_ptr<views::View> SidePanelCoordinator::CreateHeader() { @@ -269,8 +308,8 @@ std::unique_ptr<views::Combobox> SidePanelCoordinator::CreateCombobox() { auto combobox = std::make_unique<views::Combobox>(combobox_model_.get()); - combobox->SetSelectedIndex( - combobox_model_->GetIndexForId(GetLastActiveEntry())); + combobox->SetSelectedIndex(combobox_model_->GetIndexForId( + GetLastActiveEntryId().value_or(kDefaultEntry))); // TODO(corising): Replace this with something appropriate. combobox->SetAccessibleName( combobox_model_->GetItemAt(combobox->GetSelectedIndex())); @@ -320,3 +359,49 @@ void SidePanelCoordinator::OnEntryRegistered(SidePanelEntry* entry) { combobox_model_->AddItem(entry); } + +void SidePanelCoordinator::OnEntryWillDeregister(SidePanelEntry* entry) { + // Update the current entry to make sure we don't show an entry that is being + // removed. + if (GetContentView()) + Show(GetLastActiveEntryId().value_or(kDefaultEntry)); +} + +void SidePanelCoordinator::OnTabStripModelChanged( + TabStripModel* tab_strip_model, + const TabStripModelChange& change, + const TabStripSelectionChange& selection) { + if (change.type() != TabStripModelChange::kSelectionOnly || + !selection.active_tab_changed()) { + return; + } + // Handle removing the previous tab's contextual registry if one exists and + // update the combobox. + if (auto* old_contextual_registry = + SidePanelRegistry::Get(selection.old_contents)) { + old_contextual_registry->RemoveObserver(this); + combobox_model_->RemoveItems(old_contextual_registry->entries()); + } + + // Add the current tab's contextual registry and update the combobox. + auto* new_contextual_registry = + SidePanelRegistry::Get(selection.new_contents); + if (new_contextual_registry) { + new_contextual_registry->AddObserver(this); + combobox_model_->AddItems(new_contextual_registry->entries()); + } + + // If an active entry is available, show it. If not, close the panel. + if (GetContentView()) { + if ((!new_contextual_registry || + !new_contextual_registry->active_entry().has_value()) && + !global_registry_->active_entry().has_value()) { + Close(); + } else { + Show(GetLastActiveEntryId().value_or(kDefaultEntry)); + } + } else if (new_contextual_registry && + new_contextual_registry->active_entry().has_value()) { + Show(new_contextual_registry->active_entry().value()->id()); + } +}
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator.h b/chrome/browser/ui/views/side_panel/side_panel_coordinator.h index d4af393..8fe8ff5 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_coordinator.h +++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_COORDINATOR_H_ #include "base/memory/raw_ptr.h" +#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/ui/views/side_panel/side_panel_entry.h" #include "chrome/browser/ui/views/side_panel/side_panel_registry.h" #include "chrome/browser/ui/views/side_panel/side_panel_registry_observer.h" @@ -25,7 +26,13 @@ // This class is also responsible for consolidating multiple SidePanelEntry // classes across multiple SidePanelRegistry instances, potentially merging them // into a single unified side panel. -class SidePanelCoordinator final : public SidePanelRegistryObserver { +// Existence and value of registries' active_entry() determines which entry is +// visible for a given tab where the order of precedence is contextual +// registry's active_entry() then global registry's. These values are reset when +// the side panel is closed and |last_active_global_entry_id_| is used to +// determine what entry is seen when the panel is reopened. +class SidePanelCoordinator final : public SidePanelRegistryObserver, + public TabStripModelObserver { public: explicit SidePanelCoordinator(BrowserView* browser_view, SidePanelRegistry* global_registry); @@ -38,6 +45,8 @@ void Toggle(); private: + friend class SidePanelCoordinatorTest; + views::View* GetContentView(); SidePanelEntry* GetEntryForId(SidePanelEntry::Id entry_id); @@ -50,7 +59,9 @@ // Returns the last active entry or the reading list entry if no last active // entry exists. - SidePanelEntry::Id GetLastActiveEntry() const; + absl::optional<SidePanelEntry::Id> GetLastActiveEntryId() const; + + SidePanelRegistry* GetActiveContextualRegistry() const; std::unique_ptr<views::View> CreateHeader(); std::unique_ptr<views::Combobox> CreateCombobox(); @@ -61,9 +72,17 @@ // SidePanelRegistryObserver: void OnEntryRegistered(SidePanelEntry* entry) override; + void OnEntryWillDeregister(SidePanelEntry* entry) override; + + // TabStripModelObserver: + void OnTabStripModelChanged( + TabStripModel* tab_strip_model, + const TabStripModelChange& change, + const TabStripSelectionChange& selection) override; const raw_ptr<BrowserView> browser_view_; raw_ptr<SidePanelRegistry> global_registry_; + absl::optional<SidePanelEntry::Id> last_active_global_entry_id_; // Used to update SidePanelEntry options in the header_combobox_ based on // their availability in the observed side panel registries.
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc b/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc index e0ef87ce..3cc04f1 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator_unittest.cc
@@ -5,11 +5,14 @@ #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h" #include "base/feature_list.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/test_with_browser_view.h" #include "chrome/browser/ui/views/side_panel/side_panel.h" #include "chrome/browser/ui/views/side_panel/side_panel_entry.h" +#include "chrome/browser/ui/views/side_panel/side_panel_registry.h" class SidePanelCoordinatorTest : public TestWithBrowserView { public: @@ -19,17 +22,75 @@ {features::kSidePanel, features::kUnifiedSidePanel}, {}); TestWithBrowserView::SetUp(); - // Create an active web contents. - AddTab(browser_view()->browser(), GURL("about:blank")); + AddTab(browser_view()->browser(), GURL("http://foo1.com")); + AddTab(browser_view()->browser(), GURL("http://foo2.com")); + + // Add a kSideSearch entry to the contextual registry for the first tab. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + content::WebContents* active_contents = + browser_view()->GetActiveWebContents(); + auto* registry = SidePanelRegistry::Get(active_contents); + registry->Register(std::make_unique<SidePanelEntry>( + SidePanelEntry::Id::kSideSearch, u"testing1", + ui::ImageModel::FromVectorIcon(kReadLaterIcon, ui::kColorIcon), + base::BindRepeating([]() { return std::make_unique<views::View>(); }))); + contextual_registries_.push_back(registry); + + // Add a kLens entry to the contextual registry for the second tab. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(1); + active_contents = browser_view()->GetActiveWebContents(); + registry = SidePanelRegistry::Get(active_contents); + registry->Register(std::make_unique<SidePanelEntry>( + SidePanelEntry::Id::kLens, u"testing1", + ui::ImageModel::FromVectorIcon(kReadLaterIcon, ui::kColorIcon), + base::BindRepeating([]() { return std::make_unique<views::View>(); }))); + contextual_registries_.push_back(SidePanelRegistry::Get(active_contents)); + coordinator_ = browser_view()->side_panel_coordinator(); + global_registry_ = coordinator_->global_registry_; + + // Verify the first tab has one entry, kSideSearch. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + active_contents = browser_view()->GetActiveWebContents(); + SidePanelRegistry* contextual_registry = + SidePanelRegistry::Get(active_contents); + EXPECT_EQ(contextual_registry->entries().size(), 1u); + EXPECT_EQ(contextual_registry->entries()[0]->id(), + SidePanelEntry::Id::kSideSearch); + + // Verify the second tab has one entry, kLens. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(1); + active_contents = browser_view()->GetActiveWebContents(); + contextual_registry = SidePanelRegistry::Get(active_contents); + EXPECT_EQ(contextual_registry->entries().size(), 1u); + EXPECT_EQ(contextual_registry->entries()[0]->id(), + SidePanelEntry::Id::kLens); } - absl::optional<SidePanelEntry::Id> GetLastActiveEntry() { - return browser_view()->global_side_panel_registry()->last_active_entry(); + void VerifyEntryExistanceAndValue(absl::optional<SidePanelEntry*> entry, + SidePanelEntry::Id id) { + EXPECT_TRUE(entry.has_value()); + EXPECT_EQ(entry.value()->id(), id); + } + + void VerifyEntryExistanceAndValue(absl::optional<SidePanelEntry::Id> entry, + SidePanelEntry::Id id) { + EXPECT_TRUE(entry.has_value()); + EXPECT_EQ(entry.value(), id); + } + + absl::optional<SidePanelEntry::Id> GetLastActiveEntryId() { + return coordinator_->GetLastActiveEntryId(); + } + + absl::optional<SidePanelEntry::Id> GetLastActiveGlobalEntry() { + return coordinator_->last_active_global_entry_id_; } protected: raw_ptr<SidePanelCoordinator> coordinator_; + raw_ptr<SidePanelRegistry> global_registry_; + std::vector<raw_ptr<SidePanelRegistry>> contextual_registries_; }; TEST_F(SidePanelCoordinatorTest, ToggleSidePanel) { @@ -40,17 +101,347 @@ EXPECT_FALSE(browser_view()->right_aligned_side_panel()->GetVisible()); } -TEST_F(SidePanelCoordinatorTest, SwitchBetweenSidePanelEntries) { +TEST_F(SidePanelCoordinatorTest, SidePanelReopensToLastSeenGlobalEntry) { coordinator_->Toggle(); EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); coordinator_->Show(SidePanelEntry::Id::kBookmarks); - EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); - EXPECT_TRUE(GetLastActiveEntry().has_value()); - EXPECT_EQ(GetLastActiveEntry().value(), SidePanelEntry::Id::kBookmarks); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kBookmarks); + coordinator_->Toggle(); + EXPECT_FALSE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kBookmarks); + + coordinator_->Toggle(); + EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kBookmarks); +} + +TEST_F(SidePanelCoordinatorTest, ShowOpensSidePanel) { + coordinator_->Show(SidePanelEntry::Id::kBookmarks); + EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kBookmarks); +} + +TEST_F(SidePanelCoordinatorTest, SwapBetweenTabsWithReadingListOpen) { + // Verify side panel opens to kReadingList by default. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Toggle(); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); + + // Verify switching tabs does not change side panel visibility or entry seen + // if it is in the global registry. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(1); + EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); +} + +TEST_F(SidePanelCoordinatorTest, SwapBetweenTabsWithBookmarksOpen) { + // Open side panel and switch to kBookmarks and verify the active entry is + // updated. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Toggle(); + coordinator_->Show(SidePanelEntry::Id::kBookmarks); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kBookmarks); + + // Verify switching tabs does not change entry seen if it is in the global + // registry. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(1); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kBookmarks); +} + +TEST_F(SidePanelCoordinatorTest, ContextualEntryDeregistered) { + // Verify the first tab has one entry, kSideSearch. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + EXPECT_EQ(contextual_registries_[0]->entries().size(), 1u); + EXPECT_EQ(contextual_registries_[0]->entries()[0]->id(), + SidePanelEntry::Id::kSideSearch); + + // Deregister kSideSearch from the first tab. + contextual_registries_[0]->Deregister(SidePanelEntry::Id::kSideSearch); + EXPECT_EQ(contextual_registries_[0]->entries().size(), 0u); +} + +TEST_F(SidePanelCoordinatorTest, ContextualEntryDeregisteredWhileVisible) { + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Show(SidePanelEntry::Id::kSideSearch); + EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(global_registry_->active_entry().has_value()); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Deregister kSideSearch from the first tab. + contextual_registries_[0]->Deregister(SidePanelEntry::Id::kSideSearch); + EXPECT_EQ(contextual_registries_[0]->entries().size(), 0u); + + // Verify the panel defaults back to the last visible global entry or the + // reading list. + EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kReadingList); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); +} + +TEST_F(SidePanelCoordinatorTest, ShowContextualEntry) { + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Show(SidePanelEntry::Id::kSideSearch); + EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kSideSearch); +} + +TEST_F(SidePanelCoordinatorTest, + SwapBetweenTabsAfterNavaigatingToContextualEntry) { + // Open side panel and verify it opens to kReadingList by default. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Toggle(); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kReadingList); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch to a different global entry and verify the active entry is updated. + coordinator_->Show(SidePanelEntry::Id::kBookmarks); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kBookmarks); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kBookmarks); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch to a contextual entry and verify the active entry is updated. + coordinator_->Show(SidePanelEntry::Id::kSideSearch); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kSideSearch); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kBookmarks); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch to a tab where this contextual entry is not available and verify we + // fall back to the last seen global entry. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(1); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kBookmarks); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kBookmarks); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch back to the tab where the contextual entry was visible and verify it + // is shown. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kSideSearch); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kBookmarks); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); +} + +TEST_F(SidePanelCoordinatorTest, TogglePanelWithContextualEntryShowing) { + // Open side panel and verify it opens to kReadingList by default. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Toggle(); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kReadingList); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch to a different global entry and verify the active entry is updated. + coordinator_->Show(SidePanelEntry::Id::kBookmarks); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kBookmarks); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kBookmarks); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch to a contextual entry and verify the active entry is updated. + coordinator_->Show(SidePanelEntry::Id::kSideSearch); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kSideSearch); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kBookmarks); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Close the side panel and verify the contextual registry's last active entry + // is reset. + coordinator_->Toggle(); + EXPECT_FALSE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kBookmarks); + VerifyEntryExistanceAndValue(GetLastActiveGlobalEntry(), + SidePanelEntry::Id::kBookmarks); + EXPECT_FALSE(global_registry_->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Reopen the side panel and verify it reopens to the last active global + // entry. + coordinator_->Toggle(); + EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kBookmarks); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kBookmarks); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); +} + +TEST_F(SidePanelCoordinatorTest, + SwitchBetweenTabWithContextualEntryAndTabWithNoEntry) { + // Open side panel to contextual entry and verify. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Show(SidePanelEntry::Id::kSideSearch); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(global_registry_->active_entry().has_value()); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch to another tab and verify the side panel is closed. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(1); + EXPECT_FALSE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_FALSE(GetLastActiveEntryId().has_value()); + EXPECT_FALSE(global_registry_->active_entry().has_value()); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch back to the tab with the contextual entry open and verify the side + // panel is then open. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Show(SidePanelEntry::Id::kSideSearch); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(global_registry_->active_entry().has_value()); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); +} + +TEST_F( + SidePanelCoordinatorTest, + SwitchBetweenTabWithContextualEntryAndTabWithNoEntryWhenThereIsALastActiveGlobalEntry) { + coordinator_->Toggle(); + EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kReadingList); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + coordinator_->Toggle(); + EXPECT_FALSE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); + VerifyEntryExistanceAndValue(GetLastActiveGlobalEntry(), + SidePanelEntry::Id::kReadingList); + EXPECT_FALSE(global_registry_->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Open side panel to contextual entry and verify. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Show(SidePanelEntry::Id::kSideSearch); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(global_registry_->active_entry().has_value()); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch to another tab and verify the side panel is closed. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(1); + EXPECT_FALSE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); + EXPECT_FALSE(global_registry_->active_entry().has_value()); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch back to the tab with the contextual entry open and verify the side + // panel is then open. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Show(SidePanelEntry::Id::kSideSearch); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(global_registry_->active_entry().has_value()); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); +} + +TEST_F(SidePanelCoordinatorTest, + SwitchBackToTabWithPreviouslyVisibleContextualEntry) { + // Open side panel to contextual entry and verify. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + coordinator_->Show(SidePanelEntry::Id::kSideSearch); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(global_registry_->active_entry().has_value()); + VerifyEntryExistanceAndValue(contextual_registries_[0]->active_entry(), + SidePanelEntry::Id::kSideSearch); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch to a global entry and verify the contextual entry is no longer + // active. coordinator_->Show(SidePanelEntry::Id::kReadingList); EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); - EXPECT_TRUE(GetLastActiveEntry().has_value()); - EXPECT_EQ(GetLastActiveEntry().value(), SidePanelEntry::Id::kReadingList); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kReadingList); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch to a different tab and verify state. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(1); + EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kReadingList); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); + + // Switch back to the original tab and verify the contextual entry is not + // active or showing. + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + EXPECT_TRUE(browser_view()->right_aligned_side_panel()->GetVisible()); + EXPECT_TRUE(GetLastActiveEntryId().has_value()); + EXPECT_EQ(GetLastActiveEntryId().value(), SidePanelEntry::Id::kReadingList); + VerifyEntryExistanceAndValue(global_registry_->active_entry(), + SidePanelEntry::Id::kReadingList); + EXPECT_FALSE(contextual_registries_[0]->active_entry().has_value()); + EXPECT_FALSE(contextual_registries_[1]->active_entry().has_value()); }
diff --git a/chrome/browser/ui/views/side_panel/side_panel_entry.cc b/chrome/browser/ui/views/side_panel/side_panel_entry.cc index 4c55fe9..0ae2e91 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_entry.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_entry.cc
@@ -28,7 +28,7 @@ void SidePanelEntry::OnEntryShown() { for (SidePanelEntryObserver& observer : observers_) - observer.OnEntryShown(id_); + observer.OnEntryShown(this); } void SidePanelEntry::AddObserver(SidePanelEntryObserver* observer) {
diff --git a/chrome/browser/ui/views/side_panel/side_panel_entry.h b/chrome/browser/ui/views/side_panel/side_panel_entry.h index 2ea279a0..d61aef4 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_entry.h +++ b/chrome/browser/ui/views/side_panel/side_panel_entry.h
@@ -20,7 +20,7 @@ class SidePanelEntry final { public: // Note this order matches that of the combobox options in the side panel. - enum class Id { kReadingList, kBookmarks, kReaderMode }; + enum class Id { kReadingList, kBookmarks, kReaderMode, kSideSearch, kLens }; // TODO(pbos): Add an icon ImageModel here. SidePanelEntry(Id id,
diff --git a/chrome/browser/ui/views/side_panel/side_panel_entry_observer.h b/chrome/browser/ui/views/side_panel/side_panel_entry_observer.h index 0a187e2..8a5c0c87c 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_entry_observer.h +++ b/chrome/browser/ui/views/side_panel/side_panel_entry_observer.h
@@ -11,7 +11,7 @@ class SidePanelEntryObserver : public base::CheckedObserver { public: // Called when a SidePanelEntry is shown. - virtual void OnEntryShown(SidePanelEntry::Id id) {} + virtual void OnEntryShown(SidePanelEntry* entry) {} protected: ~SidePanelEntryObserver() override = default;
diff --git a/chrome/browser/ui/views/side_panel/side_panel_registry.cc b/chrome/browser/ui/views/side_panel/side_panel_registry.cc index 2f67b00..ab95f075 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_registry.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_registry.cc
@@ -4,13 +4,45 @@ #include "chrome/browser/ui/views/side_panel/side_panel_registry.h" +#include "base/containers/cxx20_erase.h" +#include "base/containers/unique_ptr_adapters.h" #include "base/observer_list.h" #include "chrome/browser/ui/views/side_panel/side_panel_registry_observer.h" +#include "content/public/browser/web_contents.h" + +const char kSidePanelRegistryKey[] = "side_panel_registry_key"; SidePanelRegistry::SidePanelRegistry() = default; SidePanelRegistry::~SidePanelRegistry() = default; +// static +SidePanelRegistry* SidePanelRegistry::Get(content::WebContents* web_contents) { + if (!web_contents) + return nullptr; + SidePanelRegistry* registry = static_cast<SidePanelRegistry*>( + web_contents->GetUserData(kSidePanelRegistryKey)); + if (!registry) { + auto new_registry = std::make_unique<SidePanelRegistry>(); + registry = new_registry.get(); + web_contents->SetUserData(kSidePanelRegistryKey, std::move(new_registry)); + } + return registry; +} + +SidePanelEntry* SidePanelRegistry::GetEntryForId(SidePanelEntry::Id entry_id) { + auto it = + std::find_if(entries_.begin(), entries_.end(), + [entry_id](const std::unique_ptr<SidePanelEntry>& entry) { + return entry.get()->id() == entry_id; + }); + return it == entries_.end() ? nullptr : it->get(); +} + +void SidePanelRegistry::ResetActiveEntry() { + active_entry_.reset(); +} + void SidePanelRegistry::AddObserver(SidePanelRegistryObserver* observer) { observers_.AddObserver(observer); } @@ -26,6 +58,27 @@ entries_.push_back(std::move(entry)); } -void SidePanelRegistry::OnEntryShown(SidePanelEntry::Id id) { - last_active_entry_ = id; +void SidePanelRegistry::Deregister(SidePanelEntry::Id id) { + for (auto const& entry : entries_) { + if (entry.get()->id() == id) { + entry.get()->RemoveObserver(this); + if (active_entry_.has_value() && + entry.get()->id() == active_entry_.value()->id()) { + active_entry_.reset(); + } + for (SidePanelRegistryObserver& observer : observers_) { + observer.OnEntryWillDeregister(entry.get()); + } + RemoveEntry(entry.get()); + return; + } + } +} + +void SidePanelRegistry::OnEntryShown(SidePanelEntry* entry) { + active_entry_ = entry; +} + +void SidePanelRegistry::RemoveEntry(SidePanelEntry* entry) { + base::EraseIf(entries_, base::MatchesUniquePtr(entry)); }
diff --git a/chrome/browser/ui/views/side_panel/side_panel_registry.h b/chrome/browser/ui/views/side_panel/side_panel_registry.h index c4da24a..9cec2b1 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_registry.h +++ b/chrome/browser/ui/views/side_panel/side_panel_registry.h
@@ -9,35 +9,53 @@ #include <vector> #include "base/observer_list.h" +#include "base/supports_user_data.h" #include "chrome/browser/ui/views/side_panel/side_panel_entry.h" #include "chrome/browser/ui/views/side_panel/side_panel_entry_observer.h" +namespace content { +class WebContents; +} // namespace content + class SidePanelRegistryObserver; // This class is used for storing SidePanelEntries specific to a context. This // context can be one per tab or one per window. See also SidePanelCoordinator. -class SidePanelRegistry final : public SidePanelEntryObserver { +class SidePanelRegistry final : public base::SupportsUserData::Data, + public SidePanelEntryObserver { public: SidePanelRegistry(); SidePanelRegistry(const SidePanelRegistry&) = delete; SidePanelRegistry& operator=(const SidePanelRegistry&) = delete; ~SidePanelRegistry() override; + // Gets the contextual registry for the tab associated with |web_contents|. + // Can return null for non-tab contents. + static SidePanelRegistry* Get(content::WebContents* web_contents); + + SidePanelEntry* GetEntryForId(SidePanelEntry::Id entry_id); + void ResetActiveEntry(); + void AddObserver(SidePanelRegistryObserver* observer); void RemoveObserver(SidePanelRegistryObserver* observer); void Register(std::unique_ptr<SidePanelEntry> entry); + void Deregister(SidePanelEntry::Id id); - absl::optional<SidePanelEntry::Id> last_active_entry() { - return last_active_entry_; - } + absl::optional<SidePanelEntry*> active_entry() { return active_entry_; } std::vector<std::unique_ptr<SidePanelEntry>>& entries() { return entries_; } // SidePanelEntryObserver: - void OnEntryShown(SidePanelEntry::Id id) override; + void OnEntryShown(SidePanelEntry* id) override; private: - absl::optional<SidePanelEntry::Id> last_active_entry_; + void RemoveEntry(SidePanelEntry* entry); + + // The last active entry hosted in the side panel used to determine what entry + // should be visible. This is reset by the coordinator when the panel is + // closed. When there are multiple registries, this may not be the entry + // currently visible in the side panel. + absl::optional<SidePanelEntry*> active_entry_; std::vector<std::unique_ptr<SidePanelEntry>> entries_;
diff --git a/chrome/browser/ui/views/side_panel/side_panel_registry_observer.h b/chrome/browser/ui/views/side_panel/side_panel_registry_observer.h index 135cc56..341c148d 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_registry_observer.h +++ b/chrome/browser/ui/views/side_panel/side_panel_registry_observer.h
@@ -14,6 +14,10 @@ // Called when a SidePanelEntry is added to the registry. virtual void OnEntryRegistered(SidePanelEntry* entry) {} + // Called immediately before a SidePanelEntry is being removed from the + // registry. + virtual void OnEntryWillDeregister(SidePanelEntry* entry) {} + protected: ~SidePanelRegistryObserver() override = default; };
diff --git a/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.cc b/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.cc index 52e3c70b..7752d0c 100644 --- a/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.cc +++ b/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.cc
@@ -70,8 +70,6 @@ set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH)); - SetIcon(gfx::CreateVectorIcon(chromeos::kNotificationSupervisedUserIcon, - SK_ColorDKGRAY)); SetShowIcon(true); ConfigureTitle(); CreateContents(); @@ -83,6 +81,12 @@ std::move(done_callback_).Run(); } +void ExtensionInstallBlockedByParentDialogView::OnThemeChanged() { + views::DialogDelegateView::OnThemeChanged(); + SetIcon(gfx::CreateVectorIcon(chromeos::kNotificationSupervisedUserIcon, + GetColorProvider()->GetColor(ui::kColorIcon))); +} + void ExtensionInstallBlockedByParentDialogView::ConfigureTitle() { std::u16string title_string; switch (action_) { @@ -121,9 +125,6 @@ break; } - icon_ = gfx::CreateVectorIcon(chromeos::kNotificationSupervisedUserIcon, - SK_ColorDKGRAY); - const ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); const gfx::Insets content_insets = provider->GetDialogInsetsForContentType( views::DialogContentType::kText, views::DialogContentType::kText);
diff --git a/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.h b/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.h index 0a20053..6b7ec98 100644 --- a/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.h +++ b/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog_view.h
@@ -43,6 +43,8 @@ const ExtensionInstallBlockedByParentDialogView&) = delete; ~ExtensionInstallBlockedByParentDialogView() override; + void OnThemeChanged() override; + private: void ConfigureTitle(); void CreateContents(); @@ -50,7 +52,6 @@ const extensions::Extension* extension_ = nullptr; chrome::ExtensionInstalledBlockedByParentDialogAction action_; - gfx::ImageSkia icon_; base::OnceClosure done_callback_; };
diff --git a/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.cc b/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.cc index 22ed6a1..4f17b0a 100644 --- a/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.cc +++ b/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.cc
@@ -289,6 +289,8 @@ SetModalType(ui::MODAL_TYPE_WINDOW); SetShowCloseButton(true); + SetCloseCallback(base::BindOnce(&ParentPermissionDialogView::OnDialogClose, + base::Unretained(this))); set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH)); @@ -384,12 +386,24 @@ GetBubbleFrameView()->SetTitleView(std::move(message_container).Build()); } +void ParentPermissionDialogView::OnDialogClose() { + // If the dialog is closed without the user clicking "approve" consider this + // as ParentPermissionCanceled to avoid showing an error message. If the + // user clicked "accept", then that async process will send the result, or if + // that doesn't complete, eventually the destructor will send a failure + // result. + if (!is_approve_clicked_) { + SendResultOnce(ParentPermissionDialog::Result::kParentPermissionCanceled); + } +} + bool ParentPermissionDialogView::Cancel() { - SendResult(ParentPermissionDialog::Result::kParentPermissionCanceled); + SendResultOnce(ParentPermissionDialog::Result::kParentPermissionCanceled); return true; } bool ParentPermissionDialogView::Accept() { + is_approve_clicked_ = true; // Disable the dialog temporarily while we validate the parent's credentials, // which can take some time because it involves a series of async network // requests. @@ -601,7 +615,7 @@ supervised_user_metrics_recorder_.RecordParentPermissionDialogUmaMetrics( SupervisedUserExtensionsMetricsRecorder::ParentPermissionDialogState:: kNoParentError); - SendResult(ParentPermissionDialog::Result::kParentPermissionFailed); + SendResultOnce(ParentPermissionDialog::Result::kParentPermissionFailed); } } @@ -692,7 +706,7 @@ signin::AccessTokenInfo access_token_info) { oauth2_access_token_fetcher_.reset(); if (error.state() != GoogleServiceAuthError::NONE) { - SendResult(ParentPermissionDialog::Result::kParentPermissionFailed); + SendResultOnce(ParentPermissionDialog::Result::kParentPermissionFailed); CloseWithReason(views::Widget::ClosedReason::kUnspecified); return; } @@ -714,7 +728,7 @@ child_access_token, parent_obfuscated_gaia_id, credential); } -void ParentPermissionDialogView::SendResult( +void ParentPermissionDialogView::SendResultOnce( ParentPermissionDialog::Result result) { if (!params_->done_callback) return; @@ -741,7 +755,7 @@ void ParentPermissionDialogView::OnReAuthProofTokenSuccess( const std::string& reauth_proof_token) { - SendResult(ParentPermissionDialog::Result::kParentPermissionReceived); + SendResultOnce(ParentPermissionDialog::Result::kParentPermissionReceived); CloseWithReason(views::Widget::ClosedReason::kAcceptButtonClicked); } @@ -764,7 +778,7 @@ return; } } - SendResult(ParentPermissionDialog::Result::kParentPermissionFailed); + SendResultOnce(ParentPermissionDialog::Result::kParentPermissionFailed); CloseWithReason(views::Widget::ClosedReason::kUnspecified); }
diff --git a/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.h b/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.h index 7d0a9350..4d71aaf 100644 --- a/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.h +++ b/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.h
@@ -108,6 +108,7 @@ void OnExtensionIconLoaded(const gfx::Image& image); void LoadExtensionIcon(); void CloseWithReason(views::Widget::ClosedReason reason); + void OnDialogClose(); // Given an email address of the child's parent, return the parents' // obfuscated gaia id. @@ -136,7 +137,9 @@ void OnReAuthProofTokenFailure( const GaiaAuthConsumer::ReAuthProofTokenStatus error) override; - void SendResult(ParentPermissionDialog::Result result); + // The first time it is called, logs the result to UMA and passes it to the + // callback. No effect if called subsequent times. + void SendResultOnce(ParentPermissionDialog::Result result); // Sets the |extension| to be optionally displayed in the dialog. This // causes the view to show several extension properties including the @@ -173,6 +176,10 @@ // Used to ensure we don't try to show same dialog twice. bool is_showing_ = false; + // Used to set close reason if the dialog is closed without clicking + // "approve." + bool is_approve_clicked_ = false; + // Used to fetch the Reauth token. std::unique_ptr<GaiaAuthFetcher> reauth_token_fetcher_;
diff --git a/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view_browsertest.cc b/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view_browsertest.cc index 8adfdb69..ba3e157 100644 --- a/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view_browsertest.cc
@@ -56,6 +56,7 @@ enum class NextDialogAction { kCancel, kAccept, + kClose, }; ParentPermissionDialogViewTest() @@ -123,6 +124,9 @@ case NextDialogAction::kAccept: view_->AcceptDialog(); break; + case NextDialogAction::kClose: + view_->CloseDialog(); + break; } } } @@ -313,6 +317,13 @@ CheckResult(ParentPermissionDialog::Result::kParentPermissionCanceled); } +IN_PROC_BROWSER_TEST_F(ParentPermissionDialogViewTest, PermissionDialogClosed) { + set_next_dialog_action( + ParentPermissionDialogViewTest::NextDialogAction::kClose); + ShowPrompt(); + CheckResult(ParentPermissionDialog::Result::kParentPermissionCanceled); +} + IN_PROC_BROWSER_TEST_F(ParentPermissionDialogViewTest, PermissionReceivedForExtension) { base::HistogramTester histogram_tester;
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index aed490a8..6c75eb6 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -100,6 +100,7 @@ #include "ui/views/cascading_property.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/scroll_view.h" +#include "ui/views/interaction/element_tracker_views.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/masked_targeter_delegate.h" #include "ui/views/mouse_watcher_view_host.h" @@ -2063,6 +2064,8 @@ // isn't the tab we just added. AnnounceTabAddedToGroup(target_group.value()); controller_->AddTabToGroup(start_index, target_group.value()); + views::ElementTrackerViews::GetInstance()->NotifyCustomEvent( + kTabGroupedCustomEventId, tab); return; } }
diff --git a/chrome/browser/ui/views/user_education/browser_feature_promo_controller.cc b/chrome/browser/ui/views/user_education/browser_feature_promo_controller.cc index 55050b6..0b37f0e 100644 --- a/chrome/browser/ui/views/user_education/browser_feature_promo_controller.cc +++ b/chrome/browser/ui/views/user_education/browser_feature_promo_controller.cc
@@ -11,8 +11,10 @@ #include "chrome/grit/generated_resources.h" #include "ui/base/interaction/element_tracker.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/views/accessible_pane_view.h" #include "ui/views/interaction/element_tracker_views.h" #include "ui/views/view.h" +#include "ui/views/view_utils.h" BrowserFeaturePromoController::BrowserFeaturePromoController( BrowserView* browser_view, @@ -88,7 +90,7 @@ std::u16string BrowserFeaturePromoController::GetFocusHelpBubbleScreenReaderHint( FeaturePromoSpecification::PromoType promo_type, - const ui::TrackedElement* anchor_element, + ui::TrackedElement* anchor_element, bool is_critical_promo) const { // No message is required as this is a background bubble with a // screen reader-specific prompt and will dismiss itself. @@ -105,7 +107,9 @@ // Present the user with the full help bubble navigation shortcut. auto* const anchor_view = anchor_element->AsA<views::TrackedElementViews>(); - if (anchor_view && anchor_view->view()->IsAccessibilityFocusable()) { + if (anchor_view && + (anchor_view->view()->IsAccessibilityFocusable() || + views::IsViewClass<views::AccessiblePaneView>(anchor_view->view()))) { return l10n_util::GetStringFUTF16(IDS_FOCUS_HELP_BUBBLE_TOGGLE_DESCRIPTION, accelerator_text); }
diff --git a/chrome/browser/ui/views/user_education/browser_feature_promo_controller.h b/chrome/browser/ui/views/user_education/browser_feature_promo_controller.h index f63a3c2..94b87e1 100644 --- a/chrome/browser/ui/views/user_education/browser_feature_promo_controller.h +++ b/chrome/browser/ui/views/user_education/browser_feature_promo_controller.h
@@ -89,7 +89,7 @@ // accelerator to focus the help bubble. std::u16string GetFocusHelpBubbleScreenReaderHint( FeaturePromoSpecification::PromoType promo_type, - const ui::TrackedElement* anchor_element, + ui::TrackedElement* anchor_element, bool is_critical_promo) const override; private:
diff --git a/chrome/browser/ui/views/user_education/help_bubble_factory_views.cc b/chrome/browser/ui/views/user_education/help_bubble_factory_views.cc index 24fe9fb..a29dbd6 100644 --- a/chrome/browser/ui/views/user_education/help_bubble_factory_views.cc +++ b/chrome/browser/ui/views/user_education/help_bubble_factory_views.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/logging.h" #include "base/memory/ptr_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" @@ -16,7 +17,28 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/base/interaction/element_identifier.h" #include "ui/base/interaction/element_tracker.h" +#include "ui/views/accessible_pane_view.h" +#include "ui/views/bubble/bubble_dialog_delegate_view.h" #include "ui/views/interaction/element_tracker_views.h" +#include "ui/views/view_utils.h" + +namespace { + +// Returns whether losing focus would cause a widget to be destroyed. +// This prevents us from accidentally closing a widget a bubble is anchored to +// at the cost of not being able to directly access the help bubble. +bool BlurWouldCloseWidget(const views::Widget* widget) { + // Right now, we can only ask the question if we know the bubble is + // controlled by a BubbleDialogDelegateView, since runtime type information + // isn't present for any of the other objects involved. + auto* const contents = widget->widget_delegate()->GetContentsView(); + return contents && + views::IsViewClass<views::BubbleDialogDelegateView>(contents) && + static_cast<const views::BubbleDialogDelegateView*>(contents) + ->close_on_deactivate(); +} + +} // namespace DEFINE_FRAMEWORK_SPECIFIC_METADATA(HelpBubbleViews) DEFINE_FRAMEWORK_SPECIFIC_METADATA(HelpBubbleFactoryViews) @@ -51,16 +73,34 @@ ->GetFocusedView(); // If the focus isn't in the help bubble, focus the help bubble. - if (is_focus_in_ancestor_widget) { + // Note that if is_focus_in_ancestor_widget is true, then anchor both exists + // and has a widget, so anchor->GetWidget() will always be valid. + if (is_focus_in_ancestor_widget && + !BlurWouldCloseWidget(anchor->GetWidget())) { help_bubble_view_->GetWidget()->Activate(); help_bubble_view_->RequestFocus(); return true; } - // If the anchor isn't accessibility-focusable, we can't toggle focus. - if (!anchor || !anchor->IsAccessibilityFocusable()) + if (!anchor) return false; + // An AccessiblePaneView can receive focus, but is not necessarily itself + // accessibility focusable. Use the built-in functionality for focusing + // elements of AccessiblePaneView instead. + if (!anchor->IsAccessibilityFocusable()) { + if (views::IsViewClass<views::AccessiblePaneView>(anchor)) { + // You can't focus an accessible pane if it's already in accessibility + // mode, so avoid doing that; the SetPaneFocus() call will go back into + // accessibility navigation mode. + anchor->GetFocusManager()->SetKeyboardAccessible(false); + return static_cast<views::AccessiblePaneView*>(anchor)->SetPaneFocus( + nullptr); + } else { + return false; + } + } + // Focus the anchor. We can't request focus for an accessibility-only view // until we turn on keyboard accessibility for its focus manager. anchor->GetFocusManager()->SetKeyboardAccessible(true);
diff --git a/chrome/browser/ui/views/user_education/help_bubble_view.cc b/chrome/browser/ui/views/user_education/help_bubble_view.cc index 973b200..dfedc65 100644 --- a/chrome/browser/ui/views/user_education/help_bubble_view.cc +++ b/chrome/browser/ui/views/user_education/help_bubble_view.cc
@@ -203,6 +203,8 @@ void OnThemeChanged() override { views::ImageButton::OnThemeChanged(); + constexpr float kCloseButtonFocusRingHaloThickness = 1.25f; + const auto* theme_provider = GetThemeProvider(); SetImage(views::ImageButton::STATE_NORMAL, gfx::CreateVectorIcon( @@ -211,6 +213,10 @@ ThemeProperties::COLOR_FEATURE_PROMO_BUBBLE_FOREGROUND))); views::InkDrop::Get(this)->SetBaseColor(theme_provider->GetColor( ThemeProperties::COLOR_FEATURE_PROMO_BUBBLE_CLOSE_BUTTON_INK_DROP)); + views::FocusRing::Get(this)->SetColor(theme_provider->GetColor( + ThemeProperties::COLOR_FEATURE_PROMO_BUBBLE_FOREGROUND)); + views::FocusRing::Get(this)->SetHaloThickness( + kCloseButtonFocusRingHaloThickness); } }; @@ -546,14 +552,17 @@ views::FlexSpecification(button_layout.GetDefaultFlexRule())); // Want a consistent initial focused view if one is available. - if (close_button) - SetInitiallyFocusedView(close_button); - else if (!button_container->children().empty()) + if (!button_container->children().empty()) { SetInitiallyFocusedView(button_container->children()[0]); + } else if (close_button) { + SetInitiallyFocusedView(close_button); + } set_margins(gfx::Insets()); set_title_margins(gfx::Insets()); SetButtons(ui::DIALOG_BUTTON_NONE); + set_close_on_deactivate(false); + set_focus_traversable_from_anchor_view(false); views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(this);
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index 1805574..bb2804b 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -1556,13 +1556,13 @@ GURL(ash::multidevice::kChromeUIProximityAuthURL), GURL(chrome::kOsUIRestartURL), GURL(chrome::kChromeUIScanningAppURL), GURL(chrome::kOsUIScanningAppURL), GURL(chrome::kChromeUISetTimeURL), - GURL(chrome::kChromeUIOSSettingsURL), GURL(chrome::kChromeUISettingsURL), + GURL(chrome::kChromeUIOSSettingsURL), GURL(chrome::kOsUISettingsURL), GURL(chrome::kOsUISettingsURL), GURL(chrome::kOsUISignInInternalsURL), GURL(chrome::kChromeUISlowURL), GURL(chrome::kChromeUISmbShareURL), - GURL(chrome::kOsUISyncInternalsURL), - GURL(chrome::kChromeUISysInternalsUrl), GURL(chrome::kOsUITermsURL), - GURL(chrome::kChromeUIUserImageURL), GURL(chrome::kOsUIVersionURL), - GURL(chrome::kChromeUIVmUrl), GURL(chrome::kOsUISystemURL), + GURL(chrome::kOsUISyncInternalsURL), GURL(chrome::kOsUISysInternalsUrl), + GURL(chrome::kOsUITermsURL), GURL(chrome::kChromeUIUserImageURL), + GURL(chrome::kOsUIVersionURL), GURL(chrome::kChromeUIVmUrl), + GURL(chrome::kOsUISystemURL), // The CL to land this didn't land yet. Once landed they need to be moved // to Lacros. However - as the refactor might precede this, there is no // TODO for it.
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index 840e967..220c465 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -255,10 +255,6 @@ AddCallback("launchIncognito", &SigninScreenHandler::HandleLaunchIncognito); AddCallback("offlineLogin", &SigninScreenHandler::HandleOfflineLogin); - // TODO(crbug.com/1168114): This is also called by GAIA screen, - // but might not be needed anymore - AddCallback("loginUIStateChanged", - &SigninScreenHandler::HandleLoginUIStateChanged); AddCallback("showLoadingTimeoutError", &SigninScreenHandler::HandleShowLoadingTimeoutError); } @@ -510,28 +506,6 @@ LoginDisplayHost::default_host()->StartWizard(OfflineLoginView::kScreenId); } -void SigninScreenHandler::HandleToggleKioskAutolaunchScreen() { - if (delegate_ && !webui::IsEnterpriseManaged()) - delegate_->ShowKioskAutolaunchScreen(); -} - -void SigninScreenHandler::HandleLoginUIStateChanged(const std::string& source, - bool active) { - VLOG(0) << "Login WebUI >> active: " << active << ", " - << "source: " << source; - - if (!KioskAppManager::Get()->GetAutoLaunchApp().empty() && - KioskAppManager::Get()->IsAutoLaunchRequested()) { - VLOG(0) << "Showing auto-launch warning"; - // On slow devices, the wallpaper animation is not shown initially, so we - // must explicitly load the wallpaper. This is also the case for the - // account-picker and gaia-signin UI states. - LoginDisplayHost::default_host()->LoadSigninWallpaper(); - HandleToggleKioskAutolaunchScreen(); - return; - } -} - void SigninScreenHandler::HandleShowLoadingTimeoutError() { UpdateState(NetworkError::ERROR_REASON_LOADING_TIMEOUT); }
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h index c148dae..dad44a3f 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
@@ -55,9 +55,6 @@ // Returns true if sign in is in progress. virtual bool IsSigninInProgress() const = 0; - // Shows Reset screen. - virtual void ShowKioskAutolaunchScreen() = 0; - // --------------- Rest of the methods. // Whether user sign in has completed. @@ -134,11 +131,7 @@ // WebUI message handlers. void HandleLaunchIncognito(); void HandleOfflineLogin(); - void HandleToggleEnrollmentScreen(); - void HandleToggleResetScreen(); - void HandleToggleKioskAutolaunchScreen(); - void HandleLoginUIStateChanged(const std::string& source, bool active); void HandleShowLoadingTimeoutError(); // Returns true if current visible screen is the Gaia sign-in page.
diff --git a/chrome/browser/ui/webui/feedback/feedback_ui.cc b/chrome/browser/ui/webui/feedback/feedback_ui.cc index 9391c8a4..5e30c5a 100644 --- a/chrome/browser/ui/webui/feedback/feedback_ui.cc +++ b/chrome/browser/ui/webui/feedback/feedback_ui.cc
@@ -7,6 +7,7 @@ #include "build/chromeos_buildflags.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/webui_url_constants.h" +#include "chrome/grit/browser_resources.h" #include "chrome/grit/feedback_resources.h" #include "chrome/grit/feedback_resources_map.h" #include "chrome/grit/generated_resources.h" @@ -71,7 +72,13 @@ content::WebUIDataSource::Create(chrome::kChromeUIFeedbackHost); source->AddResourcePaths( base::make_span(kFeedbackResources, kFeedbackResourcesSize)); + source->AddResourcePath("", IDR_FEEDBACK_DEFAULT_HTML); + + // Register the CSS file from chrome://system manually as that style is + // re-used by chrome://feedback/html/sys_info.html. + source->AddResourcePath("css/about_sys.css", IDR_ABOUT_SYS_CSS); + source->UseStringsJs(); AddStringResources(source, profile);
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc index c99f8ed..eba14d7 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -279,8 +279,6 @@ {"printToPDF", IDS_PRINT_PREVIEW_PRINT_TO_PDF}, {"printing", IDS_PRINT_PREVIEW_PRINTING}, {"recentDestinationsTitle", IDS_PRINT_PREVIEW_RECENT_DESTINATIONS_TITLE}, - {"registerPrinterInformationMessage", - IDS_CLOUD_PRINT_REGISTER_PRINTER_INFORMATION}, {"resolveExtensionUSBDialogTitle", IDS_PRINT_PREVIEW_RESOLVE_EXTENSION_USB_DIALOG_TITLE}, {"resolveExtensionUSBErrorMessage",
diff --git a/chrome/browser/ui/webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos.cc b/chrome/browser/ui/webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos.cc new file mode 100644 index 0000000..c1472ef5 --- /dev/null +++ b/chrome/browser/ui/webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos.cc
@@ -0,0 +1,228 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos.h" + +#include "base/json/json_string_value_serializer.h" +#include "base/strings/stringprintf.h" +#include "components/policy/core/browser/browser_policy_connector.h" +#include "google_apis/gaia/gaia_constants.h" +#include "google_apis/gaia/gaia_urls.h" +#include "google_apis/gaia/google_service_auth_error.h" +#include "net/base/load_flags.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "services/network/public/mojom/url_response_head.mojom.h" + +namespace ash { + +namespace { + +const char kAuthorizationHeaderFormat[] = "Bearer %s"; +const char kSecureConnectApiGetSecondaryGoogleAccountUsageUrl[] = + "https://secureconnect-pa.clients6.google.com/" + "v1:getManagedAccountsSigninRestriction"; +const char kJsonContentType[] = "application/json"; +const char kChromeOSPolicyHeader[] = "x-chromeos-policy"; +const char kSecondaryGoogleAccountUsage[] = "SecondaryGoogleAccountUsage"; +// Presence of this key in the user info response indicates whether the user is +// on a hosted domain. +const char kHostedDomainKey[] = "hd"; +constexpr net::NetworkTrafficAnnotationTag annotation = + net::DefineNetworkTrafficAnnotation( + "managed_acccount_signin_restrictions_secure_connect", + R"( + semantics { + sender: "Chrome OS sign-in restrictions" + description: + "A request to the SecureConnect API to retrieve the value of the " + "SecondaryGoogleAccountUsage policy for the signed in user." + trigger: + "After a user signs into a managed account as a secondary account in " + "Chrome OS." + data: + "Gaia access token." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: NO + chrome_policy { + SigninInterceptionEnabled { + SigninInterceptionEnabled: false + } + } + })"); + +std::unique_ptr<network::SimpleURLLoader> CreateUrlLoader( + const GURL& url, + const std::string& access_token, + const net::NetworkTrafficAnnotationTag& annotation) { + auto resource_request = std::make_unique<network::ResourceRequest>(); + + resource_request->url = url; + resource_request->method = net::HttpRequestHeaders::kGetMethod; + resource_request->load_flags = net::LOAD_DISABLE_CACHE; + resource_request->headers.SetHeader(net::HttpRequestHeaders::kContentType, + kJsonContentType); + + resource_request->headers.SetHeader( + net::HttpRequestHeaders::kAuthorization, + base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str())); + resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit; + // Add header to fetch the SecondaryGoogleAccountUsage policy from the API. + resource_request->headers.SetHeader(kChromeOSPolicyHeader, + kSecondaryGoogleAccountUsage); + auto url_loader = + network::SimpleURLLoader::Create(std::move(resource_request), annotation); + return url_loader; +} + +} // namespace + +UserCloudSigninRestrictionPolicyFetcherChromeOS:: + UserCloudSigninRestrictionPolicyFetcherChromeOS( + const std::string& email, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + : email_(email), url_loader_factory_(url_loader_factory) { + DCHECK(url_loader_factory_); +} + +UserCloudSigninRestrictionPolicyFetcherChromeOS:: + ~UserCloudSigninRestrictionPolicyFetcherChromeOS() = default; + +void UserCloudSigninRestrictionPolicyFetcherChromeOS:: + GetSecondaryGoogleAccountUsage( + std::unique_ptr<OAuth2AccessTokenFetcher> access_token_fetcher, + PolicyInfoCallback callback) { + DCHECK(access_token_fetcher); + DCHECK(callback); + DCHECK(!callback_) << "A request is already in progress"; + callback_ = std::move(callback); + if (policy::BrowserPolicyConnector::IsNonEnterpriseUser(email_)) { + // Non Enterprise accounts do not have restrictions. + std::move(callback_).Run(/*status=*/Status::kUnsupportedAccountTypeError, + /*policy=*/absl::nullopt, + /*domain=*/std::string()); + return; + } + access_token_fetcher_ = std::move(access_token_fetcher); + FetchAccessToken(); +} + +void UserCloudSigninRestrictionPolicyFetcherChromeOS::FetchAccessToken() { + access_token_fetcher_->Start( + GaiaUrls::GetInstance()->oauth2_chrome_client_id(), + GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), + {GaiaConstants::kGoogleUserInfoEmail, + GaiaConstants::kGoogleUserInfoProfile}); +} + +void UserCloudSigninRestrictionPolicyFetcherChromeOS::OnGetTokenSuccess( + const TokenResponse& token_response) { + access_token_ = token_response.access_token; + FetchUserInfo(); +} + +void UserCloudSigninRestrictionPolicyFetcherChromeOS::OnGetTokenFailure( + const GoogleServiceAuthError& error) { + // TODO(b/223628330): Implement retry strategy. + LOG(ERROR) << "Failed to fetch access token for consumer: " + << GetConsumerName() << " with error: " << error.ToString(); + std::move(callback_).Run(/*status=*/Status::kGetTokenError, + /*policy=*/absl::nullopt, + /*domain=*/std::string()); +} + +std::string UserCloudSigninRestrictionPolicyFetcherChromeOS::GetConsumerName() + const { + return "signin_restriction_policy_fetcher"; +} + +void UserCloudSigninRestrictionPolicyFetcherChromeOS::FetchUserInfo() { + // TODO(b/224743604): Inject UserInfoFetcher as a dependency. + user_info_fetcher_ = + std::make_unique<policy::UserInfoFetcher>(this, url_loader_factory_); + user_info_fetcher_->Start(access_token_); +} + +void UserCloudSigninRestrictionPolicyFetcherChromeOS::OnGetUserInfoSuccess( + const base::DictionaryValue* user_info) { + // Check if the user account has a hosted domain. + if (user_info->HasKey(kHostedDomainKey)) { + hosted_domain_ = user_info->FindKey(kHostedDomainKey)->GetString(); + GetSecondaryGoogleAccountUsageInternal(); + } else { + // Non Enterprise accounts do not have restrictions. + DVLOG(1) << "User account is not an Enterprise account"; + std::move(callback_).Run(/*status=*/Status::kUnsupportedAccountTypeError, + /*policy=*/absl::nullopt, + /*domain=*/std::string()); + } +} + +void UserCloudSigninRestrictionPolicyFetcherChromeOS::OnGetUserInfoFailure( + const GoogleServiceAuthError& error) { + LOG(ERROR) << "Failed to fetch user info: " << error.ToString(); + std::move(callback_).Run(/*status=*/Status::kGetUserInfoError, + /*policy=*/absl::nullopt, + /*domain=*/std::string()); +} + +void UserCloudSigninRestrictionPolicyFetcherChromeOS:: + GetSecondaryGoogleAccountUsageInternal() { + // Each url loader can only be used for one request. + url_loader_ = + CreateUrlLoader(GURL(kSecureConnectApiGetSecondaryGoogleAccountUsageUrl), + access_token_, annotation); + // base::Unretained is safe here because `url_loader_` is owned by `this`. + url_loader_->DownloadToString( + url_loader_factory_.get(), + base::BindOnce(&UserCloudSigninRestrictionPolicyFetcherChromeOS:: + OnSecondaryGoogleAccountUsageResult, + base::Unretained(this)), + 1024 * 1024 /* 1 MiB */); +} + +void UserCloudSigninRestrictionPolicyFetcherChromeOS:: + OnSecondaryGoogleAccountUsageResult( + std::unique_ptr<std::string> response_body) { + absl::optional<std::string> restriction; + Status status = Status::kUnknownError; + std::unique_ptr<network::SimpleURLLoader> url_loader = std::move(url_loader_); + + GoogleServiceAuthError error = GoogleServiceAuthError::AuthErrorNone(); + absl::optional<int> response_code; + if (url_loader->ResponseInfo() && url_loader->ResponseInfo()->headers) + response_code = url_loader->ResponseInfo()->headers->response_code(); + + if (url_loader->NetError() != net::OK) { + if (response_code) { + LOG(ERROR) << "SecondaryGoogleAccountUsage request " + "failed with HTTP code: " + << response_code.value(); + status = Status::kHttpError; + } else { + error = + GoogleServiceAuthError::FromConnectionError(url_loader->NetError()); + LOG(ERROR) << "SecondaryGoogleAccountUsage request " + "failed with error: " + << url_loader->NetError(); + status = Status::kNetworkError; + } + } else if (error.state() == GoogleServiceAuthError::NONE) { + auto result = base::JSONReader::Read(*response_body, base::JSON_PARSE_RFC); + constexpr base::StringPiece policy_value_key = "policyValue"; + if (response_body && result && result->FindStringKey(policy_value_key)) { + restriction = *result->FindStringKey(policy_value_key); + status = Status::kSuccess; + } else { + LOG(ERROR) << "Failed to parse SecondaryGoogleAccountUsage response"; + status = Status::kParsingResponseError; + } + } + + std::move(callback_).Run(status, restriction, hosted_domain_); +} + +} // namespace ash
diff --git a/chrome/browser/ui/webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos.h b/chrome/browser/ui/webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos.h new file mode 100644 index 0000000..04d8c585 --- /dev/null +++ b/chrome/browser/ui/webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos.h
@@ -0,0 +1,149 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_SIGNIN_USER_CLOUD_SIGNIN_RESTRICTION_POLICY_FETCHER_CHROMEOS_H_ +#define CHROME_BROWSER_UI_WEBUI_SIGNIN_USER_CLOUD_SIGNIN_RESTRICTION_POLICY_FETCHER_CHROMEOS_H_ + +#include <string> + +#include "components/policy/core/common/cloud/user_info_fetcher.h" +#include "google_apis/gaia/oauth2_access_token_consumer.h" +#include "google_apis/gaia/oauth2_access_token_fetcher.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace network { +class SimpleURLLoader; +} + +namespace ash { + +// UserCloudSigninRestrictionPolicyFetcherChromeOS handles requesting +// SecondaryGoogleAccountUsage policy value for Chrome OS. +// During this fetch, two extra requests need to be made: +// +// 1 - Requesting access token with the following scopes: +// - GaiaConstants::kGoogleUserInfoEmail +// - GaiaConstants::kGoogleUserInfoProfile +// 2 - Checking if the account is an Enterprise account +// +// After fetching the policy value, it will run `callback` with the fetched +// value, `Status::kSuccess` status and the hosted domain of the account. If any +// error occurs during the process of fetching the policy value, `callback` will +// run with `absl::nullopt` and a proper error status value to inform about the +// error. If the account is not an Enterprise account, `callback` will run with +// `absl::nullopt` and `Status::kUnsupportedAccountTypeError`. +// +// Note: This class is meant to be used in a one-shot fashion and cannot handle +// multiple requests at the same time. +// +// Example usage: +// +// std::unique_ptr<GaiaAccessTokenFetcher> access_token_fetcher = ...; +// base::OnceCallback<void( +// UserCloudSigninRestrictionPolicyFetcherChromeOS::Status, +// absl::optional<std::string>, const std::string&)> callback = ...; +// +// UserCloudSigninRestrictionPolicyFetcherChromeOS +// restriction_fetcher("alice@example.com", url_loader_factory); +// restriction_fetcher.GetSecondaryGoogleAccountUsage( +// std::move(access_token_fetcher), callback); +// TODO(b/222695699): Refactor this class to share code with +// UserCloudSigninRestrictionPolicyFetcher. +class UserCloudSigninRestrictionPolicyFetcherChromeOS + : public policy::UserInfoFetcher::Delegate, + public OAuth2AccessTokenConsumer { + public: + enum Status { + kSuccess = 0, + kNetworkError, + kHttpError, + kParsingResponseError, + kUnsupportedAccountTypeError, + kGetTokenError, + kGetUserInfoError, + kUnknownError + }; + + // Callback invoked when SecondaryGoogleAccountUsage policy value + // is fetched. `policy` is the fetched policy value. `domain` is the + // Enterprise account hosted domain. + using PolicyInfoCallback = + base::OnceCallback<void(Status status, + absl::optional<std::string> policy, + const std::string& domain)>; + + // `email` can be a raw email (abc.123.4@gmail.com) or a canonicalized email + // (abc1234@gmail.com). It's used to skip API requests for domains such as + // gmail.com and others since these type of users are known to be + // non-enterprise. For more information check + // policy::BrowserPolicyConnector::IsNonEnterpriseUser. + UserCloudSigninRestrictionPolicyFetcherChromeOS( + const std::string& email, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); + ~UserCloudSigninRestrictionPolicyFetcherChromeOS() override; + + UserCloudSigninRestrictionPolicyFetcherChromeOS( + const UserCloudSigninRestrictionPolicyFetcherChromeOS&) = delete; + UserCloudSigninRestrictionPolicyFetcherChromeOS& operator=( + const UserCloudSigninRestrictionPolicyFetcherChromeOS&) = delete; + + // Fetches the value of the SecondaryGoogleAccountUsage policy and runs + // `callback` with the fetched value and `Status::kSuccess` status. + // + // If the policy was not set, `callback` will run with `absl::nullopt` and + // `Status::kSuccess` status. + // If there was an error in fetching the policy, `callback` will run with + // `absl::nullopt` and the proper error status. + void GetSecondaryGoogleAccountUsage( + std::unique_ptr<OAuth2AccessTokenFetcher> access_token_fetcher, + PolicyInfoCallback callback); + + // Protected for testing. + protected: + // UserInfoFetcher::Delegate. + void OnGetUserInfoSuccess(const base::DictionaryValue* user_info) override; + void OnGetUserInfoFailure(const GoogleServiceAuthError& error) override; + + // UserInfoFetcher::OAuth2AccessTokenConsumer. + void OnGetTokenSuccess(const TokenResponse& token_response) override; + void OnGetTokenFailure(const GoogleServiceAuthError& error) override; + std::string GetConsumerName() const override; + + // Retrieves the policy value from `response_body` and runs `callback` with + // the retrieved value and `Status::kSuccess` status if successful. + // If there was an error in fetching the policy, it will runs `callback` with + // `absl::nullopt` and the proper error status. + void OnSecondaryGoogleAccountUsageResult( + std::unique_ptr<std::string> response_body); + + private: + // Fetch access token with `GaiaConstants::kGoogleUserInfoEmail` and + // `GaiaConstants::kGoogleUserInfoProfile` scopes to get the policy + // restriction value for the account. + // Virtual for testing. + virtual void FetchAccessToken(); + // Fetch user info to check if the account is an Enterprise account or not. + // Virtual for testing. + virtual void FetchUserInfo(); + // Calls the SecureConnect API to get the SecondaryGoogleAccountUsage + // policy using `access_token` for the authentication. Calls + // `OnSecondaryGoogleAccountUsageResult` with the result from the API. + void GetSecondaryGoogleAccountUsageInternal(); + + std::string email_; + std::string hosted_domain_; + std::string access_token_; + + std::unique_ptr<OAuth2AccessTokenFetcher> access_token_fetcher_; + std::unique_ptr<policy::UserInfoFetcher> user_info_fetcher_; + PolicyInfoCallback callback_; + + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; + std::unique_ptr<network::SimpleURLLoader> url_loader_; +}; + +} // namespace ash + +#endif // CHROME_BROWSER_UI_WEBUI_SIGNIN_USER_CLOUD_SIGNIN_RESTRICTION_POLICY_FETCHER_CHROMEOS_H_
diff --git a/chrome/browser/ui/webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos_unittest.cc b/chrome/browser/ui/webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos_unittest.cc new file mode 100644 index 0000000..03ffe01 --- /dev/null +++ b/chrome/browser/ui/webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos_unittest.cc
@@ -0,0 +1,356 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos.h" + +#include <memory> + +#include "base/bind.h" +#include "base/json/json_string_value_serializer.h" +#include "base/test/bind.h" +#include "base/test/task_environment.h" +#include "google_apis/gaia/gaia_access_token_fetcher.h" +#include "google_apis/gaia/google_service_auth_error.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace ash { + +namespace { +const char kSecureConnectApiGetSecondaryGoogleAccountUsageUrl[] = + "https://secureconnect-pa.clients6.google.com/" + "v1:getManagedAccountsSigninRestriction"; +const char kFakeAccessToken[] = "fake-access-token"; +const char kFakeRefreshToken[] = "fake-refresh-token"; +const char kFakeEnterpriseAccount[] = "alice@acme.com"; +const char kFakeEnterpriseDomain[] = "acme.com"; +const char kFakeGmailAccount[] = "example@gmail.com"; +const char kFakeNonEnterpriseAccount[] = "alice@nonenterprise.com"; +const char KBadResponseBody[] = "bad-response-body"; +} // namespace + +class MockUserCloudSigninRestrictionPolicyFetcherChromeOS + : public UserCloudSigninRestrictionPolicyFetcherChromeOS { + public: + MockUserCloudSigninRestrictionPolicyFetcherChromeOS( + const std::string& email, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + : UserCloudSigninRestrictionPolicyFetcherChromeOS(email, + url_loader_factory) { + ON_CALL(*this, FetchAccessToken).WillByDefault([this]() { + return this->OnGetTokenSuccess( + OAuth2AccessTokenConsumer::TokenResponse::Builder() + .WithAccessToken(kFakeAccessToken) + .build()); + }); + ON_CALL(*this, FetchUserInfo).WillByDefault([this]() { + return this->OnGetUserInfoSuccess( + std::move(user_info_response_dictionary_.get())); + }); + } + + MockUserCloudSigninRestrictionPolicyFetcherChromeOS( + const MockUserCloudSigninRestrictionPolicyFetcherChromeOS&) = delete; + MockUserCloudSigninRestrictionPolicyFetcherChromeOS& operator=( + const MockUserCloudSigninRestrictionPolicyFetcherChromeOS&) = delete; + + // TODO(b/224747082): Remove overrides. + void OnGetTokenFailure(const GoogleServiceAuthError& error); + void OnGetUserInfoFailure(const GoogleServiceAuthError& error); + + MOCK_METHOD(void, FetchAccessToken, ()); + MOCK_METHOD(void, FetchUserInfo, ()); + + std::unique_ptr<base::DictionaryValue> user_info_response_dictionary_ = + std::make_unique<base::DictionaryValue>(); +}; + +void MockUserCloudSigninRestrictionPolicyFetcherChromeOS::OnGetTokenFailure( + const GoogleServiceAuthError& error) { + UserCloudSigninRestrictionPolicyFetcherChromeOS::OnGetTokenFailure(error); +} + +void MockUserCloudSigninRestrictionPolicyFetcherChromeOS::OnGetUserInfoFailure( + const GoogleServiceAuthError& error) { + UserCloudSigninRestrictionPolicyFetcherChromeOS::OnGetUserInfoFailure(error); +} + +class UserCloudSigninRestrictionPolicyFetcherChromeOSTest + : public ::testing::Test { + public: + UserCloudSigninRestrictionPolicyFetcherChromeOSTest() = default; + + scoped_refptr<network::SharedURLLoaderFactory> GetSharedURLLoaderFactory() { + return base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &url_loader_factory_); + } + + // Set dictionary values that will be used by `OnGetUserInfoResponse` to fake + // API server response. + void SetHostedDomain( + MockUserCloudSigninRestrictionPolicyFetcherChromeOS& restriction_fetcher, + const std::string& hosted_domain) { + restriction_fetcher.user_info_response_dictionary_->DictClear(); + restriction_fetcher.user_info_response_dictionary_->SetKey( + "hd", base::Value(hosted_domain)); + } + + protected: + // Get policy value for SecondaryGoogleAccountUsage. + void GetSecondaryGoogleAccountUsageBlocking( + MockUserCloudSigninRestrictionPolicyFetcherChromeOS* const + restriction_fetcher, + std::unique_ptr<OAuth2AccessTokenFetcher> access_token_fetcher) { + base::RunLoop run_loop; + restriction_fetcher->GetSecondaryGoogleAccountUsage( + std::move(access_token_fetcher), + base::BindLambdaForTesting( + [this, &run_loop]( + MockUserCloudSigninRestrictionPolicyFetcherChromeOS::Status st, + absl::optional<std::string> res, const std::string& hd) { + this->policy_result_ = res; + this->status_ = st; + this->hosted_domain_ = hd; + run_loop.Quit(); + })); + run_loop.Run(); + } + std::unique_ptr<OAuth2AccessTokenFetcher> CreateAccessTokenFetcher( + MockUserCloudSigninRestrictionPolicyFetcherChromeOS* + restriction_fetcher) { + return GaiaAccessTokenFetcher:: + CreateExchangeRefreshTokenForAccessTokenInstance( + restriction_fetcher, GetSharedURLLoaderFactory(), + kFakeRefreshToken); + } + + // Check base/test/task_environment.h. This must be the first member / + // declared before any member that cares about tasks. + base::test::SingleThreadTaskEnvironment task_environment_{ + base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED}; + + MockUserCloudSigninRestrictionPolicyFetcherChromeOS::Status status_ = + MockUserCloudSigninRestrictionPolicyFetcherChromeOS::Status:: + kUnknownError; + absl::optional<std::string> policy_result_; + std::string hosted_domain_; + network::TestURLLoaderFactory url_loader_factory_; +}; + +TEST_F(UserCloudSigninRestrictionPolicyFetcherChromeOSTest, + FetchingPolicyValueSucceeds) { + // Set API response. + base::Value expected_response(base::Value::Type::DICTIONARY); + expected_response.SetStringKey("policyValue", "primary_account_signin"); + std::string response; + JSONStringValueSerializer serializer(&response); + ASSERT_TRUE(serializer.Serialize(expected_response)); + url_loader_factory_.AddResponse( + kSecureConnectApiGetSecondaryGoogleAccountUsageUrl, std::move(response)); + + // Create policy fetcher. + MockUserCloudSigninRestrictionPolicyFetcherChromeOS restriction_fetcher( + kFakeEnterpriseAccount, GetSharedURLLoaderFactory()); + SetHostedDomain(restriction_fetcher, kFakeEnterpriseDomain); + + // Create access token fetcher. + std::unique_ptr<OAuth2AccessTokenFetcher> access_token_fetcher = + CreateAccessTokenFetcher(&restriction_fetcher); + + GetSecondaryGoogleAccountUsageBlocking(&restriction_fetcher, + std::move(access_token_fetcher)); + + EXPECT_TRUE(policy_result_.has_value()); + EXPECT_EQ(policy_result_.value(), "primary_account_signin"); + EXPECT_EQ( + status_, + MockUserCloudSigninRestrictionPolicyFetcherChromeOS::Status::kSuccess); + EXPECT_EQ(hosted_domain_, kFakeEnterpriseDomain); +} + +TEST_F(UserCloudSigninRestrictionPolicyFetcherChromeOSTest, + FetchingUserInfoFailsForNetworkConnectionErrors) { + // Create policy fetcher. + MockUserCloudSigninRestrictionPolicyFetcherChromeOS restriction_fetcher( + kFakeEnterpriseAccount, GetSharedURLLoaderFactory()); + + // Create access token fetcher. + std::unique_ptr<OAuth2AccessTokenFetcher> access_token_fetcher = + CreateAccessTokenFetcher(&restriction_fetcher); + + // TODO(b/224754860): Use mocked dependency injection and remove this. + // Fake a failed UserInfo fetch. + EXPECT_CALL(restriction_fetcher, FetchUserInfo()) + .WillOnce([&restriction_fetcher]() { + return restriction_fetcher.OnGetUserInfoFailure( + GoogleServiceAuthError::FromConnectionError(0)); + }); + + // Try to fetch policy value. + GetSecondaryGoogleAccountUsageBlocking(&restriction_fetcher, + std::move(access_token_fetcher)); + + EXPECT_FALSE(policy_result_.has_value()); + EXPECT_EQ(status_, MockUserCloudSigninRestrictionPolicyFetcherChromeOS:: + Status::kGetUserInfoError); + EXPECT_EQ(hosted_domain_, std::string()); +} + +TEST_F(UserCloudSigninRestrictionPolicyFetcherChromeOSTest, + FetchingAccessTokenFailsForNetworkConnectionErrors) { + // Create policy fetcher. + MockUserCloudSigninRestrictionPolicyFetcherChromeOS restriction_fetcher( + kFakeEnterpriseAccount, GetSharedURLLoaderFactory()); + + // Create access token fetcher. + std::unique_ptr<OAuth2AccessTokenFetcher> access_token_fetcher = + CreateAccessTokenFetcher(&restriction_fetcher); + + // TODO(b/224754860): Use mocked dependency injection and remove this. + // Fake a failed AccessToken fetch. + EXPECT_CALL(restriction_fetcher, FetchAccessToken()) + .WillOnce([&restriction_fetcher]() { + return restriction_fetcher.OnGetTokenFailure( + GoogleServiceAuthError::FromConnectionError(0)); + }); + + // Try to fetch policy value. + GetSecondaryGoogleAccountUsageBlocking(&restriction_fetcher, + std::move(access_token_fetcher)); + + EXPECT_FALSE(policy_result_.has_value()); + EXPECT_EQ(status_, MockUserCloudSigninRestrictionPolicyFetcherChromeOS:: + Status::kGetTokenError); + EXPECT_EQ(hosted_domain_, std::string()); +} + +TEST_F(UserCloudSigninRestrictionPolicyFetcherChromeOSTest, + FetchingPolicyValueFailsForNetworkErrors) { + // Fake network error. + url_loader_factory_.AddResponse( + GURL(kSecureConnectApiGetSecondaryGoogleAccountUsageUrl), + /*head=*/network::mojom::URLResponseHead::New(), + /*content=*/std::string(), + network::URLLoaderCompletionStatus(net::ERR_INTERNET_DISCONNECTED), + network::TestURLLoaderFactory::Redirects(), + network::TestURLLoaderFactory::ResponseProduceFlags:: + kSendHeadersOnNetworkError); + + // Create policy fetcher. + MockUserCloudSigninRestrictionPolicyFetcherChromeOS restriction_fetcher( + kFakeEnterpriseAccount, GetSharedURLLoaderFactory()); + SetHostedDomain(restriction_fetcher, kFakeEnterpriseDomain); + + // Create access token fetcher. + std::unique_ptr<OAuth2AccessTokenFetcher> access_token_fetcher = + CreateAccessTokenFetcher(&restriction_fetcher); + + // Try to fetch policy value. + GetSecondaryGoogleAccountUsageBlocking(&restriction_fetcher, + std::move(access_token_fetcher)); + + EXPECT_FALSE(policy_result_.has_value()); + EXPECT_EQ(status_, MockUserCloudSigninRestrictionPolicyFetcherChromeOS:: + Status::kNetworkError); + EXPECT_EQ(hosted_domain_, kFakeEnterpriseDomain); +} + +TEST_F(UserCloudSigninRestrictionPolicyFetcherChromeOSTest, + FetchingPolicyValueFailsForHTTPErrors) { + url_loader_factory_.AddResponse( + kSecureConnectApiGetSecondaryGoogleAccountUsageUrl, std::string(), + net::HTTP_BAD_GATEWAY); + + // Create policy fetcher. + MockUserCloudSigninRestrictionPolicyFetcherChromeOS restriction_fetcher( + kFakeEnterpriseAccount, GetSharedURLLoaderFactory()); + SetHostedDomain(restriction_fetcher, kFakeEnterpriseDomain); + + // Create access token fetcher. + std::unique_ptr<OAuth2AccessTokenFetcher> access_token_fetcher = + CreateAccessTokenFetcher(&restriction_fetcher); + + // Try to fetch policy value. + GetSecondaryGoogleAccountUsageBlocking(&restriction_fetcher, + std::move(access_token_fetcher)); + + EXPECT_FALSE(policy_result_.has_value()); + EXPECT_EQ( + status_, + MockUserCloudSigninRestrictionPolicyFetcherChromeOS::Status::kHttpError); + EXPECT_EQ(hosted_domain_, kFakeEnterpriseDomain); +} + +TEST_F(UserCloudSigninRestrictionPolicyFetcherChromeOSTest, + FetchingPolicyReturnsEmptyPolicyForResponsesNotParsable) { + url_loader_factory_.AddResponse( + kSecureConnectApiGetSecondaryGoogleAccountUsageUrl, KBadResponseBody); + + // Create policy fetcher. + MockUserCloudSigninRestrictionPolicyFetcherChromeOS restriction_fetcher( + kFakeEnterpriseAccount, GetSharedURLLoaderFactory()); + SetHostedDomain(restriction_fetcher, kFakeEnterpriseDomain); + + // Create access token fetcher. + std::unique_ptr<OAuth2AccessTokenFetcher> access_token_fetcher = + CreateAccessTokenFetcher(&restriction_fetcher); + + // Try to fetch policy value. + GetSecondaryGoogleAccountUsageBlocking(&restriction_fetcher, + std::move(access_token_fetcher)); + + EXPECT_FALSE(policy_result_.has_value()); + EXPECT_EQ(status_, MockUserCloudSigninRestrictionPolicyFetcherChromeOS:: + Status::kParsingResponseError); + EXPECT_EQ(hosted_domain_, kFakeEnterpriseDomain); +} + +TEST_F(UserCloudSigninRestrictionPolicyFetcherChromeOSTest, + FetchingPolicyReturnsEmptyPolicyForNonEnterpriseAccounts) { + url_loader_factory_.AddResponse( + kSecureConnectApiGetSecondaryGoogleAccountUsageUrl, KBadResponseBody); + + // Create policy fetcher. + MockUserCloudSigninRestrictionPolicyFetcherChromeOS restriction_fetcher( + kFakeGmailAccount, GetSharedURLLoaderFactory()); + + // Create access token fetcher. + std::unique_ptr<OAuth2AccessTokenFetcher> access_token_fetcher = + CreateAccessTokenFetcher(&restriction_fetcher); + + EXPECT_CALL(restriction_fetcher, FetchUserInfo()).Times(0); + + // Try to fetch policy value. + GetSecondaryGoogleAccountUsageBlocking(&restriction_fetcher, + std::move(access_token_fetcher)); + + EXPECT_FALSE(policy_result_.has_value()); + EXPECT_EQ(status_, MockUserCloudSigninRestrictionPolicyFetcherChromeOS:: + Status::kUnsupportedAccountTypeError); + EXPECT_EQ(hosted_domain_, std::string()); + + MockUserCloudSigninRestrictionPolicyFetcherChromeOS restriction_fetcherother( + kFakeNonEnterpriseAccount, GetSharedURLLoaderFactory()); + EXPECT_CALL(restriction_fetcherother, FetchUserInfo()).Times(1); + + // Recreate access token fetcher. + access_token_fetcher = + GaiaAccessTokenFetcher::CreateExchangeRefreshTokenForAccessTokenInstance( + &restriction_fetcherother, GetSharedURLLoaderFactory(), + kFakeRefreshToken); + + // Try to fetch policy value. + GetSecondaryGoogleAccountUsageBlocking(&restriction_fetcherother, + std::move(access_token_fetcher)); + + EXPECT_FALSE(policy_result_.has_value()); + EXPECT_EQ(status_, MockUserCloudSigninRestrictionPolicyFetcherChromeOS:: + Status::kUnsupportedAccountTypeError); + EXPECT_EQ(hosted_domain_, std::string()); +} + +} // namespace ash
diff --git a/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/AddToHomescreenIPHController.java b/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/AddToHomescreenIPHController.java index 8fafe62..a5009d7e 100644 --- a/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/AddToHomescreenIPHController.java +++ b/chrome/browser/webapps/android/java/src/org/chromium/chrome/browser/webapps/AddToHomescreenIPHController.java
@@ -32,6 +32,7 @@ import org.chromium.components.messages.MessageDispatcher; import org.chromium.components.messages.MessageIdentifier; import org.chromium.components.messages.MessageScopeType; +import org.chromium.components.messages.PrimaryActionClickBehavior; import org.chromium.components.webapk.lib.client.WebApkValidator; import org.chromium.components.webapps.AddToHomescreenCoordinator; import org.chromium.components.webapps.AppBannerManager; @@ -186,7 +187,10 @@ R.string.iph_message_add_to_home_screen_action)) .with(MessageBannerProperties.ON_DISMISSED, this::onMessageDismissed) .with(MessageBannerProperties.ON_PRIMARY_ACTION, - () -> onMessageAddButtonClicked(tab)) + () -> { + onMessageAddButtonClicked(tab); + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; + }) .build(); mMessageDispatcher.enqueueMessage( model, tab.getWebContents(), MessageScopeType.NAVIGATION, false);
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 4cd66c3a..7e5b6f1 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1647345463-736d059e8af0251b8a386c0b345b3ea057c9a337.profdata +chrome-linux-main-1647367193-3ef6ef3f3d4faa5595f47be738b88b95eca51ec1.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 2a994009..7e9d838 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1647345463-da66cb39271225e688567ed8e7aa84b009733159.profdata +chrome-win32-main-1647356256-21e2b821f156a158c08bae662871bba15024150b.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index b73eead9..97c867d 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1647345463-13f8b0d86512c492de6a208c6ccace24196256ca.profdata +chrome-win64-main-1647356256-ab140ee892f376cc05c3352af5873da75ff35bc5.profdata
diff --git a/chrome/common/extensions/api/tabs.json b/chrome/common/extensions/api/tabs.json index f92fdcb..421c39e 100644 --- a/chrome/common/extensions/api/tabs.json +++ b/chrome/common/extensions/api/tabs.json
@@ -206,6 +206,12 @@ "optional": true, "minimum": 0, "description": "Open a port to a specific <a href='webNavigation#frame_ids'>frame</a> identified by <code>frameId</code> instead of all frames in the tab." + }, + "documentId": { + "type": "string", + "optional": true, + "nodoc": true, + "description": "Open a port to a specific <a href='webNavigation#document_ids'>document</a> identified by <code>documentId</code> instead of all frames in the tab." } }, "optional": true @@ -270,6 +276,12 @@ "optional": true, "minimum": 0, "description": "Send a message to a specific <a href='webNavigation#frame_ids'>frame</a> identified by <code>frameId</code> instead of all frames in the tab." + }, + "documentId": { + "type": "string", + "optional": true, + "nodoc": true, + "description": "Send a message to a specific <a href='webNavigation#document_ids'>document</a> identified by <code>documentId</code> instead of all frames in the tab." } }, "optional": true
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 7fae1ce..52dcf9b 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -377,6 +377,7 @@ const char kOsUISettingsURL[] = "os://settings"; const char kOsUISignInInternalsURL[] = "os://signin-internals"; const char kOsUISyncInternalsURL[] = "os://sync-internals"; +const char kOsUISysInternalsUrl[] = "os://sys-internals"; const char kOsUISystemURL[] = "os://system"; const char kOsUITermsURL[] = "os://terms";
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h index 58dfe701..3b4bd8d 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -354,6 +354,7 @@ extern const char kOsUISettingsURL[]; extern const char kOsUISignInInternalsURL[]; extern const char kOsUISyncInternalsURL[]; +extern const char kOsUISysInternalsUrl[]; extern const char kOsUISystemURL[]; extern const char kOsUITermsURL[];
diff --git a/chrome/renderer/extensions/tabs_hooks_delegate.cc b/chrome/renderer/extensions/tabs_hooks_delegate.cc index 78c2857..5df7ef36 100644 --- a/chrome/renderer/extensions/tabs_hooks_delegate.cc +++ b/chrome/renderer/extensions/tabs_hooks_delegate.cc
@@ -142,7 +142,8 @@ response_callback = arguments[3].As<v8::Function>(); v8::Local<v8::Promise> promise = messaging_service_->SendOneTimeMessage( - script_context, MessageTarget::ForTab(tab_id, options.frame_id), + script_context, + MessageTarget::ForTab(tab_id, options.frame_id, options.document_id), messaging_util::kSendMessageChannel, *message, parse_result.async_type, response_callback); DCHECK_EQ(parse_result.async_type == binding::AsyncResponseType::kPromise, @@ -174,7 +175,8 @@ } gin::Handle<GinPort> port = messaging_service_->Connect( - script_context, MessageTarget::ForTab(tab_id, options.frame_id), + script_context, + MessageTarget::ForTab(tab_id, options.frame_id, options.document_id), options.channel_name, messaging_util::GetSerializationFormat(*script_context)); DCHECK(!port.IsEmpty());
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 4ac1a7a..781c92d 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -5271,6 +5271,7 @@ "../browser/performance_manager/policies/working_set_trimmer_policy_chromeos_unittest.cc", "../browser/support_tool/ash/ui_hierarchy_data_collector_unittest.cc", "../browser/ui/views/crostini/crostini_app_restart_dialog_unittest.cc", + "../browser/ui/webui/signin/user_cloud_signin_restriction_policy_fetcher_chromeos_unittest.cc", ] if (target_cpu == "x64") { @@ -6725,7 +6726,6 @@ "../browser/ui/views/passwords/password_save_unsynced_credentials_locally_view_unittest.cc", "../browser/ui/views/passwords/password_save_update_view_unittest.cc", "../browser/ui/views/passwords/post_save_compromised_bubble_view_unittest.cc", - "../browser/ui/views/side_panel/side_panel_coordinator_unittest.cc", "../renderer/media/webrtc_logging_agent_impl_unittest.cc", ] @@ -6809,6 +6809,7 @@ "../browser/lacros/account_manager/account_profile_mapper_unittest.cc", "../browser/lacros/account_manager/get_account_information_helper_unittest.cc", "../browser/lacros/account_manager/profile_account_manager_unittest.cc", + "../browser/lacros/account_manager/web_signin_helper_lacros_unittest.cc", "../browser/lacros/cert/client_cert_store_lacros_unittest.cc", "../browser/lacros/force_installed_tracker_lacros_unittest.cc", "../browser/lacros/lacros_memory_pressure_evaluator_unittest.cc", @@ -8126,6 +8127,7 @@ "../browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl_unittest.cc", "../browser/ui/views/send_tab_to_self/send_tab_to_self_toolbar_bubble_view_unittest.cc", "../browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble_unittest.cc", + "../browser/ui/views/side_panel/side_panel_coordinator_unittest.cc", "../browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_unittest.cc", "../browser/ui/views/tabs/color_picker_view_unittest.cc", "../browser/ui/views/tabs/fake_base_tab_strip_controller.cc",
diff --git a/chrome/test/data/extensions/api_test/messaging/connect/test.js b/chrome/test/data/extensions/api_test/messaging/connect/test.js index 9eddd7f2..d02d427 100644 --- a/chrome/test/data/extensions/api_test/messaging/connect/test.js +++ b/chrome/test/data/extensions/api_test/messaging/connect/test.js
@@ -182,6 +182,62 @@ 'Could not establish connection. Receiving end does not exist.')); }, + // connect with a valid documentId should trigger onConnect in that specific + // document only. + function sendMessageToDocumentInTab() { + chrome.webNavigation.getAllFrames({ + tabId: testTab.id + }, function(details) { + var frames = details.filter(function(frame) { + return /\?testSendMessageFromFrame1$/.test(frame.url); + }); + chrome.test.assertEq(1, frames.length); + connectToTabWithDocumentId(frames[0].documentId, ['from_1']); + }); + }, + + // connect with a valid frameId and documentId should trigger onConnect in + // that specific document only. + function sendMessageToDocumentInTab() { + chrome.webNavigation.getAllFrames({ + tabId: testTab.id + }, function(details) { + var frames = details.filter(function(frame) { + return /\?testSendMessageFromFrame1$/.test(frame.url); + }); + chrome.test.assertEq(1, frames.length); + connectToTabWithOptions({documentId: frames[0].documentId, + frameId: frames[0].frameId + }, ['from_1']); + }); + }, + + // sendMessage with a valid documentId but invalid frameId should fail. + function sendMessageToInvalidDocumentFrameIdInTab() { + chrome.webNavigation.getAllFrames({ + tabId: testTab.id + }, function(details) { + var frames = details.filter(function(frame) { + return /\?testSendMessageFromFrame1$/.test(frame.url); + }); + chrome.test.assertEq(1, frames.length); + chrome.tabs.sendMessage(testTab.id, {}, { + documentId: frames[0].documentId, + // Some (hopefully) invalid frameId. + frameId: 999999999 + }, chrome.test.callbackFail( + 'Could not establish connection. Receiving end does not exist.')); + }); + }, + + // sendMessage with an invalid documentId should fail. + function sendMessageToInvalidDocumentInTab() { + chrome.tabs.sendMessage(testTab.id, {}, { + documentId: '0123456789ABCDEF' // A truncated documentId. + }, chrome.test.callbackFail( + 'Could not establish connection. Receiving end does not exist.')); + }, + // Tests error handling when sending a request from a content script to an // invalid extension. function sendMessageFromTabError() { @@ -388,16 +444,15 @@ ]); }); -function connectToTabWithFrameId(frameId, expectedMessages) { - var port = chrome.tabs.connect(testTab.id, { - frameId: frameId - }); +function connectToTabWithOptions(options, expectedMessages) { + var port = chrome.tabs.connect(testTab.id, options); var messages = []; var isDone = false; port.onMessage.addListener(function(message) { if (isDone) { // Should not get any messages after completing the test. chrome.test.fail( - 'Unexpected message from port to frame ' + frameId + ': ' + message); + 'Unexpected message from port to frame ' + JSON.stringify(options) + + ': ' + message); return; } @@ -410,10 +465,24 @@ }); port.onDisconnect.addListener(function() { if (!isDone) // The event should never be triggered when we expect messages. - chrome.test.fail('Unexpected disconnect from port to frame ' + frameId); + chrome.test.fail('Unexpected disconnect from port to frame ' + + JSON.stringify(options)); }); port.postMessage({testSendMessageToFrame: true}); - chrome.test.log('connectToTabWithFrameId: port to frame ' + frameId); + chrome.test.log('connectToTabWithOptions: port to frame ' + + JSON.stringify(options)); +} + +function connectToTabWithFrameId(frameId, expectedMessages) { + connectToTabWithOptions({ + frameId: frameId + }, expectedMessages); +} + +function connectToTabWithDocumentId(documentId, expectedMessages) { + connectToTabWithOptions({ + documentId: documentId + }, expectedMessages); } // Listens to |event| and returns a callback to run to stop listening. While
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 13ea5055..4c30f58 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -17184,10 +17184,7 @@ ] }, "SideSearchEnabled": { - "os": [ - "chromeos_ash", - "chromeos_lacros" - ], + "os": ["win", "linux", "mac", "chromeos_ash", "chromeos_lacros"], "policy_pref_mapping_tests": [ { "policies": {
diff --git a/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_element_test.ts index 22de30b9..ee8e5338 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/google_photos_photos_element_test.ts
@@ -9,7 +9,7 @@ import {WallpaperGridItem} from 'chrome://personalization/trusted/wallpaper/wallpaper_grid_item_element.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {String16} from 'chrome://resources/mojo/mojo/public/mojom/base/string16.mojom-webui.js'; -import {assertDeepEquals, assertEquals, assertNotEquals} from 'chrome://webui-test/chai_assert.js'; +import {assertDeepEquals, assertEquals, assertNotEquals, assertNotReached} from 'chrome://webui-test/chai_assert.js'; import {waitAfterNextRender} from 'chrome://webui-test/test_util.js'; import {baseSetup, initElement, teardownElement} from './personalization_app_test_utils.js'; @@ -39,6 +39,19 @@ return matches ? [...matches] : null; } + /** Scrolls the specified |element| until |predicate| returns true. */ + async function scrollElementUntil( + element: HTMLElement, predicate: () => boolean) { + const timeout = +new Date() + 1000; + while (!predicate()) { + element.scrollBy(0, 500); + await waitAfterNextRender(googlePhotosPhotosElement!); + if (+new Date() > timeout) { + assertNotReached('Timed out while scrolling.'); + } + } + } + /** * Returns a list of |GooglePhotosPhotosSection|'s for the specified |photos| * and number of |photosPerRow|. @@ -300,6 +313,103 @@ assertEquals(photoEls[1]!.selected, false); }); + test('incrementally loads photos', async () => { + // Set photos count returned by |wallpaperProvider|. + const photosCount = 200; + wallpaperProvider.setGooglePhotosCount(photosCount); + + // Set initial list of photos returned by |wallpaperProvider|. + let nextPhotoId = 1; + wallpaperProvider.setGooglePhotosPhotos( + Array.from({length: photosCount / 2}).map(() => { + return { + id: `id-${nextPhotoId}`, + name: `name-${nextPhotoId}`, + date: {data: []}, + url: {url: `url-${nextPhotoId++}`}, + }; + })); + + // Set initial photos resume token returned by |wallpaperProvider|. When + // resume token is defined, it indicates additional photos exist. + const resumeToken = 'resumeToken'; + wallpaperProvider.setGooglePhotosPhotosResumeToken(resumeToken); + + // Initialize Google Photos data in |personalizationStore|. + await initializeGooglePhotosData(wallpaperProvider, personalizationStore); + assertDeepEquals( + await wallpaperProvider.whenCalled('fetchGooglePhotosPhotos'), + [/*itemId=*/ null, /*albumId=*/ null, /*resumeToken=*/ null]); + + // Reset |wallpaperProvider| expectations. + wallpaperProvider.resetResolver('fetchGooglePhotosPhotos'); + + // Set the next list of photos returned by |wallpaperProvider|. + wallpaperProvider.setGooglePhotosPhotos( + Array.from({length: photosCount / 2}).map(() => { + return { + id: `id-${nextPhotoId}`, + name: `name-${nextPhotoId}`, + date: {data: []}, + url: {url: `url-${nextPhotoId++}`}, + }; + })); + + // Set the next photos resume token returned by |wallpaperProvider|. When + // resume token is undefined, it indicates no additional photos exist. + wallpaperProvider.setGooglePhotosPhotosResumeToken(undefined); + + // Restrict the viewport so that |googlePhotosPhotosElement| will lazily + // create photos instead of creating them all at once. + const style = document.createElement('style'); + style.appendChild(document.createTextNode(` + html, + body { + height: 100%; + width: 100%; + } + `)); + document.head.appendChild(style); + + // Initialize |googlePhotosPhotosElement|. + googlePhotosPhotosElement = + initElement(GooglePhotosPhotos, {hidden: false}); + await waitAfterNextRender(googlePhotosPhotosElement); + + // Register an event listener to cache whether the |gridScrollThreshold| has + // been reached. + let gridScrollThresholdReached = false; + const gridScrollThreshold = googlePhotosPhotosElement.$.gridScrollThreshold; + gridScrollThreshold.addEventListener('lower-threshold', () => { + gridScrollThresholdReached = true; + }); + + // Scroll until the |gridScrollThreshold| is reached. + await scrollElementUntil(gridScrollThreshold, () => { + return gridScrollThresholdReached; + }); + + // Wait for and verify that the next batch of photos have been requested. + assertDeepEquals( + await wallpaperProvider.whenCalled('fetchGooglePhotosPhotos'), + [/*itemId=*/ null, /*albumId=*/ null, /*resumeToken=*/ resumeToken]); + await waitAfterNextRender(googlePhotosPhotosElement); + + // Reset |wallpaperProvider| expectations. + wallpaperProvider.resetResolver('fetchGooglePhotosPhotos'); + + // Scroll until the bottom of the grid is reached. + let scrollTop = -1; + await scrollElementUntil(gridScrollThreshold, () => { + const oldScrollTop = scrollTop; + scrollTop = gridScrollThreshold.scrollTop; + return scrollTop === oldScrollTop; + }); + + // Verify that no next batch of photos has been requested. + assertEquals(wallpaperProvider.getCallCount('fetchGooglePhotosPhotos'), 0); + }); + test('selects photo', async () => { const photo: GooglePhotosPhoto = { id: '9bd1d7a3-f995-4445-be47-53c5b58ce1cb',
diff --git a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts index e7ffd75..476877b 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/personalization_app_controller_test.ts
@@ -85,8 +85,9 @@ albums: expectedAlbums, }, { - name: 'set_google_photos_photos', + name: 'append_google_photos_photos', photos: expectedPhotos, + resumeToken: null, }, ], personalizationStore.actions); @@ -106,6 +107,7 @@ albums: undefined, photos: undefined, photosByAlbumId: {}, + resumeTokens: {photos: null}, }, }, // SET_GOOGLE_PHOTOS_COUNT. @@ -121,6 +123,7 @@ albums: undefined, photos: undefined, photosByAlbumId: {}, + resumeTokens: {photos: null}, }, }, // BEGIN_LOAD_GOOGLE_PHOTOS_ALBUMS. @@ -136,6 +139,7 @@ albums: undefined, photos: undefined, photosByAlbumId: {}, + resumeTokens: {photos: null}, }, }, // BEGIN_LOAD_GOOGLE_PHOTOS_PHOTOS. @@ -151,6 +155,7 @@ albums: undefined, photos: undefined, photosByAlbumId: {}, + resumeTokens: {photos: null}, }, }, // SET_GOOGLE_PHOTOS_ALBUMS. @@ -166,9 +171,10 @@ albums: expectedAlbums, photos: undefined, photosByAlbumId: {}, + resumeTokens: {photos: null}, }, }, - // SET_GOOGLE_PHOTOS_PHOTOS. + // APPEND_GOOGLE_PHOTOS_PHOTOS. { 'wallpaper.loading.googlePhotos': { count: false, @@ -181,6 +187,7 @@ albums: expectedAlbums, photos: expectedPhotos, photosByAlbumId: {}, + resumeTokens: {photos: null}, }, }, ], @@ -253,6 +260,7 @@ ], photos: undefined, photosByAlbumId: {}, + resumeTokens: {photos: null}, }, }, // SET_GOOGLE_PHOTOS_ALBUM @@ -276,6 +284,7 @@ photosByAlbumId: { [album.id]: photos, }, + resumeTokens: {photos: null}, }, }, ],
diff --git a/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts b/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts index 2695e2f5f..742e3ab 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/test_wallpaper_interface_provider.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {CurrentWallpaper, FetchGooglePhotosAlbumsResponse, FetchGooglePhotosPhotosResponse, GooglePhotosAlbum, GooglePhotosPhoto, OnlineImageType, WallpaperCollection, WallpaperImage, WallpaperLayout, WallpaperObserverInterface, WallpaperObserverRemote, WallpaperProviderInterface, WallpaperType} from 'chrome://personalization/trusted/personalization_app.mojom-webui.js'; +import {CurrentWallpaper, FetchGooglePhotosAlbumsResponse, FetchGooglePhotosPhotosResponse, GooglePhotosAlbum, GooglePhotosEnablementState, GooglePhotosPhoto, OnlineImageType, WallpaperCollection, WallpaperImage, WallpaperLayout, WallpaperObserverInterface, WallpaperObserverRemote, WallpaperProviderInterface, WallpaperType} from 'chrome://personalization/trusted/personalization_app.mojom-webui.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {FilePath} from 'chrome://resources/mojo/mojo/public/mojom/base/file_path.mojom-webui.js'; import {assertTrue} from 'chrome://webui-test/chai_assert.js'; @@ -18,6 +18,7 @@ 'fetchImagesForCollection', 'fetchGooglePhotosAlbums', 'fetchGooglePhotosCount', + 'fetchGooglePhotosEnabled', 'fetchGooglePhotosPhotos', 'getLocalImages', 'getLocalImageThumbnail', @@ -97,7 +98,10 @@ private images_: WallpaperImage[]|null; private googlePhotosAlbums_: GooglePhotosAlbum[]|undefined = []; private googlePhotosCount_: number = 0; + private googlePhotosEnabled_: GooglePhotosEnablementState = + GooglePhotosEnablementState.kError; private googlePhotosPhotos_: GooglePhotosPhoto[]|undefined = []; + private googlePhotosPhotosResumeToken_: string|undefined; private googlePhotosPhotosByAlbumId_: Record<string, GooglePhotosPhoto[]|undefined> = {}; localImages: FilePath[]|null; @@ -156,15 +160,25 @@ return Promise.resolve({count}); } - fetchGooglePhotosPhotos(itemId: string, albumId: string) { - this.methodCalled('fetchGooglePhotosPhotos', itemId, albumId); + fetchGooglePhotosEnabled() { + this.methodCalled('fetchGooglePhotosEnabled'); + const state = loadTimeData.getBoolean('isGooglePhotosIntegrationEnabled') ? + this.googlePhotosEnabled_ : + GooglePhotosEnablementState.kError; + return Promise.resolve({state}); + } + + fetchGooglePhotosPhotos( + itemId: string, albumId: string, resumeToken: string) { + this.methodCalled('fetchGooglePhotosPhotos', itemId, albumId, resumeToken); const response = new FetchGooglePhotosPhotosResponse(); response.photos = loadTimeData.getBoolean('isGooglePhotosIntegrationEnabled') ? albumId ? this.googlePhotosPhotosByAlbumId_[albumId] : this.googlePhotosPhotos_ : undefined; - response.resumeToken = undefined; + response.resumeToken = + albumId ? undefined : this.googlePhotosPhotosResumeToken_; return Promise.resolve({response}); } @@ -249,10 +263,18 @@ this.googlePhotosCount_ = googlePhotosCount; } + setGooglePhotosEnabled(googlePhotosEnabled: number) { + this.googlePhotosEnabled_ = googlePhotosEnabled; + } + setGooglePhotosPhotos(googlePhotosPhotos: GooglePhotosPhoto[]|undefined) { this.googlePhotosPhotos_ = googlePhotosPhotos; } + setGooglePhotosPhotosResumeToken(resumeToken: string|undefined) { + this.googlePhotosPhotosResumeToken_ = resumeToken; + } + setGooglePhotosPhotosByAlbumId( albumId: string, googlePhotosPhotos: GooglePhotosPhoto[]|undefined) { this.googlePhotosPhotosByAlbumId_[albumId] = googlePhotosPhotos;
diff --git a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts index 88a259b6..c8b09275 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/wallpaper_grid_item_element_test.ts
@@ -46,6 +46,7 @@ // Verify state. assertEquals(querySelector('img')?.getAttribute('auto-src'), imageSrc); + assertEquals(querySelector('img')?.hasAttribute('clear-src'), true); assertEquals(querySelector('img')?.hasAttribute('with-cookies'), true); assertEquals(querySelector('.text'), null); assertEquals(querySelector('.primary-text'), null);
diff --git a/chrome/updater/app/app_install.cc b/chrome/updater/app/app_install.cc index cc0876f..55287a3d 100644 --- a/chrome/updater/app/app_install.cc +++ b/chrome/updater/app/app_install.cc
@@ -91,9 +91,7 @@ AppInstall::~AppInstall() = default; -void AppInstall::Initialize() { - base::i18n::InitializeICU(); -} +void AppInstall::Initialize() {} void AppInstall::Uninitialize() { if (update_service_) {
diff --git a/chrome/updater/app/server/mac/service_delegate.mm b/chrome/updater/app/server/mac/service_delegate.mm index 2001673..308df520 100644 --- a/chrome/updater/app/server/mac/service_delegate.mm +++ b/chrome/updater/app/server/mac/service_delegate.mm
@@ -144,6 +144,7 @@ } - (void)checkForUpdateWithAppID:(NSString* _Nonnull)appID + installDataIndex:(NSString* _Nullable)installDataIndex priority:(CRUPriorityWrapper* _Nonnull)priority policySameVersionUpdate: (CRUPolicySameVersionUpdateWrapper* _Nonnull)policySameVersionUpdate @@ -189,7 +190,9 @@ _callbackRunner->PostTask( FROM_HERE, base::BindOnce(&updater::UpdateService::Update, _service, - base::SysNSStringToUTF8(appID), [priority priority], + base::SysNSStringToUTF8(appID), + base::SysNSStringToUTF8(installDataIndex), + [priority priority], [policySameVersionUpdate policySameVersionUpdate], std::move(sccb), std::move(cb))); } @@ -300,6 +303,7 @@ } - (void)checkForUpdateWithAppID:(NSString* _Nonnull)appID + installDataIndex:(NSString* _Nullable)installDataIndex priority:(CRUPriorityWrapper* _Nonnull)priority policySameVersionUpdate: (CRUPolicySameVersionUpdateWrapper* _Nonnull)policySameVersionUpdate @@ -307,6 +311,7 @@ reply:(void (^_Nonnull)(int rc))reply { // This function may be called by any user. [_service checkForUpdateWithAppID:appID + installDataIndex:installDataIndex priority:priority policySameVersionUpdate:policySameVersionUpdate updateState:updateState
diff --git a/chrome/updater/app/server/mac/service_protocol.h b/chrome/updater/app/server/mac/service_protocol.h index c87d218..53ad351 100644 --- a/chrome/updater/app/server/mac/service_protocol.h +++ b/chrome/updater/app/server/mac/service_protocol.h
@@ -43,6 +43,7 @@ // Checks for update of a given app, with specified priority. Sends repeated // updates of progress and returns the result in the reply block. - (void)checkForUpdateWithAppID:(NSString* _Nonnull)appID + installDataIndex:(NSString* _Nullable)installDataIndex priority:(CRUPriorityWrapper* _Nonnull)priority policySameVersionUpdate: (CRUPolicySameVersionUpdateWrapper* _Nonnull)policySameVersionUpdate
diff --git a/chrome/updater/app/server/mac/service_protocol.mm b/chrome/updater/app/server/mac/service_protocol.mm index d86549f..6cf34a7 100644 --- a/chrome/updater/app/server/mac/service_protocol.mm +++ b/chrome/updater/app/server/mac/service_protocol.mm
@@ -24,8 +24,9 @@ setInterface:updateStateObservingInterface forSelector:@selector (checkForUpdateWithAppID: - priority:policySameVersionUpdate:updateState:reply:) - argumentIndex:3 + installDataIndex:priority:policySameVersionUpdate:updateState + :reply:) + argumentIndex:4 ofReply:NO]; return updateCheckingInterface;
diff --git a/chrome/updater/app/server/win/com_classes.cc b/chrome/updater/app/server/win/com_classes.cc index 98951dbd..7fd183c9 100644 --- a/chrome/updater/app/server/win/com_classes.cc +++ b/chrome/updater/app/server/win/com_classes.cc
@@ -279,6 +279,7 @@ // calls must be done through a task runner, bound to the closures provided // as parameters for the UpdateService::Update call. HRESULT UpdaterImpl::Update(const wchar_t* app_id, + const wchar_t* install_data_index, BOOL same_version_update_allowed, IUpdaterObserver* observer) { // This task runner is responsible for sequencing the callbacks posted @@ -296,10 +297,11 @@ base::BindOnce( [](scoped_refptr<UpdateService> update_service, scoped_refptr<base::SequencedTaskRunner> task_runner, - const std::string& app_id, bool same_version_update_allowed, - IUpdaterObserverPtr observer) { + const std::string& app_id, const std::string& install_data_index, + bool same_version_update_allowed, IUpdaterObserverPtr observer) { update_service->Update( - app_id, UpdateService::Priority::kForeground, + app_id, install_data_index, + UpdateService::Priority::kForeground, same_version_update_allowed ? UpdateService::PolicySameVersionUpdate::kAllowed : UpdateService::PolicySameVersionUpdate::kNotAllowed, @@ -324,7 +326,8 @@ task_runner, observer)); }, com_server->update_service(), task_runner, base::WideToUTF8(app_id), - same_version_update_allowed, observer_local)); + base::WideToUTF8(install_data_index), same_version_update_allowed, + observer_local)); // Always return S_OK from this function. Errors must be reported using the // observer interface.
diff --git a/chrome/updater/app/server/win/com_classes.h b/chrome/updater/app/server/win/com_classes.h index 033e1b9..423ad33 100644 --- a/chrome/updater/app/server/win/com_classes.h +++ b/chrome/updater/app/server/win/com_classes.h
@@ -98,6 +98,7 @@ IUpdaterRegisterAppCallback* callback) override; IFACEMETHODIMP RunPeriodicTasks(IUpdaterCallback* callback) override; IFACEMETHODIMP Update(const wchar_t* app_id, + const wchar_t* install_data_index, BOOL same_version_update_allowed, IUpdaterObserver* observer) override; IFACEMETHODIMP UpdateAll(IUpdaterObserver* observer) override;
diff --git a/chrome/updater/app/server/win/com_classes_legacy.cc b/chrome/updater/app/server/win/com_classes_legacy.cc index 347c5681..69ff512 100644 --- a/chrome/updater/app/server/win/com_classes_legacy.cc +++ b/chrome/updater/app/server/win/com_classes_legacy.cc
@@ -161,7 +161,7 @@ [](scoped_refptr<UpdateService> update_service, LegacyOnDemandImplPtr obj) { update_service->Update( - obj->app_id(), UpdateService::Priority::kForeground, + obj->app_id(), "", UpdateService::Priority::kForeground, UpdateService::PolicySameVersionUpdate::kNotAllowed, base::BindRepeating( [](LegacyOnDemandImplPtr obj,
diff --git a/chrome/updater/app/server/win/updater_idl.template b/chrome/updater/app/server/win/updater_idl.template index 561dcd2..eabec2a 100644 --- a/chrome/updater/app/server/win/updater_idl.template +++ b/chrome/updater/app/server/win/updater_idl.template
@@ -92,6 +92,7 @@ [in] IUpdaterRegisterAppCallback* callback); HRESULT RunPeriodicTasks([in] IUpdaterCallback* callback); HRESULT Update([in, string] const WCHAR* app_id, + [in, string] const WCHAR* install_data_index, [in] BOOL same_version_update_allowed, [in] IUpdaterObserver* observer); HRESULT UpdateAll([in] IUpdaterObserver * observer);
diff --git a/chrome/updater/installer.cc b/chrome/updater/installer.cc index e18e7771..de32b95 100644 --- a/chrome/updater/installer.cc +++ b/chrome/updater/installer.cc
@@ -52,6 +52,7 @@ Installer::Installer( const std::string& app_id, + const std::string& install_data_index, const std::string& target_channel, const std::string& target_version_prefix, bool rollback_allowed, @@ -61,6 +62,7 @@ crx_file::VerifierFormat crx_verifier_format) : updater_scope_(GetUpdaterScope()), app_id_(app_id), + install_data_index_(install_data_index), rollback_allowed_(rollback_allowed), target_channel_(target_channel), target_version_prefix_(target_version_prefix), @@ -96,6 +98,7 @@ component.requires_network_encryption = false; component.crx_format_requirement = crx_verifier_format_; component.app_id = app_id_; + component.install_data_index = install_data_index_; component.ap = ap_; component.brand = persisted_data_->GetBrandCode(app_id_); component.name = app_id_;
diff --git a/chrome/updater/installer.h b/chrome/updater/installer.h index 129fec46..6cf30ad3 100644 --- a/chrome/updater/installer.h +++ b/chrome/updater/installer.h
@@ -40,6 +40,7 @@ class Installer final : public update_client::CrxInstaller { public: Installer(const std::string& app_id, + const std::string& install_data_index, const std::string& target_channel, const std::string& target_version_prefix, bool rollback_allowed, @@ -110,6 +111,7 @@ UpdaterScope updater_scope_; const std::string app_id_; + const std::string install_data_index_; const bool rollback_allowed_; const std::string target_channel_; const std::string target_version_prefix_;
diff --git a/chrome/updater/mac/keystone/ksadmin.mm b/chrome/updater/mac/keystone/ksadmin.mm index eccfcbe..eb4729a 100644 --- a/chrome/updater/mac/keystone/ksadmin.mm +++ b/chrome/updater/mac/keystone/ksadmin.mm
@@ -396,7 +396,7 @@ } ServiceProxy(scope)->Update( - app_id, + app_id, GetInstallDataIndexFromAppArgs(app_id), HasSwitch(kCommandUserInitiated) ? UpdateService::Priority::kForeground : UpdateService::Priority::kBackground, UpdateService::PolicySameVersionUpdate::kNotAllowed, @@ -590,7 +590,7 @@ base::CommandLine::Init(argc, argv); std::map<std::string, std::string> command_line = ParseCommandLine(argc, argv); - updater::InitLogging(Scope(command_line), FILE_PATH_LITERAL("updater.log")); + updater::InitLogging(Scope(command_line)); base::SingleThreadTaskExecutor main_task_executor(base::MessagePumpType::UI); return base::MakeRefCounted<KSAdminApp>(command_line)->Run(); }
diff --git a/chrome/updater/mac/keystone/ksinstall.mm b/chrome/updater/mac/keystone/ksinstall.mm index 8d10df5..1790a60 100644 --- a/chrome/updater/mac/keystone/ksinstall.mm +++ b/chrome/updater/mac/keystone/ksinstall.mm
@@ -111,7 +111,7 @@ base::AtExitManager exit_manager; base::CommandLine::Init(argc, argv); - updater::InitLogging(GetUpdaterScope(), FILE_PATH_LITERAL("updater.log")); + updater::InitLogging(GetUpdaterScope()); base::SingleThreadTaskExecutor main_task_executor(base::MessagePumpType::UI); return MakeKSInstallApp(argc, argv)->Run();
diff --git a/chrome/updater/mac/update_service_proxy.h b/chrome/updater/mac/update_service_proxy.h index c6406d8..d408f40 100644 --- a/chrome/updater/mac/update_service_proxy.h +++ b/chrome/updater/mac/update_service_proxy.h
@@ -48,6 +48,7 @@ void RunPeriodicTasks(base::OnceClosure callback) override; void UpdateAll(StateChangeCallback state_update, Callback callback) override; void Update(const std::string& app_id, + const std::string& install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, StateChangeCallback state_update,
diff --git a/chrome/updater/mac/update_service_proxy.mm b/chrome/updater/mac/update_service_proxy.mm index 9bfb5bea..77cece90 100644 --- a/chrome/updater/mac/update_service_proxy.mm +++ b/chrome/updater/mac/update_service_proxy.mm
@@ -151,6 +151,7 @@ } - (void)checkForUpdateWithAppID:(NSString* _Nonnull)appID + installDataIndex:(NSString* _Nullable)installDataIndex priority:(CRUPriorityWrapper* _Nonnull)priority policySameVersionUpdate: (CRUPolicySameVersionUpdateWrapper* _Nonnull)policySameVersionUpdate @@ -165,6 +166,7 @@ [[_updateCheckXPCConnection remoteObjectProxyWithErrorHandler:errorHandler] checkForUpdateWithAppID:appID + installDataIndex:installDataIndex priority:priority policySameVersionUpdate:policySameVersionUpdate updateState:updateState @@ -276,6 +278,7 @@ void UpdateServiceProxy::Update( const std::string& app_id, + const std::string& install_data_index, UpdateService::Priority priority, PolicySameVersionUpdate policy_same_version_update, StateChangeCallback state_update, @@ -301,6 +304,7 @@ callbackRunner:callback_runner_]); [client_ checkForUpdateWithAppID:SysUTF8ToNSString(app_id) + installDataIndex:SysUTF8ToNSString(install_data_index) priority:priorityWrapper.get() policySameVersionUpdate:policySameVersionUpdateWrapper.get() updateState:stateObserver.get()
diff --git a/chrome/updater/mac/update_service_proxy_test.mm b/chrome/updater/mac/update_service_proxy_test.mm index 863dace..235c5d2 100644 --- a/chrome/updater/mac/update_service_proxy_test.mm +++ b/chrome/updater/mac/update_service_proxy_test.mm
@@ -497,6 +497,7 @@ OCMockObjectCapturer<CRUUpdateStateObserver> update_state_observer_capturer; const std::string test_app_id("test_app_id"); + const std::string test_install_data_index("test_install_data_index"); base::scoped_nsobject<CRUPriorityWrapper> wrapped_priority( [[CRUPriorityWrapper alloc] initWithPriority:UpdateService::Priority::kForeground]); @@ -522,6 +523,8 @@ auto* state_change_engine_ptr = &state_change_engine; OCMExpect([mock_remote_object checkForUpdateWithAppID:base::SysUTF8ToNSString(test_app_id) + installDataIndex:base::SysUTF8ToNSString( + test_install_data_index) priority:wrapped_priority.get() policySameVersionUpdate:wrapped_policySameVersionUpdate.get() updateState:update_state_observer_capturer.Capture() @@ -537,7 +540,8 @@ base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindLambdaForTesting([this, &state_change_engine]() { - service_->Update("test_app_id", UpdateService::Priority::kForeground, + service_->Update("test_app_id", "test_install_data_index", + UpdateService::Priority::kForeground, UpdateService::PolicySameVersionUpdate::kNotAllowed, state_change_engine.Watch(), base::BindLambdaForTesting(
diff --git a/chrome/updater/test/integration_test_commands.h b/chrome/updater/test/integration_test_commands.h index 55402d3..da89160 100644 --- a/chrome/updater/test/integration_test_commands.h +++ b/chrome/updater/test/integration_test_commands.h
@@ -40,6 +40,7 @@ virtual void ExpectSelfUpdateSequence(ScopedServer* test_server) const = 0; virtual void ExpectUpdateSequence(ScopedServer* test_server, const std::string& app_id, + const std::string& install_data_index, const base::Version& from_version, const base::Version& to_version) const = 0; virtual void ExpectVersionActive(const std::string& version) const = 0; @@ -59,7 +60,8 @@ const base::Version& version) const = 0; virtual void RunWake(int exit_code) const = 0; virtual void RunWakeActive(int exit_code) const = 0; - virtual void Update(const std::string& app_id) const = 0; + virtual void Update(const std::string& app_id, + const std::string& install_data_index) const = 0; virtual void UpdateAll() const = 0; virtual void PrintLog() const = 0; virtual base::FilePath GetDifferentUserPath() const = 0; @@ -77,6 +79,7 @@ #endif // BUILDFLAG(IS_WIN) virtual void StressUpdateService() const = 0; virtual void CallServiceUpdate(const std::string& app_id, + const std::string& install_data_index, UpdateService::PolicySameVersionUpdate policy_same_version_update) const = 0;
diff --git a/chrome/updater/test/integration_test_commands_system.cc b/chrome/updater/test/integration_test_commands_system.cc index c894a6c..2d69678 100644 --- a/chrome/updater/test/integration_test_commands_system.cc +++ b/chrome/updater/test/integration_test_commands_system.cc
@@ -74,10 +74,12 @@ void ExpectUpdateSequence(ScopedServer* test_server, const std::string& app_id, + const std::string& install_data_index, const base::Version& from_version, const base::Version& to_version) const override { updater::test::ExpectUpdateSequence(updater_scope_, test_server, app_id, - from_version, to_version); + install_data_index, from_version, + to_version); } void ExpectVersionActive(const std::string& version) const override { @@ -151,8 +153,10 @@ {Param("exit_code", base::NumberToString(expected_exit_code))}); } - void Update(const std::string& app_id) const override { - RunCommand("update", {Param("app_id", app_id)}); + void Update(const std::string& app_id, + const std::string& install_data_index) const override { + RunCommand("update", {Param("app_id", app_id), + Param("install_data_index", install_data_index)}); } void UpdateAll() const override { RunCommand("update_all", {}); } @@ -213,10 +217,12 @@ } void CallServiceUpdate(const std::string& app_id, + const std::string& install_data_index, UpdateService::PolicySameVersionUpdate policy_same_version_update) const override { RunCommand("call_service_update", {Param("app_id", app_id), + Param("install_data_index", install_data_index), Param("same_version_update_allowed", policy_same_version_update == UpdateService::PolicySameVersionUpdate::kAllowed
diff --git a/chrome/updater/test/integration_test_commands_user.cc b/chrome/updater/test/integration_test_commands_user.cc index 0dbc0124..acbd9b2 100644 --- a/chrome/updater/test/integration_test_commands_user.cc +++ b/chrome/updater/test/integration_test_commands_user.cc
@@ -67,10 +67,12 @@ void ExpectUpdateSequence(ScopedServer* test_server, const std::string& app_id, + const std::string& install_data_index, const base::Version& from_version, const base::Version& to_version) const override { updater::test::ExpectUpdateSequence(updater_scope_, test_server, app_id, - from_version, to_version); + install_data_index, from_version, + to_version); } void ExpectVersionActive(const std::string& version) const override { @@ -139,8 +141,9 @@ updater::test::RunWakeActive(updater_scope_, exit_code); } - void Update(const std::string& app_id) const override { - updater::test::Update(updater_scope_, app_id); + void Update(const std::string& app_id, + const std::string& install_data_index) const override { + updater::test::Update(updater_scope_, app_id, install_data_index); } void UpdateAll() const override { updater::test::UpdateAll(updater_scope_); } @@ -193,10 +196,11 @@ } void CallServiceUpdate(const std::string& app_id, + const std::string& install_data_index, UpdateService::PolicySameVersionUpdate policy_same_version_update) const override { updater::test::CallServiceUpdate( - updater_scope_, app_id, + updater_scope_, app_id, install_data_index, policy_same_version_update == UpdateService::PolicySameVersionUpdate::kAllowed); }
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index 847188e..3400339 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -221,7 +221,10 @@ test_commands_->RunWakeActive(exit_code); } - void Update(const std::string& app_id) { test_commands_->Update(app_id); } + void Update(const std::string& app_id, + const std::string& install_data_index) { + test_commands_->Update(app_id, install_data_index); + } void UpdateAll() { test_commands_->UpdateAll(); } @@ -245,10 +248,11 @@ void ExpectUpdateSequence(ScopedServer* test_server, const std::string& app_id, + const std::string& install_data_index, const base::Version& from_version, const base::Version& to_version) { - test_commands_->ExpectUpdateSequence(test_server, app_id, from_version, - to_version); + test_commands_->ExpectUpdateSequence( + test_server, app_id, install_data_index, from_version, to_version); } void ExpectSelfUpdateSequence(ScopedServer* test_server) { @@ -269,8 +273,10 @@ void CallServiceUpdate( const std::string& app_id, + const std::string& install_data_index, UpdateService::PolicySameVersionUpdate policy_same_version_update) { - test_commands_->CallServiceUpdate(app_id, policy_same_version_update); + test_commands_->CallServiceUpdate(app_id, install_data_index, + policy_same_version_update); } void SetupFakeLegacyUpdaterData() { @@ -346,8 +352,8 @@ ExpectVersionNotActive(kUpdaterVersion); ExpectRegistrationEvent(&test_server, kQualificationAppId); - ExpectUpdateSequence(&test_server, kQualificationAppId, base::Version("0.1"), - base::Version("0.2")); + ExpectUpdateSequence(&test_server, kQualificationAppId, "", + base::Version("0.1"), base::Version("0.2")); RunWake(0); WaitForUpdaterExit(); @@ -372,7 +378,7 @@ Install(); base::Version next_version(base::StringPrintf("%s1", kUpdaterVersion)); - ExpectUpdateSequence(&test_server, kUpdaterAppId, + ExpectUpdateSequence(&test_server, kUpdaterAppId, "", base::Version(kUpdaterVersion), next_version); RunWake(0); @@ -433,12 +439,13 @@ ExpectRegistrationEvent(&test_server, kAppId); InstallApp(kAppId); base::Version v1("1"); - ExpectUpdateSequence(&test_server, kAppId, base::Version("0.1"), v1); + ExpectUpdateSequence(&test_server, kAppId, "", base::Version("0.1"), v1); RunWake(0); base::Version v2("2"); - ExpectUpdateSequence(&test_server, kAppId, v1, v2); - Update(kAppId); + const std::string kInstallDataIndex("test_install_data_index"); + ExpectUpdateSequence(&test_server, kAppId, kInstallDataIndex, v1, v2); + Update(kAppId, kInstallDataIndex); WaitForUpdaterExit(); ExpectAppVersion(kAppId, v2); ExpectLastChecked(); @@ -489,7 +496,7 @@ ExpectNoUpdateSequence(&test_server, kAppId); ExpectLegacyUpdate3WebSucceeds(kAppId, STATE_NO_UPDATE, S_OK); - ExpectUpdateSequence(&test_server, kAppId, base::Version("0.1"), + ExpectUpdateSequence(&test_server, kAppId, "", base::Version("0.1"), base::Version("0.2")); ExpectLegacyUpdate3WebSucceeds(kAppId, STATE_INSTALL_COMPLETE, S_OK); @@ -637,8 +644,8 @@ // Qualify the new instance. ExpectRegistrationEvent(&test_server, kQualificationAppId); - ExpectUpdateSequence(&test_server, kQualificationAppId, base::Version("0.1"), - base::Version("0.2")); + ExpectUpdateSequence(&test_server, kQualificationAppId, "", + base::Version("0.1"), base::Version("0.2")); RunWake(0); WaitForUpdaterExit(); @@ -689,17 +696,60 @@ RequestMatcherRegex, R"(.*"updatecheck":{"sameversionupdate":true},"version":"0.1"}.*)")}, response); - CallServiceUpdate(app_id, UpdateService::PolicySameVersionUpdate::kAllowed); + CallServiceUpdate(app_id, "", + UpdateService::PolicySameVersionUpdate::kAllowed); test_server.ExpectOnce( {base::BindRepeating(RequestMatcherRegex, R"(.*"updatecheck":{},"version":"0.1"}.*)")}, response); - CallServiceUpdate(app_id, + CallServiceUpdate(app_id, "", UpdateService::PolicySameVersionUpdate::kNotAllowed); Uninstall(); } +TEST_F(IntegrationTest, InstallDataIndex) { + ScopedServer test_server(test_commands_); + ExpectRegistrationEvent(&test_server, kUpdaterAppId); + Install(); + ExpectInstalled(); + + const std::string app_id = "test-appid"; + const std::string install_data_index = "test-install-data-index"; + + ExpectRegistrationEvent(&test_server, app_id); + InstallApp(app_id); + + const std::string response = base::StringPrintf( + ")]}'\n" + R"({"response":{)" + R"( "protocol":"3.1",)" + R"( "app":[)" + R"( {)" + R"( "appid":"%s",)" + R"( "status":"ok",)" + R"( "updatecheck":{)" + R"( "status":"noupdate")" + R"( })" + R"( })" + R"( ])" + R"(}})", + app_id.c_str()); + + test_server.ExpectOnce( + {base::BindRepeating( + RequestMatcherRegex, + base::StringPrintf( + R"(.*"data":\[{"index":"%s","name":"install"}],.*)", + install_data_index.c_str()))}, + response); + + CallServiceUpdate(app_id, install_data_index, + UpdateService::PolicySameVersionUpdate::kAllowed); + + Uninstall(); +} + TEST_F(IntegrationTest, MigrateLegacyUpdater) { SetupFakeLegacyUpdaterData(); Install();
diff --git a/chrome/updater/test/integration_tests_helper.cc b/chrome/updater/test/integration_tests_helper.cc index 98cd3c5..45f0a734 100644 --- a/chrome/updater/test/integration_tests_helper.cc +++ b/chrome/updater/test/integration_tests_helper.cc
@@ -232,7 +232,9 @@ {"run_wake", WithSwitch("exit_code", WithSystemScope(Wrap(&RunWake)))}, {"run_wake_active", WithSwitch("exit_code", WithSystemScope(Wrap(&RunWakeActive)))}, - {"update", WithSwitch("app_id", WithSystemScope(Wrap(&Update)))}, + {"update", + WithSwitch("install_data_index", + (WithSwitch("app_id", WithSystemScope(Wrap(&Update)))))}, {"update_all", WithSystemScope(Wrap(&UpdateAll))}, {"install_app", WithSwitch("app_id", WithSystemScope(Wrap(&InstallApp)))}, {"uninstall_app", @@ -252,9 +254,10 @@ {"stress_update_service", WithSystemScope(Wrap(&StressUpdateService))}, {"uninstall", WithSystemScope(Wrap(&Uninstall))}, {"call_service_update", - WithSwitch( - "same_version_update_allowed", - WithSwitch("app_id", WithSystemScope(Wrap(&CallServiceUpdate))))}, + WithSwitch("same_version_update_allowed", + WithSwitch("install_data_index", + WithSwitch("app_id", WithSystemScope(Wrap( + &CallServiceUpdate)))))}, {"setup_fake_legacy_updater_data", WithSystemScope(Wrap(&SetupFakeLegacyUpdaterData))}, {"expect_legacy_updater_data_migrated",
diff --git a/chrome/updater/test/integration_tests_impl.cc b/chrome/updater/test/integration_tests_impl.cc index 7b5e786..f94a477 100644 --- a/chrome/updater/test/integration_tests_impl.cc +++ b/chrome/updater/test/integration_tests_impl.cc
@@ -90,6 +90,7 @@ } std::string GetUpdateResponse(const std::string& app_id, + const std::string& install_data_index, const std::string& codebase, const base::Version& version, const base::FilePath& update_file, @@ -103,6 +104,7 @@ R"( {)" R"( "appid":"%s",)" R"( "status":"ok",)" + R"(%s)" R"( "updatecheck":{)" R"( "status":"ok",)" R"( "urls":{"url":[{"codebase":"%s"}]},)" @@ -120,9 +122,16 @@ R"( })" R"( ])" R"(}})", - app_id.c_str(), codebase.c_str(), version.GetString().c_str(), - run_action.c_str(), arguments.c_str(), - update_file.BaseName().AsUTF8Unsafe().c_str(), + app_id.c_str(), + !install_data_index.empty() + ? base::StringPrintf( + R"( "data":[{ "status":"ok", "name":"install", )" + R"("index":"%s", "#text":"%s_text" }],)", + install_data_index.c_str(), install_data_index.c_str()) + .c_str() + : "", + codebase.c_str(), version.GetString().c_str(), run_action.c_str(), + arguments.c_str(), update_file.BaseName().AsUTF8Unsafe().c_str(), GetHashHex(update_file).c_str()); } @@ -285,11 +294,13 @@ EXPECT_EQ(exit_code, expected_exit_code); } -void Update(UpdaterScope scope, const std::string& app_id) { +void Update(UpdaterScope scope, + const std::string& app_id, + const std::string& install_data_index) { scoped_refptr<UpdateService> update_service = CreateUpdateServiceProxy(scope); base::RunLoop loop; update_service->Update( - app_id, UpdateService::Priority::kForeground, + app_id, install_data_index, UpdateService::Priority::kForeground, UpdateService::PolicySameVersionUpdate::kNotAllowed, base::DoNothing(), base::BindOnce(base::BindLambdaForTesting( [&loop](UpdateService::Result result_unused) { loop.Quit(); }))); @@ -440,7 +451,7 @@ base::StringPrintf(R"(.*"appid":"%s".*)", kUpdaterAppId)), GetScopePredicate(scope)}, GetUpdateResponse( - kUpdaterAppId, test_server->base_url().spec(), + kUpdaterAppId, "", test_server->base_url().spec(), base::Version(kUpdaterVersion), crx_path, kSelfUpdateCRXRun, base::StrCat( {"--update", scope == UpdaterScope::kSystem ? " --system" : "", @@ -467,6 +478,7 @@ void ExpectUpdateSequence(UpdaterScope scope, ScopedServer* test_server, const std::string& app_id, + const std::string& install_data_index, const base::Version& from_version, const base::Version& to_version) { base::FilePath test_data_path; @@ -480,9 +492,20 @@ {base::BindRepeating( RequestMatcherRegex, base::StringPrintf(R"(.*"appid":"%s".*)", app_id.c_str())), + base::BindRepeating( + RequestMatcherRegex, + base::StringPrintf( + R"(.*%s)", + !install_data_index.empty() + ? base::StringPrintf( + R"("data":\[{"index":"%s","name":"install"}],.*)", + install_data_index.c_str()) + .c_str() + : "")), GetScopePredicate(scope)}, - GetUpdateResponse(app_id, test_server->base_url().spec(), to_version, - crx_path, kDoNothingCRXRun, {})); + GetUpdateResponse(app_id, install_data_index, + test_server->base_url().spec(), to_version, crx_path, + kDoNothingCRXRun, {})); // Second request: update download. std::string crx_bytes; @@ -572,6 +595,7 @@ void CallServiceUpdate(UpdaterScope updater_scope, const std::string& app_id, + const std::string& install_data_index, bool same_version_update_allowed) { UpdateService::PolicySameVersionUpdate policy_same_version_update = same_version_update_allowed @@ -583,7 +607,8 @@ base::RunLoop loop; service_proxy->Update( - app_id, UpdateService::Priority::kForeground, policy_same_version_update, + app_id, install_data_index, UpdateService::Priority::kForeground, + policy_same_version_update, base::BindLambdaForTesting([](const UpdateService::UpdateState&) {}), base::BindLambdaForTesting([&](UpdateService::Result result) { EXPECT_EQ(result, UpdateService::Result::kSuccess);
diff --git a/chrome/updater/test/integration_tests_impl.h b/chrome/updater/test/integration_tests_impl.h index 9c6d619..a550605 100644 --- a/chrome/updater/test/integration_tests_impl.h +++ b/chrome/updater/test/integration_tests_impl.h
@@ -88,7 +88,9 @@ void RunWakeActive(UpdaterScope scope, int exit_code); // Invokes the active instance's UpdateService::Update (via RPC) for an app. -void Update(UpdaterScope scope, const std::string& app_id); +void Update(UpdaterScope scope, + const std::string& app_id, + const std::string& install_data_index); // Invokes the active instance's UpdateService::UpdateAll (via RPC). void UpdateAll(UpdaterScope scope); @@ -184,6 +186,7 @@ void ExpectUpdateSequence(UpdaterScope scope, ScopedServer* test_server, const std::string& app_id, + const std::string& install_data_index, const base::Version& from_version, const base::Version& to_version); @@ -191,6 +194,7 @@ void CallServiceUpdate(UpdaterScope updater_scope, const std::string& app_id, + const std::string& install_data_index, bool same_version_update_allowed); void SetupFakeLegacyUpdaterData(UpdaterScope scope);
diff --git a/chrome/updater/update_service.h b/chrome/updater/update_service.h index fbe2019..e7c1c40 100644 --- a/chrome/updater/update_service.h +++ b/chrome/updater/update_service.h
@@ -238,6 +238,7 @@ // |callback| arg: // Result: the final result from the update engine. virtual void Update(const std::string& app_id, + const std::string& install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, StateChangeCallback state_update,
diff --git a/chrome/updater/update_service_impl.cc b/chrome/updater/update_service_impl.cc index 53e005f0..4ba2ee9 100644 --- a/chrome/updater/update_service_impl.cc +++ b/chrome/updater/update_service_impl.cc
@@ -4,6 +4,8 @@ #include "chrome/updater/update_service_impl.h" +#include <algorithm> +#include <iterator> #include <string> #include <utility> #include <vector> @@ -13,6 +15,7 @@ #include "base/callback.h" #include "base/callback_helpers.h" #include "base/containers/contains.h" +#include "base/containers/flat_map.h" #include "base/containers/queue.h" #include "base/logging.h" #include "base/run_loop.h" @@ -148,6 +151,7 @@ std::vector<absl::optional<update_client::CrxComponent>> GetComponents( scoped_refptr<Configurator> config, scoped_refptr<PersistedData> persisted_data, + const AppInstallDataIndex& app_install_data_index, bool foreground, bool update_blocked, UpdateService::PolicySameVersionUpdate policy_same_version_update, @@ -160,6 +164,10 @@ components.push_back( base::MakeRefCounted<Installer>( id, + [&app_install_data_index, &id]() { + auto it = app_install_data_index.find(id); + return it != app_install_data_index.end() ? it->second : ""; + }(), [&config, &id]() { std::string component_channel; return config->GetPolicyService()->GetTargetChannel( @@ -357,12 +365,15 @@ std::move(callback).Run(result); }, std::move(callback), persisted_data_), - app_ids, priority, - UpdateService::PolicySameVersionUpdate::kNotAllowed)); + base::MakeFlatMap<std::string, std::string>( + app_ids, {}, + [](const auto& app_id) { return std::make_pair(app_id, ""); }), + priority, UpdateService::PolicySameVersionUpdate::kNotAllowed)); } void UpdateServiceImpl::Update( const std::string& app_id, + const std::string& install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, StateChangeCallback state_update, @@ -378,12 +389,13 @@ return; } - std::vector<std::string> ids = {app_id}; ShouldBlockUpdateForMeteredNetwork( priority, - base::BindOnce(&UpdateServiceImpl::OnShouldBlockUpdateForMeteredNetwork, - this, state_update, std::move(callback), ids, priority, - policy_same_version_update)); + base::BindOnce( + &UpdateServiceImpl::OnShouldBlockUpdateForMeteredNetwork, this, + state_update, std::move(callback), + AppInstallDataIndex({std::make_pair(app_id, install_data_index)}), + priority, policy_same_version_update)); } bool UpdateServiceImpl::IsUpdateDisabledByPolicy( @@ -441,7 +453,7 @@ void UpdateServiceImpl::OnShouldBlockUpdateForMeteredNetwork( StateChangeCallback state_update, Callback callback, - const std::vector<std::string>& ids, + const AppInstallDataIndex& app_install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, bool update_blocked) { @@ -450,9 +462,19 @@ main_task_runner_->PostTask( FROM_HERE, base::BindOnce( - &update_client::UpdateClient::Update, update_client_, ids, - base::BindOnce(&GetComponents, config_, persisted_data_, false, - update_blocked, policy_same_version_update), + &update_client::UpdateClient::Update, update_client_, + [&app_install_data_index]() { + std::vector<std::string> app_ids; + app_ids.reserve(app_install_data_index.size()); + std::transform(app_install_data_index.begin(), + app_install_data_index.end(), + std::back_inserter(app_ids), + [](const auto& param) { return param.first; }); + return app_ids; + }(), + base::BindOnce(&GetComponents, config_, persisted_data_, + app_install_data_index, false, update_blocked, + policy_same_version_update), MakeUpdateClientCrxStateChangeCallback(config_, state_update), priority == Priority::kForeground, MakeUpdateClientCallback(std::move(callback))));
diff --git a/chrome/updater/update_service_impl.h b/chrome/updater/update_service_impl.h index d47c509..3c2a726 100644 --- a/chrome/updater/update_service_impl.h +++ b/chrome/updater/update_service_impl.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/callback_forward.h" +#include "base/containers/flat_map.h" #include "base/containers/queue.h" #include "base/memory/scoped_refptr.h" #include "base/sequence_checker.h" @@ -29,6 +30,8 @@ struct RegistrationRequest; struct RegistrationResponse; +using AppInstallDataIndex = base::flat_map<std::string, std::string>; + // All functions and callbacks must be called on the same sequence. class UpdateServiceImpl : public UpdateService { public: @@ -45,6 +48,7 @@ void RunPeriodicTasks(base::OnceClosure callback) override; void UpdateAll(StateChangeCallback state_update, Callback callback) override; void Update(const std::string& app_id, + const std::string& install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, StateChangeCallback state_update, @@ -76,7 +80,7 @@ void OnShouldBlockUpdateForMeteredNetwork( StateChangeCallback state_update, Callback callback, - const std::vector<std::string>& ids, + const AppInstallDataIndex& app_install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, bool update_blocked);
diff --git a/chrome/updater/update_service_impl_inactive.cc b/chrome/updater/update_service_impl_inactive.cc index 30ef919..e6854ad 100644 --- a/chrome/updater/update_service_impl_inactive.cc +++ b/chrome/updater/update_service_impl_inactive.cc
@@ -56,6 +56,7 @@ } void Update(const std::string& app_id, + const std::string& install_data_index, Priority /*priority*/, PolicySameVersionUpdate /*policy_same_version_update*/, StateChangeCallback /*state_update*/,
diff --git a/chrome/updater/update_service_internal_impl_qualifying.cc b/chrome/updater/update_service_internal_impl_qualifying.cc index 23773c5..2cb45f59 100644 --- a/chrome/updater/update_service_internal_impl_qualifying.cc +++ b/chrome/updater/update_service_internal_impl_qualifying.cc
@@ -73,12 +73,13 @@ // an `Update` task for `kQualificationAppId`. DVLOG(2) << "RegistrationResponse: " << response.status_code; base::MakeRefCounted<CheckForUpdatesTask>( - config_, base::BindOnce( - &UpdateServiceImpl::Update, - base::MakeRefCounted<UpdateServiceImpl>(config_), - kQualificationAppId, UpdateService::Priority::kBackground, - UpdateService::PolicySameVersionUpdate::kNotAllowed, - base::DoNothing())) + config_, + base::BindOnce(&UpdateServiceImpl::Update, + base::MakeRefCounted<UpdateServiceImpl>(config_), + kQualificationAppId, "", + UpdateService::Priority::kBackground, + UpdateService::PolicySameVersionUpdate::kNotAllowed, + base::DoNothing())) ->Run(base::BindOnce( &UpdateServiceInternalQualifyingImpl::QualificationDone, this, std::move(callback)));
diff --git a/chrome/updater/updater.cc b/chrome/updater/updater.cc index 8a36b88..f68fbd69 100644 --- a/chrome/updater/updater.cc +++ b/chrome/updater/updater.cc
@@ -61,25 +61,6 @@ namespace updater { namespace { -// The log file is created in DIR_LOCAL_APP_DATA or DIR_ROAMING_APP_DATA. -void InitLogging(UpdaterScope updater_scope) { - logging::LoggingSettings settings; - const absl::optional<base::FilePath> log_dir = - GetBaseDirectory(updater_scope); - if (!log_dir) { - LOG(ERROR) << "Error getting base dir."; - return; - } - const auto log_file = log_dir->Append(FILE_PATH_LITERAL("updater.log")); - settings.log_file_path = log_file.value().c_str(); - settings.logging_dest = logging::LOG_TO_ALL; - logging::InitLogging(settings); - logging::SetLogItems(true, // enable_process_id - true, // enable_thread_id - true, // enable_timestamp - false); // enable_tickcount -} - void ReinitializeLoggingAfterCrashHandler(UpdaterScope updater_scope) { // Initializing the logging more than two times is not supported. In this // case, logging has been initialized once in the updater main, and the
diff --git a/chrome/updater/util.cc b/chrome/updater/util.cc index 0ec579a..b0af7e1e 100644 --- a/chrome/updater/util.cc +++ b/chrome/updater/util.cc
@@ -213,6 +213,11 @@ return app_args ? app_args->ap : std::string(); } +std::string GetInstallDataIndexFromAppArgs(const std::string& app_id) { + const absl::optional<tagging::AppArgs> app_args = GetAppArgs(app_id); + return app_args ? app_args->install_data_index : std::string(); +} + base::CommandLine MakeElevated(base::CommandLine command_line) { #if BUILDFLAG(IS_MAC) command_line.PrependWrapper("/usr/bin/sudo"); @@ -221,8 +226,7 @@ } // The log file is created in DIR_LOCAL_APP_DATA or DIR_ROAMING_APP_DATA. -void InitLogging(UpdaterScope updater_scope, - const base::FilePath::StringType& filename) { +void InitLogging(UpdaterScope updater_scope) { logging::LoggingSettings settings; const absl::optional<base::FilePath> log_dir = GetBaseDirectory(updater_scope); @@ -230,7 +234,8 @@ LOG(ERROR) << "Error getting base dir."; return; } - const base::FilePath log_file = log_dir->Append(filename); + const base::FilePath log_file = + log_dir->Append(FILE_PATH_LITERAL("updater.log")); settings.log_file_path = log_file.value().c_str(); settings.logging_dest = logging::LOG_TO_ALL; logging::InitLogging(settings);
diff --git a/chrome/updater/util.h b/chrome/updater/util.h index a252d15..8dc15e5 100644 --- a/chrome/updater/util.h +++ b/chrome/updater/util.h
@@ -120,12 +120,13 @@ // empty string if no tag or "ap" is specified. std::string GetAPFromAppArgs(const std::string& app_id); +std::string GetInstallDataIndexFromAppArgs(const std::string& app_id); + // Returns true if the user running the updater also owns the `path`. bool PathOwnedByUser(const base::FilePath& path); // Initializes logging for an executable. -void InitLogging(UpdaterScope updater_scope, - const base::FilePath::StringType& filename); +void InitLogging(UpdaterScope updater_scope); // Wraps the 'command_line' to be executed in an elevated context. // On macOS this is done with 'sudo'.
diff --git a/chrome/updater/win/app_install_controller.cc b/chrome/updater/win/app_install_controller.cc index a3e941a..4535dbb 100644 --- a/chrome/updater/win/app_install_controller.cc +++ b/chrome/updater/win/app_install_controller.cc
@@ -500,7 +500,8 @@ DCHECK(response.status_code == kRegistrationSuccess || response.status_code == kRegistrationAlreadyRegistered); self->update_service_->Update( - self->app_id_, UpdateService::Priority::kForeground, + self->app_id_, GetInstallDataIndexFromAppArgs(self->app_id_), + UpdateService::Priority::kForeground, UpdateService::PolicySameVersionUpdate::kAllowed, base::BindRepeating(&AppInstallControllerImpl::StateChange, self),
diff --git a/chrome/updater/win/installer/BUILD.gn b/chrome/updater/win/installer/BUILD.gn index e9f55e0..d06a951b 100644 --- a/chrome/updater/win/installer/BUILD.gn +++ b/chrome/updater/win/installer/BUILD.gn
@@ -93,7 +93,6 @@ ] deps = invoker.archive_deps - deps += [ "//third_party/icu:icudata" ] if (is_component_build) { args += [ "--component_build=1" ]
diff --git a/chrome/updater/win/installer/updater.release b/chrome/updater/win/installer/updater.release index 903b54b2..9d20d88 100644 --- a/chrome/updater/win/installer/updater.release +++ b/chrome/updater/win/installer/updater.release
@@ -1,4 +1,3 @@ [GENERAL] -icudtl.dat: %(UpdaterDir)s\ updater.exe: %(UpdaterDir)s\ gen\chrome\updater\win\uninstall.cmd: %(UpdaterDir)s\
diff --git a/chrome/updater/win/installer/updater_test.release b/chrome/updater/win/installer/updater_test.release index c3fd7918..980f5342 100644 --- a/chrome/updater/win/installer/updater_test.release +++ b/chrome/updater/win/installer/updater_test.release
@@ -1,4 +1,3 @@ [GENERAL] -icudtl.dat: %(UpdaterDir)s\ updater_test.exe: %(UpdaterDir)s\updater.exe gen\chrome\updater\win\uninstall.cmd: %(UpdaterDir)s\
diff --git a/chrome/updater/win/task_scheduler_unittest.cc b/chrome/updater/win/task_scheduler_unittest.cc index 69b76d83..6ecbfa4 100644 --- a/chrome/updater/win/task_scheduler_unittest.cc +++ b/chrome/updater/win/task_scheduler_unittest.cc
@@ -128,9 +128,7 @@ return command_line; } - static void SetUpTestCase() { - InitLogging(GetTestScope(), FILE_PATH_LITERAL("updater.log")); - } + static void SetUpTestCase() { InitLogging(GetTestScope()); } protected: std::unique_ptr<TaskScheduler> task_scheduler_;
diff --git a/chrome/updater/win/test/test_process_main.cc b/chrome/updater/win/test/test_process_main.cc index d70ed5e..b15f7c0a 100644 --- a/chrome/updater/win/test/test_process_main.cc +++ b/chrome/updater/win/test/test_process_main.cc
@@ -27,8 +27,7 @@ if (command_line->HasSwitch(updater::kEnableLoggingSwitch)) { InitLogging(command_line->HasSwitch(updater::kSystemSwitch) ? updater::UpdaterScope::kSystem - : updater::UpdaterScope::kUser, - FILE_PATH_LITERAL("updater.log")); + : updater::UpdaterScope::kUser); } updater::NotifyInitializationDoneForTesting();
diff --git a/chrome/updater/win/update_service_proxy.cc b/chrome/updater/win/update_service_proxy.cc index 55870ae..d3ae0821 100644 --- a/chrome/updater/win/update_service_proxy.cc +++ b/chrome/updater/win/update_service_proxy.cc
@@ -414,6 +414,7 @@ void UpdateServiceProxy::Update( const std::string& app_id, + const std::string& install_data_index, UpdateService::Priority /*priority*/, PolicySameVersionUpdate policy_same_version_update, StateChangeCallback state_update, @@ -427,7 +428,7 @@ base::BindOnce(&UpdateServiceProxy::InitializeSTA, this) .Then(base::BindOnce( &UpdateServiceProxy::UpdateOnSTA, this, app_id, - policy_same_version_update, + install_data_index, policy_same_version_update, base::BindPostTask(main_task_runner_, state_update), base::BindPostTask(main_task_runner_, std::move(callback))))); } @@ -606,6 +607,7 @@ void UpdateServiceProxy::UpdateOnSTA( const std::string& app_id, + const std::string& install_data_index, PolicySameVersionUpdate policy_same_version_update, StateChangeCallback state_update, Callback callback, @@ -625,6 +627,7 @@ std::move(callback)); HRESULT hr = updater->Update(base::UTF8ToWide(app_id).c_str(), + base::UTF8ToWide(install_data_index).c_str(), policy_same_version_update == UpdateService::PolicySameVersionUpdate::kAllowed, observer.Get());
diff --git a/chrome/updater/win/update_service_proxy.h b/chrome/updater/win/update_service_proxy.h index d491fb2..93ab95bd 100644 --- a/chrome/updater/win/update_service_proxy.h +++ b/chrome/updater/win/update_service_proxy.h
@@ -54,6 +54,7 @@ void RunPeriodicTasks(base::OnceClosure callback) override; void UpdateAll(StateChangeCallback state_update, Callback callback) override; void Update(const std::string& app_id, + const std::string& install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, StateChangeCallback state_update, @@ -79,6 +80,7 @@ Callback callback, HRESULT prev_hr); void UpdateOnSTA(const std::string& app_id, + const std::string& install_data_index, PolicySameVersionUpdate policy_same_version_update, StateChangeCallback state_update, Callback callback,
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt index 48ad21b38..c644ec3 100644 --- a/chromeos/profiles/atom.afdo.newest.txt +++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-atom-101-4918.0-1646651687-benchmark-101.0.4940.0-r1-redacted.afdo.xz +chromeos-chrome-amd64-atom-101-4928.0-1647252934-benchmark-101.0.4943.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt index a1a8c7f..2635ae6 100644 --- a/chromeos/profiles/bigcore.afdo.newest.txt +++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-bigcore-101-4896.16-1646649426-benchmark-101.0.4940.0-r1-redacted.afdo.xz +chromeos-chrome-amd64-bigcore-101-4928.0-1647252364-benchmark-101.0.4943.0-r1-redacted.afdo.xz
diff --git a/components/browser_ui/styles/android/BUILD.gn b/components/browser_ui/styles/android/BUILD.gn index c780d9c..d8d44370 100644 --- a/components/browser_ui/styles/android/BUILD.gn +++ b/components/browser_ui/styles/android/BUILD.gn
@@ -221,7 +221,6 @@ "java/res/values-night/dimens.xml", "java/res/values-night/drawables.xml", "java/res/values-night/styles.xml", - "java/res/values-night/themes.xml", "java/res/values-night/values.xml", "java/res/values-sw600dp-v27/styles.xml", "java/res/values-v27/styles.xml",
diff --git a/components/browser_ui/styles/android/java/res/values/styles.xml b/components/browser_ui/styles/android/java/res/values/styles.xml index cfa567d..ea1d824c 100644 --- a/components/browser_ui/styles/android/java/res/values/styles.xml +++ b/components/browser_ui/styles/android/java/res/values/styles.xml
@@ -4,30 +4,6 @@ found in the LICENSE file. --> <resources xmlns:tools="http://schemas.android.com/tools"> - <!-- This theme is used instead of android:style/Theme.NoDisplay so that it has the required - attributes in case the context ends up being used to inflate views. --> - <style name="Theme.BrowserUI.NoDisplay" parent="Theme.BrowserUI.DayNight"> - <item name="android:windowBackground">@null</item> - <item name="android:windowContentOverlay">@null</item> - <item name="android:windowIsTranslucent">true</item> - <item name="android:windowAnimationStyle">@null</item> - <item name="android:windowDisablePreview">true</item> - <item name="android:windowNoDisplay">true</item> - </style> - - <!-- These themes are used instead of android:style/Theme.Translucent* so that they have the - required attributes in case the context ends up being used to inflate views. --> - <style name="Theme.BrowserUI.Translucent" parent="Theme.BrowserUI.DayNight"> - <item name="android:windowBackground">@android:color/transparent</item> - <item name="android:colorBackgroundCacheHint">@null</item> - <item name="android:windowIsTranslucent">true</item> - <item name="android:windowAnimationStyle">@android:style/Animation</item> - </style> - <style name="Theme.BrowserUI.Translucent.NoTitleBar"> - <item name="android:windowNoTitle">true</item> - <item name="android:windowContentOverlay">@null</item> - </style> - <!-- Control styles --> <style name="Widget.BrowserUI.CheckBox" parent="Widget.Material3.CompoundButton.CheckBox"> <item name="buttonTint">@color/selection_control_button_tint</item>
diff --git a/components/browser_ui/styles/android/java/res/values/themes.xml b/components/browser_ui/styles/android/java/res/values/themes.xml index 19762889..0b9e3ee 100644 --- a/components/browser_ui/styles/android/java/res/values/themes.xml +++ b/components/browser_ui/styles/android/java/res/values/themes.xml
@@ -4,157 +4,6 @@ found in the LICENSE file. --> <resources xmlns:tools="http://schemas.android.com/tools"> - <!-- Full themes. --> - - <!-- Colors should be mirrored by Theme.BrowserUI.DialogWhenLarge. --> - <style name="Base.V21.Theme.BrowserUI" parent="Theme.MaterialComponents.DayNight.NoActionBar"> - <item name="dynamicColorThemeOverlay">@style/ThemeOverlay.BrowserUI.DynamicColors</item> - - <!-- Color palettes --> - <item name="colorPrimary">@color/baseline_primary_600</item> - <item name="colorPrimaryDark">@android:color/black</item> - <item name="colorPrimaryInverse">@color/baseline_primary_200</item> - <item name="colorOnPrimary">@color/baseline_primary_0</item> - <item name="colorPrimaryContainer">@color/baseline_primary_100</item> - <item name="colorOnPrimaryContainer">@color/baseline_primary_900</item> - <item name="colorSecondaryContainer">@color/baseline_secondary_100</item> - <item name="colorOnSecondaryContainer">@color/baseline_secondary_900</item> - <item name="colorAccent">@macro/default_control_color_active</item> - <item name="android:colorBackground">@color/baseline_neutral_0</item> - <item name="colorOnBackground">@color/baseline_neutral_900</item> - <item name="colorSurface">@color/baseline_neutral_0</item> - <item name="colorOnSurface">@color/baseline_neutral_900</item> - <item name="colorSurfaceVariant">@color/baseline_neutral_variant_100</item> - <item name="colorOnSurfaceVariant">@color/baseline_neutral_variant_700</item> - <item name="colorOnSurfaceInverse">@color/baseline_neutral_50</item> - <item name="colorOutline">@color/baseline_neutral_variant_500</item> - <item name="colorError">@color/baseline_error_600</item> - - <!-- Text colors--> - <item name="android:textColorPrimary">@color/default_text_color_list</item> - <item name="android:textColorSecondary">@color/default_text_color_secondary_list</item> - <item name="android:textColorLink">@macro/default_text_color_link</item> - <item name="android:textColorHighlight">@color/text_highlight_color</item> - <item name="android:textColorHint">@color/default_text_color_hint_list</item> - - <!-- Widget colors: checkboxes, switches, buttons, etc. --> - <item name="colorControlNormal">@macro/default_control_color_normal</item> - <item name="colorControlActivated">@macro/default_control_color_active</item> - <item name="colorControlHighlight">@color/control_highlight_color</item> - - <!-- Elevation overlays --> - <item name="elevationOverlayEnabled">true</item> - <item name="elevationOverlayColor">@color/baseline_neutral_600</item> - <item name="elevationOverlayAccentColor">?attr/colorPrimary</item> - - <!-- Custom semantic names --> - <!-- Supports dynamic colors now. --> - <item name="default_bg_color_dynamic">?attr/colorSurface</item> - <item name="divider_line_bg_color_dynamic">?attr/colorSurfaceVariant</item> - - <!-- Baseline values for the theme attributes in ThemeOverlay.DynamicButtons, used to - prevent crashes when the DynamicColorCTAAndroid flag is disabled. --> - <item name="globalFilledButtonBgColor">@color/filled_button_bg</item> - <item name="globalFilledButtonTextColor">@color/default_text_color_on_accent1_baseline_list</item> - <item name="globalTextButtonTextColor">@color/blue_when_enabled</item> - <item name="globalLinkTextColor">@color/default_text_color_link_baseline</item> - <item name="globalClickableSpanColor">@color/default_text_color_blue_baseline</item> - </style> - <style name="Base.V31.Theme.BrowserUI" parent="Base.V21.Theme.BrowserUI" /> - <style name="Base.Theme.BrowserUI" parent="Base.V31.Theme.BrowserUI" /> - <style name="Theme.BrowserUI" parent="Base.Theme.BrowserUI"> - <!-- Control styles --> - <item name="checkboxStyle">@style/Widget.BrowserUI.CheckBox</item> - <item name="radioButtonStyle">@style/Widget.BrowserUI.RadioButton</item> - <item name="switchStyle">@style/Widget.BrowserUI.Switch</item> - - <!-- Window Properties --> - <item name="android:windowBackground">@macro/default_bg_color</item> - - <!-- Status bar color --> - <item name="android:statusBarColor" tools:targetApi="21">@android:color/black</item> - <item name="android:windowLightStatusBar" tools:targetApi="23">false</item> - - <!-- Spinner styles --> - <item name="spinnerStyle">@style/SpinnerStyle</item> - <item name="android:progressBarStyle">@style/ProgressBarStyle</item> - - <!-- Popup styles --> - <!-- Set android popup menu attributes for context menu styles because the context menus are - OS-dependent. --> - <item name="android:popupMenuStyle">@style/PopupMenuStyle</item> - <item name="android:textAppearanceLargePopupMenu"> - @style/TextAppearance.TextLarge.Primary - </item> - <item name="android:textAppearanceSmallPopupMenu"> - @style/TextAppearance.TextLarge.Primary - </item> - <item name="android:contextPopupMenuStyle" tools:targetApi="24">@style/PopupMenuStyle</item> - - <!-- This is for keeping the current TextInputLayout style. - TODO(crbug.com/1206024): Remove or update once the design for the app is updated. --> - <item name="textInputStyle">@style/Widget.BrowserUI.TextInputLayout</item> - </style> - <!-- Overridden by night mode. --> - <style name="Theme.BrowserUI.DayNight" parent="Theme.BrowserUI" /> - - <!-- Colors should be mirrored by Base.V21.Theme.BrowserUI. --> - <style name="Theme.BrowserUI.DialogWhenLarge" parent="Theme.MaterialComponents.DayNight.DialogWhenLarge"> - <item name="dynamicColorThemeOverlay">@style/ThemeOverlay.BrowserUI.DynamicColors</item> - - <!-- Color palettes --> - <item name="colorPrimary">@color/baseline_primary_600</item> - <item name="colorPrimaryInverse">@color/baseline_primary_200</item> - <item name="colorPrimaryDark">@android:color/black</item> - <item name="colorOnPrimary">@color/baseline_primary_0</item> - <item name="colorPrimaryContainer">@color/baseline_primary_100</item> - <item name="colorOnPrimaryContainer">@color/baseline_primary_900</item> - <item name="colorSecondaryContainer">@color/baseline_secondary_100</item> - <item name="colorOnSecondaryContainer">@color/baseline_secondary_900</item> - <item name="colorAccent">@macro/default_control_color_active</item> - <item name="android:colorBackground">@color/baseline_neutral_0</item> - <item name="colorOnBackground">@color/baseline_neutral_900</item> - <item name="colorSurface">@color/baseline_neutral_0</item> - <item name="colorOnSurface">@color/baseline_neutral_900</item> - <item name="colorSurfaceVariant">@color/baseline_neutral_variant_100</item> - <item name="colorOnSurfaceVariant">@color/baseline_neutral_variant_700</item> - <item name="colorOnSurfaceInverse">@color/baseline_neutral_50</item> - <item name="colorOutline">@color/baseline_neutral_variant_500</item> - <item name="colorError">@color/baseline_error_600</item> - - <!-- Text colors--> - <item name="android:textColorPrimary">@color/default_text_color_list</item> - <item name="android:textColorSecondary">@color/default_text_color_secondary_list</item> - <item name="android:textColorLink">@macro/default_text_color_link</item> - <item name="android:textColorHighlight">@color/text_highlight_color</item> - <item name="android:textColorHint">@color/default_text_color_hint_list</item> - - <!-- Widget colors: checkboxes, switches, buttons, etc. --> - <item name="colorControlNormal">@macro/default_control_color_normal</item> - <item name="colorControlActivated">@macro/default_control_color_active</item> - <item name="colorControlHighlight">@color/control_highlight_color</item> - - <!-- Elevation overlays --> - <item name="elevationOverlayEnabled">true</item> - <item name="elevationOverlayColor">@color/baseline_neutral_600</item> - <item name="elevationOverlayAccentColor">?attr/colorPrimary</item> - - <!-- Custom semantic names --> - <!-- Supports dynamic colors now. --> - <item name="default_bg_color_dynamic">?attr/colorSurface</item> - <item name="divider_line_bg_color_dynamic">?attr/colorSurfaceVariant</item> - - <!-- Baseline values for the theme attributes in ThemeOverlay.DynamicButtons, used to - prevent crashes when the DynamicColorCTAAndroid flag is disabled. --> - <item name="globalFilledButtonBgColor">@color/filled_button_bg</item> - <item name="globalFilledButtonTextColor">@color/default_text_color_on_accent1_baseline_list</item> - <item name="globalTextButtonTextColor">@color/blue_when_enabled</item> - <item name="globalLinkTextColor">@color/default_text_color_link_baseline</item> - <item name="globalClickableSpanColor">@color/default_text_color_blue_baseline</item> - </style> - <!-- Overridden by night mode. --> - <style name="Theme.BrowserUI.DialogWhenLarge.DayNight" parent="Theme.BrowserUI.DialogWhenLarge"/> - <!-- Theme overlays --> <!-- Fullscreen -->
diff --git a/components/browser_ui/test/android/BUILD.gn b/components/browser_ui/test/android/BUILD.gn index 1d4e7de..f1c352d7 100644 --- a/components/browser_ui/test/android/BUILD.gn +++ b/components/browser_ui/test/android/BUILD.gn
@@ -10,6 +10,7 @@ sources = [ "src/org/chromium/components/browser_ui/test/BrowserUiDummyFragmentActivity.java" ] deps = [ "//components/browser_ui/styles/android:java_resources", + "//components/browser_ui/theme/android:java_resources", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_fragment_fragment_java", "//ui/android:ui_java_test_support",
diff --git a/components/browser_ui/theme/android/BUILD.gn b/components/browser_ui/theme/android/BUILD.gn new file mode 100644 index 0000000..bbb1f9a --- /dev/null +++ b/components/browser_ui/theme/android/BUILD.gn
@@ -0,0 +1,16 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/android/rules.gni") + +android_resources("java_resources") { + sources = [ + "java/res/values-night/themes.xml", + "java/res/values/themes.xml", + ] + deps = [ + "//components/browser_ui/styles/android:java_resources", + "//components/browser_ui/widget/android:java_resources", + ] +}
diff --git a/components/browser_ui/theme/android/OWNERS b/components/browser_ui/theme/android/OWNERS new file mode 100644 index 0000000..1f427c66 --- /dev/null +++ b/components/browser_ui/theme/android/OWNERS
@@ -0,0 +1,2 @@ +sinansahin@google.com +skym@chromium.org
diff --git a/components/browser_ui/styles/android/java/res/values-night/themes.xml b/components/browser_ui/theme/android/java/res/values-night/themes.xml similarity index 96% rename from components/browser_ui/styles/android/java/res/values-night/themes.xml rename to components/browser_ui/theme/android/java/res/values-night/themes.xml index 4e100109..512dc28 100644 --- a/components/browser_ui/styles/android/java/res/values-night/themes.xml +++ b/components/browser_ui/theme/android/java/res/values-night/themes.xml
@@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2021 The Chromium Authors. All rights reserved. +<!-- Copyright 2022 The Chromium Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. -->
diff --git a/components/browser_ui/theme/android/java/res/values/themes.xml b/components/browser_ui/theme/android/java/res/values/themes.xml new file mode 100644 index 0000000..ef61a1e --- /dev/null +++ b/components/browser_ui/theme/android/java/res/values/themes.xml
@@ -0,0 +1,209 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2022 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<resources xmlns:tools="http://schemas.android.com/tools"> + <!-- Colors should be mirrored by Theme.BrowserUI.DialogWhenLarge. --> + <style name="Base.V21.Theme.BrowserUI" parent="Theme.MaterialComponents.DayNight.NoActionBar"> + <item name="dynamicColorThemeOverlay">@style/ThemeOverlay.BrowserUI.DynamicColors</item> + + <!-- Color palettes --> + <item name="colorPrimary">@color/baseline_primary_600</item> + <item name="colorPrimaryDark">@android:color/black</item> + <item name="colorPrimaryInverse">@color/baseline_primary_200</item> + <item name="colorOnPrimary">@color/baseline_primary_0</item> + <item name="colorPrimaryContainer">@color/baseline_primary_100</item> + <item name="colorOnPrimaryContainer">@color/baseline_primary_900</item> + <item name="colorSecondaryContainer">@color/baseline_secondary_100</item> + <item name="colorOnSecondaryContainer">@color/baseline_secondary_900</item> + <item name="colorAccent">@macro/default_control_color_active</item> + <item name="android:colorBackground">@color/baseline_neutral_0</item> + <item name="colorOnBackground">@color/baseline_neutral_900</item> + <item name="colorSurface">@color/baseline_neutral_0</item> + <item name="colorOnSurface">@color/baseline_neutral_900</item> + <item name="colorSurfaceVariant">@color/baseline_neutral_variant_100</item> + <item name="colorOnSurfaceVariant">@color/baseline_neutral_variant_700</item> + <item name="colorOnSurfaceInverse">@color/baseline_neutral_50</item> + <item name="colorOutline">@color/baseline_neutral_variant_500</item> + <item name="colorError">@color/baseline_error_600</item> + + <!-- Text colors--> + <item name="android:textColorPrimary">@color/default_text_color_list</item> + <item name="android:textColorSecondary">@color/default_text_color_secondary_list</item> + <item name="android:textColorLink">@macro/default_text_color_link</item> + <item name="android:textColorHighlight">@color/text_highlight_color</item> + <item name="android:textColorHint">@color/default_text_color_hint_list</item> + + <!-- Widget colors: checkboxes, switches, buttons, etc. --> + <item name="colorControlNormal">@macro/default_control_color_normal</item> + <item name="colorControlActivated">@macro/default_control_color_active</item> + <item name="colorControlHighlight">@color/control_highlight_color</item> + + <!-- Elevation overlays --> + <item name="elevationOverlayEnabled">true</item> + <item name="elevationOverlayColor">@color/baseline_neutral_600</item> + <item name="elevationOverlayAccentColor">?attr/colorPrimary</item> + + <!-- Custom semantic names --> + <!-- Supports dynamic colors now. --> + <item name="default_bg_color_dynamic">?attr/colorSurface</item> + <item name="divider_line_bg_color_dynamic">?attr/colorSurfaceVariant</item> + + <!-- Baseline values for the theme attributes in ThemeOverlay.DynamicButtons, used to + prevent crashes when the DynamicColorCTAAndroid flag is disabled. --> + <item name="globalFilledButtonBgColor">@color/filled_button_bg</item> + <item name="globalFilledButtonTextColor">@color/default_text_color_on_accent1_baseline_list</item> + <item name="globalTextButtonTextColor">@color/blue_when_enabled</item> + <item name="globalLinkTextColor">@color/default_text_color_link_baseline</item> + <item name="globalClickableSpanColor">@color/default_text_color_blue_baseline</item> + </style> + <style name="Base.V31.Theme.BrowserUI" parent="Base.V21.Theme.BrowserUI" /> + <style name="Base.Theme.BrowserUI" parent="Base.V31.Theme.BrowserUI" /> + <style name="Theme.BrowserUI" parent="Base.Theme.BrowserUI"> + <!-- Control styles --> + <item name="checkboxStyle">@style/Widget.BrowserUI.CheckBox</item> + <item name="radioButtonStyle">@style/Widget.BrowserUI.RadioButton</item> + <item name="switchStyle">@style/Widget.BrowserUI.Switch</item> + + <!-- Window Properties --> + <item name="android:windowBackground">@macro/default_bg_color</item> + + <!-- Status bar color --> + <item name="android:statusBarColor" tools:targetApi="21">@android:color/black</item> + <item name="android:windowLightStatusBar" tools:targetApi="23">false</item> + + <!-- Spinner styles --> + <item name="spinnerStyle">@style/SpinnerStyle</item> + <item name="android:progressBarStyle">@style/ProgressBarStyle</item> + + <!-- Popup styles --> + <!-- Set android popup menu attributes for context menu styles because the context menus are + OS-dependent. --> + <item name="android:popupMenuStyle">@style/PopupMenuStyle</item> + <item name="android:textAppearanceLargePopupMenu"> + @style/TextAppearance.TextLarge.Primary + </item> + <item name="android:textAppearanceSmallPopupMenu"> + @style/TextAppearance.TextLarge.Primary + </item> + <item name="android:contextPopupMenuStyle" tools:targetApi="24">@style/PopupMenuStyle</item> + + <!-- This is for keeping the current TextInputLayout style. + TODO(crbug.com/1206024): Remove or update once the design for the app is updated. --> + <item name="textInputStyle">@style/Widget.BrowserUI.TextInputLayout</item> + </style> + <!-- Overridden by night mode. --> + <style name="Theme.BrowserUI.DayNight" parent="Theme.BrowserUI" /> + + <!-- Colors should be mirrored by Base.V21.Theme.BrowserUI. --> + <style name="Theme.BrowserUI.DialogWhenLarge" parent="Theme.MaterialComponents.DayNight.DialogWhenLarge"> + <item name="dynamicColorThemeOverlay">@style/ThemeOverlay.BrowserUI.DynamicColors</item> + + <!-- Color palettes --> + <item name="colorPrimary">@color/baseline_primary_600</item> + <item name="colorPrimaryInverse">@color/baseline_primary_200</item> + <item name="colorPrimaryDark">@android:color/black</item> + <item name="colorOnPrimary">@color/baseline_primary_0</item> + <item name="colorPrimaryContainer">@color/baseline_primary_100</item> + <item name="colorOnPrimaryContainer">@color/baseline_primary_900</item> + <item name="colorSecondaryContainer">@color/baseline_secondary_100</item> + <item name="colorOnSecondaryContainer">@color/baseline_secondary_900</item> + <item name="colorAccent">@macro/default_control_color_active</item> + <item name="android:colorBackground">@color/baseline_neutral_0</item> + <item name="colorOnBackground">@color/baseline_neutral_900</item> + <item name="colorSurface">@color/baseline_neutral_0</item> + <item name="colorOnSurface">@color/baseline_neutral_900</item> + <item name="colorSurfaceVariant">@color/baseline_neutral_variant_100</item> + <item name="colorOnSurfaceVariant">@color/baseline_neutral_variant_700</item> + <item name="colorOnSurfaceInverse">@color/baseline_neutral_50</item> + <item name="colorOutline">@color/baseline_neutral_variant_500</item> + <item name="colorError">@color/baseline_error_600</item> + + <!-- Text colors--> + <item name="android:textColorPrimary">@color/default_text_color_list</item> + <item name="android:textColorSecondary">@color/default_text_color_secondary_list</item> + <item name="android:textColorLink">@macro/default_text_color_link</item> + <item name="android:textColorHighlight">@color/text_highlight_color</item> + <item name="android:textColorHint">@color/default_text_color_hint_list</item> + + <!-- Widget colors: checkboxes, switches, buttons, etc. --> + <item name="colorControlNormal">@macro/default_control_color_normal</item> + <item name="colorControlActivated">@macro/default_control_color_active</item> + <item name="colorControlHighlight">@color/control_highlight_color</item> + + <!-- Elevation overlays --> + <item name="elevationOverlayEnabled">true</item> + <item name="elevationOverlayColor">@color/baseline_neutral_600</item> + <item name="elevationOverlayAccentColor">?attr/colorPrimary</item> + + <!-- Custom semantic names --> + <!-- Supports dynamic colors now. --> + <item name="default_bg_color_dynamic">?attr/colorSurface</item> + <item name="divider_line_bg_color_dynamic">?attr/colorSurfaceVariant</item> + + <!-- Baseline values for the theme attributes in ThemeOverlay.DynamicButtons, used to + prevent crashes when the DynamicColorCTAAndroid flag is disabled. --> + <item name="globalFilledButtonBgColor">@color/filled_button_bg</item> + <item name="globalFilledButtonTextColor">@color/default_text_color_on_accent1_baseline_list</item> + <item name="globalTextButtonTextColor">@color/blue_when_enabled</item> + <item name="globalLinkTextColor">@color/default_text_color_link_baseline</item> + <item name="globalClickableSpanColor">@color/default_text_color_blue_baseline</item> + </style> + <!-- Overridden by night mode. --> + <style name="Theme.BrowserUI.DialogWhenLarge.DayNight" parent="Theme.BrowserUI.DialogWhenLarge"/> + + <!-- Unlike |Theme.Chromium.AlertDialog|, this is a complete theme that can be used as an + activity theme on its own. This should be kept in sync with |Theme.Chromium.AlertDialog|. + --> + <style name="Theme.BrowserUI.AlertDialog.NoActionBar" + parent="Theme.MaterialComponents.DayNight.Dialog.Alert"> + <item name="android:textColorPrimary">@macro/default_text_color</item> + <item name="android:windowBackground">@drawable/dialog_bg_no_shadow</item> + <item name="android:windowTitleStyle">@style/TextAppearance.AlertDialogTitleStyle</item> + <item name="android:textColorHighlight">@color/text_highlight_color</item> + + <!-- Overriding AppCompat values --> + <item name="colorAccent">@macro/default_control_color_active</item> + <item name="colorControlNormal">@macro/default_control_color_normal</item> + <item name="colorControlActivated">@macro/default_control_color_active</item> + <item name="colorControlHighlight">@color/control_highlight_color</item> + <item name="spinnerStyle">@style/SpinnerStyle</item> + + <!-- Depending on if the support library or framework is inflating the + dialog, a different layout is used, that names this style slightly + differently. WebView will use the framework version for the + foreseeable future, so both of these need to be specified. See + https://crbug.com/1234129. --> + <item name="android:buttonBarButtonStyle">@style/AlertDialogButtonStyle</item> + <item name="buttonBarButtonStyle">@style/AlertDialogButtonStyle</item> + + <!-- NoActionBar --> + <item name="windowNoTitle">true</item> + <item name="windowActionBar">false</item> + </style> + + <!-- This theme is used instead of android:style/Theme.NoDisplay so that it has the required + attributes in case the context ends up being used to inflate views. --> + <style name="Theme.BrowserUI.NoDisplay" parent="Theme.BrowserUI.DayNight"> + <item name="android:windowBackground">@null</item> + <item name="android:windowContentOverlay">@null</item> + <item name="android:windowIsTranslucent">true</item> + <item name="android:windowAnimationStyle">@null</item> + <item name="android:windowDisablePreview">true</item> + <item name="android:windowNoDisplay">true</item> + </style> + + <!-- These themes are used instead of android:style/Theme.Translucent* so that they have the + required attributes in case the context ends up being used to inflate views. --> + <style name="Theme.BrowserUI.Translucent" parent="Theme.BrowserUI.DayNight"> + <item name="android:windowBackground">@android:color/transparent</item> + <item name="android:colorBackgroundCacheHint">@null</item> + <item name="android:windowIsTranslucent">true</item> + <item name="android:windowAnimationStyle">@android:style/Animation</item> + </style> + <style name="Theme.BrowserUI.Translucent.NoTitleBar"> + <item name="android:windowNoTitle">true</item> + <item name="android:windowContentOverlay">@null</item> + </style> +</resources>
diff --git a/components/browser_ui/widget/android/BUILD.gn b/components/browser_ui/widget/android/BUILD.gn index 6912044..2db5ca7 100644 --- a/components/browser_ui/widget/android/BUILD.gn +++ b/components/browser_ui/widget/android/BUILD.gn
@@ -265,7 +265,6 @@ "java/res/values/drawables.xml", "java/res/values/ids.xml", "java/res/values/styles.xml", - "java/res/values/themes.xml", "java/res/values/values.xml", ] deps = [ @@ -324,6 +323,7 @@ "//base:base_java", "//base:base_java_test_support", "//components/browser_ui/test/android:test_support_java", + "//components/browser_ui/theme/android:java_resources", "//content/public/test/android:content_java_test_support", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java",
diff --git a/components/browser_ui/widget/android/java/res/values/themes.xml b/components/browser_ui/widget/android/java/res/values/themes.xml deleted file mode 100644 index 80acd7a43..0000000 --- a/components/browser_ui/widget/android/java/res/values/themes.xml +++ /dev/null
@@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2022 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> - -<resources> - <!-- Unlike |Theme.Chromium.AlertDialog|, this is a complete theme that can be used as an - activity theme on its own. This should be kept in sync with |Theme.Chromium.AlertDialog|. - --> - <style name="Theme.BrowserUI.AlertDialog.NoActionBar" - parent="Theme.MaterialComponents.DayNight.Dialog.Alert"> - <item name="android:textColorPrimary">@macro/default_text_color</item> - <item name="android:windowBackground">@drawable/dialog_bg_no_shadow</item> - <item name="android:windowTitleStyle">@style/TextAppearance.AlertDialogTitleStyle</item> - <item name="android:textColorHighlight">@color/text_highlight_color</item> - - <!-- Overriding AppCompat values --> - <item name="colorAccent">@macro/default_control_color_active</item> - <item name="colorControlNormal">@macro/default_control_color_normal</item> - <item name="colorControlActivated">@macro/default_control_color_active</item> - <item name="colorControlHighlight">@color/control_highlight_color</item> - <item name="spinnerStyle">@style/SpinnerStyle</item> - - <!-- Depending on if the support library or framework is inflating the - dialog, a different layout is used, that names this style slightly - differently. WebView will use the framework version for the - foreseeable future, so both of these need to be specified. See - https://crbug.com/1234129. --> - <item name="android:buttonBarButtonStyle">@style/AlertDialogButtonStyle</item> - <item name="buttonBarButtonStyle">@style/AlertDialogButtonStyle</item> - - <!-- NoActionBar --> - <item name="windowNoTitle">true</item> - <item name="windowActionBar">false</item> - </style> -</resources>
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/highlight/ViewHighlighterTest.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/highlight/ViewHighlighterTest.java index 1247682..e2d99f4 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/highlight/ViewHighlighterTest.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/highlight/ViewHighlighterTest.java
@@ -27,7 +27,7 @@ import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Batch; -import org.chromium.components.browser_ui.widget.R; +import org.chromium.components.browser_ui.widget.test.R; /** * Tests the utility methods for highlighting of a view.
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardCoordinatorTest.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardCoordinatorTest.java index 9114a57..c6889715 100644 --- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardCoordinatorTest.java +++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/promo/PromoCardCoordinatorTest.java
@@ -56,8 +56,8 @@ // is based on material theme. For now we need the theme wrapper to inflate the layout; // because we are not setting our theme overlay for the test apk TestThreadUtils.runOnUiThreadBlocking(() -> { - ContextThemeWrapper wrapperTheme = new ContextThemeWrapper(mContext, - org.chromium.components.browser_ui.widget.R.style.Theme_BrowserUI_DayNight); + ContextThemeWrapper wrapperTheme = + new ContextThemeWrapper(mContext, R.style.Theme_BrowserUI_DayNight); mPromoCardCoordinator = new PromoCardCoordinator(wrapperTheme, mModel, "test-feature", layoutStyle); mView = (PromoCardView) mPromoCardCoordinator.getView();
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json index 530e9f7..01d75e5 100644 --- a/components/certificate_transparency/data/log_list.json +++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@ { - "version": "6.10", - "log_list_timestamp": "2022-03-14T01:34:10Z", + "version": "7.1", + "log_list_timestamp": "2022-03-15T01:34:41Z", "operators": [ { "name": "Google", @@ -312,6 +312,22 @@ "timestamp": "2019-02-16T00:00:00Z" } } + }, + { + "description": "DigiCert Yeti2022-2 Log", + "log_id": "BZwB0yDgB4QTlYBJjRF8kDJmr69yULWvO0akPhGEDUo=", + "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHWlePwrycXfNnV3DNEkA7mB34XJ2dKh8XH0J8jIdBX4u/lsx1Tr9czRuSRROUFiWWsTH9L4FZKT31+WxbTMMww==", + "url": "https://yeti2022-2.ct.digicert.com/log/", + "mmd": 86400, + "state": { + "qualified": { + "timestamp": "2022-03-11T00:00:00Z" + } + }, + "temporal_interval": { + "start_inclusive": "2022-01-01T00:00:00Z", + "end_exclusive": "2023-01-01T00:00:00Z" + } } ] },
diff --git a/components/content_settings/browser/page_specific_content_settings.cc b/components/content_settings/browser/page_specific_content_settings.cc index 5088539..6802b52 100644 --- a/components/content_settings/browser/page_specific_content_settings.cc +++ b/components/content_settings/browser/page_specific_content_settings.cc
@@ -29,6 +29,7 @@ #include "components/content_settings/core/browser/content_settings_utils.h" #include "components/prefs/pref_service.h" #include "components/privacy_sandbox/canonical_topic.h" +#include "components/privacy_sandbox/privacy_sandbox_features.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/cookie_access_details.h" #include "content/public/browser/navigation_handle.h" @@ -916,6 +917,7 @@ std::vector<privacy_sandbox::CanonicalTopic> PageSpecificContentSettings::GetAccessedTopics() const { if (accessed_topics_.empty() && + privacy_sandbox::kPrivacySandboxSettings3ShowSampleDataForTesting.Get() && page().GetMainDocument().GetLastCommittedURL().host() == "example.com") { // TODO(crbug.com/1286276): Remove sample topic when API is ready. return {privacy_sandbox::CanonicalTopic(
diff --git a/components/feed/core/v2/config.h b/components/feed/core/v2/config.h index 0b942e17..95b16cc 100644 --- a/components/feed/core/v2/config.h +++ b/components/feed/core/v2/config.h
@@ -103,13 +103,7 @@ // Set of optional capabilities included in requests. See // CreateFeedQueryRequest() for required capabilities. base::flat_set<feedwire::Capability> experimental_capabilities = { - feedwire::Capability::DISMISS_COMMAND, - feedwire::Capability::INFINITE_FEED, feedwire::Capability::MATERIAL_NEXT_BASELINE, - feedwire::Capability::PREFETCH_METADATA, - feedwire::Capability::REQUEST_SCHEDULE, - feedwire::Capability::UI_THEME_V2, - feedwire::Capability::UNDO_FOR_DISMISS_COMMAND, feedwire::Capability::CONTENT_LIFETIME, };
diff --git a/components/feed/core/v2/proto_util.cc b/components/feed/core/v2/proto_util.cc index 7cab5fc..c565ee1 100644 --- a/components/feed/core/v2/proto_util.cc +++ b/components/feed/core/v2/proto_util.cc
@@ -33,6 +33,8 @@ namespace feed { namespace { +using feedwire::Capability; + feedwire::Version::Architecture GetBuildArchitecture() { #if defined(ARCH_CPU_X86_64) return feedwire::Version::X86_64; @@ -126,44 +128,42 @@ request.set_request_version(feedwire::Request::FEED_QUERY); feedwire::FeedRequest& feed_request = *request.mutable_feed_request(); - feed_request.add_client_capability(feedwire::Capability::CARD_MENU); - feed_request.add_client_capability(feedwire::Capability::LOTTIE_ANIMATIONS); - feed_request.add_client_capability( - feedwire::Capability::LONG_PRESS_CARD_MENU); - feed_request.add_client_capability(feedwire::Capability::SHARE); - feed_request.add_client_capability(feedwire::Capability::OPEN_IN_TAB); - feed_request.add_client_capability(feedwire::Capability::OPEN_IN_INCOGNITO); + for (Capability capability : + {Capability::CARD_MENU, Capability::LOTTIE_ANIMATIONS, + Capability::LONG_PRESS_CARD_MENU, Capability::SHARE, + Capability::OPEN_IN_TAB, Capability::OPEN_IN_INCOGNITO, + Capability::DISMISS_COMMAND, Capability::INFINITE_FEED, + Capability::PREFETCH_METADATA, Capability::REQUEST_SCHEDULE, + Capability::UI_THEME_V2, Capability::UNDO_FOR_DISMISS_COMMAND}) { + feed_request.add_client_capability(capability); + } for (auto capability : GetFeedConfig().experimental_capabilities) feed_request.add_client_capability(capability); + if (base::FeatureList::IsEnabled(kInterestFeedV2Hearts)) { - feed_request.add_client_capability(feedwire::Capability::HEART); + feed_request.add_client_capability(Capability::HEART); } if (request_metadata.autoplay_enabled) { - feed_request.add_client_capability( - feedwire::Capability::INLINE_VIDEO_AUTOPLAY); - feed_request.add_client_capability( - feedwire::Capability::OPEN_VIDEO_COMMAND); + feed_request.add_client_capability(Capability::INLINE_VIDEO_AUTOPLAY); + feed_request.add_client_capability(Capability::OPEN_VIDEO_COMMAND); } if (base::FeatureList::IsEnabled(kFeedStamp)) { - feed_request.add_client_capability( - feedwire::Capability::SILK_AMP_OPEN_COMMAND); - feed_request.add_client_capability(feedwire::Capability::AMP_STORY_PLAYER); - feed_request.add_client_capability( - feedwire::Capability::AMP_GROUP_DATASTORE); + feed_request.add_client_capability(Capability::SILK_AMP_OPEN_COMMAND); + feed_request.add_client_capability(Capability::AMP_STORY_PLAYER); + feed_request.add_client_capability(Capability::AMP_GROUP_DATASTORE); } if (base::FeatureList::IsEnabled(reading_list::switches::kReadLater)) { - feed_request.add_client_capability(feedwire::Capability::READ_LATER); + feed_request.add_client_capability(Capability::READ_LATER); } else { - feed_request.add_client_capability(feedwire::Capability::DOWNLOAD_LINK); + feed_request.add_client_capability(Capability::DOWNLOAD_LINK); } if (base::FeatureList::IsEnabled(kPersonalizeFeedUnsignedUsers)) { - feed_request.add_client_capability( - feedwire::Capability::ON_DEVICE_USER_PROFILE); + feed_request.add_client_capability(Capability::ON_DEVICE_USER_PROFILE); } *feed_request.mutable_client_info() = CreateClientInfo(request_metadata);
diff --git a/components/feed/core/v2/proto_util_unittest.cc b/components/feed/core/v2/proto_util_unittest.cc index faae10e..2c9a56d8 100644 --- a/components/feed/core/v2/proto_util_unittest.cc +++ b/components/feed/core/v2/proto_util_unittest.cc
@@ -106,7 +106,7 @@ // Try to disable _INFINITE_FEED. base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeatureWithParameters( - kInterestFeedV2, {{"enable_INFINITE_FEED", "false"}}); + kInterestFeedV2, {{"enable_MATERIAL_NEXT_BASELINE", "false"}}); OverrideConfigWithFinchForTesting(); feedwire::FeedRequest request = @@ -117,19 +117,11 @@ .feed_request(); // Additional features may be present based on the current testing config. - ASSERT_THAT( - request.client_capability(), - testing::IsSupersetOf( - {feedwire::Capability::REQUEST_SCHEDULE, - feedwire::Capability::LOTTIE_ANIMATIONS, - feedwire::Capability::LONG_PRESS_CARD_MENU, - feedwire::Capability::OPEN_IN_TAB, feedwire::Capability::CARD_MENU, - feedwire::Capability::DISMISS_COMMAND, feedwire::Capability::SHARE, - feedwire::Capability::MATERIAL_NEXT_BASELINE, - feedwire::Capability::UI_THEME_V2, - feedwire::Capability::UNDO_FOR_DISMISS_COMMAND, - feedwire::Capability::PREFETCH_METADATA, - feedwire::Capability::CONTENT_LIFETIME})); + ASSERT_THAT(request.client_capability(), + Not(Contains(feedwire::Capability::MATERIAL_NEXT_BASELINE))); + + ASSERT_THAT(request.client_capability(), + Contains(feedwire::Capability::CONTENT_LIFETIME)); } TEST(ProtoUtilTest, PrivacyNoticeCardAcknowledged) {
diff --git a/components/feed/core/v2/xsurface_datastore.cc b/components/feed/core/v2/xsurface_datastore.cc index 60df155..fe55ec1 100644 --- a/components/feed/core/v2/xsurface_datastore.cc +++ b/components/feed/core/v2/xsurface_datastore.cc
@@ -42,11 +42,13 @@ return entries_; } -void XsurfaceDatastoreSlice::AddObserver(Observer* o) { +void XsurfaceDatastoreSlice::AddObserver( + XsurfaceDatastoreDataReader::Observer* o) { observers_.AddObserver(o); } -void XsurfaceDatastoreSlice::RemoveObserver(Observer* o) { +void XsurfaceDatastoreSlice::RemoveObserver( + XsurfaceDatastoreDataReader::Observer* o) { observers_.RemoveObserver(o); } @@ -63,11 +65,13 @@ s->RemoveObserver(this); } } -void XsurfaceDatastoreAggregate::AddObserver(Observer* o) { +void XsurfaceDatastoreAggregate::AddObserver( + XsurfaceDatastoreDataReader::Observer* o) { observers_.AddObserver(o); } -void XsurfaceDatastoreAggregate::RemoveObserver(Observer* o) { +void XsurfaceDatastoreAggregate::RemoveObserver( + XsurfaceDatastoreDataReader::Observer* o) { observers_.RemoveObserver(o); } @@ -86,7 +90,7 @@ void XsurfaceDatastoreAggregate::DatastoreEntryUpdated( XsurfaceDatastoreDataReader* source, const std::string& key) { - for (Observer& o : observers_) { + for (XsurfaceDatastoreDataReader::Observer& o : observers_) { o.DatastoreEntryUpdated(this, key); } } @@ -94,7 +98,7 @@ void XsurfaceDatastoreAggregate::DatastoreEntryRemoved( XsurfaceDatastoreDataReader* source, const std::string& key) { - for (Observer& o : observers_) { + for (XsurfaceDatastoreDataReader::Observer& o : observers_) { o.DatastoreEntryRemoved(this, key); } }
diff --git a/components/feed/core/v2/xsurface_datastore.h b/components/feed/core/v2/xsurface_datastore.h index 8b3f1c8..7a079adb 100644 --- a/components/feed/core/v2/xsurface_datastore.h +++ b/components/feed/core/v2/xsurface_datastore.h
@@ -41,8 +41,8 @@ // Begin observing. Data already present before `AddObserver()` is called can // be read using `GetAllEntries()`. - virtual void AddObserver(Observer* o) = 0; - virtual void RemoveObserver(Observer* o) = 0; + virtual void AddObserver(XsurfaceDatastoreDataReader::Observer* o) = 0; + virtual void RemoveObserver(XsurfaceDatastoreDataReader::Observer* o) = 0; // Find an entry with the given key. Returns nullptr if the entry does not // exist. virtual const std::string* FindEntry(const std::string& key) const = 0; @@ -91,8 +91,8 @@ delete; // XsurfaceDatastoreDataReader. - void AddObserver(Observer* o) override; - void RemoveObserver(Observer* o) override; + void AddObserver(XsurfaceDatastoreDataReader::Observer* o) override; + void RemoveObserver(XsurfaceDatastoreDataReader::Observer* o) override; const std::string* FindEntry(const std::string& key) const override; std::map<std::string, std::string> GetAllEntries() const override; @@ -103,7 +103,7 @@ const std::string& key) override; private: - base::ObserverList<Observer> observers_; + base::ObserverList<XsurfaceDatastoreDataReader::Observer> observers_; std::vector<raw_ptr<XsurfaceDatastoreDataReader>> sources_; };
diff --git a/components/infobars/android/BUILD.gn b/components/infobars/android/BUILD.gn index a4871503..9b47155 100644 --- a/components/infobars/android/BUILD.gn +++ b/components/infobars/android/BUILD.gn
@@ -108,7 +108,7 @@ ":java", "//base:base_java", "//base:base_java_test_support", - "//components/browser_ui/styles/android:java_resources", + "//components/browser_ui/theme/android:java_resources", "//components/browser_ui/widget/android:java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", @@ -117,4 +117,5 @@ "//third_party/androidx:androidx_test_runner_java", "//third_party/junit:junit", ] + resources_package = "org.chromium.components.infobars.test" }
diff --git a/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarControlLayoutTest.java b/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarControlLayoutTest.java index b3edb2c..58e8dc47 100644 --- a/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarControlLayoutTest.java +++ b/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarControlLayoutTest.java
@@ -20,6 +20,7 @@ import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.UiThreadTest; import org.chromium.components.infobars.InfoBarControlLayout.ControlLayoutParams; +import org.chromium.components.infobars.test.R; /** * Tests for InfoBarControlLayout. This suite doesn't check for specific details, like margins
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageDispatcherUnitTest.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageDispatcherUnitTest.java index d9633357..418e8f5 100644 --- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageDispatcherUnitTest.java +++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageDispatcherUnitTest.java
@@ -53,7 +53,8 @@ .with(MessageBannerProperties.TITLE, "test") .with(MessageBannerProperties.DESCRIPTION, "Description") .with(MessageBannerProperties.ICON, null) - .with(MessageBannerProperties.ON_PRIMARY_ACTION, () -> {}) + .with(MessageBannerProperties.ON_PRIMARY_ACTION, + () -> PrimaryActionClickBehavior.DISMISS_IMMEDIATELY) .with(MessageBannerProperties.ON_DISMISSED, (dismissReason) -> {}) .build(); }
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessage.java b/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessage.java index e08a071..09b481d 100644 --- a/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessage.java +++ b/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessage.java
@@ -150,12 +150,14 @@ } return true; } - private void handlePrimaryAction(View v) { // Avoid running the primary action callback if the message has already been dismissed. if (mMessageDismissed) return; - mModel.get(MessageBannerProperties.ON_PRIMARY_ACTION).run(); - mDismissHandler.invoke(mModel, DismissReason.PRIMARY_ACTION); + + if (mModel.get(MessageBannerProperties.ON_PRIMARY_ACTION).get() + == PrimaryActionClickBehavior.DISMISS_IMMEDIATELY) { + mDismissHandler.invoke(mModel, DismissReason.PRIMARY_ACTION); + } } private void handleSecondaryAction() {
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessageTest.java b/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessageTest.java index 874da49..718654d8 100644 --- a/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessageTest.java +++ b/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessageTest.java
@@ -248,7 +248,10 @@ ApiCompatibilityUtils.getDrawable( sActivity.getResources(), android.R.drawable.ic_menu_add)) .with(MessageBannerProperties.ON_PRIMARY_ACTION, - () -> { mPrimaryActionCallback.notifyCalled(); }) + () -> { + mPrimaryActionCallback.notifyCalled(); + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; + }) .with(MessageBannerProperties.ON_SECONDARY_ACTION, () -> { mSecondaryActionCallback.notifyCalled(); }) .with(MessageBannerProperties.ON_TOUCH_RUNNABLE, () -> {})
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java b/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java index 48a7995f..cbc86b0 100644 --- a/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java +++ b/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java
@@ -12,6 +12,7 @@ import org.chromium.base.Callback; import org.chromium.base.supplier.BooleanSupplier; +import org.chromium.base.supplier.Supplier; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel.ReadableIntPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey; @@ -35,8 +36,13 @@ public static final ReadableIntPropertyKey MESSAGE_IDENTIFIER = new ReadableIntPropertyKey(); public static final WritableObjectPropertyKey<String> PRIMARY_BUTTON_TEXT = new WritableObjectPropertyKey<>(); - public static final WritableObjectPropertyKey<Runnable> ON_PRIMARY_ACTION = - new WritableObjectPropertyKey<>(); + /** + * See the documentation of PrimaryActionClickBehavior in + * components/messages/android/message_enums.h for more information about the return value of + * the primary action callback. + */ + public static final WritableObjectPropertyKey<Supplier</*@PrimaryActionClickBehavior*/ Integer>> + ON_PRIMARY_ACTION = new WritableObjectPropertyKey<>(); public static final WritableObjectPropertyKey<Runnable> ON_SECONDARY_ACTION = new WritableObjectPropertyKey<>(); public static final WritableObjectPropertyKey<String> TITLE = new WritableObjectPropertyKey<>();
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageWrapper.java b/components/messages/android/java/src/org/chromium/components/messages/MessageWrapper.java index 8ddbd63a..cb4ed1cf 100644 --- a/components/messages/android/java/src/org/chromium/components/messages/MessageWrapper.java +++ b/components/messages/android/java/src/org/chromium/components/messages/MessageWrapper.java
@@ -167,9 +167,11 @@ return ((BitmapDrawable) drawable).getBitmap(); } - private void handleActionClick() { - if (mNativeMessageWrapper == 0) return; - MessageWrapperJni.get().handleActionClick(mNativeMessageWrapper); + private @PrimaryActionClickBehavior int handleActionClick() { + if (mNativeMessageWrapper != 0) { + MessageWrapperJni.get().handleActionClick(mNativeMessageWrapper); + } + return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY; } private void handleSecondaryActionClick() {
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageWrapperTest.java b/components/messages/android/java/src/org/chromium/components/messages/MessageWrapperTest.java index 9550e1f..11b64b5 100644 --- a/components/messages/android/java/src/org/chromium/components/messages/MessageWrapperTest.java +++ b/components/messages/android/java/src/org/chromium/components/messages/MessageWrapperTest.java
@@ -96,7 +96,7 @@ final long nativePtr = 1; MessageWrapper message = MessageWrapper.create(nativePtr, MessageIdentifier.TEST_MESSAGE); PropertyModel messageProperties = message.getMessageProperties(); - messageProperties.get(MessageBannerProperties.ON_PRIMARY_ACTION).run(); + messageProperties.get(MessageBannerProperties.ON_PRIMARY_ACTION).get(); Mockito.verify(mNativeMock).handleActionClick(nativePtr); messageProperties.get(MessageBannerProperties.ON_SECONDARY_ACTION).run(); Mockito.verify(mNativeMock).handleSecondaryActionClick(nativePtr); @@ -116,7 +116,7 @@ PropertyModel messageProperties = message.getMessageProperties(); message.clearNativePtr(); - messageProperties.get(MessageBannerProperties.ON_PRIMARY_ACTION).run(); + messageProperties.get(MessageBannerProperties.ON_PRIMARY_ACTION).get(); Mockito.verify(mNativeMock, never()).handleActionClick(nativePtr); messageProperties.get(MessageBannerProperties.ON_SECONDARY_ACTION).run(); Mockito.verify(mNativeMock, never()).handleSecondaryActionClick(nativePtr);
diff --git a/components/messages/android/message_enums.h b/components/messages/android/message_enums.h index 56c6bd5..d4a3509a 100644 --- a/components/messages/android/message_enums.h +++ b/components/messages/android/message_enums.h
@@ -105,6 +105,15 @@ COUNT }; +// The behavior the message should follow when the primary button is clicked, +// after running the primary action callback. +// +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.messages +enum class PrimaryActionClickBehavior { + DO_NOT_DISMISS = 0, + DISMISS_IMMEDIATELY = 1 +}; + } // namespace messages #endif // COMPONENTS_MESSAGES_ANDROID_MESSAGE_ENUMS_H_
diff --git a/components/messages/android/message_wrapper.h b/components/messages/android/message_wrapper.h index def74b4..14febee0 100644 --- a/components/messages/android/message_wrapper.h +++ b/components/messages/android/message_wrapper.h
@@ -74,6 +74,10 @@ void SetDuration(long customDuration); + // Note that the message will immediately be dismissed after the primary + // action callback is run. Making the message remain visible after the primary + // action button is clicked is supported in the messages API in Java, but not + // currently in here in the messages API in C++. void SetActionClick(base::OnceClosure callback); void SetDismissCallback(DismissCallback callback);
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoAdPersonalizationController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoAdPersonalizationController.java index 8dd70e05..7196650 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoAdPersonalizationController.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoAdPersonalizationController.java
@@ -8,6 +8,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; import java.util.List; @@ -16,6 +17,7 @@ */ public class PageInfoAdPersonalizationController extends PageInfoPreferenceSubpageController { public static final int ROW_ID = View.generateViewId(); + private static List<String> sTopicsForTesting; private final PageInfoMainController mMainController; private final PageInfoRowView mRowView; @@ -32,6 +34,9 @@ public void setTopicsDisplay(List<String> topics) { mInfo = topics; + if (mInfo.isEmpty() && sTopicsForTesting != null) { + mInfo = sTopicsForTesting; + } PageInfoRowView.ViewParams rowParams = new PageInfoRowView.ViewParams(); rowParams.visible = !mInfo.isEmpty(); rowParams.title = getSubpageTitle(); @@ -83,4 +88,9 @@ removeSubpageFragment(); mSubPage = null; } + + @VisibleForTesting + public static void setTopicsForTesting(List<String> topics) { + sTopicsForTesting = topics; + } }
diff --git a/components/password_manager/core/browser/bulk_leak_check_service.cc b/components/password_manager/core/browser/bulk_leak_check_service.cc index 5248c2cb..8ab3e314 100644 --- a/components/password_manager/core/browser/bulk_leak_check_service.cc +++ b/components/password_manager/core/browser/bulk_leak_check_service.cc
@@ -42,9 +42,6 @@ base::UmaHistogramCounts1000( "PasswordManager.BulkCheck.CheckedCredentialsOnErrorOrCanceled", credential_count_); - base::UmaHistogramCounts100( - "PasswordManager.BulkCheck.LeaksFoundOnErrorOrCanceled", - leaked_credential_count_); } else { base::UmaHistogramMediumTimes("PasswordManager.BulkCheck.Time", timer_since_start_.Elapsed());
diff --git a/components/password_manager/core/browser/bulk_leak_check_service_unittest.cc b/components/password_manager/core/browser/bulk_leak_check_service_unittest.cc index f44ed4a..039b24e 100644 --- a/components/password_manager/core/browser/bulk_leak_check_service_unittest.cc +++ b/components/password_manager/core/browser/bulk_leak_check_service_unittest.cc
@@ -240,7 +240,6 @@ expected_counts ["PasswordManager.BulkCheck.CheckedCredentialsOnErrorOrCanceled"] = 1; expected_counts["PasswordManager.BulkCheck.Error"] = 1; - expected_counts["PasswordManager.BulkCheck.LeaksFoundOnErrorOrCanceled"] = 1; EXPECT_THAT( histogram_tester().GetTotalCountsForPrefix("PasswordManager.BulkCheck"), expected_counts); @@ -289,8 +288,6 @@ histogram_tester().ExpectUniqueSample( "PasswordManager.BulkCheck.CanceledTime", kMockElapsedTime, 1); histogram_tester().ExpectUniqueSample( - "PasswordManager.BulkCheck.LeaksFoundOnErrorOrCanceled", 1, 1); - histogram_tester().ExpectUniqueSample( "PasswordManager.BulkCheck.CheckedCredentialsOnErrorOrCanceled", TestCredentials().size(), 1); @@ -446,7 +443,6 @@ expected_counts ["PasswordManager.BulkCheck.CheckedCredentialsOnErrorOrCanceled"] = 1; expected_counts["PasswordManager.BulkCheck.Error"] = 1; - expected_counts["PasswordManager.BulkCheck.LeaksFoundOnErrorOrCanceled"] = 1; EXPECT_THAT( histogram_tester().GetTotalCountsForPrefix("PasswordManager.BulkCheck"), expected_counts); @@ -478,7 +474,6 @@ expected_counts ["PasswordManager.BulkCheck.CheckedCredentialsOnErrorOrCanceled"] = 1; expected_counts["PasswordManager.BulkCheck.Error"] = 1; - expected_counts["PasswordManager.BulkCheck.LeaksFoundOnErrorOrCanceled"] = 1; EXPECT_THAT( histogram_tester().GetTotalCountsForPrefix("PasswordManager.BulkCheck"), expected_counts);
diff --git a/components/permissions/android/BUILD.gn b/components/permissions/android/BUILD.gn index b474329ef..40b48d59 100644 --- a/components/permissions/android/BUILD.gn +++ b/components/permissions/android/BUILD.gn
@@ -159,7 +159,7 @@ ":java_resources", "//base:base_java_test_support", "//base:base_junit_test_support", - "//components/browser_ui/styles/android:java_resources", + "//components/browser_ui/theme/android:java_resources", "//third_party/android_deps:robolectric_all_java", "//third_party/junit", "//third_party/mockito:mockito_java",
diff --git a/components/policy/core/browser/BUILD.gn b/components/policy/core/browser/BUILD.gn index d5c7b9d..aab14c8 100644 --- a/components/policy/core/browser/BUILD.gn +++ b/components/policy/core/browser/BUILD.gn
@@ -52,6 +52,15 @@ "webui/policy_status_provider.h", ] + if (!is_chromeos_ash) { + sources += [ + "cloud/user_policy_signin_service_base.cc", + "cloud/user_policy_signin_service_base.h", + "cloud/user_policy_signin_service_util.cc", + "cloud/user_policy_signin_service_util.h", + ] + } + configs += [ "//components/policy:component_implementation" ] public_deps = [ "//base" ]
diff --git a/components/policy/core/browser/DEPS b/components/policy/core/browser/DEPS index a4e3f33e..18ff86b 100644 --- a/components/policy/core/browser/DEPS +++ b/components/policy/core/browser/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+components/google/core", + "+components/keyed_service", "+components/pref_registry", "+components/reporting", "+components/signin",
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_base.cc b/components/policy/core/browser/cloud/user_policy_signin_service_base.cc similarity index 62% rename from chrome/browser/policy/cloud/user_policy_signin_service_base.cc rename to components/policy/core/browser/cloud/user_policy_signin_service_base.cc index ccbb6bc..a59e1d2 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service_base.cc +++ b/components/policy/core/browser/cloud/user_policy_signin_service_base.cc
@@ -1,8 +1,8 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// Copyright 2022 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/policy/cloud/user_policy_signin_service_base.h" +#include "components/policy/core/browser/cloud/user_policy_signin_service_base.h" #include <utility> @@ -12,47 +12,27 @@ #include "base/task/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/enterprise/util/managed_browser_utils.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/profiles/profile_attributes_entry.h" -#include "chrome/browser/profiles/profile_attributes_storage.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/signin/account_id_from_account_info.h" -#include "chrome/common/chrome_content_client.h" -#include "chrome/common/pref_names.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/policy/core/common/cloud/device_management_service.h" #include "components/policy/core/common/cloud/user_cloud_policy_manager.h" #include "components/prefs/pref_service.h" #include "components/signin/public/identity_manager/account_info.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/storage_partition.h" #include "services/network/public/cpp/shared_url_loader_factory.h" namespace policy { UserPolicySigninServiceBase::UserPolicySigninServiceBase( - Profile* profile, PrefService* local_state, DeviceManagementService* device_management_service, UserCloudPolicyManager* policy_manager, signin::IdentityManager* identity_manager, scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory) - : profile_(profile), - policy_manager_(policy_manager), + : policy_manager_(policy_manager), identity_manager_(identity_manager), local_state_(local_state), device_management_service_(device_management_service), system_url_loader_factory_(system_url_loader_factory), - consent_level_(signin::ConsentLevel::kSignin) { - // Register a listener to be called back once the current profile has finished - // initializing, so we can startup/shutdown the UserCloudPolicyManager. - registrar_.Add(this, - chrome::NOTIFICATION_PROFILE_ADDED, - content::Source<Profile>(profile)); -} + consent_level_(signin::ConsentLevel::kSignin) {} UserPolicySigninServiceBase::~UserPolicySigninServiceBase() {} @@ -84,43 +64,6 @@ manager->core()->service()->RefreshPolicy(std::move(callback)); } -void UserPolicySigninServiceBase::OnPrimaryAccountChanged( - const signin::PrimaryAccountChangeEvent& event) { - if (event.GetEventTypeFor(signin::ConsentLevel::kSignin) == - signin::PrimaryAccountChangeEvent::Type::kCleared) { - ProfileManager* profile_manager = g_browser_process->profile_manager(); - // Some tests do not have a profile manager. - if (profile_manager) { - ProfileAttributesEntry* entry = - profile_manager->GetProfileAttributesStorage() - .GetProfileAttributesWithPath(profile_->GetPath()); - if (entry) - entry->SetUserAcceptedAccountManagement(false); - ShutdownUserCloudPolicyManager(); - } else if (event.GetEventTypeFor(signin::ConsentLevel::kSync) == - signin::PrimaryAccountChangeEvent::Type::kCleared) { - ShutdownUserCloudPolicyManager(); - } - } -} - -void UserPolicySigninServiceBase::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(chrome::NOTIFICATION_PROFILE_ADDED, type); - - // A new profile has been loaded - if it's signed in, then initialize the - // UCPM, otherwise shut down the UCPM (which deletes any cached policy - // data). This must be done here instead of at constructor time because - // the Profile is not fully initialized when this object is constructed - // (DoFinalInit() has not yet been called, so ProfileIOData and - // SSLConfigServiceManager have not been created yet). - // TODO(atwilson): Switch to using a timer instead, to avoid contention - // with other services at startup (http://crbug.com/165468). - InitializeOnProfileReady(content::Source<Profile>(source).ptr()); -} - void UserPolicySigninServiceBase:: OnCloudPolicyServiceInitializationCompleted() { // This is meant to be overridden by subclasses. Starting and stopping to @@ -157,8 +100,6 @@ } void UserPolicySigninServiceBase::Shutdown() { - if (identity_manager()) - identity_manager()->RemoveObserver(this); PrepareForUserCloudPolicyManagerShutdown(); } @@ -199,32 +140,6 @@ return !BrowserPolicyConnector::IsNonEnterpriseUser(username); } -void UserPolicySigninServiceBase::InitializeOnProfileReady(Profile* profile) { - DCHECK_EQ(profile, profile_); - // If using a TestingProfile with no IdentityManager or - // UserCloudPolicyManager, skip initialization. - if (!policy_manager() || !identity_manager()) { - DVLOG(1) << "Skipping initialization for tests due to missing components."; - return; - } - - // Shutdown the UserCloudPolicyManager when the user signs out. We start - // observing the IdentityManager here because we don't want to get signout - // notifications until after the profile has started initializing - // (http://crbug.com/316229). - identity_manager()->AddObserver(this); - - AccountId account_id = AccountIdFromAccountInfo( - identity_manager()->GetPrimaryAccountInfo(consent_level())); - if (!CanApplyPoliciesForSignedInUser(/*check_for_refresh_token=*/false)) { - ShutdownUserCloudPolicyManager(); - } else { - InitializeForSignedInUser(account_id, - profile->GetDefaultStoragePartition() - ->GetURLLoaderFactoryForBrowserProcess()); - } -} - void UserPolicySigninServiceBase::InitializeForSignedInUser( const AccountId& account_id, scoped_refptr<network::SharedURLLoaderFactory> profile_url_loader_factory) { @@ -280,15 +195,4 @@ manager->DisconnectAndRemovePolicy(); } -bool UserPolicySigninServiceBase::CanApplyPoliciesForSignedInUser( - bool check_for_refresh_token) { - return (check_for_refresh_token - ? identity_manager()->HasPrimaryAccountWithRefreshToken( - signin::ConsentLevel::kSignin) - : identity_manager()->HasPrimaryAccount( - signin::ConsentLevel::kSignin)) && - (profile_can_be_managed_for_testing_ || - chrome::enterprise_util::ProfileCanBeManaged(profile())); -} - } // namespace policy
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_base.h b/components/policy/core/browser/cloud/user_policy_signin_service_base.h similarity index 73% rename from chrome/browser/policy/cloud/user_policy_signin_service_base.h rename to components/policy/core/browser/cloud/user_policy_signin_service_base.h index ae24882..bf54691af 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service_base.h +++ b/components/policy/core/browser/cloud/user_policy_signin_service_base.h
@@ -1,9 +1,9 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// Copyright 2022 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_BASE_H_ -#define CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_BASE_H_ +#ifndef COMPONENTS_POLICY_CORE_BROWSER_CLOUD_USER_POLICY_SIGNIN_SERVICE_BASE_H_ +#define COMPONENTS_POLICY_CORE_BROWSER_CLOUD_USER_POLICY_SIGNIN_SERVICE_BASE_H_ #include <memory> #include <string> @@ -16,12 +16,9 @@ #include "components/policy/core/common/cloud/cloud_policy_client.h" #include "components/policy/core/common/cloud/cloud_policy_service.h" #include "components/signin/public/identity_manager/identity_manager.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" class AccountId; class PrefService; -class Profile; namespace network { class SharedURLLoaderFactory; @@ -44,11 +41,10 @@ // // Finally, if the user signs out, this class is responsible for shutting down // the policy infrastructure to ensure that any cached policy is cleared. -class UserPolicySigninServiceBase : public KeyedService, - public CloudPolicyClient::Observer, - public CloudPolicyService::Observer, - public content::NotificationObserver, - public signin::IdentityManager::Observer { +class POLICY_EXPORT UserPolicySigninServiceBase + : public KeyedService, + public CloudPolicyClient::Observer, + public CloudPolicyService::Observer { public: // The callback invoked once policy registration is complete. Passed // |dm_token| and |client_id| parameters are empty if policy registration @@ -63,7 +59,6 @@ // Creates a UserPolicySigninServiceBase associated with the passed |profile|. UserPolicySigninServiceBase( - Profile* profile, PrefService* local_state, DeviceManagementService* device_management_service, UserCloudPolicyManager* policy_manager, @@ -86,19 +81,6 @@ scoped_refptr<network::SharedURLLoaderFactory> profile_url_loader_factory, PolicyFetchCallback callback); - void set_profile_can_be_managed_for_testing(bool can_be_managed) { - profile_can_be_managed_for_testing_ = can_be_managed; - } - - // signin::IdentityManager::Observer implementation: - void OnPrimaryAccountChanged( - const signin::PrimaryAccountChangeEvent& event_details) override; - - // content::NotificationObserver implementation: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - // CloudPolicyService::Observer implementation: void OnCloudPolicyServiceInitializationCompleted() override; @@ -121,21 +103,14 @@ // BrowserPolicyConnector::IsNonEnterpriseUser()). bool ShouldLoadPolicyForUser(const std::string& email_address); - // Invoked to initialize the UserPolicySigninService once its owning Profile - // becomes ready. If the Profile has a signed-in account associated with it - // at startup then this initializes the cloud policy manager by calling - // InitializeForSignedInUser(); otherwise it clears any stored policies. - void InitializeOnProfileReady(Profile* profile); - // Invoked to initialize the cloud policy service for |account_id|, which is // the account associated with the Profile that owns this service. This is // invoked from InitializeOnProfileReady() if the Profile already has a // signed-in account at startup, or (on the desktop platforms) as soon as the // user signs-in and an OAuth2 login refresh token becomes available. - void InitializeForSignedInUser( - const AccountId& account_id, - scoped_refptr<network::SharedURLLoaderFactory> - profile_url_loader_factory); + void InitializeForSignedInUser(const AccountId& account_id, + scoped_refptr<network::SharedURLLoaderFactory> + profile_url_loader_factory); // Initializes the cloud policy manager with the passed |client|. This is // called from InitializeForSignedInUser() when the Profile already has a @@ -153,36 +128,27 @@ // out) and deletes any cached policy. virtual void ShutdownUserCloudPolicyManager(); - bool CanApplyPoliciesForSignedInUser(bool check_for_refresh_token); - - Profile* profile() { return profile_; } // Convenience helpers to get the associated UserCloudPolicyManager and // IdentityManager. UserCloudPolicyManager* policy_manager() { return policy_manager_; } signin::IdentityManager* identity_manager() { return identity_manager_; } - content::NotificationRegistrar* registrar() { return ®istrar_; } signin::ConsentLevel consent_level() const { return consent_level_; } private: - // Parent profile for this service. - raw_ptr<Profile> profile_; // Weak pointer to the UserCloudPolicyManager and IdentityManager this service // is associated with. raw_ptr<UserCloudPolicyManager> policy_manager_; raw_ptr<signin::IdentityManager> identity_manager_; - content::NotificationRegistrar registrar_; - raw_ptr<PrefService> local_state_; raw_ptr<DeviceManagementService> device_management_service_; scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory_; signin::ConsentLevel consent_level_; - bool profile_can_be_managed_for_testing_ = false; base::WeakPtrFactory<UserPolicySigninServiceBase> weak_factory_{this}; }; } // namespace policy -#endif // CHROME_BROWSER_POLICY_CLOUD_USER_POLICY_SIGNIN_SERVICE_BASE_H_ +#endif // COMPONENTS_POLICY_CORE_BROWSER_CLOUD_USER_POLICY_SIGNIN_SERVICE_BASE_H_
diff --git a/components/policy/core/browser/cloud/user_policy_signin_service_util.cc b/components/policy/core/browser/cloud/user_policy_signin_service_util.cc new file mode 100644 index 0000000..b8c14a0b --- /dev/null +++ b/components/policy/core/browser/cloud/user_policy_signin_service_util.cc
@@ -0,0 +1,39 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/policy/core/browser/cloud/user_policy_signin_service_util.h" + +#include "components/signin/public/base/consent_level.h" +#include "components/signin/public/identity_manager/identity_manager.h" + +namespace policy { + +bool IsSignoutEvent(const signin::PrimaryAccountChangeEvent& event) { + return event.GetEventTypeFor(signin::ConsentLevel::kSignin) == + signin::PrimaryAccountChangeEvent::Type::kCleared; +} + +bool IsTurnOffSyncEvent(const signin::PrimaryAccountChangeEvent& event) { + return event.GetEventTypeFor(signin::ConsentLevel::kSync) == + signin::PrimaryAccountChangeEvent::Type::kCleared; +} + +bool IsAnySigninEvent(const signin::PrimaryAccountChangeEvent& event) { + return event.GetEventTypeFor(signin::ConsentLevel::kSync) == + signin::PrimaryAccountChangeEvent::Type::kSet || + event.GetEventTypeFor(signin::ConsentLevel::kSignin) == + signin::PrimaryAccountChangeEvent::Type::kSet; +} + +bool CanApplyPoliciesForSignedInUser( + bool check_for_refresh_token, + signin::IdentityManager* identity_manager) { + return ( + check_for_refresh_token + ? identity_manager->HasPrimaryAccountWithRefreshToken( + signin::ConsentLevel::kSignin) + : identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)); +} + +} // namespace policy
diff --git a/components/policy/core/browser/cloud/user_policy_signin_service_util.h b/components/policy/core/browser/cloud/user_policy_signin_service_util.h new file mode 100644 index 0000000..a3e22a9 --- /dev/null +++ b/components/policy/core/browser/cloud/user_policy_signin_service_util.h
@@ -0,0 +1,36 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_POLICY_CORE_BROWSER_CLOUD_USER_POLICY_SIGNIN_SERVICE_UTIL_H_ +#define COMPONENTS_POLICY_CORE_BROWSER_CLOUD_USER_POLICY_SIGNIN_SERVICE_UTIL_H_ + +#include "components/policy/policy_export.h" +#include "components/signin/public/identity_manager/primary_account_change_event.h" + +namespace signin { +class IdentityManager; +} // namespace signin + +namespace policy { + +// Returns true if the account was signed out. +POLICY_EXPORT bool IsSignoutEvent( + const signin::PrimaryAccountChangeEvent& event); + +// Returns true if sync was turned off for the account. +POLICY_EXPORT bool IsTurnOffSyncEvent( + const signin::PrimaryAccountChangeEvent& event); + +// Returns true if the event is related to sign-in. +POLICY_EXPORT bool IsAnySigninEvent( + const signin::PrimaryAccountChangeEvent& event); + +// Returns true if policies can be applied for the signed in user. +POLICY_EXPORT bool CanApplyPoliciesForSignedInUser( + bool check_for_refresh_token, + signin::IdentityManager* identity_manager); + +} // namespace policy + +#endif // COMPONENTS_POLICY_CORE_BROWSER_CLOUD_USER_POLICY_SIGNIN_SERVICE_UTIL_H_
diff --git a/components/policy/core/common/policy_map.cc b/components/policy/core/common/policy_map.cc index 70a2af7..dc42d9b53 100644 --- a/components/policy/core/common/policy_map.cc +++ b/components/policy/core/common/policy_map.cc
@@ -656,16 +656,18 @@ void PolicyMap::UpdateStoredComputedMetapolicies() { cloud_policy_overrides_platform_policy_ = - GetValue(key::kCloudPolicyOverridesPlatformPolicy) && - GetValue(key::kCloudPolicyOverridesPlatformPolicy) - ->GetIfBool() - .value_or(false); + GetValue(key::kCloudPolicyOverridesPlatformPolicy, + base::Value::Type::BOOLEAN) && + GetValue(key::kCloudPolicyOverridesPlatformPolicy, + base::Value::Type::BOOLEAN) + ->GetBool(); cloud_user_policy_overrides_cloud_machine_policy_ = - GetValue(key::kCloudUserPolicyOverridesCloudMachinePolicy) && - GetValue(key::kCloudUserPolicyOverridesCloudMachinePolicy) - ->GetIfBool() - .value_or(false); + GetValue(key::kCloudUserPolicyOverridesCloudMachinePolicy, + base::Value::Type::BOOLEAN) && + GetValue(key::kCloudUserPolicyOverridesCloudMachinePolicy, + base::Value::Type::BOOLEAN) + ->GetBool(); } void PolicyMap::UpdateStoredUserAffiliation() {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index ebc2524..781a1310 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -8284,7 +8284,7 @@ 'owners': ['tluk@chromium.org', 'chrome-cros@google.com'], 'type': 'main', 'schema' : {'type': 'boolean'}, - 'supported_on': ['chrome_os:96-'], + 'supported_on': ['chrome_os:96-', 'chrome.*:101-'], 'example_value': False, 'features':{ 'dynamic_refresh': False, @@ -8293,20 +8293,20 @@ 'items': [ { 'value': True, - 'caption': 'Enable showing <ph name="GOOGLE_SEARCH_PRODUCT_NAME">Google Search</ph> results in a Browser side panel.', + 'caption': 'Enable showing default search engine results pages in a Browser side panel.', }, { 'value': False, - 'caption': 'Disable showing <ph name="GOOGLE_SEARCH_PRODUCT_NAME">Google Search</ph> results in a Browser side panel.', + 'caption': 'Disable showing default search engine results pages in a Browser side panel.', }, ], 'id': 906, 'default': True, - 'caption': '''Allow showing the most recent <ph name="GOOGLE_SEARCH_PRODUCT_NAME">Google Search</ph> results in a Browser side panel''', + 'caption': '''Allow showing the most recent default search engine results page in a Browser side panel''', 'tags': [], - 'desc': '''Setting the policy to Enabled or leaving the policy unset means that users can bring up their most recent <ph name="GOOGLE_SEARCH_PRODUCT_NAME">Google Search</ph> results in a side panel via toggling an icon in the toolbar. + 'desc': '''Setting the policy to Enabled or leaving the policy unset means that users can bring up their most recent default search engine results page in a side panel via toggling an icon in the toolbar. - Setting the policy to Disabled removes the icon from the toolbar that opens the side panel with the <ph name="GOOGLE_SEARCH_PRODUCT_NAME">Google Search</ph> results.''', + Setting the policy to Disabled removes the icon from the toolbar that opens the side panel with the default search engine results page.''', }, { 'name': 'InsecurePrivateNetworkRequestsAllowed',
diff --git a/components/privacy_sandbox/privacy_sandbox_features.cc b/components/privacy_sandbox/privacy_sandbox_features.cc index 5a274e7..68f0b09 100644 --- a/components/privacy_sandbox/privacy_sandbox_features.cc +++ b/components/privacy_sandbox/privacy_sandbox_features.cc
@@ -18,5 +18,7 @@ const base::FeatureParam<bool> kPrivacySandboxSettings3ForceShowNoticeForTesting{ &kPrivacySandboxSettings3, "force-show-notice-for-testing", false}; +const base::FeatureParam<bool> kPrivacySandboxSettings3ShowSampleDataForTesting{ + &kPrivacySandboxSettings3, "show-sample-data", false}; } // namespace privacy_sandbox
diff --git a/components/privacy_sandbox/privacy_sandbox_features.h b/components/privacy_sandbox/privacy_sandbox_features.h index 225acc7..a724071 100644 --- a/components/privacy_sandbox/privacy_sandbox_features.h +++ b/components/privacy_sandbox/privacy_sandbox_features.h
@@ -24,6 +24,8 @@ kPrivacySandboxSettings3ForceShowConsentForTesting; extern const base::FeatureParam<bool> kPrivacySandboxSettings3ForceShowNoticeForTesting; +extern const base::FeatureParam<bool> + kPrivacySandboxSettings3ShowSampleDataForTesting; } // namespace privacy_sandbox
diff --git a/components/resources/default_100_percent/chromium/product_logo.png b/components/resources/default_100_percent/chromium/product_logo.png index f0c3470..7b60bd8c 100644 --- a/components/resources/default_100_percent/chromium/product_logo.png +++ b/components/resources/default_100_percent/chromium/product_logo.png Binary files differ
diff --git a/components/resources/default_100_percent/chromium/product_logo_white.png b/components/resources/default_100_percent/chromium/product_logo_white.png index 454b33f..854f414e 100644 --- a/components/resources/default_100_percent/chromium/product_logo_white.png +++ b/components/resources/default_100_percent/chromium/product_logo_white.png Binary files differ
diff --git a/components/resources/default_200_percent/chromium/product_logo.png b/components/resources/default_200_percent/chromium/product_logo.png index 52a636ef..876c2922 100644 --- a/components/resources/default_200_percent/chromium/product_logo.png +++ b/components/resources/default_200_percent/chromium/product_logo.png Binary files differ
diff --git a/components/resources/default_200_percent/chromium/product_logo_white.png b/components/resources/default_200_percent/chromium/product_logo_white.png index 0cdf603..fffaf67 100644 --- a/components/resources/default_200_percent/chromium/product_logo_white.png +++ b/components/resources/default_200_percent/chromium/product_logo_white.png Binary files differ
diff --git a/components/safe_browsing/core/browser/tailored_security_service/tailored_security_service.cc b/components/safe_browsing/core/browser/tailored_security_service/tailored_security_service.cc index d7e5acb..469e424 100644 --- a/components/safe_browsing/core/browser/tailored_security_service/tailored_security_service.cc +++ b/components/safe_browsing/core/browser/tailored_security_service/tailored_security_service.cc
@@ -41,7 +41,7 @@ namespace safe_browsing { namespace { -const int kRepeatingCheckTailoredSecurityBitDelayInMinutes = 5; +const int kRepeatingCheckTailoredSecurityBitDelayInMinutes = 10; constexpr char kAPIScope[] = "https://www.googleapis.com/auth/chrome-safe-browsing";
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector.cc b/components/segmentation_platform/internal/data_collection/training_data_collector.cc index fadeee8c..7302b516 100644 --- a/components/segmentation_platform/internal/data_collection/training_data_collector.cc +++ b/components/segmentation_platform/internal/data_collection/training_data_collector.cc
@@ -17,6 +17,7 @@ #include "components/segmentation_platform/internal/data_collection/dummy_training_data_collector.h" #include "components/segmentation_platform/internal/database/metadata_utils.h" #include "components/segmentation_platform/internal/database/segment_info_database.h" +#include "components/segmentation_platform/internal/database/signal_storage_config.h" #include "components/segmentation_platform/internal/execution/feature_list_query_processor.h" #include "components/segmentation_platform/internal/proto/model_metadata.pb.h" #include "components/segmentation_platform/internal/proto/model_prediction.pb.h" @@ -54,10 +55,12 @@ TrainingDataCollectorImpl(SegmentInfoDatabase* segment_info_database, FeatureListQueryProcessor* processor, HistogramSignalHandler* histogram_signal_handler, + SignalStorageConfig* signal_storage_config, base::Clock* clock) : segment_info_database_(segment_info_database), feature_list_query_processor_(processor), histogram_signal_handler_(histogram_signal_handler), + signal_storage_config_(signal_storage_config), clock_(clock) {} ~TrainingDataCollectorImpl() override { @@ -140,7 +143,7 @@ if (hash_index_map.find(output_metric_hash) == hash_index_map.end()) continue; - if (!segment_info.has_model_version()) + if (!CanReportImmediateTrainingData(segment.second)) continue; // Generate training data input. @@ -158,6 +161,31 @@ } } + bool CanReportImmediateTrainingData(const proto::SegmentInfo& segment_info) { + if (!segment_info.has_model_version() || + !segment_info.has_model_update_time_s() || + segment_info.model_update_time_s() == 0) { + return false; + } + + base::TimeDelta min_signal_collection_length = + segment_info.model_metadata().min_signal_collection_length() * + metadata_utils::GetTimeUnit(segment_info.model_metadata()); + base::Time model_update_time = base::Time::FromDeltaSinceWindowsEpoch( + base::Seconds(segment_info.model_update_time_s())); + + // Data must be collected for enough time after a new model is downloaded. + // It's recommended to get the A/B testing experiment fully ramped up before + // deploying a new model. Or the data collected might be partially based on + // old behavior of Chrome. + if (model_update_time + min_signal_collection_length >= clock_->Now()) + return false; + + // Each input must be collected for enough time. + return signal_storage_config_->MeetsSignalCollectionRequirement( + segment_info.model_metadata()); + } + void OnGetInputTensor(float output_value, int output_index, OptimizationTarget segment_id, @@ -178,6 +206,7 @@ raw_ptr<SegmentInfoDatabase> segment_info_database_; raw_ptr<FeatureListQueryProcessor> feature_list_query_processor_; raw_ptr<HistogramSignalHandler> histogram_signal_handler_; + raw_ptr<SignalStorageConfig> signal_storage_config_; raw_ptr<base::Clock> clock_; // Hash of histograms for immediate training data collection. When any @@ -195,11 +224,13 @@ SegmentInfoDatabase* segment_info_database, FeatureListQueryProcessor* processor, HistogramSignalHandler* histogram_signal_handler, + SignalStorageConfig* signal_storage_config, base::Clock* clock) { if (base::FeatureList::IsEnabled( features::kSegmentationStructuredMetricsFeature)) { return std::make_unique<TrainingDataCollectorImpl>( - segment_info_database, processor, histogram_signal_handler, clock); + segment_info_database, processor, histogram_signal_handler, + signal_storage_config, clock); } return std::make_unique<DummyTrainingDataCollector>();
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector.h b/components/segmentation_platform/internal/data_collection/training_data_collector.h index bfc2df6a..d25717c 100644 --- a/components/segmentation_platform/internal/data_collection/training_data_collector.h +++ b/components/segmentation_platform/internal/data_collection/training_data_collector.h
@@ -18,6 +18,7 @@ class FeatureListQueryProcessor; class HistogramSignalHandler; class SegmentInfoDatabase; +class SignalStorageConfig; // Collect training data and report as Ukm message. Live on main thread. // TODO(xingliu): Make a new class that owns the training data collector and @@ -28,6 +29,7 @@ SegmentInfoDatabase* segment_info_database, FeatureListQueryProcessor* processor, HistogramSignalHandler* histogram_signal_handler, + SignalStorageConfig* signal_storage_config, base::Clock* clock); // Called when model metadata is updated. May result in training data
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector_unittest.cc b/components/segmentation_platform/internal/data_collection/training_data_collector_unittest.cc index b0e3617..50ffce9 100644 --- a/components/segmentation_platform/internal/data_collection/training_data_collector_unittest.cc +++ b/components/segmentation_platform/internal/data_collection/training_data_collector_unittest.cc
@@ -11,6 +11,8 @@ #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_clock.h" #include "base/test/task_environment.h" +#include "components/segmentation_platform/internal/database/metadata_utils.h" +#include "components/segmentation_platform/internal/database/mock_signal_storage_config.h" #include "components/segmentation_platform/internal/database/test_segment_info_database.h" #include "components/segmentation_platform/internal/execution/mock_feature_list_query_processor.h" #include "components/segmentation_platform/internal/proto/model_metadata.pb.h" @@ -26,6 +28,7 @@ using ::base::test::RunOnceCallback; using ::testing::_; using ::testing::NiceMock; +using ::testing::Return; using Segmentation_ModelExecution = ::ukm::builders::Segmentation_ModelExecution; @@ -59,11 +62,13 @@ std::vector<float> inputs({1.f}); ON_CALL(feature_list_processor_, ProcessFeatureList(_, _, _, _)) .WillByDefault(RunOnceCallback<3>(true, inputs)); + ON_CALL(signal_storage_config_, MeetsSignalCollectionRequirement(_)) + .WillByDefault(Return(true)); test_segment_info_db_ = std::make_unique<test::TestSegmentInfoDatabase>(); collector_ = TrainingDataCollector::Create( test_segment_info_db_.get(), &feature_list_processor_, - &histogram_signal_handler_, &clock_); + &histogram_signal_handler_, &signal_storage_config_, &clock_); } protected: @@ -72,8 +77,12 @@ return test_segment_info_db_.get(); } base::test::TaskEnvironment* task_environment() { return &task_environment_; } + base::SimpleTestClock* clock() { return &clock_; } + MockSignalStorageConfig* signal_storage_config() { + return &signal_storage_config_; + } - void CreateSegmentInfo() { + proto::SegmentInfo* CreateSegmentInfo() { test_segment_db()->AddUserActionFeature(kTestOptimizationTarget0, "action", 1, 1, proto::Aggregation::COUNT); // Segment 0 contains 1 immediate collection uma output for for @@ -83,6 +92,7 @@ AddOutput(segment_info, kHistogramName0); proto::TrainingOutput* output1 = AddOutput(segment_info, kHistogramName1); output1->mutable_uma_output()->set_duration(1u); + return segment_info; } proto::SegmentInfo* CreateSegment(OptimizationTarget optimization_target) { @@ -90,6 +100,9 @@ test_segment_db()->FindOrCreateSegment(optimization_target); segment_info->mutable_model_metadata()->set_time_unit(proto::TimeUnit::DAY); segment_info->set_model_version(kModelVersion); + auto model_update_time = clock()->Now() - base::Days(365); + segment_info->set_model_update_time_s( + model_update_time.ToDeltaSinceWindowsEpoch().InSeconds()); return segment_info; } @@ -144,6 +157,7 @@ ukm::TestAutoSetUkmRecorder test_recorder_; NiceMock<MockFeatureListQueryProcessor> feature_list_processor_; NiceMock<MockHistogramSignalHandler> histogram_signal_handler_; + NiceMock<MockSignalStorageConfig> signal_storage_config_; std::unique_ptr<test::TestSegmentInfoDatabase> test_segment_info_db_; std::unique_ptr<TrainingDataCollector> collector_; }; @@ -156,7 +170,7 @@ ExpectUkmCount(0u); } -// No segment info in database. Do nothing. +// Histogram not in the output list will not trigger a training data report.. TEST_F(TrainingDataCollectorTest, IrrelevantHistogramNotReported) { CreateSegmentInfo(); Init(); @@ -170,6 +184,8 @@ ExpectUkmCount(0u); } +// Immediate training data collection for a certain histogram will be reported +// as a UKM. TEST_F(TrainingDataCollectorTest, HistogramImmediatelyReported) { CreateSegmentInfo(); Init(); @@ -181,6 +197,7 @@ SegmentationUkmHelper::FloatToInt64(kSample)}); } +// A histogram interested by multiple model will trigger multiple UKM reports. TEST_F(TrainingDataCollectorTest, HistogramImmediatelyReported_MultipleModel) { CreateSegmentInfo(); // Segment 1 contains 1 immediate collection uma output for for @@ -192,5 +209,36 @@ ExpectUkmCount(2u); } +// No UKM report due to minimum data collection time not met. +TEST_F(TrainingDataCollectorTest, SignalCollectionRequirementNotMet) { + EXPECT_CALL(*signal_storage_config(), MeetsSignalCollectionRequirement(_)) + .WillOnce(Return(false)); + + CreateSegmentInfo(); + Init(); + collector()->OnHistogramSignalUpdated(kHistogramName0, kSample); + task_environment()->RunUntilIdle(); + ExpectUkmCount(0u); +} + +// No UKM report due to model updated recently. +TEST_F(TrainingDataCollectorTest, ModelUpdatedRecently) { + auto* segment_info = CreateSegmentInfo(); + base::TimeDelta min_signal_collection_length = + segment_info->model_metadata().min_signal_collection_length() * + metadata_utils::GetTimeUnit(segment_info->model_metadata()); + + // Set the model update timestamp to be closer to Now(). + segment_info->set_model_update_time_s( + (clock()->Now() - min_signal_collection_length + base::Seconds(30)) + .ToDeltaSinceWindowsEpoch() + .InSeconds()); + + Init(); + collector()->OnHistogramSignalUpdated(kHistogramName0, kSample); + task_environment()->RunUntilIdle(); + ExpectUkmCount(0u); +} + } // namespace } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc index 700358a..b91ef47 100644 --- a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc +++ b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc
@@ -246,7 +246,7 @@ training_data_collector_ = TrainingDataCollector::Create( segment_info_database_.get(), feature_list_query_processor_.get(), - histogram_signal_handler_.get(), clock_); + histogram_signal_handler_.get(), signal_storage_config_.get(), clock_); training_data_collector_->OnServiceInitialized(); model_execution_manager_ = CreateModelExecutionManager(
diff --git a/components/signin/core/browser/account_reconcilor.cc b/components/signin/core/browser/account_reconcilor.cc index ca48fbc..250fc43 100644 --- a/components/signin/core/browser/account_reconcilor.cc +++ b/components/signin/core/browser/account_reconcilor.cc
@@ -230,11 +230,12 @@ } void AccountReconcilor::DisableReconcile(bool logout_all_accounts) { + const bool log_out_in_progress = log_out_in_progress_; AbortReconcile(); SetState(AccountReconcilorState::ACCOUNT_RECONCILOR_INACTIVE); UnregisterWithAllDependencies(); - if (logout_all_accounts) + if (logout_all_accounts && !log_out_in_progress) PerformLogoutAllAccountsAction(); } @@ -596,7 +597,8 @@ std::vector<CoreAccountId> chrome_accounts = LoadValidAccountsFromTokenService(); - if (delegate_->ShouldAbortReconcileIfPrimaryHasError() && + if (!primary_account.empty() && + delegate_->ShouldAbortReconcileIfPrimaryHasError() && !base::Contains(chrome_accounts, primary_account)) { VLOG(1) << "Primary account has error, abort."; DCHECK(is_reconcile_started_);
diff --git a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.cc b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.cc index 255d8e5..0d9458f 100644 --- a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.cc +++ b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service_delegate.cc
@@ -92,6 +92,12 @@ void FakeProfileOAuth2TokenServiceDelegate::RevokeAllCredentials() { std::vector<CoreAccountId> account_ids = GetAccounts(); + if (account_ids.empty()) + return; + + // Use `ScopedBatchChange` so that `OnEndBatchOfRefreshTokenStateChanges()` is + // fired only once, like in production. + ScopedBatchChange batch(this); for (const auto& account : account_ids) RevokeCredentials(account); }
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.h b/content/browser/accessibility/browser_accessibility_cocoa.h index 31ac270..27ef520 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.h +++ b/content/browser/accessibility/browser_accessibility_cocoa.h
@@ -163,7 +163,6 @@ @property(nonatomic, readonly) NSString* subrole; // The tabs owned by a tablist. @property(nonatomic, readonly) NSArray* tabs; -@property(nonatomic, readonly) NSString* title; @property(nonatomic, readonly) NSString* value; @property(nonatomic, readonly) NSString* valueDescription; @property(nonatomic, readonly) NSValue* visibleCharacterRange;
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index 177866b..7a83157f 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -637,7 +637,6 @@ {NSAccessibilitySortDirectionAttribute, @"sortDirection"}, {NSAccessibilitySubroleAttribute, @"subrole"}, {NSAccessibilityTabsAttribute, @"tabs"}, - {NSAccessibilityTitleAttribute, @"title"}, {NSAccessibilityTopLevelUIElementAttribute, @"window"}, {NSAccessibilityValueAttribute, @"value"}, {NSAccessibilityValueAutofillAvailableAttribute, @@ -1525,36 +1524,6 @@ return tabSubtree; } -- (NSString*)AXTitle { - return [self title]; -} -- (NSString*)title { - if (![self instanceActive]) - return nil; - // Mac OS X wants static text exposed in AXValue. - if (ui::IsNameExposedInAXValueForRole([self internalRole])) - return @""; - - if ([self isNameFromLabel]) - return @""; - - // If we're exposing the title in TitleUIElement, don't also redundantly - // expose it in AXDescription. - if ([self titleUIElement]) - return @""; - - ax::mojom::NameFrom nameFrom = static_cast<ax::mojom::NameFrom>( - _owner->GetIntAttribute(ax::mojom::IntAttribute::kNameFrom)); - - // On Mac OS X, cell titles are "" if it it came from content. - NSString* role = [self role]; - if ([role isEqualToString:NSAccessibilityCellRole] && - nameFrom == ax::mojom::NameFrom::kContents) - return @""; - - return base::SysUTF8ToNSString(_owner->GetName()); -} - - (id)AXValue { return [self value]; } @@ -2492,7 +2461,6 @@ NSAccessibilitySizeAttribute, NSAccessibilityStartTextMarkerAttribute, NSAccessibilitySubroleAttribute, - NSAccessibilityTitleAttribute, NSAccessibilityTopLevelUIElementAttribute, NSAccessibilityValueAttribute, NSAccessibilityWindowAttribute, nil];
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index 125cca7..62253dc 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -1806,7 +1806,8 @@ BrowserAccessibility* BrowserAccessibilityManager::AXTreeHitTest( const gfx::Point& blink_screen_point) const { - DCHECK(IsRootTree()); + // TODO(crbug.com/1287526): assert that this gets called on a valid node. This + // should usually be the root node except for Paint Preview. DCHECK(cached_node_rtree_); std::vector<ui::AXNodeID> results;
diff --git a/content/browser/android/gesture_listener_manager.cc b/content/browser/android/gesture_listener_manager.cc index 0770176..17167bf 100644 --- a/content/browser/android/gesture_listener_manager.cc +++ b/content/browser/android/gesture_listener_manager.cc
@@ -11,8 +11,10 @@ #include "content/public/android/content_jni_headers/GestureListenerManagerImpl_jni.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/common/use_zoom_for_dsf_policy.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "ui/events/android/gesture_event_type.h" +#include "ui/events/blink/did_overscroll_params.h" #include "ui/gfx/geometry/size_f.h" using blink::WebGestureEvent; @@ -200,6 +202,22 @@ gesture.PositionInWidget().y() * dip_scale); } +void GestureListenerManager::DidOverscroll( + const ui::DidOverscrollParams& params) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); + if (j_obj.is_null()) + return; + float x = params.accumulated_overscroll.x(); + float y = params.accumulated_overscroll.y(); + if (!IsUseZoomForDSFEnabled()) { + float dip_scale = web_contents_->GetNativeView()->GetDipScale(); + x *= dip_scale; + y *= dip_scale; + } + return Java_GestureListenerManagerImpl_didOverscroll(env, j_obj, x, y); +} + // All positions and sizes (except |top_shown_pix|) are in CSS pixels. // Note that viewport_width/height is a best effort based. void GestureListenerManager::UpdateScrollInfo(const gfx::PointF& scroll_offset,
diff --git a/content/browser/android/gesture_listener_manager.h b/content/browser/android/gesture_listener_manager.h index d46229f3..2b4d45b 100644 --- a/content/browser/android/gesture_listener_manager.h +++ b/content/browser/android/gesture_listener_manager.h
@@ -21,6 +21,10 @@ class PointF; } // namespace gfx +namespace ui { +struct DidOverscrollParams; +} + namespace content { class NavigationHandle; @@ -54,6 +58,7 @@ blink::mojom::InputEventResultState ack_result); void DidStopFlinging(); bool FilterInputEvent(const blink::WebInputEvent& event); + void DidOverscroll(const ui::DidOverscrollParams& params); // All sizes and offsets are in CSS pixels (except |top_show_pix|) // as cached by the renderer.
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc b/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc index 06b6f1a..6d190cd 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc +++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc
@@ -14,16 +14,10 @@ #include "content/browser/attribution_reporting/attribution_filter_data.h" #include "content/browser/attribution_reporting/attribution_host_utils.h" #include "content/browser/attribution_reporting/attribution_manager.h" -#include "content/browser/attribution_reporting/attribution_metrics.h" #include "content/browser/attribution_reporting/attribution_reporting.pb.h" #include "content/browser/attribution_reporting/attribution_trigger.h" #include "content/browser/attribution_reporting/common_source_info.h" #include "content/browser/attribution_reporting/storable_source.h" -#include "content/browser/storage_partition_impl.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/content_browser_client.h" -#include "content/public/common/content_client.h" -#include "net/base/schemeful_site.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/attribution_reporting/constants.h" #include "url/origin.h" @@ -51,11 +45,8 @@ } // namespace AttributionDataHostManagerImpl::AttributionDataHostManagerImpl( - BrowserContext* browser_context, AttributionManager* attribution_manager) - : browser_context_(browser_context), - attribution_manager_(attribution_manager) { - DCHECK(browser_context_); + : attribution_manager_(attribution_manager) { DCHECK(attribution_manager_); // It's safe to use `base::Unretained()` as `receivers_` is owned by `this` @@ -91,16 +82,6 @@ base::Time source_time = base::Time::Now(); const url::Origin& reporting_origin = data->reporting_origin; - const bool allowed = - GetContentClient()->browser()->IsConversionMeasurementOperationAllowed( - browser_context_, - ContentBrowserClient::ConversionMeasurementOperation::kImpression, - &context.context_origin, /*conversion_origin=*/nullptr, - &reporting_origin); - RecordRegisterImpressionAllowed(allowed); - if (!allowed) - return; - // The API is only allowed in secure contexts. if (!attribution_host_utils::IsOriginTrustworthyForAttributions( context.context_origin) || @@ -148,16 +129,6 @@ const FrozenContext& context = receivers_.current_context(); const url::Origin& reporting_origin = data->reporting_origin; - const bool allowed = - GetContentClient()->browser()->IsConversionMeasurementOperationAllowed( - browser_context_, - ContentBrowserClient::ConversionMeasurementOperation::kConversion, - /*impression_origin=*/nullptr, - /*conversion_origin=*/&context.context_origin, &reporting_origin); - RecordRegisterConversionAllowed(allowed); - if (!allowed) - return; - // The API is only allowed in secure contexts. if (!attribution_host_utils::IsOriginTrustworthyForAttributions( context.context_origin) || @@ -200,8 +171,8 @@ } AttributionTrigger trigger( - /*conversion_destination=*/net::SchemefulSite(context.context_origin), - reporting_origin, std::move(*filters), + /*destination_origin=*/context.context_origin, reporting_origin, + std::move(*filters), data->debug_key ? absl::make_optional(data->debug_key->value) : absl::nullopt, std::move(event_triggers));
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl.h b/content/browser/attribution_reporting/attribution_data_host_manager_impl.h index 80aa3aa4..dd37549 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager_impl.h +++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl.h
@@ -17,7 +17,6 @@ namespace content { class AttributionManager; -class BrowserContext; // Manages a receiver set of all ongoing `AttributionDataHost`s and forwards // events to the AttributionManager which owns `this`. Because attributionsrc @@ -28,8 +27,8 @@ : public AttributionDataHostManager, public blink::mojom::AttributionDataHost { public: - AttributionDataHostManagerImpl(BrowserContext* storage_partition, - AttributionManager* attribution_manager); + explicit AttributionDataHostManagerImpl( + AttributionManager* attribution_manager); AttributionDataHostManagerImpl(const AttributionDataHostManager& other) = delete; AttributionDataHostManagerImpl& operator=( @@ -68,10 +67,6 @@ void OnDataHostDisconnected(); - // Safe because the owning `AttributionManager` is guaranteed to outlive the - // browser context. - raw_ptr<BrowserContext> browser_context_; - // Owns `this`. raw_ptr<AttributionManager> attribution_manager_;
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc index 51e88d27..a321bb0 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc
@@ -13,15 +13,11 @@ #include "base/containers/flat_map.h" #include "base/strings/string_number_conversions.h" -#include "base/test/metrics/histogram_tester.h" #include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_manager.h" #include "content/browser/attribution_reporting/attribution_source_type.h" #include "content/browser/attribution_reporting/attribution_test_utils.h" -#include "content/public/browser/browser_context.h" -#include "content/public/common/content_client.h" #include "content/public/test/browser_task_environment.h" -#include "content/public/test/test_browser_context.h" #include "content/public/test/test_utils.h" #include "mojo/public/cpp/bindings/remote.h" #include "testing/gmock/include/gmock/gmock.h" @@ -35,19 +31,13 @@ namespace { -using ConversionMeasurementOperation = - ::content::ContentBrowserClient::ConversionMeasurementOperation; - using ::testing::_; using ::testing::AllOf; using ::testing::ElementsAre; using ::testing::Eq; using ::testing::InSequence; -using ::testing::IsNull; using ::testing::Mock; using ::testing::Optional; -using ::testing::Pointee; -using ::testing::Return; using Checkpoint = ::testing::MockFunction<void(int step)>; @@ -57,19 +47,15 @@ public: AttributionDataHostManagerImplTest() : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME), - browser_context_(std::make_unique<TestBrowserContext>()), - data_host_manager_(browser_context_.get(), &mock_manager_) {} + data_host_manager_(&mock_manager_) {} protected: BrowserTaskEnvironment task_environment_; - std::unique_ptr<TestBrowserContext> browser_context_; MockAttributionManager mock_manager_; AttributionDataHostManagerImpl data_host_manager_; }; TEST_F(AttributionDataHostManagerImplTest, SourceDataHost_SourceRegistered) { - base::HistogramTester histograms; - auto page_origin = url::Origin::Create(GURL("https://page.example")); auto destination_origin = url::Origin::Create(GURL("https://trigger.example")); @@ -107,9 +93,6 @@ .Build(); data_host_remote->SourceDataAvailable(std::move(source_data)); data_host_remote.FlushForTesting(); - - histograms.ExpectUniqueSample("Conversions.RegisterImpressionAllowed", true, - 1); } TEST_F(AttributionDataHostManagerImplTest, @@ -243,43 +226,6 @@ } TEST_F(AttributionDataHostManagerImplTest, - SourceDataHostEmbedderDisallow_SourceDropped) { - base::HistogramTester histograms; - - EXPECT_CALL(mock_manager_, HandleSource).Times(0); - - auto page_origin = url::Origin::Create(GURL("https://page.example")); - auto destination_origin = - url::Origin::Create(GURL("https://trigger.example")); - auto reporting_origin = url::Origin::Create(GURL("https://reporter.example")); - - MockAttributionReportingContentBrowserClient browser_client; - EXPECT_CALL(browser_client, - IsConversionMeasurementOperationAllowed( - _, ConversionMeasurementOperation::kImpression, - Pointee(page_origin), IsNull(), Pointee(reporting_origin))) - .Times(1) - .WillRepeatedly(Return(false)); - ScopedContentBrowserClientSetting setting(&browser_client); - mojo::Remote<blink::mojom::AttributionDataHost> data_host_remote; - data_host_manager_.RegisterDataHost( - data_host_remote.BindNewPipeAndPassReceiver(), page_origin); - - auto source_data = blink::mojom::AttributionSourceData::New(); - source_data->source_event_id = 10; - source_data->destination = destination_origin; - source_data->reporting_origin = reporting_origin; - source_data->filter_data = blink::mojom::AttributionFilterData::New(); - source_data->aggregatable_source = - blink::mojom::AttributionAggregatableSource::New(); - data_host_remote->SourceDataAvailable(std::move(source_data)); - data_host_remote.FlushForTesting(); - - histograms.ExpectUniqueSample("Conversions.RegisterImpressionAllowed", false, - 1); -} - -TEST_F(AttributionDataHostManagerImplTest, SourceDataHost_ReceiverDestinationCheckPerformed) { Checkpoint checkpoint; { @@ -387,15 +333,13 @@ } TEST_F(AttributionDataHostManagerImplTest, TriggerDataHost_TriggerRegistered) { - base::HistogramTester histograms; - auto destination_origin = url::Origin::Create(GURL("https://trigger.example")); auto reporting_origin = url::Origin::Create(GURL("https://reporter.example")); EXPECT_CALL( mock_manager_, HandleTrigger(AttributionTriggerMatches({ - .conversion_destination = net::SchemefulSite(destination_origin), + .destination_origin = destination_origin, .reporting_origin = reporting_origin, .filters = *AttributionFilterData::FromTriggerFilterValues({ {"a", {"b"}}, @@ -456,9 +400,6 @@ data_host_remote->TriggerDataAvailable(std::move(trigger_data)); data_host_remote.FlushForTesting(); - - histograms.ExpectUniqueSample("Conversions.RegisterConversionAllowed", true, - 1); } TEST_F(AttributionDataHostManagerImplTest, @@ -608,41 +549,6 @@ } TEST_F(AttributionDataHostManagerImplTest, - TriggerDataHostEmbedderDisallow_TriggerDropped) { - base::HistogramTester histograms; - - EXPECT_CALL(mock_manager_, HandleTrigger).Times(0); - - auto destination_origin = - url::Origin::Create(GURL("https://trigger.example")); - auto reporting_origin = url::Origin::Create(GURL("https://reporter.example")); - - MockAttributionReportingContentBrowserClient browser_client; - EXPECT_CALL(browser_client, - IsConversionMeasurementOperationAllowed( - _, ConversionMeasurementOperation::kConversion, IsNull(), - Pointee(destination_origin), Pointee(reporting_origin))) - .WillRepeatedly(Return(false)); - ScopedContentBrowserClientSetting setting(&browser_client); - mojo::Remote<blink::mojom::AttributionDataHost> data_host_remote; - data_host_manager_.RegisterDataHost( - data_host_remote.BindNewPipeAndPassReceiver(), destination_origin); - - auto trigger_data = blink::mojom::AttributionTriggerData::New(); - trigger_data->reporting_origin = reporting_origin; - - trigger_data->filters = blink::mojom::AttributionFilterData::New(); - trigger_data->aggregatable_trigger = - blink::mojom::AttributionAggregatableTrigger::New(); - - data_host_remote->TriggerDataAvailable(std::move(trigger_data)); - data_host_remote.FlushForTesting(); - - histograms.ExpectUniqueSample("Conversions.RegisterConversionAllowed", false, - 1); -} - -TEST_F(AttributionDataHostManagerImplTest, TriggerDataHost_EventTriggerDataSizeCheckPerformed) { const struct { size_t size;
diff --git a/content/browser/attribution_reporting/attribution_host.cc b/content/browser/attribution_reporting/attribution_host.cc index 5009c56..167a64e 100644 --- a/content/browser/attribution_reporting/attribution_host.cc +++ b/content/browser/attribution_reporting/attribution_host.cc
@@ -214,22 +214,9 @@ return; } - VerifyAndStoreImpression(AttributionSourceType::kNavigation, - impression_origin, impression, *attribution_manager); -} - -bool AttributionHost::VerifyAndStoreImpression( - AttributionSourceType source_type, - const url::Origin& impression_origin, - const blink::Impression& impression, - AttributionManager& attribution_manager) { - attribution_host_utils::VerifyResult result = - attribution_host_utils::VerifyAndStoreImpression( - source_type, impression_origin, impression, - web_contents()->GetBrowserContext(), attribution_manager, - base::Time::Now()); - RecordRegisterImpressionAllowed(result.allowed); - return result.stored; + attribution_host_utils::VerifyAndStoreImpression( + AttributionSourceType::kNavigation, impression_origin, impression, + *attribution_manager, base::Time::Now()); } void AttributionHost::RegisterConversion( @@ -274,20 +261,8 @@ return; } - const bool allowed = - GetContentClient()->browser()->IsConversionMeasurementOperationAllowed( - web_contents()->GetBrowserContext(), - ContentBrowserClient::ConversionMeasurementOperation::kConversion, - /*impression_origin=*/nullptr, &main_frame_origin, - &conversion->reporting_origin); - RecordRegisterConversionAllowed(allowed); - if (!allowed) - return; - - net::SchemefulSite conversion_destination(main_frame_origin); - AttributionTrigger storable_conversion( - conversion->conversion_data, std::move(conversion_destination), + conversion->conversion_data, /*destination_origin=*/main_frame_origin, conversion->reporting_origin, conversion->event_source_trigger_data, conversion->priority, conversion->dedup_key.is_null() @@ -380,8 +355,9 @@ // No navigation in progress and we've already committed the destination for // the conversion, so just store the impression. - VerifyAndStoreImpression(AttributionSourceType::kNavigation, - impression_origin, impression, *attribution_manager); + attribution_host_utils::VerifyAndStoreImpression( + AttributionSourceType::kNavigation, impression_origin, impression, + *attribution_manager, base::Time::Now()); } // static
diff --git a/content/browser/attribution_reporting/attribution_host.h b/content/browser/attribution_reporting/attribution_host.h index 6e91d52..77821ce 100644 --- a/content/browser/attribution_reporting/attribution_host.h +++ b/content/browser/attribution_reporting/attribution_host.h
@@ -10,7 +10,6 @@ #include <memory> #include "base/containers/flat_map.h" -#include "content/browser/attribution_reporting/attribution_source_type.h" #include "content/common/content_export.h" #include "content/public/browser/render_frame_host_receiver_set.h" #include "content/public/browser/web_contents_observer.h" @@ -20,7 +19,6 @@ namespace content { -class AttributionManager; class AttributionManagerProvider; class AttributionPageMetrics; class WebContents; @@ -91,15 +89,6 @@ void NotifyImpressionInitiatedByPage(const url::Origin& impression_origin, const blink::Impression& impression); - // Stores the impression if conversion measurement is allowed for the - // impression origin and reporting origin and the impressionorigin, reporting - // origin, and conversion destination are potentially trustworthy. Returns - // whether the impression was stored. - bool VerifyAndStoreImpression(AttributionSourceType source_type, - const url::Origin& impression_origin, - const blink::Impression& impression, - AttributionManager& attribution_manager); - // Map which stores the top-frame origin an impression occurred on for all // navigations with an associated impression, keyed by navigation ID. // Initiator origins are stored at navigation start time to have the best
diff --git a/content/browser/attribution_reporting/attribution_host_unittest.cc b/content/browser/attribution_reporting/attribution_host_unittest.cc index 77361ae..20961a4 100644 --- a/content/browser/attribution_reporting/attribution_host_unittest.cc +++ b/content/browser/attribution_reporting/attribution_host_unittest.cc
@@ -25,7 +25,6 @@ #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/test_support/fake_message_dispatch_context.h" #include "mojo/public/cpp/test_support/test_utils.h" -#include "net/base/schemeful_site.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/conversions/conversions.mojom.h" @@ -59,12 +58,8 @@ ::content::ContentBrowserClient::ConversionMeasurementOperation; using testing::_; -using testing::AllOf; using testing::InSequence; -using testing::IsNull; using testing::Mock; -using testing::Pointee; -using testing::Return; using Checkpoint = ::testing::MockFunction<void(int step)>; @@ -127,8 +122,8 @@ TEST_F(AttributionHostTest, ValidConversionInSubframe_NoBadMessage) { EXPECT_CALL(mock_manager_, - HandleTrigger(TriggerConversionDestinationIs( - net::SchemefulSite(GURL("https://www.example.com"))))); + HandleTrigger(TriggerDestinationOriginIs( + url::Origin::Create(GURL("https://www.example.com"))))); contents()->NavigateAndCommit(GURL("https://www.example.com")); @@ -157,8 +152,8 @@ TEST_F(AttributionHostTest, ConversionInSubframe_ConversionDestinationMatchesMainFrame) { EXPECT_CALL(mock_manager_, - HandleTrigger(TriggerConversionDestinationIs( - net::SchemefulSite(GURL("https://www.example.com"))))); + HandleTrigger(TriggerDestinationOriginIs( + url::Origin::Create(GURL("https://www.example.com"))))); contents()->NavigateAndCommit(GURL("https://www.example.com")); @@ -214,44 +209,6 @@ bad_message_observer.WaitForBadMessage()); } -TEST_F(AttributionHostTest, ConversionInSubframe_ChecksCorrectOrigins) { - // Verifies that conversions from subframes use the correct origins when - // checking if the operation is allowed by the embedded. - - MockAttributionReportingContentBrowserClient browser_client; - EXPECT_CALL( - browser_client, - IsConversionMeasurementOperationAllowed( - _, ConversionMeasurementOperation::kConversion, IsNull(), - Pointee(url::Origin::Create(GURL("https://www.example.com/"))), - Pointee(url::Origin::Create(GURL("https://report.example/"))))) - .WillOnce(Return(false)) - .WillOnce(Return(true)); - ScopedContentBrowserClientSetting setting(&browser_client); - - for (bool conversion_allowed : {false, true}) { - EXPECT_CALL(mock_manager_, HandleTrigger).Times(conversion_allowed); - - contents()->NavigateAndCommit(GURL("https://www.example.com")); - - // Create a subframe and use it as a target for the conversion registration - // mojo. - content::RenderFrameHostTester* rfh_tester = - content::RenderFrameHostTester::For(main_rfh()); - content::RenderFrameHost* subframe = rfh_tester->AppendChild("subframe"); - subframe = NavigationSimulatorImpl::NavigateAndCommitFromDocument( - GURL("https://www.another.com"), subframe); - SetCurrentTargetFrameForTesting(subframe); - - blink::mojom::ConversionPtr conversion = blink::mojom::Conversion::New(); - conversion->reporting_origin = - url::Origin::Create(GURL("https://report.example")); - conversion_host_mojom()->RegisterConversion(std::move(conversion)); - - Mock::VerifyAndClear(&mock_manager_); - } -} - TEST_F(AttributionHostTest, ConversionOnInsecurePage_BadMessage) { EXPECT_CALL(mock_manager_, HandleTrigger).Times(0); @@ -314,59 +271,12 @@ EXPECT_FALSE(bad_message_observer.got_bad_message()); } -TEST_F(AttributionHostTest, ValidConversionWithEmbedderDisable_NoConversion) { - EXPECT_CALL(mock_manager_, HandleTrigger).Times(0); - - MockAttributionReportingContentBrowserClient browser_client; - EXPECT_CALL( - browser_client, - IsConversionMeasurementOperationAllowed( - _, ConversionMeasurementOperation::kConversion, IsNull(), - Pointee(url::Origin::Create(GURL("https://www.example.com/"))), - Pointee(url::Origin::Create(GURL("https://secure.com/"))))) - .WillOnce(Return(false)); - ScopedContentBrowserClientSetting setting(&browser_client); - - // Create a page with a secure origin. - contents()->NavigateAndCommit(GURL("https://www.example.com")); - SetCurrentTargetFrameForTesting(main_rfh()); - - blink::mojom::ConversionPtr conversion = blink::mojom::Conversion::New(); - conversion->reporting_origin = - url::Origin::Create(GURL("https://secure.com")); - conversion_host_mojom()->RegisterConversion(std::move(conversion)); -} - -TEST_F(AttributionHostTest, ValidImpressionWithEmbedderDisable_NoImpression) { - EXPECT_CALL(mock_manager_, HandleSource).Times(0); - - MockAttributionReportingContentBrowserClient browser_client; - // This is called twice because the real AttributionHost is still active for - // the test. - EXPECT_CALL( - browser_client, - IsConversionMeasurementOperationAllowed( - _, ConversionMeasurementOperation::kImpression, - Pointee(url::Origin::Create(GURL("https://secure_impression.com/"))), - IsNull(), Pointee(url::Origin::Create(GURL("https://c.com/"))))) - .Times(2) - .WillRepeatedly(Return(false)); - ScopedContentBrowserClientSetting setting(&browser_client); - - contents()->NavigateAndCommit(GURL("https://secure_impression.com")); - auto navigation = NavigationSimulatorImpl::CreateRendererInitiated( - GURL(kConversionUrl), main_rfh()); - navigation->SetInitiatorFrame(main_rfh()); - navigation->set_impression(CreateValidImpression()); - navigation->Commit(); -} - TEST_F(AttributionHostTest, Conversion_AssociatedWithConversionSite) { // Verify that we use the domain of the page where the conversion occurred // instead of the origin. EXPECT_CALL(mock_manager_, - HandleTrigger(TriggerConversionDestinationIs( - net::SchemefulSite(GURL("https://conversion.com"))))); + HandleTrigger(TriggerDestinationOriginIs( + url::Origin::Create(GURL("https://sub.conversion.com"))))); // Create a page with a secure origin. contents()->NavigateAndCommit(GURL("https://sub.conversion.com")); @@ -745,38 +655,6 @@ bad_message_observer.WaitForBadMessage()); } -TEST_F(AttributionHostTest, RegisterConversion_RecordsAllowedMetric) { - // Create a page with a secure origin. - contents()->NavigateAndCommit(GURL("https://www.example.com")); - SetCurrentTargetFrameForTesting(main_rfh()); - - MockAttributionReportingContentBrowserClient browser_client; - EXPECT_CALL(browser_client, - IsConversionMeasurementOperationAllowed( - _, ConversionMeasurementOperation::kConversion, IsNull(), - Pointee(_), Pointee(_))) - .WillOnce(Return(true)) - .WillOnce(Return(false)); - ScopedContentBrowserClientSetting setting(&browser_client); - - const struct { - bool want_allowed; - } kTestCases[] = { - {true}, - {false}, - }; - - for (const auto& test_case : kTestCases) { - base::HistogramTester histograms; - blink::mojom::ConversionPtr conversion = blink::mojom::Conversion::New(); - conversion->reporting_origin = - url::Origin::Create(GURL("https://secure.com")); - conversion_host_mojom()->RegisterConversion(std::move(conversion)); - histograms.ExpectUniqueSample("Conversions.RegisterConversionAllowed", - test_case.want_allowed, 1); - } -} - // In pre-loaded CCT navigations, the attribution can arrive after the // navigation begins but before it's committed. Currently only used on Android // but should work cross-platform.
diff --git a/content/browser/attribution_reporting/attribution_host_utils.cc b/content/browser/attribution_reporting/attribution_host_utils.cc index c61a7ba..aa4004f 100644 --- a/content/browser/attribution_reporting/attribution_host_utils.cc +++ b/content/browser/attribution_reporting/attribution_host_utils.cc
@@ -15,9 +15,6 @@ #include "content/browser/attribution_reporting/common_source_info.h" #include "content/browser/attribution_reporting/storable_source.h" #include "content/common/url_utils.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/content_browser_client.h" -#include "content/public/common/content_client.h" #include "services/network/public/cpp/is_potentially_trustworthy.h" #include "third_party/blink/public/common/navigation/impression.h" #include "url/gurl.h" @@ -32,12 +29,11 @@ network::IsOriginPotentiallyTrustworthy(origin); } -VerifyResult VerifyAndStoreImpression(AttributionSourceType source_type, - const url::Origin& impression_origin, - const blink::Impression& impression, - BrowserContext* browser_context, - AttributionManager& attribution_manager, - base::Time impression_time) { +void VerifyAndStoreImpression(AttributionSourceType source_type, + const url::Origin& impression_origin, + const blink::Impression& impression, + AttributionManager& attribution_manager, + base::Time impression_time) { // Convert |impression| into a StorableImpression that can be forwarded to // storage. If a reporting origin was not provided, default to the conversion // destination for reporting. @@ -45,19 +41,11 @@ ? impression_origin : *impression.reporting_origin; - const bool allowed = - GetContentClient()->browser()->IsConversionMeasurementOperationAllowed( - browser_context, - ContentBrowserClient::ConversionMeasurementOperation::kImpression, - &impression_origin, /*conversion_origin=*/nullptr, &reporting_origin); - if (!allowed) - return VerifyResult{.allowed = false, .stored = false}; - // Conversion measurement is only allowed in secure contexts. if (!IsOriginTrustworthyForAttributions(impression_origin) || !IsOriginTrustworthyForAttributions(reporting_origin) || !IsOriginTrustworthyForAttributions(impression.conversion_destination)) { - return VerifyResult{.allowed = true, .stored = false}; + return; } StorableSource storable_impression( @@ -74,7 +62,6 @@ // DevTools in the event that a debug key is present but the corresponding // cookie is not. attribution_manager.HandleSource(std::move(storable_impression)); - return VerifyResult{.allowed = true, .stored = true}; } absl::optional<blink::Impression> ParseImpressionFromApp(
diff --git a/content/browser/attribution_reporting/attribution_host_utils.h b/content/browser/attribution_reporting/attribution_host_utils.h index 6ed3a0f..17b891b3b 100644 --- a/content/browser/attribution_reporting/attribution_host_utils.h +++ b/content/browser/attribution_reporting/attribution_host_utils.h
@@ -28,31 +28,21 @@ namespace content { class AttributionManager; -class BrowserContext; namespace attribution_host_utils { -// Contains result for `VerifyAndStoreImpression()`. -struct VerifyResult { - // Indicates whether the measurement operation is allowed by the - // ContentClient. - bool allowed; - // Indicates whether the impression is stored. - bool stored; -}; - // Checks if the origin is trustworthy or an android app origin. -bool IsOriginTrustworthyForAttributions(const url::Origin& origin); +CONTENT_EXPORT bool IsOriginTrustworthyForAttributions( + const url::Origin& origin); // Performs required checks on an incoming impression's data (trustworthy -// origins, etc), and if verified, generates a StorableImpression and persists +// origins, etc), and if verified, generates a `StorableSource` and persists // it. -VerifyResult VerifyAndStoreImpression(AttributionSourceType source_type, - const url::Origin& impression_origin, - const blink::Impression& impression, - BrowserContext* browser_context, - AttributionManager& attribution_manager, - base::Time impression_time); +void VerifyAndStoreImpression(AttributionSourceType source_type, + const url::Origin& impression_origin, + const blink::Impression& impression, + AttributionManager& attribution_manager, + base::Time impression_time); CONTENT_EXPORT absl::optional<blink::Impression> ParseImpressionFromApp( const std::string& attribution_source_event_id,
diff --git a/content/browser/attribution_reporting/attribution_internals_browsertest.cc b/content/browser/attribution_reporting/attribution_internals_browsertest.cc index 64b3874..38dd90e 100644 --- a/content/browser/attribution_reporting/attribution_internals_browsertest.cc +++ b/content/browser/attribution_reporting/attribution_internals_browsertest.cc
@@ -376,6 +376,7 @@ AttributionInfoBuilder(SourceBuilder(now).BuildStored()).Build()) .SetReportTime(now + base::Hours(3)) .Build(), + /*is_debug_report=*/false, SendResult(SendResult::Status::kSent, /*http_response_code=*/200)); manager_.NotifyReportSent( @@ -384,6 +385,7 @@ .SetReportTime(now + base::Hours(4)) .SetPriority(-1) .Build(), + /*is_debug_report=*/false, SendResult(SendResult::Status::kDropped, /*http_response_code=*/0)); manager_.NotifyReportSent( @@ -392,8 +394,19 @@ .SetReportTime(now + base::Hours(5)) .SetPriority(-2) .Build(), + /*is_debug_report=*/false, SendResult(SendResult::Status::kFailure, /*http_response_code=*/0)); + manager_.NotifyReportSent( + ReportBuilder( + AttributionInfoBuilder(SourceBuilder(now).BuildStored()).Build()) + .SetReportTime(now + base::Hours(11)) + .SetPriority(-8) + .Build(), + /*is_debug_report=*/true, + SendResult(SendResult::Status::kTransientFailure, + /*http_response_code=*/0)); + ON_CALL(manager_, GetPendingReportsForInternalUse) .WillByDefault(InvokeCallback<std::vector<AttributionReport>>( {ReportBuilder(AttributionInfoBuilder( @@ -483,7 +496,7 @@ static constexpr char wait_script[] = R"( let table = document.querySelector("#report-table-wrapper tbody"); let obs = new MutationObserver(() => { - if (table.children.length === 11 && + if (table.children.length === 12 && table.children[0].children[2].innerText === "https://conversion.test" && table.children[0].children[3].innerText === "https://report.test/.well-known/attribution-reporting/report-event-attribution" && @@ -503,7 +516,9 @@ table.children[7].children[8].innerText === "Dropped due to excessive reporting origins" && table.children[8].children[8].innerText === "Deduplicated" && table.children[9].children[8].innerText === "No report capacity for destination site" && - table.children[10].children[8].innerText === "Internal error") { + table.children[10].children[8].innerText === "Internal error" && + table.children[11].children[3].innerText === + "https://report.test/.well-known/attribution-reporting/debug/report-event-attribution") { document.title = $1; } }); @@ -519,27 +534,29 @@ static constexpr char wait_script[] = R"( let table = document.querySelector("#report-table-wrapper tbody"); let obs = new MutationObserver(() => { - if (table.children.length === 11 && - table.children[10].children[2].innerText === "https://conversion.test" && - table.children[10].children[3].innerText === + if (table.children.length === 12 && + table.children[11].children[2].innerText === "https://conversion.test" && + table.children[11].children[3].innerText === "https://report.test/.well-known/attribution-reporting/report-event-attribution" && - table.children[10].children[6].innerText === "13" && - table.children[10].children[7].innerText === "yes" && - table.children[10].children[8].innerText === "Pending" && - table.children[9].children[6].innerText === "12" && - table.children[9].children[8].innerText === "Dropped for noise" && - table.children[8].children[6].innerText === "11" && - table.children[8].children[8].innerText === "Dropped due to low priority" && - table.children[7].children[6].innerText === "0" && - table.children[7].children[7].innerText === "no" && - table.children[7].children[8].innerText === "Sent: HTTP 200" && - table.children[6].children[8].innerText === "Prohibited by browser policy" && - table.children[5].children[8].innerText === "Network error" && - table.children[4].children[8].innerText === "Dropped due to excessive attributions" && - table.children[3].children[8].innerText === "Dropped due to excessive reporting origins" && - table.children[2].children[8].innerText === "Deduplicated" && - table.children[1].children[8].innerText === "No report capacity for destination site" && - table.children[0].children[8].innerText === "Internal error") { + table.children[11].children[6].innerText === "13" && + table.children[11].children[7].innerText === "yes" && + table.children[11].children[8].innerText === "Pending" && + table.children[10].children[6].innerText === "12" && + table.children[10].children[8].innerText === "Dropped for noise" && + table.children[9].children[6].innerText === "11" && + table.children[9].children[8].innerText === "Dropped due to low priority" && + table.children[8].children[6].innerText === "0" && + table.children[8].children[7].innerText === "no" && + table.children[8].children[8].innerText === "Sent: HTTP 200" && + table.children[7].children[8].innerText === "Prohibited by browser policy" && + table.children[6].children[8].innerText === "Network error" && + table.children[5].children[8].innerText === "Dropped due to excessive attributions" && + table.children[4].children[8].innerText === "Dropped due to excessive reporting origins" && + table.children[3].children[8].innerText === "Deduplicated" && + table.children[2].children[8].innerText === "No report capacity for destination site" && + table.children[1].children[8].innerText === "Internal error" && + table.children[0].children[3].innerText === + "https://report.test/.well-known/attribution-reporting/debug/report-event-attribution") { document.title = $1; } }); @@ -557,7 +574,7 @@ static constexpr char wait_script[] = R"( let table = document.querySelector("#report-table-wrapper tbody"); let obs = new MutationObserver(() => { - if (table.children.length === 11 && + if (table.children.length === 12 && table.children[0].children[2].innerText === "https://conversion.test" && table.children[0].children[3].innerText === "https://report.test/.well-known/attribution-reporting/report-event-attribution" && @@ -577,7 +594,9 @@ table.children[7].children[8].innerText === "Dropped due to excessive reporting origins" && table.children[8].children[8].innerText === "Deduplicated" && table.children[9].children[8].innerText === "No report capacity for destination site" && - table.children[10].children[8].innerText === "Internal error") { + table.children[10].children[8].innerText === "Internal error" && + table.children[11].children[3].innerText === + "https://report.test/.well-known/attribution-reporting/debug/report-event-attribution") { document.title = $1; } }); @@ -611,8 +630,10 @@ .WillOnce(InvokeCallback<std::vector<AttributionReport>>({report})); report.set_report_time(report.report_time() + base::Hours(1)); - manager_.NotifyReportSent(report, SendResult(SendResult::Status::kSent, - /*http_response_code=*/200)); + manager_.NotifyReportSent(report, + /*is_debug_report=*/false, + SendResult(SendResult::Status::kSent, + /*http_response_code=*/200)); EXPECT_CALL(manager_, ClearData) .WillOnce([](base::Time delete_begin, base::Time delete_end,
diff --git a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc index dd0cfe2..21dad56 100644 --- a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc +++ b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
@@ -86,6 +86,7 @@ mojom::WebUIAttributionReportPtr WebUIAttributionReport( const AttributionReport& report, + bool is_debug_report, int http_response_code, mojom::WebUIAttributionReport::Status status) { const auto* data = @@ -95,7 +96,7 @@ return mojom::WebUIAttributionReport::New( data->id, attribution_info.source.common_info().ConversionDestination().Serialize(), - report.ReportURL(), + report.ReportURL(is_debug_report), /*trigger_time=*/attribution_info.time.ToJsTime(), /*report_time=*/report.report_time().ToJsTime(), data->priority, SerializeAttributionJson(report.ReportBody(), /*pretty_print=*/true), @@ -112,7 +113,7 @@ web_ui_reports.reserve(pending_reports.size()); for (const AttributionReport& report : pending_reports) { web_ui_reports.push_back(WebUIAttributionReport( - report, /*http_response_code=*/0, + report, /*is_debug_report=*/false, /*http_response_code=*/0, mojom::WebUIAttributionReport::Status::kPending)); } @@ -265,6 +266,7 @@ void AttributionInternalsHandlerImpl::OnReportSent( const AttributionReport& report, + bool is_debug_report, const SendResult& info) { // TODO(crbug.com/1285317): Show aggregatable reports in internal page. if (!absl::holds_alternative<AttributionReport::EventLevelData>( @@ -282,16 +284,16 @@ mojom::WebUIAttributionReport::Status::kProhibitedByBrowserPolicy; break; case SendResult::Status::kFailure: + case SendResult::Status::kTransientFailure: status = mojom::WebUIAttributionReport::Status::kNetworkError; break; - case SendResult::Status::kTransientFailure: case SendResult::Status::kFailedToAssemble: NOTREACHED(); return; } - auto web_report = - WebUIAttributionReport(report, info.http_response_code, status); + auto web_report = WebUIAttributionReport(report, is_debug_report, + info.http_response_code, status); for (auto& observer : observers_) { observer->OnReportSent(web_report.Clone()); @@ -344,6 +346,7 @@ DCHECK_EQ(result.dropped_reports().size(), 1u); auto report = WebUIAttributionReport(result.dropped_reports().front(), + /*is_debug_report=*/false, /*http_response_code=*/0, status); for (auto& observer : observers_) {
diff --git a/content/browser/attribution_reporting/attribution_internals_handler_impl.h b/content/browser/attribution_reporting/attribution_internals_handler_impl.h index 38a4128b..de81c2ff 100644 --- a/content/browser/attribution_reporting/attribution_internals_handler_impl.h +++ b/content/browser/attribution_reporting/attribution_internals_handler_impl.h
@@ -74,6 +74,7 @@ void OnSourceHandled(const StorableSource& source, StorableSource::Result result) override; void OnReportSent(const AttributionReport& report, + bool is_debug_report, const SendResult& info) override; void OnTriggerHandled(const CreateReportResult& result) override;
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.cc b/content/browser/attribution_reporting/attribution_manager_impl.cc index 6b1cfb9..1eec6fc 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl.cc +++ b/content/browser/attribution_reporting/attribution_manager_impl.cc
@@ -24,6 +24,7 @@ #include "content/browser/attribution_reporting/attribution_cookie_checker_impl.h" #include "content/browser/attribution_reporting/attribution_data_host_manager_impl.h" #include "content/browser/attribution_reporting/attribution_info.h" +#include "content/browser/attribution_reporting/attribution_metrics.h" #include "content/browser/attribution_reporting/attribution_observer.h" #include "content/browser/attribution_reporting/attribution_observer_types.h" #include "content/browser/attribution_reporting/attribution_report.h" @@ -187,6 +188,18 @@ AttributionNoiseMode::kDefault, AttributionDelayMode::kDefault); } +bool IsOperationAllowed( + StoragePartitionImpl* storage_partition, + ContentBrowserClient::ConversionMeasurementOperation operation, + const url::Origin* source_origin, + const url::Origin* destination_origin, + const url::Origin* reporting_origin) { + DCHECK(storage_partition); + return GetContentClient()->browser()->IsConversionMeasurementOperationAllowed( + storage_partition->browser_context(), operation, source_origin, + destination_origin, reporting_origin); +} + } // namespace absl::optional<base::TimeDelta> GetFailedReportDelay(int failed_send_attempts) { @@ -207,11 +220,12 @@ AttributionStorageSql::RunInMemoryForTesting(); } -bool AttributionManagerImpl::IsReportAllowed(const AttributionReport& report) { +bool AttributionManagerImpl::IsReportAllowed( + const AttributionReport& report) const { const CommonSourceInfo& common_info = report.attribution_info().source.common_info(); - return GetContentClient()->browser()->IsConversionMeasurementOperationAllowed( - storage_partition_->browser_context(), + return IsOperationAllowed( + storage_partition_.get(), ContentBrowserClient::ConversionMeasurementOperation::kReport, &common_info.impression_origin(), &common_info.conversion_origin(), &common_info.reporting_origin()); @@ -244,9 +258,7 @@ MakeStorageDelegate(), std::make_unique<AttributionCookieCheckerImpl>(storage_partition), std::make_unique<AttributionReportNetworkSender>(storage_partition), - std::make_unique<AttributionDataHostManagerImpl>( - storage_partition->browser_context(), - this)) {} + std::make_unique<AttributionDataHostManagerImpl>(this)) {} AttributionManagerImpl::AttributionManagerImpl( StoragePartitionImpl* storage_partition, @@ -425,13 +437,33 @@ bool is_debug_cookie_set; void operator()(StorableSource source) { + CommonSourceInfo& common_info = source.common_info(); + + bool allowed = IsOperationAllowed( + manager->storage_partition_.get(), + ContentBrowserClient::ConversionMeasurementOperation::kImpression, + &common_info.impression_origin(), + /*destination_origin=*/nullptr, &common_info.reporting_origin()); + RecordRegisterImpressionAllowed(allowed); + if (!allowed) + return; + if (!is_debug_cookie_set) - source.common_info().ClearDebugKey(); + common_info.ClearDebugKey(); manager->StoreSource(std::move(source)); } void operator()(AttributionTrigger trigger) { + bool allowed = IsOperationAllowed( + manager->storage_partition_.get(), + ContentBrowserClient::ConversionMeasurementOperation::kConversion, + /*source_origin=*/nullptr, &trigger.destination_origin(), + &trigger.reporting_origin()); + RecordRegisterConversionAllowed(allowed); + if (!allowed) + return; + if (!is_debug_cookie_set) trigger.ClearDebugKey(); @@ -481,9 +513,11 @@ DCHECK(absl::holds_alternative<AttributionReport::EventLevelData>( report.data())); - // We don't fire observer callbacks or delete from storage for debug reports. + // We don't delete from storage for debug reports. PrepareToSendReport(std::move(report), /*is_debug_report=*/true, - base::DoNothing()); + base::BindOnce(&AttributionManagerImpl::NotifyReportSent, + weak_factory_.GetWeakPtr(), + /*is_debug_report=*/true)); } void AttributionManagerImpl::GetActiveSourcesForWebUI( @@ -710,8 +744,14 @@ return; } + NotifyReportSent(/*is_debug_report=*/false, std::move(report), info); +} + +void AttributionManagerImpl::NotifyReportSent(bool is_debug_report, + AttributionReport report, + SendResult info) { for (auto& observer : observers_) - observer.OnReportSent(report, info); + observer.OnReportSent(report, /*is_debug_report=*/is_debug_report, info); } void AttributionManagerImpl::AssembleAggregatableReport(
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.h b/content/browser/attribution_reporting/attribution_manager_impl.h index 3164ffb3..7ea13df 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl.h +++ b/content/browser/attribution_reporting/attribution_manager_impl.h
@@ -161,8 +161,9 @@ void NotifySourcesChanged(); void NotifyReportsChanged(); void NotifySourceDeactivated(const DeactivatedSource& source); + void NotifyReportSent(bool is_debug_report, AttributionReport, SendResult); - bool IsReportAllowed(const AttributionReport&); + bool IsReportAllowed(const AttributionReport&) const; // Friend to expose the AttributionStorage for certain tests. friend std::vector<AttributionReport> GetAttributionReportsForTesting(
diff --git a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc index 284742b..27a73236 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc
@@ -46,7 +46,6 @@ #include "content/public/test/browser_task_environment.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_utils.h" -#include "net/base/schemeful_site.h" #include "services/network/test/test_network_connection_tracker.h" #include "storage/browser/test/mock_special_storage_policy.h" #include "testing/gmock/include/gmock/gmock.h" @@ -61,12 +60,14 @@ using ::testing::_; using ::testing::AllOf; +using ::testing::AnyOf; using ::testing::ElementsAre; using ::testing::Expectation; using ::testing::Field; using ::testing::Ge; using ::testing::InSequence; using ::testing::IsEmpty; +using ::testing::IsNull; using ::testing::Le; using ::testing::Pointee; using ::testing::Return; @@ -99,7 +100,9 @@ MOCK_METHOD(void, OnReportSent, - (const AttributionReport& report, const SendResult& info), + (const AttributionReport& report, + bool is_debug_report, + const SendResult& info), (override)); MOCK_METHOD(void, @@ -406,6 +409,8 @@ } TEST_F(AttributionManagerImplTest, ImpressionConverted_ReportSent) { + base::HistogramTester histograms; + attribution_manager_->HandleSource( SourceBuilder().SetExpiry(kImpressionExpiry).Build()); attribution_manager_->HandleTrigger(DefaultTrigger()); @@ -417,6 +422,11 @@ task_environment_.FastForwardBy(base::Microseconds(1)); EXPECT_THAT(report_sender_->calls(), SizeIs(1)); + + histograms.ExpectUniqueSample("Conversions.RegisterImpressionAllowed", true, + 1); + histograms.ExpectUniqueSample("Conversions.RegisterConversionAllowed", true, + 1); } TEST_F(AttributionManagerImplTest, @@ -700,9 +710,12 @@ &observer); observation.Observe(attribution_manager_.get()); - EXPECT_CALL(observer, OnReportSent(ReportSourceIs(SourceEventIdIs(1u)), _)); - EXPECT_CALL(observer, OnReportSent(ReportSourceIs(SourceEventIdIs(2u)), _)); - EXPECT_CALL(observer, OnReportSent(ReportSourceIs(SourceEventIdIs(3u)), _)); + EXPECT_CALL(observer, OnReportSent(ReportSourceIs(SourceEventIdIs(1u)), + /*is_debug_report=*/false, _)); + EXPECT_CALL(observer, OnReportSent(ReportSourceIs(SourceEventIdIs(2u)), + /*is_debug_report=*/false, _)); + EXPECT_CALL(observer, OnReportSent(ReportSourceIs(SourceEventIdIs(3u)), + /*is_debug_report=*/false, _)); attribution_manager_->HandleSource( SourceBuilder().SetSourceEventId(1).SetExpiry(kImpressionExpiry).Build()); @@ -1189,11 +1202,75 @@ run_loop.Run(); } +TEST_F(AttributionManagerImplTest, + EmbedderDisallowsImpressions_SourceNotStored) { + base::HistogramTester histograms; + + MockAttributionReportingContentBrowserClient browser_client; + EXPECT_CALL( + browser_client, + IsConversionMeasurementOperationAllowed( + _, ContentBrowserClient::ConversionMeasurementOperation::kImpression, + Pointee(url::Origin::Create(GURL("https://impression.test/"))), + IsNull(), Pointee(url::Origin::Create(GURL("https://report.test/"))))) + .WillOnce(Return(false)); + ScopedContentBrowserClientSetting setting(&browser_client); + + attribution_manager_->HandleSource( + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); + EXPECT_THAT(StoredSources(), IsEmpty()); + + histograms.ExpectUniqueSample("Conversions.RegisterImpressionAllowed", false, + 1); +} + +TEST_F(AttributionManagerImplTest, + EmbedderDisallowsConversions_ReportNotStored) { + base::HistogramTester histograms; + + MockAttributionReportingContentBrowserClient browser_client; + EXPECT_CALL( + browser_client, + IsConversionMeasurementOperationAllowed( + _, ContentBrowserClient::ConversionMeasurementOperation::kImpression, + _, _, _)) + .WillRepeatedly(Return(true)); + EXPECT_CALL( + browser_client, + IsConversionMeasurementOperationAllowed( + _, ContentBrowserClient::ConversionMeasurementOperation::kConversion, + IsNull(), + Pointee(url::Origin::Create(GURL("https://sub.conversion.test/"))), + Pointee(url::Origin::Create(GURL("https://report.test/"))))) + .WillOnce(Return(false)); + ScopedContentBrowserClientSetting setting(&browser_client); + + attribution_manager_->HandleSource( + SourceBuilder().SetExpiry(kImpressionExpiry).Build()); + EXPECT_THAT(StoredSources(), SizeIs(1)); + + attribution_manager_->HandleTrigger(DefaultTrigger()); + EXPECT_THAT(StoredReports(), IsEmpty()); + + histograms.ExpectUniqueSample("Conversions.RegisterConversionAllowed", false, + 1); +} + TEST_F(AttributionManagerImplTest, EmbedderDisallowsReporting_ReportNotSent) { MockAttributionReportingContentBrowserClient browser_client; EXPECT_CALL( browser_client, IsConversionMeasurementOperationAllowed( + _, + AnyOf( + ContentBrowserClient::ConversionMeasurementOperation::kImpression, + ContentBrowserClient::ConversionMeasurementOperation:: + kConversion), + _, _, _)) + .WillRepeatedly(Return(true)); + EXPECT_CALL( + browser_client, + IsConversionMeasurementOperationAllowed( _, ContentBrowserClient::ConversionMeasurementOperation::kReport, Pointee(url::Origin::Create(GURL("https://impression.test/"))), Pointee(url::Origin::Create(GURL("https://sub.conversion.test/"))), @@ -1213,8 +1290,9 @@ &observer); observation.Observe(attribution_manager_.get()); - EXPECT_CALL(observer, OnReportSent(_, Field(&SendResult::status, - SendResult::Status::kDropped))); + EXPECT_CALL(observer, OnReportSent(_, /*is_debug_report=*/false, + Field(&SendResult::status, + SendResult::Status::kDropped))); task_environment_.FastForwardBy(kFirstReportingWindow); @@ -1237,6 +1315,16 @@ EXPECT_CALL( browser_client, IsConversionMeasurementOperationAllowed( + _, + AnyOf( + ContentBrowserClient::ConversionMeasurementOperation::kImpression, + ContentBrowserClient::ConversionMeasurementOperation:: + kConversion), + _, _, _)) + .WillRepeatedly(Return(true)); + EXPECT_CALL( + browser_client, + IsConversionMeasurementOperationAllowed( _, ContentBrowserClient::ConversionMeasurementOperation::kReport, Pointee(source_origin), Pointee(destination_origin), Pointee(reporting_origin))) @@ -1254,7 +1342,7 @@ attribution_manager_->HandleTrigger( TriggerBuilder() - .SetConversionDestination(net::SchemefulSite(destination_origin)) + .SetDestinationOrigin(destination_origin) .SetReportingOrigin(reporting_origin) .SetDebugKey(456) .Build()); @@ -1563,6 +1651,13 @@ }; for (const auto& test_case : kTestCases) { + MockAttributionObserver observer; + base::ScopedObservation<AttributionManager, AttributionObserver> + observation(&observer); + observation.Observe(attribution_manager_.get()); + EXPECT_CALL(observer, OnReportSent(_, /*is_debug_report=*/true, _)) + .Times(test_case.send_expected); + attribution_manager_->HandleSource( SourceBuilder() .SetReportingOrigin(reporting_origin) @@ -1588,12 +1683,17 @@ ReportSourceIs(SourceDebugKeyIs(test_case.source_debug_key)), TriggerDebugKeyIs(test_case.trigger_debug_key)))) << test_case.name; + + report_sender_->RunCallbacksAndReset( + {SendResult::Status::kTransientFailure}); } else { EXPECT_THAT(report_sender_->debug_calls(), IsEmpty()); } attribution_manager_->ClearData(base::Time::Min(), base::Time::Max(), base::NullCallback(), base::DoNothing()); + + ::testing::Mock::VerifyAndClear(&observer); } }
diff --git a/content/browser/attribution_reporting/attribution_observer.h b/content/browser/attribution_reporting/attribution_observer.h index 65134c3..7247f49 100644 --- a/content/browser/attribution_reporting/attribution_observer.h +++ b/content/browser/attribution_reporting/attribution_observer.h
@@ -39,6 +39,7 @@ // Called when a report is sent, regardless of success, but not for attempts // that will be retried. virtual void OnReportSent(const AttributionReport& report, + bool is_debug_report, const SendResult& info) {} // Called when a trigger is registered, regardless of success.
diff --git a/content/browser/attribution_reporting/attribution_reporter_android.cc b/content/browser/attribution_reporting/attribution_reporter_android.cc index 3485f29..df7759e 100644 --- a/content/browser/attribution_reporting/attribution_reporter_android.cc +++ b/content/browser/attribution_reporting/attribution_reporter_android.cc
@@ -52,7 +52,7 @@ OriginFromAndroidPackageName(source_package_name); attribution_host_utils::VerifyAndStoreImpression( - AttributionSourceType::kEvent, impression_origin, *impression, context, + AttributionSourceType::kEvent, impression_origin, *impression, attribution_manager, impression_time); }
diff --git a/content/browser/attribution_reporting/attribution_reporter_android_unittest.cc b/content/browser/attribution_reporting/attribution_reporter_android_unittest.cc index 805a83a..2f8d3870 100644 --- a/content/browser/attribution_reporting/attribution_reporter_android_unittest.cc +++ b/content/browser/attribution_reporting/attribution_reporter_android_unittest.cc
@@ -21,11 +21,7 @@ namespace { -using testing::_; using testing::AllOf; -using testing::IsNull; -using testing::Pointee; -using testing::Return; const char kPackageName[] = "org.chromium.chrome.test"; const char kConversionUrl[] = "https://b.com"; @@ -75,23 +71,6 @@ base::Time::Now()); } -TEST_F(AttributionReporterTest, ValidImpression_Disallowed) { - MockAttributionReportingContentBrowserClient browser_client; - EXPECT_CALL( - browser_client, - IsConversionMeasurementOperationAllowed( - _, ContentBrowserClient::ConversionMeasurementOperation::kImpression, - Pointee(_), IsNull(), Pointee(_))) - .WillOnce(Return(false)); - ScopedContentBrowserClientSetting setting(&browser_client); - - EXPECT_CALL(mock_manager_, HandleSource).Times(0); - - attribution_reporter_android::ReportAppImpression( - mock_manager_, nullptr, kPackageName, kEventId, kConversionUrl, - kReportToUrl, 56789, base::Time::Now()); -} - TEST_F(AttributionReporterTest, InvalidImpression) { EXPECT_CALL(mock_manager_, HandleSource).Times(0);
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc index ea5155c..4e0a66b 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -41,6 +41,7 @@ #include "content/browser/attribution_reporting/sql_utils.h" #include "content/browser/attribution_reporting/storable_source.h" #include "content/browser/attribution_reporting/stored_source.h" +#include "net/base/schemeful_site.h" #include "sql/database.h" #include "sql/recovery.h" #include "sql/statement.h" @@ -727,8 +728,7 @@ DCHECK(report.has_value()); - switch ( - CapacityForStoringReport(trigger.conversion_destination().Serialize())) { + switch (CapacityForStoringReport(trigger)) { case ConversionCapacityStatus::kHasCapacity: break; case ConversionCapacityStatus::kNoCapacity: @@ -849,9 +849,8 @@ const AttributionTrigger& trigger, absl::optional<StoredSource::Id>& source_id_to_attribute, std::vector<StoredSource::Id>& source_ids_to_delete) { - const net::SchemefulSite& conversion_destination = - trigger.conversion_destination(); - DCHECK(!conversion_destination.opaque()); + const url::Origin& destination_origin = trigger.destination_origin(); + DCHECK(!destination_origin.opaque()); const url::Origin& reporting_origin = trigger.reporting_origin(); DCHECK(!reporting_origin.opaque()); @@ -871,7 +870,7 @@ sql::Statement statement( db_->GetCachedStatement(SQL_FROM_HERE, kGetMatchingSourcesSql)); - statement.BindString(0, conversion_destination.Serialize()); + statement.BindString(0, net::SchemefulSite(destination_origin).Serialize()); statement.BindString(1, SerializeOrigin(reporting_origin)); statement.BindTime(2, base::Time::Now()); @@ -1676,7 +1675,7 @@ AttributionStorageSql::ConversionCapacityStatus AttributionStorageSql::CapacityForStoringReport( - const std::string& serialized_origin) { + const AttributionTrigger& trigger) { // This query should be reasonably optimized via // `kConversionDestinationIndexSql`. The conversion origin is the second // column in a multi-column index where the first column is just a boolean. @@ -1695,7 +1694,8 @@ "(aggregatable_active BETWEEN 0 AND 1)"; sql::Statement statement( db_->GetCachedStatement(SQL_FROM_HERE, kCountReportsSql)); - statement.BindString(0, serialized_origin); + statement.BindString( + 0, net::SchemefulSite(trigger.destination_origin()).Serialize()); if (!statement.Step()) return ConversionCapacityStatus::kError; int64_t count = statement.ColumnInt64(0);
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.h b/content/browser/attribution_reporting/attribution_storage_sql.h index ae6bb62..0fa21b3 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.h +++ b/content/browser/attribution_reporting/attribution_storage_sql.h
@@ -167,8 +167,7 @@ kError, }; - ConversionCapacityStatus CapacityForStoringReport( - const std::string& serialized_origin) + ConversionCapacityStatus CapacityForStoringReport(const AttributionTrigger&) VALID_CONTEXT_REQUIRED(sequence_checker_); enum class MaybeReplaceLowerPriorityEventLevelReportResult {
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc b/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc index 5d00ff6..bfd81f01 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc
@@ -599,13 +599,12 @@ .Build()); task_environment_.FastForwardBy(base::Days(1)); - EXPECT_EQ( - AttributionTrigger::EventLevelResult::kSuccess, - MaybeCreateAndStoreEventLevelReport( - TriggerBuilder() - .SetConversionDestination(net::SchemefulSite(conversion_origin)) - .SetReportingOrigin(reporting_origin) - .Build())); + EXPECT_EQ(AttributionTrigger::EventLevelResult::kSuccess, + MaybeCreateAndStoreEventLevelReport( + TriggerBuilder() + .SetDestinationOrigin(conversion_origin) + .SetReportingOrigin(reporting_origin) + .Build())); EXPECT_THAT(storage()->GetActiveSources(), SizeIs(1)); task_environment_.FastForwardBy(base::Days(1)); @@ -645,13 +644,12 @@ .Build()); task_environment_.FastForwardBy(base::Days(1)); - EXPECT_EQ( - AttributionTrigger::EventLevelResult::kSuccess, - MaybeCreateAndStoreEventLevelReport( - TriggerBuilder() - .SetConversionDestination(net::SchemefulSite(conversion_origin)) - .SetReportingOrigin(reporting_origin) - .Build())); + EXPECT_EQ(AttributionTrigger::EventLevelResult::kSuccess, + MaybeCreateAndStoreEventLevelReport( + TriggerBuilder() + .SetDestinationOrigin(conversion_origin) + .SetReportingOrigin(reporting_origin) + .Build())); EXPECT_THAT(storage()->GetActiveSources(), SizeIs(1)); task_environment_.FastForwardBy(base::Days(1)); @@ -734,8 +732,8 @@ MaybeCreateAndStoreEventLevelReport( TriggerBuilder() .SetTriggerData(kMaxUint64) - .SetConversionDestination( - impression.common_info().ConversionDestination()) + .SetDestinationOrigin( + impression.common_info().conversion_origin()) .SetReportingOrigin(impression.common_info().reporting_origin()) .Build()));
diff --git a/content/browser/attribution_reporting/attribution_storage_unittest.cc b/content/browser/attribution_reporting/attribution_storage_unittest.cc index 2b5810c4..da33886c 100644 --- a/content/browser/attribution_reporting/attribution_storage_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_unittest.cc
@@ -222,8 +222,7 @@ AttributionTrigger::EventLevelResult::kSuccess, MaybeCreateAndStoreEventLevelReport( TriggerBuilder() - .SetConversionDestination( - net::SchemefulSite(GURL("https://a.test"))) + .SetDestinationOrigin(url::Origin::Create(GURL("https://a.test"))) .SetReportingOrigin(impression.common_info().reporting_origin()) .Build())); } @@ -659,23 +658,23 @@ for (int i = 0; i < 5; i++) { auto origin = url::Origin::Create(GURL(base::StringPrintf("https://%d.com/", i))); - EXPECT_EQ(AttributionTrigger::EventLevelResult::kSuccess, - MaybeCreateAndStoreEventLevelReport( - TriggerBuilder() - .SetConversionDestination(net::SchemefulSite(origin)) - .SetReportingOrigin(origin) - .Build())); + EXPECT_EQ( + AttributionTrigger::EventLevelResult::kSuccess, + MaybeCreateAndStoreEventLevelReport(TriggerBuilder() + .SetDestinationOrigin(origin) + .SetReportingOrigin(origin) + .Build())); } task_environment_.FastForwardBy(base::Days(1)); for (int i = 5; i < 10; i++) { auto origin = url::Origin::Create(GURL(base::StringPrintf("https://%d.com/", i))); - EXPECT_EQ(AttributionTrigger::EventLevelResult::kSuccess, - MaybeCreateAndStoreEventLevelReport( - TriggerBuilder() - .SetConversionDestination(net::SchemefulSite(origin)) - .SetReportingOrigin(origin) - .Build())); + EXPECT_EQ( + AttributionTrigger::EventLevelResult::kSuccess, + MaybeCreateAndStoreEventLevelReport(TriggerBuilder() + .SetDestinationOrigin(origin) + .SetReportingOrigin(origin) + .Build())); } auto null_filter = base::RepeatingCallback<bool(const url::Origin&)>(); @@ -1312,8 +1311,8 @@ EXPECT_EQ(AttributionTrigger::EventLevelResult::kSuccess, MaybeCreateAndStoreEventLevelReport( TriggerBuilder() - .SetConversionDestination(net::SchemefulSite( - url::Origin::Create(GURL("https://a.example")))) + .SetDestinationOrigin( + url::Origin::Create(GURL("https://a.example"))) .SetDedupKey(11) .SetTriggerData(71) .Build())); @@ -1323,8 +1322,8 @@ EXPECT_EQ(AttributionTrigger::EventLevelResult::kSuccess, MaybeCreateAndStoreEventLevelReport( TriggerBuilder() - .SetConversionDestination(net::SchemefulSite( - url::Origin::Create(GURL("https://a.example")))) + .SetDestinationOrigin( + url::Origin::Create(GURL("https://a.example"))) .SetDedupKey(12) .SetTriggerData(72) .Build())); @@ -1334,8 +1333,8 @@ EXPECT_EQ(AttributionTrigger::EventLevelResult::kSuccess, MaybeCreateAndStoreEventLevelReport( TriggerBuilder() - .SetConversionDestination(net::SchemefulSite( - url::Origin::Create(GURL("https://b.example")))) + .SetDestinationOrigin( + url::Origin::Create(GURL("https://b.example"))) .SetDedupKey(12) .SetTriggerData(73) .Build())); @@ -1343,8 +1342,7 @@ // Shouldn't be stored because conversion destination and dedup key match. auto result = storage()->MaybeCreateAndStoreReport( TriggerBuilder() - .SetConversionDestination(net::SchemefulSite( - url::Origin::Create(GURL("https://a.example")))) + .SetDestinationOrigin(url::Origin::Create(GURL("https://a.example"))) .SetDedupKey(11) .SetTriggerData(74) .Build()); @@ -1357,8 +1355,8 @@ EXPECT_EQ(AttributionTrigger::EventLevelResult::kDeduplicated, MaybeCreateAndStoreEventLevelReport( TriggerBuilder() - .SetConversionDestination(net::SchemefulSite( - url::Origin::Create(GURL("https://b.example")))) + .SetDestinationOrigin( + url::Origin::Create(GURL("https://b.example"))) .SetDedupKey(12) .SetTriggerData(75) .Build())); @@ -1387,8 +1385,8 @@ EXPECT_EQ(AttributionTrigger::EventLevelResult::kSuccess, MaybeCreateAndStoreEventLevelReport( TriggerBuilder() - .SetConversionDestination(net::SchemefulSite( - url::Origin::Create(GURL("https://a.example")))) + .SetDestinationOrigin( + url::Origin::Create(GURL("https://a.example"))) .SetDedupKey(2) .SetTriggerData(3) .Build())); @@ -1409,8 +1407,8 @@ EXPECT_EQ(AttributionTrigger::EventLevelResult::kDeduplicated, MaybeCreateAndStoreEventLevelReport( TriggerBuilder() - .SetConversionDestination(net::SchemefulSite( - url::Origin::Create(GURL("https://a.example")))) + .SetDestinationOrigin( + url::Origin::Create(GURL("https://a.example"))) .SetDedupKey(2) .SetTriggerData(5) .Build())); @@ -2197,7 +2195,7 @@ EXPECT_EQ(AttributionTrigger::EventLevelResult::kSuccess, MaybeCreateAndStoreEventLevelReport(AttributionTrigger( - net::SchemefulSite(origin), origin, + origin, origin, /*filters=*/AttributionFilterData(), /*debug_key=*/absl::nullopt, {AttributionTrigger::EventTriggerData( @@ -2287,7 +2285,7 @@ EXPECT_EQ(AttributionTrigger::EventLevelResult::kSuccess, MaybeCreateAndStoreEventLevelReport(AttributionTrigger( - net::SchemefulSite(origin), origin, + origin, origin, /*filters=*/AttributionFilterData(), /*debug_key=*/absl::nullopt, event_triggers))); @@ -2310,7 +2308,7 @@ {{"abc", {"123"}}})) .Build()); - AttributionTrigger trigger1(net::SchemefulSite(origin), origin, + AttributionTrigger trigger1(origin, origin, /*filters=*/ *AttributionFilterData::FromTriggerFilterValues({ {"abc", {"456"}}, @@ -2318,7 +2316,7 @@ /*debug_key=*/absl::nullopt, /*event_triggers=*/{}); - AttributionTrigger trigger2(net::SchemefulSite(origin), origin, + AttributionTrigger trigger2(origin, origin, /*filters=*/ *AttributionFilterData::FromTriggerFilterValues({ {"abc", {"123"}},
diff --git a/content/browser/attribution_reporting/attribution_test_utils.cc b/content/browser/attribution_reporting/attribution_test_utils.cc index f4679f92..d26275e 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.cc +++ b/content/browser/attribution_reporting/attribution_test_utils.cc
@@ -34,7 +34,6 @@ const char kDefaultImpressionOrigin[] = "https://impression.test/"; const char kDefaultTriggerOrigin[] = "https://sub.conversion.test/"; -const char kDefaultTriggerDestination[] = "https://conversion.test/"; const char kDefaultReportOrigin[] = "https://report.test/"; // Default expiry time for impressions for testing. @@ -359,9 +358,10 @@ } void MockAttributionManager::NotifyReportSent(const AttributionReport& report, + bool is_debug_report, const SendResult& info) { for (auto& observer : observers_) - observer.OnReportSent(report, info); + observer.OnReportSent(report, is_debug_report, info); } void MockAttributionManager::NotifyTriggerHandled( @@ -497,8 +497,7 @@ } TriggerBuilder::TriggerBuilder() - : conversion_destination_( - net::SchemefulSite(GURL(kDefaultTriggerDestination))), + : destination_origin_(url::Origin::Create(GURL(kDefaultTriggerOrigin))), reporting_origin_(url::Origin::Create(GURL(kDefaultReportOrigin))) {} TriggerBuilder::~TriggerBuilder() = default; @@ -514,9 +513,9 @@ return *this; } -TriggerBuilder& TriggerBuilder::SetConversionDestination( - net::SchemefulSite conversion_destination) { - conversion_destination_ = std::move(conversion_destination); +TriggerBuilder& TriggerBuilder::SetDestinationOrigin( + url::Origin destination_origin) { + destination_origin_ = std::move(destination_origin); return *this; } @@ -544,7 +543,7 @@ } AttributionTrigger TriggerBuilder::Build() const { - return AttributionTrigger(trigger_data_, conversion_destination_, + return AttributionTrigger(trigger_data_, destination_origin_, reporting_origin_, event_source_trigger_data_, priority_, dedup_key_, debug_key_); } @@ -697,7 +696,7 @@ bool operator==(const AttributionTrigger& a, const AttributionTrigger& b) { const auto tie = [](const AttributionTrigger& t) { - return std::make_tuple(t.conversion_destination(), t.reporting_origin(), + return std::make_tuple(t.destination_origin(), t.reporting_origin(), t.debug_key(), t.event_triggers()); }; return tie(a) == tie(b); @@ -930,8 +929,7 @@ std::ostream& operator<<(std::ostream& out, const AttributionTrigger& conversion) { - out << "{conversion_destination=" - << conversion.conversion_destination().Serialize() + out << "{destination_origin=" << conversion.destination_origin() << ",reporting_origin=" << conversion.reporting_origin() << ",debug_key=" << (conversion.debug_key() ? base::NumberToString(*conversion.debug_key()) : "null") @@ -1209,9 +1207,8 @@ ::testing::Matcher<AttributionTrigger> AttributionTriggerMatches( const AttributionTriggerMatcherConfig& cfg) { return AllOf( - Property("conversion_destination", - &AttributionTrigger::conversion_destination, - cfg.conversion_destination), + Property("destination_origin", &AttributionTrigger::destination_origin, + cfg.destination_origin), Property("reporting_origin", &AttributionTrigger::reporting_origin, cfg.reporting_origin), Property("filters", &AttributionTrigger::filters, cfg.filters),
diff --git a/content/browser/attribution_reporting/attribution_test_utils.h b/content/browser/attribution_reporting/attribution_test_utils.h index 2911cf1..63add89 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.h +++ b/content/browser/attribution_reporting/attribution_test_utils.h
@@ -41,7 +41,6 @@ #include "content/browser/attribution_reporting/stored_source.h" #include "content/public/browser/attribution_reporting.h" #include "content/test/test_content_browser_client.h" -#include "net/base/schemeful_site.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/attribution_reporting/constants.h" @@ -308,6 +307,7 @@ void NotifySourceHandled(const StorableSource& source, StorableSource::Result result); void NotifyReportSent(const AttributionReport& report, + bool is_debug_report, const SendResult& info); void NotifyTriggerHandled(const CreateReportResult& result); @@ -408,8 +408,7 @@ TriggerBuilder& SetEventSourceTriggerData(uint64_t event_source_trigger_data); - TriggerBuilder& SetConversionDestination( - net::SchemefulSite conversion_destination); + TriggerBuilder& SetDestinationOrigin(url::Origin destination_origin); TriggerBuilder& SetReportingOrigin(url::Origin reporting_origin); @@ -424,7 +423,7 @@ private: uint64_t trigger_data_ = 111; uint64_t event_source_trigger_data_ = 0; - net::SchemefulSite conversion_destination_; + url::Origin destination_origin_; url::Origin reporting_origin_; int64_t priority_ = 0; absl::optional<uint64_t> dedup_key_; @@ -707,9 +706,8 @@ // Trigger matchers. -MATCHER_P(TriggerConversionDestinationIs, matcher, "") { - return ExplainMatchResult(matcher, arg.conversion_destination(), - result_listener); +MATCHER_P(TriggerDestinationOriginIs, matcher, "") { + return ExplainMatchResult(matcher, arg.destination_origin(), result_listener); } // Report matchers @@ -790,8 +788,7 @@ EventTriggerDataMatches(const EventTriggerDataMatcherConfig&); struct AttributionTriggerMatcherConfig { - ::testing::Matcher<const net::SchemefulSite&> conversion_destination = - ::testing::_; + ::testing::Matcher<const url::Origin&> destination_origin = ::testing::_; ::testing::Matcher<const url::Origin&> reporting_origin = ::testing::_; ::testing::Matcher<const AttributionFilterData&> filters = ::testing::_; ::testing::Matcher<absl::optional<uint64_t>> debug_key = ::testing::_;
diff --git a/content/browser/attribution_reporting/attribution_trigger.cc b/content/browser/attribution_reporting/attribution_trigger.cc index afdf927..dc0884e 100644 --- a/content/browser/attribution_reporting/attribution_trigger.cc +++ b/content/browser/attribution_reporting/attribution_trigger.cc
@@ -24,30 +24,29 @@ not_filters(std::move(not_filters)) {} AttributionTrigger::AttributionTrigger( - net::SchemefulSite conversion_destination, + url::Origin destination_origin, url::Origin reporting_origin, AttributionFilterData filters, absl::optional<uint64_t> debug_key, std::vector<EventTriggerData> event_triggers) - : conversion_destination_(std::move(conversion_destination)), + : destination_origin_(std::move(destination_origin)), reporting_origin_(std::move(reporting_origin)), filters_(std::move(filters)), debug_key_(debug_key), event_triggers_(std::move(event_triggers)) { DCHECK(!reporting_origin_.opaque()); - DCHECK(!conversion_destination_.opaque()); + DCHECK(!destination_origin_.opaque()); } -AttributionTrigger::AttributionTrigger( - uint64_t trigger_data, - net::SchemefulSite conversion_destination, - url::Origin reporting_origin, - uint64_t event_source_trigger_data, - int64_t priority, - absl::optional<uint64_t> dedup_key, - absl::optional<uint64_t> debug_key) +AttributionTrigger::AttributionTrigger(uint64_t trigger_data, + url::Origin destination_origin, + url::Origin reporting_origin, + uint64_t event_source_trigger_data, + int64_t priority, + absl::optional<uint64_t> dedup_key, + absl::optional<uint64_t> debug_key) : AttributionTrigger( - std::move(conversion_destination), + std::move(destination_origin), std::move(reporting_origin), /*filters=*/AttributionFilterData(), debug_key,
diff --git a/content/browser/attribution_reporting/attribution_trigger.h b/content/browser/attribution_reporting/attribution_trigger.h index 83e86ca..41aa0aed 100644 --- a/content/browser/attribution_reporting/attribution_trigger.h +++ b/content/browser/attribution_reporting/attribution_trigger.h
@@ -11,7 +11,6 @@ #include "content/browser/attribution_reporting/attribution_filter_data.h" #include "content/common/content_export.h" -#include "net/base/schemeful_site.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/origin.h" @@ -77,7 +76,7 @@ // Should only be created with values that the browser process has already // validated. |conversion_destination| should be filled by a navigation origin // known by the browser process. - AttributionTrigger(net::SchemefulSite conversion_destination, + AttributionTrigger(url::Origin destination_origin, url::Origin reporting_origin, AttributionFilterData filters, absl::optional<uint64_t> debug_key, @@ -92,7 +91,7 @@ // TODO(apaseltiner): Remove this constructor once the old // trigger-registration API surface is removed. AttributionTrigger(uint64_t trigger_data, - net::SchemefulSite conversion_destination, + url::Origin destination_origin, url::Origin reporting_origin, uint64_t event_source_trigger_data, int64_t priority, @@ -105,9 +104,7 @@ AttributionTrigger& operator=(AttributionTrigger&& other); ~AttributionTrigger(); - const net::SchemefulSite& conversion_destination() const { - return conversion_destination_; - } + const url::Origin& destination_origin() const { return destination_origin_; } const url::Origin& reporting_origin() const { return reporting_origin_; } @@ -122,8 +119,8 @@ } private: - // Schemeful site that this conversion event occurred on. - net::SchemefulSite conversion_destination_; + // Origin that this conversion event occurred on. + url::Origin destination_origin_; // Origin of the conversion redirect url, and the origin that will receive any // reports.
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h index 3a156c59..21756b9 100644 --- a/content/browser/bad_message.h +++ b/content/browser/bad_message.h
@@ -295,6 +295,7 @@ RFH_CREATE_FENCED_FRAME_IN_SANDBOXED_FRAME = 268, RFH_UNLOAD_HANDLER_NOT_ALLOWED_IN_FENCED_FRAME = 269, RFH_BEFOREUNLOAD_HANDLER_NOT_ALLOWED_IN_FENCED_FRAME = 270, + MSDH_GET_OPEN_DEVICE_USE_WITHOUT_FEATURE = 271, // Please add new elements here. The naming convention is abbreviated class // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/devtools/service_worker_devtools_agent_host.cc b/content/browser/devtools/service_worker_devtools_agent_host.cc index 2d4ef85..c1895858 100644 --- a/content/browser/devtools/service_worker_devtools_agent_host.cc +++ b/content/browser/devtools/service_worker_devtools_agent_host.cc
@@ -294,6 +294,8 @@ void ServiceWorkerDevToolsAgentHost::WorkerStopped() { DCHECK_NE(WORKER_TERMINATED, state_); state_ = WORKER_TERMINATED; + worker_process_id_ = content::ChildProcessHost::kInvalidUniqueID; + worker_route_id_ = MSG_ROUTING_NONE; for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this)) inspector->TargetCrashed(); GetRendererChannel()->SetRenderer(mojo::NullRemote(), mojo::NullReceiver(), @@ -331,6 +333,10 @@ void ServiceWorkerDevToolsAgentHost::UpdateLoaderFactories( base::OnceClosure callback) { + if (state_ == WORKER_TERMINATED) { + std::move(callback).Run(); + return; + } RenderProcessHost* rph = RenderProcessHost::FromID(worker_process_id_); if (!rph) { std::move(callback).Run(); @@ -352,6 +358,12 @@ coep_reporter_for_subresource_loader.InitWithNewPipeAndPassReceiver()); } + auto* version = context_wrapper_->GetLiveVersion(version_id_); + if (!version) { + std::move(callback).Run(); + return; + } + auto script_bundle = EmbeddedWorkerInstance::CreateFactoryBundle( rph, worker_route_id_, origin, client_security_state_.Clone(), std::move(coep_reporter_for_script_loader), @@ -363,9 +375,6 @@ ContentBrowserClient::URLLoaderFactoryType::kServiceWorkerSubResource, GetId()); - auto* version = context_wrapper_->GetLiveVersion(version_id_); - if (!version) - return; version->embedded_worker()->UpdateLoaderFactories( std::move(script_bundle), std::move(subresource_bundle));
diff --git a/content/browser/interest_group/auction_runner.h b/content/browser/interest_group/auction_runner.h index 564a10c..5c52841 100644 --- a/content/browser/interest_group/auction_runner.h +++ b/content/browser/interest_group/auction_runner.h
@@ -40,10 +40,10 @@ // appropriate. struct InterestGroupKey { InterestGroupKey(url::Origin o, std::string n) : owner(o), name(n) {} - constexpr bool operator<(const InterestGroupKey& other) const { + inline bool operator<(const InterestGroupKey& other) const { return owner != other.owner ? owner < other.owner : name < other.name; } - constexpr bool operator==(const InterestGroupKey& other) const { + inline bool operator==(const InterestGroupKey& other) const { return owner == other.owner && name == other.name; } url::Origin owner;
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc index 3eca3db..9285c94c 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -565,6 +565,32 @@ } #endif +void MediaStreamDispatcherHost::GetOpenDevice( + const base::UnguessableToken& session_id, + GetOpenDeviceCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + if (!base::FeatureList::IsEnabled(features::kMediaStreamTrackTransfer)) { + ReceivedBadMessage(render_process_id_, + bad_message::MSDH_GET_OPEN_DEVICE_USE_WITHOUT_FEATURE); + + std::move(callback).Run( + blink::mojom::MediaStreamRequestResult::NOT_SUPPORTED, nullptr); + return; + } + // TODO(https://crbug.com/1288839): Implement GetOpenDevice in + // MediaStreamManager and call that. + + // TODO(https://crbug.com/1288839): Decide whether we need to have another + // mojo method, called by the first renderer to say "I'm going to be + // transferring this track, allow the receiving renderer to call GetOpenDevice + // on it", and whether we can/need to specific the destination renderer/frame + // in this case. + + std::move(callback).Run(blink::mojom::MediaStreamRequestResult::NOT_SUPPORTED, + nullptr); +} + void MediaStreamDispatcherHost::ReceivedBadMessage( int render_process_id, bad_message::BadMessageReason reason) {
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.h b/content/browser/renderer_host/media/media_stream_dispatcher_host.h index 9407d43..e127fa8 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host.h +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.h
@@ -107,6 +107,8 @@ CropCallback callback, bool crop_id_passed_validation); #endif + void GetOpenDevice(const base::UnguessableToken& session_id, + GetOpenDeviceCallback callback) override; void DoGenerateStream( int32_t request_id,
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc index c4785b5..65e7433 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -469,6 +469,12 @@ return true; } + void GetOpenDevice( + const base::UnguessableToken& session_id, + MediaStreamDispatcherHost::GetOpenDeviceCallback callback) { + host_->GetOpenDevice(session_id, std::move(callback)); + } + base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<MockMediaStreamDispatcherHost> host_; std::unique_ptr<MediaStreamManager> media_stream_manager_; @@ -1070,4 +1076,22 @@ EXPECT_EQ(group_id2, host_->opened_device_.group_id); } +TEST_F(MediaStreamDispatcherHostTest, GetOpenDeviceWithoutFeatureFails) { + EXPECT_CALL( + *this, + MockOnBadMessage(kProcessId, + bad_message::MSDH_GET_OPEN_DEVICE_USE_WITHOUT_FEATURE)); + + base::RunLoop loop; + GetOpenDevice(base::UnguessableToken(), + base::BindOnce([](blink::mojom::MediaStreamRequestResult result, + blink::mojom::GetOpenDeviceResponsePtr ptr) { + EXPECT_EQ( + blink::mojom::MediaStreamRequestResult::NOT_SUPPORTED, + result); + EXPECT_FALSE(ptr); + }).Then(loop.QuitClosure())); + loop.Run(); +} + } // namespace content
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h index 0c76683..72a09dce490 100644 --- a/content/browser/renderer_host/media/media_stream_manager.h +++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -122,6 +122,10 @@ base::RepeatingCallback<void(const std::string& label, const blink::MediaStreamDevice& device)>; + using GetOpenDeviceCallback = base::OnceCallback<void( + blink::mojom::MediaStreamRequestResult result, + absl::optional<blink::mojom::GetOpenDeviceResponse> response)>; + // Callback for testing. using GenerateStreamTestCallback = base::OnceCallback<bool(const blink::StreamControls&)>;
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 0ca1820..61e4041 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -1523,8 +1523,6 @@ } RenderFrameHostImpl::~RenderFrameHostImpl() { - CHECK_EQ(check_if_deleted_request_count_, 0); - // The lifetime of this object has ended, so remove it from the id map before // calling any delegates/observers, so that any calls to |FromID| no longer // return |this|. @@ -13346,22 +13344,4 @@ return o << LifecycleStateImplToString(s); } -std::unique_ptr<RenderFrameHostImpl::CheckOnDeleteRef> -RenderFrameHostImpl::EnableCheckIfDeleted() { - // Uses WrapUnique() as constructor is private. - return base::WrapUnique(new CheckOnDeleteRef(this)); -} - -RenderFrameHostImpl::CheckOnDeleteRef::~CheckOnDeleteRef() { - --(host_->check_if_deleted_request_count_); - CHECK_GE(host_->check_if_deleted_request_count_, 0); -} - -RenderFrameHostImpl::CheckOnDeleteRef::CheckOnDeleteRef( - RenderFrameHostImpl* host) - : host_(host) { - ++(host_->check_if_deleted_request_count_); - CHECK_GT(host_->check_if_deleted_request_count_, 0); -} - } // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index e25974b..5b9eca4 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -2429,23 +2429,6 @@ void DidChangeReferrerPolicy(network::mojom::ReferrerPolicy referrer_policy); - class CheckOnDeleteRef { - public: - CheckOnDeleteRef(const CheckOnDeleteRef&) = delete; - CheckOnDeleteRef& operator=(const CheckOnDeleteRef&) = delete; - ~CheckOnDeleteRef(); - - private: - friend class RenderFrameHostImpl; - - explicit CheckOnDeleteRef(RenderFrameHostImpl* host); - - RenderFrameHostImpl* host_; - }; - - // TODO(https://crbug.com/1262098): used to track down crash. - std::unique_ptr<CheckOnDeleteRef> EnableCheckIfDeleted(); - // TODO: While FencedFrame shadow DOM implementation exists and is dependent // on the effective frame policy in BrowsingContextState, fenced frame status // is dependent on FrameTreeNode being initialized and associated with a @@ -4149,8 +4132,6 @@ BackForwardCacheDisablingFeaturesCallback back_forward_cache_disabling_features_callback_for_testing_; - int check_if_deleted_request_count_ = 0; - #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) // Manages the snapshot processing by Screen AI, if enabled. std::unique_ptr<AXScreenAIAnnotator> ax_screen_ai_annotator_;
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc index 07f5f81..a47eae3 100644 --- a/content/browser/renderer_host/render_frame_host_manager.cc +++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -3458,9 +3458,6 @@ } } - // TODO(https://crbug.com/1262098): used to track down crash. - auto check_on_delete_ref = render_frame_host_->EnableCheckIfDeleted(); - // For all main frames, the RenderWidgetHost will not be destroyed when the // local frame is detached. https://crbug.com/419087 // @@ -3506,9 +3503,7 @@ // also exist. For a local root frame, they share lifetimes exactly. For // another child frame, the RenderWidgetHostView comes from a parent, but if // this renderer frame is live its ancestors must be as well. - // TODO(https://crbug.com/1262098): used to track down crash, converted - // from DCHECK to CHECK. - CHECK(new_view); + DCHECK(new_view); if (focus_render_view) { if (is_main_frame) { @@ -3556,8 +3551,6 @@ delegate_->NotifySwappedFromRenderManager(old_render_frame_host.get(), render_frame_host_.get()); - check_on_delete_ref.reset(); - // Make the new view show the contents of old view until it has something // useful to show. if (is_main_frame && old_view && old_view != new_view)
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 5f006f5..e620fc4 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -2098,6 +2098,9 @@ if (!view_.parent() || !is_showing_) return; + if (gesture_listener_manager_) + gesture_listener_manager_->DidOverscroll(params); + if (overscroll_controller_) overscroll_controller_->OnOverscrolled(params); }
diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc index 6e5b85d..bf456ae4 100644 --- a/content/browser/storage_partition_impl_unittest.cc +++ b/content/browser/storage_partition_impl_unittest.cc
@@ -63,7 +63,6 @@ #include "content/public/test/test_utils.h" #include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom.h" #include "net/base/network_isolation_key.h" -#include "net/base/schemeful_site.h" #include "net/base/test_completion_callback.h" #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_access_result.h" @@ -2063,11 +2062,10 @@ .SetConversionOrigin(conv) .SetExpiry(base::Days(2)) .Build()); - attribution_manager->HandleTrigger( - TriggerBuilder() - .SetConversionDestination(net::SchemefulSite(conv)) - .SetReportingOrigin(reporter) - .Build()); + attribution_manager->HandleTrigger(TriggerBuilder() + .SetDestinationOrigin(conv) + .SetReportingOrigin(reporter) + .Build()); } EXPECT_EQ(5u, GetAttributionReportsForTesting(attribution_manager,
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 9082686..f2caa45 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -6622,9 +6622,6 @@ if (old_frame && !new_frame->GetParent()) { RenderWidgetHostImpl* old_widget = old_frame->GetRenderWidgetHost(); RenderWidgetHostImpl* new_widget = new_frame->GetRenderWidgetHost(); - // TODO(https://crbug.com/1262098): CHECKs are to help track down crash. - CHECK(new_widget); - CHECK(old_widget); new_widget->SetImportance(old_widget->importance()); } #endif @@ -7951,9 +7948,6 @@ DCHECK_NE(new_frame->lifecycle_state(), RenderFrameHostImpl::LifecycleStateImpl::kSpeculative); - // TODO(https://crbug.com/1262098): CHECKs are to help track down crash. - CHECK(new_frame); - // Only fire RenderViewHostChanged if it is related to our FrameTree, as // observers can not deal with events coming from non-primary FrameTree. // TODO(https://crbug.com/1168562): Update observers to deal with the events,
diff --git a/content/public/android/java/src/org/chromium/content/browser/GestureListenerManagerImpl.java b/content/public/android/java/src/org/chromium/content/browser/GestureListenerManagerImpl.java index e76f6b4b..f38707b 100644 --- a/content/public/android/java/src/org/chromium/content/browser/GestureListenerManagerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/GestureListenerManagerImpl.java
@@ -309,6 +309,14 @@ return false; } + @CalledByNative + private void didOverscroll(float accumulatedOverscrollX, float accumulatedOverscrollY) { + for (mIterator.rewind(); mIterator.hasNext();) { + GestureStateListener listener = mIterator.next(); + listener.didOverscroll(accumulatedOverscrollX, accumulatedOverscrollY); + } + } + @SuppressWarnings("unused") @CalledByNative private void updateScrollInfo(float scrollOffsetX, float scrollOffsetY, float pageScaleFactor,
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/GestureStateListener.java b/content/public/android/java/src/org/chromium/content_public/browser/GestureStateListener.java index 56a2c13c..96a3f732 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/GestureStateListener.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/GestureStateListener.java
@@ -81,6 +81,14 @@ public void onLongPress() {} /** + * Called on overscroll. This happens when user tries to scroll beyond scroll bounds, or when + * a fling animation hits scroll bounds. + * @param accumulatedOverscrollX see `ui::DidOverscrollParams::accumulated_overscroll`. + * @param accumulatedOverscrollY see `ui::DidOverscrollParams::accumulated_overscroll`. + */ + public void didOverscroll(float accumulatedOverscrollX, float accumulatedOverscrollY) {} + + /** * Called when the gesture source is being destroyed. */ public void onDestroyed() {}
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index f4aeda8..fe52508 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -543,6 +543,10 @@ const base::Feature kMediaLicenseBackend{"MediaLicenseBackend", base::FEATURE_DISABLED_BY_DEFAULT}; +// Allow cross-context transfer of MediaStreamTracks. +const base::Feature kMediaStreamTrackTransfer{ + "MediaStreamTrackTransfer", base::FEATURE_DISABLED_BY_DEFAULT}; + // If enabled Mojo uses a dedicated background thread to listen for incoming // IPCs. Otherwise it's configured to use Content's IO thread for that purpose. const base::Feature kMojoDedicatedThread{"MojoDedicatedThread",
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index a07338b..45f123b 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -140,6 +140,7 @@ CONTENT_EXPORT extern const base::FeatureParam<MBIMode> kMBIModeParam; CONTENT_EXPORT extern const base::Feature kMediaDevicesSystemMonitorCache; CONTENT_EXPORT extern const base::Feature kMediaLicenseBackend; +CONTENT_EXPORT extern const base::Feature kMediaStreamTrackTransfer; CONTENT_EXPORT extern const base::Feature kMojoDedicatedThread; CONTENT_EXPORT extern const base::Feature kMojoVideoCapture; CONTENT_EXPORT extern const base::Feature kMojoVideoCaptureSecondary;
diff --git a/content/test/attribution_simulator_input_parser.cc b/content/test/attribution_simulator_input_parser.cc index 40566c8..db66f58c 100644 --- a/content/test/attribution_simulator_input_parser.cc +++ b/content/test/attribution_simulator_input_parser.cc
@@ -21,11 +21,11 @@ #include "base/values.h" #include "content/browser/attribution_reporting/attribution_aggregatable_source.h" #include "content/browser/attribution_reporting/attribution_filter_data.h" +#include "content/browser/attribution_reporting/attribution_host_utils.h" #include "content/browser/attribution_reporting/attribution_source_type.h" #include "content/browser/attribution_reporting/attribution_trigger.h" #include "content/browser/attribution_reporting/common_source_info.h" #include "content/browser/attribution_reporting/storable_source.h" -#include "net/base/schemeful_site.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/abseil-cpp/absl/types/variant.h" #include "url/gurl.h" @@ -220,7 +220,7 @@ base::Time trigger_time = ParseTime(trigger, "trigger_time"); url::Origin reporting_origin = ParseOrigin(trigger, "reporting_origin"); - net::SchemefulSite destination(ParseOrigin(trigger, "destination")); + url::Origin destination_origin = ParseOrigin(trigger, "destination"); absl::optional<uint64_t> debug_key; AttributionFilterData filters; @@ -245,7 +245,7 @@ events_.emplace_back( AttributionTriggerAndTime{ .trigger = AttributionTrigger( - std::move(destination), std::move(reporting_origin), + std::move(destination_origin), std::move(reporting_origin), std::move(filters), debug_key, std::move(event_triggers)), .time = trigger_time, }, @@ -302,8 +302,8 @@ if (const std::string* v = dict.FindStringKey(key)) origin = url::Origin::Create(GURL(*v)); - if (origin.opaque()) - *Error() << "must be a valid origin"; + if (!attribution_host_utils::IsOriginTrustworthyForAttributions(origin)) + *Error() << "must be a valid, secure origin"; return origin; }
diff --git a/content/test/attribution_simulator_input_parser_unittest.cc b/content/test/attribution_simulator_input_parser_unittest.cc index c1a7c62..b110dfab 100644 --- a/content/test/attribution_simulator_input_parser_unittest.cc +++ b/content/test/attribution_simulator_input_parser_unittest.cc
@@ -16,7 +16,6 @@ #include "content/browser/attribution_reporting/attribution_test_utils.h" #include "content/browser/attribution_reporting/common_source_info.h" #include "content/browser/attribution_reporting/storable_source.h" -#include "net/base/schemeful_site.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -253,8 +252,8 @@ Pair( AttributionTriggerAndTime{ .trigger = AttributionTrigger( - /*conversion_destination=*/net::SchemefulSite( - url::Origin::Create(GURL("https://a.d1.test"))), + /*destination_origin=*/ + url::Origin::Create(GURL("https://a.d1.test")), /*reporting_origin=*/ url::Origin::Create(GURL("https://a.r.test")), *AttributionFilterData::FromTriggerFilterValues({ @@ -288,8 +287,8 @@ Pair( AttributionTriggerAndTime{ .trigger = AttributionTrigger( - /*conversion_destination=*/net::SchemefulSite( - url::Origin::Create(GURL("https://a.d2.test"))), + /*destination_origin=*/ + url::Origin::Create(GURL("https://a.d2.test")), /*reporting_origin=*/ url::Origin::Create(GURL("https://b.r.test")), AttributionFilterData(), @@ -379,7 +378,7 @@ }]})json", }, { - R"(["sources"][0]["reporting_origin"]: must be a valid origin)", + R"(["sources"][0]["reporting_origin"]: must be a valid, secure origin)", R"json({"sources": [{ "source_type": "navigation", "source_time": 1643235574, @@ -391,7 +390,20 @@ }]})json", }, { - R"(["sources"][0]["source_origin"]: must be a valid origin)", + R"(["sources"][0]["reporting_origin"]: must be a valid, secure origin)", + R"json({"sources": [{ + "source_type": "navigation", + "source_time": 1643235574, + "source_origin": "https://a.s.test", + "reporting_origin": "http://r.test", + "registration_config": { + "source_event_id": "123", + "destination": "https://a.d.test" + } + }]})json", + }, + { + R"(["sources"][0]["source_origin"]: must be a valid, secure origin)", R"json({"sources": [{ "source_type": "navigation", "source_time": 1643235574, @@ -434,7 +446,7 @@ }]})json", }, { - R"(["sources"][0]["registration_config"]["destination"]: must be a valid origin)", + R"(["sources"][0]["registration_config"]["destination"]: must be a valid, secure origin)", R"json({"sources": [{ "source_type": "navigation", "source_time": 1643235574, @@ -575,7 +587,7 @@ }]})json", }, { - R"(["triggers"][0]["destination"]: must be a valid origin)", + R"(["triggers"][0]["destination"]: must be a valid, secure origin)", R"json({"triggers": [{ "trigger_time": 1643235576, "reporting_origin": "https://a.r.test", @@ -583,7 +595,7 @@ }]})json", }, { - R"(["triggers"][0]["reporting_origin"]: must be a valid origin)", + R"(["triggers"][0]["reporting_origin"]: must be a valid, secure origin)", R"json({"triggers": [{ "trigger_time": 1643235576, "destination": " https://a.d1.test",
diff --git a/extensions/browser/api/messaging/message_service.cc b/extensions/browser/api/messaging/message_service.cc index 631024c8..33f084b6 100644 --- a/extensions/browser/api/messaging/message_service.cc +++ b/extensions/browser/api/messaging/message_service.cc
@@ -514,6 +514,7 @@ const PortId& source_port_id, int tab_id, int frame_id, + const std::string& document_id, const std::string& extension_id, const std::string& channel_name) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -545,9 +546,9 @@ const PortId receiver_port_id = source_port_id.GetOppositePortId(); std::unique_ptr<MessagePort> receiver = - messaging_delegate_->CreateReceiverForTab(weak_factory_.GetWeakPtr(), - extension_id, receiver_port_id, - receiver_contents, frame_id); + messaging_delegate_->CreateReceiverForTab( + weak_factory_.GetWeakPtr(), extension_id, receiver_port_id, + receiver_contents, frame_id, document_id); if (!receiver.get()) { opener_port->DispatchOnDisconnect(kReceivingEndDoesntExistError); return;
diff --git a/extensions/browser/api/messaging/message_service.h b/extensions/browser/api/messaging/message_service.h index dad94ba2..3f2001c1 100644 --- a/extensions/browser/api/messaging/message_service.h +++ b/extensions/browser/api/messaging/message_service.h
@@ -101,6 +101,7 @@ const PortId& source_port_id, int tab_id, int frame_id, + const std::string& document_id, const std::string& extension_id, const std::string& channel_name);
diff --git a/extensions/browser/api/messaging/messaging_api_message_filter.cc b/extensions/browser/api/messaging/messaging_api_message_filter.cc index 619c6d64..abd3f6b 100644 --- a/extensions/browser/api/messaging/messaging_api_message_filter.cc +++ b/extensions/browser/api/messaging/messaging_api_message_filter.cc
@@ -324,7 +324,7 @@ source_context); MessageService::Get(browser_context_) ->OpenChannelToTab(source_endpoint, port_id, info.tab_id, info.frame_id, - extension_id, channel_name); + info.document_id, extension_id, channel_name); } void MessagingAPIMessageFilter::OnOpenMessagePort(const PortContext& source,
diff --git a/extensions/browser/api/messaging/messaging_delegate.cc b/extensions/browser/api/messaging/messaging_delegate.cc index 9553d4363..5715531 100644 --- a/extensions/browser/api/messaging/messaging_delegate.cc +++ b/extensions/browser/api/messaging/messaging_delegate.cc
@@ -35,7 +35,8 @@ const std::string& extension_id, const PortId& receiver_port_id, content::WebContents* receiver_contents, - int receiver_frame_id) { + int receiver_frame_id, + const std::string& receiver_document_id) { NOTIMPLEMENTED(); return nullptr; }
diff --git a/extensions/browser/api/messaging/messaging_delegate.h b/extensions/browser/api/messaging/messaging_delegate.h index 538a8ba9..351a70a 100644 --- a/extensions/browser/api/messaging/messaging_delegate.h +++ b/extensions/browser/api/messaging/messaging_delegate.h
@@ -63,7 +63,8 @@ const std::string& extension_id, const PortId& receiver_port_id, content::WebContents* receiver_contents, - int receiver_frame_id); + int receiver_frame_id, + const std::string& receiver_document_id); // Creates a MessagePort for a native app. If the port cannot be created, // returns nullptr and may populate |error_out|.
diff --git a/extensions/common/extension_messages.h b/extensions/common/extension_messages.h index 3767ea7e..73683a9b 100644 --- a/extensions/common/extension_messages.h +++ b/extensions/common/extension_messages.h
@@ -159,6 +159,9 @@ // Frame ID of the destination. -1 for all frames, 0 for main frame and // positive if the destination is a specific child frame. IPC_STRUCT_MEMBER(int, frame_id) + + // The unique ID of the document of the target frame. + IPC_STRUCT_MEMBER(std::string, document_id) IPC_STRUCT_END() IPC_STRUCT_TRAITS_BEGIN(extensions::MessagingEndpoint)
diff --git a/extensions/renderer/ipc_message_sender.cc b/extensions/renderer/ipc_message_sender.cc index 5e25676..5d2ac72 100644 --- a/extensions/renderer/ipc_message_sender.cc +++ b/extensions/renderer/ipc_message_sender.cc
@@ -169,6 +169,8 @@ ExtensionMsg_TabTargetConnectionInfo info; info.tab_id = *target.tab_id; info.frame_id = *target.frame_id; + if (target.document_id) + info.document_id = *target.document_id; render_frame->Send(new ExtensionHostMsg_OpenChannelToTab( frame_context, info, extension->id(), channel_name, port_id)); break;
diff --git a/extensions/renderer/message_target.cc b/extensions/renderer/message_target.cc index 892d161..18505808 100644 --- a/extensions/renderer/message_target.cc +++ b/extensions/renderer/message_target.cc
@@ -13,6 +13,17 @@ return target; } +MessageTarget MessageTarget::ForTab(int tab_id, + int frame_id, + const std::string& document_id) { + MessageTarget target(TAB); + target.tab_id = tab_id; + target.frame_id = frame_id; + if (!document_id.empty()) + target.document_id = document_id; + return target; +} + MessageTarget MessageTarget::ForExtension(const ExtensionId& extension_id) { MessageTarget target(EXTENSION); target.extension_id = extension_id;
diff --git a/extensions/renderer/message_target.h b/extensions/renderer/message_target.h index 1cafd6ca..170d511 100644 --- a/extensions/renderer/message_target.h +++ b/extensions/renderer/message_target.h
@@ -32,6 +32,9 @@ }; static MessageTarget ForTab(int tab_id, int frame_id); + static MessageTarget ForTab(int tab_id, + int frame_id, + const std::string& document_id); static MessageTarget ForExtension(const ExtensionId& extension_id); static MessageTarget ForNativeApp(const std::string& native_app_name); @@ -47,6 +50,7 @@ // Only valid for Type::TAB. absl::optional<int> tab_id; absl::optional<int> frame_id; + absl::optional<std::string> document_id; bool operator==(const MessageTarget& other) const;
diff --git a/extensions/renderer/messaging_util.cc b/extensions/renderer/messaging_util.cc index d85957d..0a5edbe 100644 --- a/extensions/renderer/messaging_util.cc +++ b/extensions/renderer/messaging_util.cc
@@ -219,6 +219,15 @@ // backwards compatibility, we do the same here. options.frame_id = frame_id < 0 ? -1 : frame_id; } + + v8::Local<v8::Value> v8_document_id; + success = options_dict.Get("documentId", &v8_document_id); + DCHECK(success); + + if (!v8_document_id->IsUndefined()) { + DCHECK(v8_document_id->IsString()); + options.document_id = gin::V8ToString(isolate, v8_document_id); + } } // Note: the options object may also include an includeTlsChannelId property.
diff --git a/extensions/renderer/messaging_util.h b/extensions/renderer/messaging_util.h index 007b3a8..60ef81c 100644 --- a/extensions/renderer/messaging_util.h +++ b/extensions/renderer/messaging_util.h
@@ -69,6 +69,7 @@ struct MessageOptions { std::string channel_name; int frame_id = kNoFrameId; + std::string document_id; }; // Parses and returns the options parameter for sendMessage or connect.
diff --git a/gpu/ipc/service/gpu_watchdog_thread.cc b/gpu/ipc/service/gpu_watchdog_thread.cc index 155f7c05..8d701a6 100644 --- a/gpu/ipc/service/gpu_watchdog_thread.cc +++ b/gpu/ipc/service/gpu_watchdog_thread.cc
@@ -622,8 +622,6 @@ base::debug::Alias(&less_than_full_thread_time_after_capped_); #endif - GpuWatchdogHistogram(GpuWatchdogThreadEvent::kGpuWatchdogKill); - crash_keys::gpu_watchdog_crashed_in_gpu_init.Set( in_gpu_initialization_ ? "1" : "0"); @@ -645,12 +643,18 @@ // Create a crash dump first base::debug::DumpWithoutCrashing(); + // A kKill event is triggered and DumpWithoutCrashing() is called in the + // watchdog timeout routine OnWatchdogTimeout(). If it turns out + // gpu does not hang after the crash dump, another histogram + // kNoKillForGpuProgressDuringCrashDumping will be recorded later. + GpuWatchdogTimeoutHistogram(GpuWatchdogTimeoutEvent::kKill); + // Final check after the crash dump. If the watched thread makes a progress // (disarmed) during generating crash dump, no need to crash the GPU process. bool gpu_hang = IsArmed(); if (gpu_hang) { - // Still armed without any progress. GPU possibly hangs. - GpuWatchdogTimeoutHistogram(GpuWatchdogTimeoutEvent::kKill); + // Still armed without any progress. The GPU process is now killed. + GpuWatchdogHistogram(GpuWatchdogThreadEvent::kGpuWatchdogKill); #if BUILDFLAG(IS_WIN) if (less_than_full_thread_time_after_capped_) GpuWatchdogTimeoutHistogram(
diff --git a/gpu/ipc/service/gpu_watchdog_thread_unittest.cc b/gpu/ipc/service/gpu_watchdog_thread_unittest.cc index 9a1f7b9..fc1e946 100644 --- a/gpu/ipc/service/gpu_watchdog_thread_unittest.cc +++ b/gpu/ipc/service/gpu_watchdog_thread_unittest.cc
@@ -40,6 +40,13 @@ [[maybe_unused]] constexpr auto kExtraGPUJobTimeForTestingSlow = base::Milliseconds(1000); +// For Fuchsia in which GpuWatchdogTest.GpuInitializationAndRunningTasks test +// is flaky. +[[maybe_unused]] constexpr auto kGpuWatchdogTimeoutForTestingSlowest = + base::Milliseconds(1000); +[[maybe_unused]] constexpr auto kExtraGPUJobTimeForTestingSlowest = + base::Milliseconds(4000); + // On Windows, the gpu watchdog check if the main thread has used the full // thread time. We want to detect the case in which the main thread is swapped // out by the OS scheduler. The task on windows is simiulated by reading @@ -105,12 +112,19 @@ void GpuWatchdogTest::SetUp() { ASSERT_TRUE(base::ThreadTaskRunnerHandle::IsSet()); ASSERT_TRUE(base::CurrentThread::IsSet()); - bool use_slow_timeout = false; + + enum TimeOutType { + kNormal, + kSlow, + kSlowest, + }; + + TimeOutType timeout_type = kNormal; #if BUILDFLAG(IS_WIN) // Win7 if (base::win::GetVersion() < base::win::Version::WIN10) { - use_slow_timeout = true; + timeout_type = kSlow; } #elif BUILDFLAG(IS_MAC) @@ -119,8 +133,10 @@ int os_version = base::mac::internal::MacOSVersion(); if (os_version <= 1100) { - use_slow_timeout = true; + // Check MacOS version. + timeout_type = kSlow; } else { + // Check Mac machine model version. std::string model_str = base::SysInfo::HardwareModelName(); size_t found_position = model_str.find("MacBookPro"); constexpr size_t model_version_pos = 10; @@ -132,7 +148,7 @@ int major_model_ver = std::atoi(model_ver_str.c_str()); // For version < 14,1 if (major_model_ver < 14) { - use_slow_timeout = true; + timeout_type = kSlow; } } } @@ -146,16 +162,19 @@ // For Android version < Android Pie (Version 9) if (major_version < 9) { - use_slow_timeout = true; + timeout_type = kSlow; } #elif BUILDFLAG(IS_FUCHSIA) - use_slow_timeout = true; + timeout_type = kSlowest; #endif - if (use_slow_timeout) { + if (timeout_type == kSlow) { timeout_ = kGpuWatchdogTimeoutForTestingSlow; extra_gpu_job_time_ = kExtraGPUJobTimeForTestingSlow; + } else if (timeout_type == kSlowest) { + timeout_ = kGpuWatchdogTimeoutForTestingSlowest; + extra_gpu_job_time_ = kExtraGPUJobTimeForTestingSlowest; } #if BUILDFLAG(IS_WIN)
diff --git a/infra/config/generated/builders/ci/android-rust-arm-dbg/properties.json b/infra/config/generated/builders/ci/android-rust-arm-dbg/properties.json new file mode 100644 index 0000000..1e3e28e --- /dev/null +++ b/infra/config/generated/builders/ci/android-rust-arm-dbg/properties.json
@@ -0,0 +1,16 @@ +{ + "$build/reclient": { + "instance": "rbe-chromium-trusted", + "jobs": 250, + "metrics_project": "chromium-reclient-metrics" + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "chromium.rust", + "recipe": "chromium" +} \ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-code-coverage/properties.json b/infra/config/generated/builders/ci/linux-code-coverage/properties.json index 573155d..0c3959d 100644 --- a/infra/config/generated/builders/ci/linux-code-coverage/properties.json +++ b/infra/config/generated/builders/ci/linux-code-coverage/properties.json
@@ -4,6 +4,7 @@ "overall", "unit" ], + "export_coverage_to_zoss": true, "use_clang_coverage": true }, "$build/goma": {
diff --git a/infra/config/generated/builders/ci/linux-rust-x64-dbg/properties.json b/infra/config/generated/builders/ci/linux-rust-x64-dbg/properties.json new file mode 100644 index 0000000..486923e --- /dev/null +++ b/infra/config/generated/builders/ci/linux-rust-x64-dbg/properties.json
@@ -0,0 +1,17 @@ +{ + "$build/goma": { + "enable_ats": true, + "rpc_extra_params": "?prod", + "server_host": "goma.chromium.org", + "use_luci_auth": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "chromium.rust", + "recipe": "chromium" +} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/android-rust-arm-dbg/properties.json b/infra/config/generated/builders/try/android-rust-arm-dbg/properties.json new file mode 100644 index 0000000..318a8a3 --- /dev/null +++ b/infra/config/generated/builders/try/android-rust-arm-dbg/properties.json
@@ -0,0 +1,17 @@ +{ + "$build/goma": { + "enable_ats": true, + "rpc_extra_params": "?prod", + "server_host": "goma.chromium.org", + "use_luci_auth": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "tryserver.chromium.rust", + "recipe": "chromium_trybot" +} \ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-rust-x64-dbg/properties.json b/infra/config/generated/builders/try/linux-rust-x64-dbg/properties.json new file mode 100644 index 0000000..318a8a3 --- /dev/null +++ b/infra/config/generated/builders/try/linux-rust-x64-dbg/properties.json
@@ -0,0 +1,17 @@ +{ + "$build/goma": { + "enable_ats": true, + "rpc_extra_params": "?prod", + "server_host": "goma.chromium.org", + "use_luci_auth": true + }, + "$recipe_engine/resultdb/test_presentation": { + "column_keys": [], + "grouping_keys": [ + "status", + "v.test_suite" + ] + }, + "builder_group": "tryserver.chromium.rust", + "recipe": "chromium_trybot" +} \ No newline at end of file
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md index bd17777..d855b59c 100644 --- a/infra/config/generated/cq-builders.md +++ b/infra/config/generated/cq-builders.md
@@ -91,6 +91,17 @@ Path regular expressions: * [`//.+/3pp/.+`](https://cs.chromium.org/search?q=+file:.+/3pp/) +* [android-cronet-arm-dbg](https://ci.chromium.org/p/chromium/builders/try/android-cronet-arm-dbg) ([definition](https://cs.chromium.org/search?q=+file:/try.star$+""android-cronet-arm-dbg"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""android-cronet-arm-dbg"")) + + Path regular expressions: + * [`//components/cronet/.+`](https://cs.chromium.org/chromium/src/components/cronet/) + * [`//components/grpc_support/.+`](https://cs.chromium.org/chromium/src/components/grpc_support/) + * [`//build/android/.+`](https://cs.chromium.org/chromium/src/build/android/) + * [`//build/config/android/.+`](https://cs.chromium.org/chromium/src/build/config/android/) + + Path exclude regular expressions: + * [`//components/cronet/ios/.+`](https://cs.chromium.org/chromium/src/components/cronet/ios/) + * [android-cronet-x86-dbg-10-tests](https://ci.chromium.org/p/chromium/builders/try/android-cronet-x86-dbg-10-tests) ([definition](https://cs.chromium.org/search?q=+file:/try.star$+""android-cronet-x86-dbg-10-tests"")) ([matching builders](https://cs.chromium.org/search?q=+file:trybots.py+""android-cronet-x86-dbg-10-tests"")) Path regular expressions:
diff --git a/infra/config/generated/cq-usage/full.cfg b/infra/config/generated/cq-usage/full.cfg index f4a112e..d6f97ee 100644 --- a/infra/config/generated/cq-usage/full.cfg +++ b/infra/config/generated/cq-usage/full.cfg
@@ -28,6 +28,16 @@ location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { + name: "chromium/try/android-cronet-arm-dbg" + location_regexp: ".+/[+]/components/cronet/.+" + location_regexp: ".+/[+]/components/grpc_support/.+" + location_regexp: ".+/[+]/build/android/.+" + location_regexp: ".+/[+]/build/config/android/.+" + location_regexp_exclude: ".+/[+]/docs/.+" + location_regexp_exclude: ".+/[+]/infra/config/.+" + location_regexp_exclude: ".+/[+]/components/cronet/ios/.+" + } + builders { name: "chromium/try/android-cronet-x86-dbg-10-tests" location_regexp: ".+/[+]/components/cronet/.+" location_regexp: ".+/[+]/components/grpc_support/.+"
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index 6b8414b2..8cbe074 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -327,7 +327,13 @@ } builders { name: "chromium/try/android-cronet-arm-dbg" - includable_only: true + location_regexp: ".+/[+]/components/cronet/.+" + location_regexp: ".+/[+]/components/grpc_support/.+" + location_regexp: ".+/[+]/build/android/.+" + location_regexp: ".+/[+]/build/config/android/.+" + location_regexp_exclude: ".+/[+]/docs/.+" + location_regexp_exclude: ".+/[+]/infra/config/.+" + location_regexp_exclude: ".+/[+]/components/cronet/ios/.+" } builders { name: "chromium/try/android-cronet-arm64-dbg" @@ -476,6 +482,10 @@ includable_only: true } builders { + name: "chromium/try/android-rust-arm-dbg" + includable_only: true + } + builders { name: "chromium/try/android-rust-arm-rel" includable_only: true } @@ -1395,6 +1405,10 @@ includable_only: true } builders { + name: "chromium/try/linux-rust-x64-dbg" + includable_only: true + } + builders { name: "chromium/try/linux-rust-x64-rel" includable_only: true }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 6e2a4aa..c969134 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -26952,6 +26952,84 @@ } } builders { + name: "android-rust-arm-dbg" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:android-rust-arm-dbg" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.ci" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/ci/android-rust-arm-dbg/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "chromium.rust",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium"' + '}' + execution_timeout_secs: 10800 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "android-rust-arm-rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "builder:android-rust-arm-rel" @@ -35912,6 +35990,84 @@ } } builders { + name: "linux-rust-x64-dbg" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:linux-rust-x64-dbg" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.ci" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/ci/linux-rust-x64-dbg/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "chromium.rust",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium"' + '}' + execution_timeout_secs: 10800 + build_numbers: YES + service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "ci_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_ci_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { name: "linux-rust-x64-rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "builder:linux-rust-x64-rel" @@ -51825,14 +51981,102 @@ } } builders { - name: "android-rust-arm-rel" + name: "android-rust-arm-dbg" swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" + dimensions: "builder:android-rust-arm-dbg" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" + dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/android-rust-arm-dbg/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "tryserver.chromium.rust",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { + name: "android-rust-arm-rel" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:android-rust-arm-rel" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.try" exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest" @@ -68125,12 +68369,11 @@ builders { name: "linux-rust-intree-x64-rel" swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" + dimensions: "builder:linux-rust-intree-x64-rel" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" + dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest" @@ -68213,14 +68456,102 @@ } } builders { - name: "linux-rust-x64-rel" + name: "linux-rust-x64-dbg" swarming_host: "chromium-swarm.appspot.com" - dimensions: "builderless:1" + dimensions: "builder:linux-rust-x64-dbg" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" + dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" + exe { + cipd_package: "infra/chromium/bootstrapper/${platform}" + cipd_version: "latest" + cmd: "bootstrapper" + } + properties: + '{' + ' "$bootstrap/exe": {' + ' "exe": {' + ' "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",' + ' "cipd_version": "refs/heads/main",' + ' "cmd": [' + ' "luciexe"' + ' ]' + ' }' + ' },' + ' "$bootstrap/properties": {' + ' "properties_file": "infra/config/generated/builders/try/linux-rust-x64-dbg/properties.json",' + ' "top_level_project": {' + ' "ref": "refs/heads/main",' + ' "repo": {' + ' "host": "chromium.googlesource.com",' + ' "project": "chromium/src"' + ' }' + ' }' + ' },' + ' "builder_group": "tryserver.chromium.rust",' + ' "led_builder_is_bootstrapped": true,' + ' "recipe": "chromium_trybot"' + '}' + execution_timeout_secs: 14400 + expiration_secs: 7200 + grace_period { + seconds: 120 + } + caches { + name: "win_toolchain" + path: "win_toolchain" + } + build_numbers: YES + service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" + task_template_canary_percentage { + value: 5 + } + experiments { + key: "luci.recipes.use_python3" + value: 100 + } + resultdb { + enable: true + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "try_test_results" + test_results {} + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "gpu_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+" + } + } + } + bq_exports { + project: "chrome-luci-data" + dataset: "chromium" + table: "blink_web_tests_try_test_results" + test_results { + predicate { + test_id_regexp: "ninja://[^/]*blink_web_tests/.+" + } + } + } + history_options { + use_invocation_timestamp: true + } + } + } + builders { + name: "linux-rust-x64-rel" + swarming_host: "chromium-swarm.appspot.com" + dimensions: "builder:linux-rust-x64-rel" + dimensions: "cores:8" + dimensions: "cpu:x86-64" + dimensions: "os:Ubuntu-18.04" + dimensions: "pool:luci.chromium.try" exe { cipd_package: "infra/chromium/bootstrapper/${platform}" cipd_version: "latest"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index c9d1bf67..ac8918a 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -2463,6 +2463,9 @@ name: "buildbucket/luci.chromium.try/android-binary-size" } builders { + name: "buildbucket/luci.chromium.try/android-cronet-arm-dbg" + } + builders { name: "buildbucket/luci.chromium.try/android-cronet-x86-dbg-10-tests" } builders { @@ -11226,14 +11229,24 @@ refs: "regexp:refs/heads/main" manifest_name: "REVISION" builders { - name: "buildbucket/luci.chromium.ci/linux-rust-x64-rel" - category: "linux|rel" - short_name: "64" + name: "buildbucket/luci.chromium.ci/android-rust-arm-dbg" + category: "Android" + short_name: "dbg" } builders { name: "buildbucket/luci.chromium.ci/android-rust-arm-rel" - category: "android|rel" - short_name: "32" + category: "Android" + short_name: "rel" + } + builders { + name: "buildbucket/luci.chromium.ci/linux-rust-x64-dbg" + category: "Linux" + short_name: "dbg" + } + builders { + name: "buildbucket/luci.chromium.ci/linux-rust-x64-rel" + category: "Linux" + short_name: "rel" } header { oncalls { @@ -14653,6 +14666,9 @@ name: "buildbucket/luci.chromium.try/android-pie-x86-rel" } builders { + name: "buildbucket/luci.chromium.try/android-rust-arm-dbg" + } + builders { name: "buildbucket/luci.chromium.try/android-rust-arm-rel" } builders { @@ -15208,6 +15224,9 @@ name: "buildbucket/luci.chromium.try/linux-rust-intree-x64-rel" } builders { + name: "buildbucket/luci.chromium.try/linux-rust-x64-dbg" + } + builders { name: "buildbucket/luci.chromium.try/linux-rust-x64-rel" } builders { @@ -16527,12 +16546,18 @@ id: "tryserver.chromium.rust" name: "tryserver.chromium.rust" builders { + name: "buildbucket/luci.chromium.try/android-rust-arm-dbg" + } + builders { name: "buildbucket/luci.chromium.try/android-rust-arm-rel" } builders { name: "buildbucket/luci.chromium.try/linux-rust-intree-x64-rel" } builders { + name: "buildbucket/luci.chromium.try/linux-rust-x64-dbg" + } + builders { name: "buildbucket/luci.chromium.try/linux-rust-x64-rel" } builder_view_only: true
diff --git a/infra/config/generated/luci/luci-notify.cfg b/infra/config/generated/luci/luci-notify.cfg index 9891b85..0d47986 100644 --- a/infra/config/generated/luci/luci-notify.cfg +++ b/infra/config/generated/luci/luci-notify.cfg
@@ -2558,7 +2558,20 @@ notifications { on_change: true email { - recipients: "chrome-memory-safety+bots@google.com" + recipients: "chrome-rust-experiments+bots@google.com" + } + } + builders { + bucket: "ci" + name: "android-rust-arm-dbg" + repository: "https://chromium.googlesource.com/chromium/src" + } +} +notifiers { + notifications { + on_change: true + email { + recipients: "chrome-rust-experiments+bots@google.com" } } builders { @@ -3441,7 +3454,20 @@ notifications { on_change: true email { - recipients: "chrome-memory-safety+bots@google.com" + recipients: "chrome-rust-experiments+bots@google.com" + } + } + builders { + bucket: "ci" + name: "linux-rust-x64-dbg" + repository: "https://chromium.googlesource.com/chromium/src" + } +} +notifiers { + notifications { + on_change: true + email { + recipients: "chrome-rust-experiments+bots@google.com" } } builders {
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg index 83fe9b0..9b0cf6007 100644 --- a/infra/config/generated/luci/luci-scheduler.cfg +++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -4652,6 +4652,16 @@ } } job { + id: "android-rust-arm-dbg" + realm: "ci" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "ci" + builder: "android-rust-arm-dbg" + } +} +job { id: "android-rust-arm-rel" realm: "ci" acl_sets: "ci" @@ -5929,6 +5939,16 @@ } } job { + id: "linux-rust-x64-dbg" + realm: "ci" + acl_sets: "ci" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "ci" + builder: "linux-rust-x64-dbg" + } +} +job { id: "linux-rust-x64-rel" realm: "ci" acl_sets: "ci" @@ -7362,6 +7382,7 @@ triggers: "android-pie-arm64-rel" triggers: "android-pie-arm64-wpt-rel-non-cq" triggers: "android-pie-x86-rel" + triggers: "android-rust-arm-dbg" triggers: "android-rust-arm-rel" triggers: "android-weblayer-pie-x86-wpt-fyi-rel" triggers: "android-weblayer-pie-x86-wpt-smoketest" @@ -7448,6 +7469,7 @@ triggers: "linux-lacros-version-skew-fyi" triggers: "linux-official" triggers: "linux-perfetto-rel" + triggers: "linux-rust-x64-dbg" triggers: "linux-rust-x64-rel" triggers: "linux-swangle-chromium-x64" triggers: "linux-swangle-tot-angle-x64"
diff --git a/infra/config/lib/args.star b/infra/config/lib/args.star index 11fbd40f..2f3bbb42a 100644 --- a/infra/config/lib/args.star +++ b/infra/config/lib/args.star
@@ -145,6 +145,9 @@ wrap_in_ignore_default = False l = [] for a in args: + should_ignore_default, a = _should_ignore_default(a) + if should_ignore_default: + wrap_in_ignore_default = True if type(a) != type([]): a = [a] for e in a:
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star index 14bc1c8..2465c36b 100644 --- a/infra/config/lib/builders.star +++ b/infra/config/lib/builders.star
@@ -244,7 +244,8 @@ use_java_coverage, use_javascript_coverage, coverage_exclude_sources, - coverage_test_types): + coverage_test_types, + export_coverage_to_zoss): code_coverage = {} use_clang_coverage = defaults.get_value( @@ -276,6 +277,13 @@ if coverage_test_types: code_coverage["coverage_test_types"] = coverage_test_types + export_coverage_to_zoss = defaults.get_value( + "export_coverage_to_zoss", + export_coverage_to_zoss, + ) + if export_coverage_to_zoss: + code_coverage["export_coverage_to_zoss"] = export_coverage_to_zoss + return code_coverage or None def _reclient_property(*, instance, service, jobs, rewrapper_env, profiler_service, publish_trace, cache_silo, ensure_verified): @@ -341,6 +349,7 @@ use_javascript_coverage = False, coverage_exclude_sources = None, coverage_test_types = None, + export_coverage_to_zoss = False, resultdb_bigquery_exports = [], resultdb_index_by_timestamp = False, reclient_instance = None, @@ -397,6 +406,7 @@ use_javascript_coverage = args.DEFAULT, coverage_exclude_sources = args.DEFAULT, coverage_test_types = args.DEFAULT, + export_coverage_to_zoss = args.DEFAULT, resultdb_bigquery_exports = args.DEFAULT, resultdb_index_by_timestamp = args.DEFAULT, reclient_instance = args.DEFAULT, @@ -543,6 +553,10 @@ coverage_test_types: a list of string as test types to process data for in code_coverage recipe module. Will be copied to '$build/code_coverage' property. By default, considered None. + export_coverage_to_zoss: a boolean indicating if the raw coverage data + be exported zoss(and eventually in code search) in code_coverage + recipe module. Will be copied to '$build/code_coverage' property + if set. Be default, considered False. resultdb_bigquery_exports: a list of resultdb.export_test_results(...) specifying parameters for exporting test results to BigQuery. By default, do not export. @@ -699,6 +713,7 @@ use_javascript_coverage = use_javascript_coverage, coverage_exclude_sources = coverage_exclude_sources, coverage_test_types = coverage_test_types, + export_coverage_to_zoss = export_coverage_to_zoss, ) if code_coverage != None: properties["$build/code_coverage"] = code_coverage
diff --git a/infra/config/notifiers.star b/infra/config/notifiers.star index c34b30d..a602bce 100644 --- a/infra/config/notifiers.star +++ b/infra/config/notifiers.star
@@ -29,6 +29,14 @@ ) luci.notifier( + name = "chrome-rust-experiments", + on_status_change = True, + notify_emails = [ + "chrome-rust-experiments+bots@google.com", + ], +) + +luci.notifier( name = "chrome-memory-sheriffs", on_status_change = True, notify_emails = [
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star index 6e79aee466..177d4e79 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -1394,6 +1394,7 @@ os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, use_clang_coverage = True, coverage_test_types = ["overall", "unit"], + export_coverage_to_zoss = True, triggered_by = [], )
diff --git a/infra/config/subprojects/chromium/ci/chromium.rust.star b/infra/config/subprojects/chromium/ci/chromium.rust.star index 89c651d6..c36cc0a 100644 --- a/infra/config/subprojects/chromium/ci/chromium.rust.star +++ b/infra/config/subprojects/chromium/ci/chromium.rust.star
@@ -9,45 +9,55 @@ ci.defaults.set( builder_group = "chromium.rust", + builderless = False, cores = 8, executable = ci.DEFAULT_EXECUTABLE, execution_timeout = ci.DEFAULT_EXECUTION_TIMEOUT, goma_backend = goma.backend.RBE_PROD, pool = ci.DEFAULT_POOL, service_account = ci.DEFAULT_SERVICE_ACCOUNT, + os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, + notifies = ["chrome-rust-experiments"], ) consoles.console_view( name = "chromium.rust", - ordering = { - None: [ - "linux", - "android", - ], - }, ) ci.builder( - name = "android-rust-arm-rel", - builderless = False, + name = "android-rust-arm-dbg", console_view_entry = consoles.console_view_entry( - category = "android|rel", - short_name = "32", + category = "Android", + short_name = "dbg", ), - notifies = ["chrome-memory-safety"], - os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, goma_backend = None, reclient_jobs = rbe_jobs.DEFAULT, reclient_instance = rbe_instance.DEFAULT, ) ci.builder( - name = "linux-rust-x64-rel", - builderless = False, + name = "android-rust-arm-rel", console_view_entry = consoles.console_view_entry( - category = "linux|rel", - short_name = "64", + category = "Android", + short_name = "rel", ), - notifies = ["chrome-memory-safety"], - os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, + goma_backend = None, + reclient_jobs = rbe_jobs.DEFAULT, + reclient_instance = rbe_instance.DEFAULT, +) + +ci.builder( + name = "linux-rust-x64-dbg", + console_view_entry = consoles.console_view_entry( + category = "Linux", + short_name = "dbg", + ), +) + +ci.builder( + name = "linux-rust-x64-rel", + console_view_entry = consoles.console_view_entry( + category = "Linux", + short_name = "rel", + ), )
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star index 5a83cc8b..829395c 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -121,6 +121,19 @@ try_.builder( name = "android-cronet-arm-dbg", + branch_selector = branches.STANDARD_MILESTONE, + main_list_view = "try", + tryjob = try_.job( + location_regexp = [ + ".+/[+]/components/cronet/.+", + ".+/[+]/components/grpc_support/.+", + ".+/[+]/build/android/.+", + ".+/[+]/build/config/android/.+", + ], + location_regexp_exclude = [ + ".+/[+]/components/cronet/ios/.+", + ], + ), ) try_.builder(
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.rust.star b/infra/config/subprojects/chromium/try/tryserver.chromium.rust.star index 6c1afc0..06159fb 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.rust.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.rust.star
@@ -9,11 +9,12 @@ try_.defaults.set( builder_group = "tryserver.chromium.rust", + builderless = False, cores = 8, executable = try_.DEFAULT_EXECUTABLE, execution_timeout = try_.DEFAULT_EXECUTION_TIMEOUT, goma_backend = goma.backend.RBE_PROD, - os = os.LINUX_DEFAULT, + os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, pool = try_.DEFAULT_POOL, service_account = try_.DEFAULT_SERVICE_ACCOUNT, ) @@ -23,13 +24,21 @@ ) try_.builder( - name = "linux-rust-x64-rel", -) - -try_.builder( - name = "linux-rust-intree-x64-rel", + name = "android-rust-arm-dbg", ) try_.builder( name = "android-rust-arm-rel", ) + +try_.builder( + name = "linux-rust-x64-rel", +) + +try_.builder( + name = "linux-rust-x64-dbg", +) + +try_.builder( + name = "linux-rust-intree-x64-rel", +)
diff --git a/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.mm b/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.mm index 2fc260a..4fd944a 100644 --- a/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.mm +++ b/ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.mm
@@ -21,8 +21,7 @@ bool is_high_priority) : infobar_(infobar->GetWeakPtr()), infobar_type_(infobar->infobar_type()), - has_badge_(BadgeTypeForInfobarType(infobar_type_) != - BadgeType::kBadgeTypeNone), + has_badge_(BadgeTypeForInfobarType(infobar_type_) != kBadgeTypeNone), is_high_priority_(is_high_priority), overlay_type_(overlay_type) {}
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm index 62d585d..483e1c4a 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
@@ -549,6 +549,11 @@ // Tests password generation on manual fallback. - (void)testPasswordGenerationOnManualFallback { + // Disable the test on iOS 15.3 due to build failure. + // TODO(crbug.com/1306530): enable the test with fix. + if (@available(iOS 15.3, *)) { + EARL_GREY_TEST_DISABLED(@"Test disabled on iOS 15.3."); + } [SigninEarlGreyUI signinWithFakeIdentity:[FakeChromeIdentity fakeIdentity1]]; [ChromeEarlGrey waitForSyncInitialized:YES syncTimeout:10.0];
diff --git a/ios/chrome/browser/ui/badges/BUILD.gn b/ios/chrome/browser/ui/badges/BUILD.gn index 3b66f6a8..44fbc679 100644 --- a/ios/chrome/browser/ui/badges/BUILD.gn +++ b/ios/chrome/browser/ui/badges/BUILD.gn
@@ -18,8 +18,8 @@ source_set("util") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ - "badge_type_util.cc", "badge_type_util.h", + "badge_type_util.mm", ] deps = [ ":public", @@ -54,7 +54,7 @@ "resources:wrench_badge", "//base", "//components/password_manager/core/common", - "//ios/chrome/app/strings:ios_strings_grit", + "//ios/chrome/app/strings", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/infobars", @@ -103,6 +103,7 @@ ":public", "//base", "//components/password_manager/core/common", + "//components/strings:components_strings_grit", "//ios/chrome/app/strings:ios_strings_grit", "//ios/chrome/browser/infobars", "//ios/chrome/browser/infobars:public",
diff --git a/ios/chrome/browser/ui/badges/OWNERS b/ios/chrome/browser/ui/badges/OWNERS index 9cf8c07297..8d0b1e93 100644 --- a/ios/chrome/browser/ui/badges/OWNERS +++ b/ios/chrome/browser/ui/badges/OWNERS
@@ -1,2 +1,3 @@ +ginnyhuang@chromium.org thegreenfrog@chromium.org sczs@chromium.org
diff --git a/ios/chrome/browser/ui/badges/badge_button_factory.mm b/ios/chrome/browser/ui/badges/badge_button_factory.mm index 96991fb..b80492f 100644 --- a/ios/chrome/browser/ui/badges/badge_button_factory.mm +++ b/ios/chrome/browser/ui/badges/badge_button_factory.mm
@@ -27,27 +27,27 @@ - (BadgeButton*)badgeButtonForBadgeType:(BadgeType)badgeType { switch (badgeType) { - case BadgeType::kBadgeTypePasswordSave: + case kBadgeTypePasswordSave: return [self passwordsSaveBadgeButton]; - case BadgeType::kBadgeTypePasswordUpdate: + case kBadgeTypePasswordUpdate: return [self passwordsUpdateBadgeButton]; - case BadgeType::kBadgeTypeSaveCard: + case kBadgeTypeSaveCard: return [self saveCardBadgeButton]; - case BadgeType::kBadgeTypeTranslate: + case kBadgeTypeTranslate: return [self translateBadgeButton]; - case BadgeType::kBadgeTypeIncognito: + case kBadgeTypeIncognito: return [self incognitoBadgeButton]; - case BadgeType::kBadgeTypeOverflow: + case kBadgeTypeOverflow: return [self overflowBadgeButton]; - case BadgeType::kBadgeTypeSaveAddressProfile: + case kBadgeTypeSaveAddressProfile: return [self saveAddressProfileBadgeButton]; - case BadgeType::kBadgeTypeAddToReadingList: + case kBadgeTypeAddToReadingList: return [self readingListBadgeButton]; - case BadgeType::kBadgeTypePermissionsCamera: + case kBadgeTypePermissionsCamera: return [self permissionsCameraBadgeButton]; - case BadgeType::kBadgeTypePermissionsMicrophone: + case kBadgeTypePermissionsMicrophone: return [self permissionsMicrophoneBadgeButton]; - case BadgeType::kBadgeTypeNone: + case kBadgeTypeNone: NOTREACHED() << "A badge should not have kBadgeTypeNone"; return nil; }
diff --git a/ios/chrome/browser/ui/badges/badge_mediator_unittest.mm b/ios/chrome/browser/ui/badges/badge_mediator_unittest.mm index 8787560..ec186059 100644 --- a/ios/chrome/browser/ui/badges/badge_mediator_unittest.mm +++ b/ios/chrome/browser/ui/badges/badge_mediator_unittest.mm
@@ -62,14 +62,14 @@ fullScreenBadge:(id<BadgeItem>)fullscreenBadgeItem { self.hasFullscreenOffTheRecordBadge = fullscreenBadgeItem != nil && - fullscreenBadgeItem.badgeType == BadgeType::kBadgeTypeIncognito; + fullscreenBadgeItem.badgeType == kBadgeTypeIncognito; self.displayedBadge = displayedBadgeItem; } - (void)updateDisplayedBadge:(id<BadgeItem>)displayedBadgeItem fullScreenBadge:(id<BadgeItem>)fullscreenBadgeItem { self.hasFullscreenOffTheRecordBadge = fullscreenBadgeItem != nil && - fullscreenBadgeItem.badgeType == BadgeType::kBadgeTypeIncognito; + fullscreenBadgeItem.badgeType == kBadgeTypeIncognito; self.displayedBadge = displayedBadgeItem; } - (void)markDisplayedBadgeAsRead:(BOOL)read { @@ -171,8 +171,7 @@ InsertActivatedWebState(/*index=*/0); AddInfobar(kFirstInfobarType, kFirstInfobarMessageText); ASSERT_TRUE(badge_consumer_.displayedBadge); - EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, - BadgeType::kBadgeTypePasswordSave); + EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, kBadgeTypePasswordSave); } // Test that the BadgeMediator handled the removal of the correct badge when two @@ -182,12 +181,10 @@ AddInfobar(kFirstInfobarType, kFirstInfobarMessageText); InfoBarIOS* second_infobar = AddInfobar(kSecondInfobarType, kSecondInfobarMessageText); - EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, - BadgeType::kBadgeTypeOverflow); + EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, kBadgeTypeOverflow); RemoveInfobar(second_infobar); ASSERT_TRUE(badge_consumer_.displayedBadge); - EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, - BadgeType::kBadgeTypePasswordSave); + EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, kBadgeTypePasswordSave); } TEST_P(BadgeMediatorTest, BadgeMediatorTestMarkAsRead) { @@ -196,8 +193,7 @@ // Since there is only one badge, it should be marked as read. EXPECT_FALSE(badge_consumer_.hasUnreadBadge); AddInfobar(kSecondInfobarType, kSecondInfobarMessageText); - ASSERT_EQ(BadgeType::kBadgeTypeOverflow, - badge_consumer_.displayedBadge.badgeType); + ASSERT_EQ(kBadgeTypeOverflow, badge_consumer_.displayedBadge.badgeType); // Second badge should be unread since the overflow badge is being shown as // the displayed badge. EXPECT_TRUE(badge_consumer_.hasUnreadBadge); @@ -212,8 +208,7 @@ InsertActivatedWebState(/*index=*/0); AddInfobar(kFirstInfobarType, kFirstInfobarMessageText); ASSERT_TRUE(badge_consumer_.displayedBadge); - EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, - BadgeType::kBadgeTypePasswordSave); + EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, kBadgeTypePasswordSave); InsertActivatedWebState(/*index=*/1); EXPECT_FALSE(badge_consumer_.displayedBadge); } @@ -225,8 +220,7 @@ InsertActivatedWebState(/*index=*/0); AddInfobar(kFirstInfobarType, kFirstInfobarMessageText); ASSERT_TRUE(badge_consumer_.displayedBadge); - EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, - BadgeType::kBadgeTypePasswordSave); + EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, kBadgeTypePasswordSave); InsertActivatedWebState(/*index=*/1); std::unique_ptr<InfoBarIOS> added_infobar = std::make_unique<FakeInfobarIOS>( kSecondInfobarType, kSecondInfobarMessageText); @@ -276,8 +270,7 @@ badge_mediator_ = [[BadgeMediator alloc] initWithBrowser:browser()]; badge_mediator_.consumer = badge_consumer_; ASSERT_TRUE(badge_consumer_.displayedBadge); - EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, - BadgeType::kBadgeTypePasswordSave); + EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, kBadgeTypePasswordSave); } // Test that the BadgeMediator clears its badges when the last WebState is @@ -287,8 +280,7 @@ InsertActivatedWebState(/*index=*/0); AddInfobar(kFirstInfobarType, kFirstInfobarMessageText); ASSERT_TRUE(badge_consumer_.displayedBadge); - EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, - BadgeType::kBadgeTypePasswordSave); + EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, kBadgeTypePasswordSave); web_state_list()->DetachWebStateAt(0); InsertActivatedWebState(/*index=*/0); ASSERT_FALSE(badge_consumer_.displayedBadge);
diff --git a/ios/chrome/browser/ui/badges/badge_popup_menu_coordinator.mm b/ios/chrome/browser/ui/badges/badge_popup_menu_coordinator.mm index 6fd8885..7c89e3c 100644 --- a/ios/chrome/browser/ui/badges/badge_popup_menu_coordinator.mm +++ b/ios/chrome/browser/ui/badges/badge_popup_menu_coordinator.mm
@@ -115,8 +115,9 @@ break; } case PopupMenuActionShowSaveAddressProfileOptions: { - // TODO(crbug.com/1167062): Record this event. - + UMA_HISTOGRAM_ENUMERATION( + kInfobarOverflowMenuTappedHistogram, + MobileMessagesInfobarType::AutofillSaveAddressProfile); [self addModalRequestForInfobarType: InfobarType::kInfobarTypeSaveAutofillAddressProfile]; break;
diff --git a/ios/chrome/browser/ui/badges/badge_popup_menu_item.mm b/ios/chrome/browser/ui/badges/badge_popup_menu_item.mm index 3e3a0cf..12ee552 100644 --- a/ios/chrome/browser/ui/badges/badge_popup_menu_item.mm +++ b/ios/chrome/browser/ui/badges/badge_popup_menu_item.mm
@@ -8,6 +8,7 @@ #import "base/notreached.h" #include "components/password_manager/core/common/password_manager_features.h" +#include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/ui/list_model/list_model.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" @@ -52,47 +53,48 @@ self.cellClass = [BadgePopupMenuCell class]; _badgeType = badgeType; switch (badgeType) { - case BadgeType::kBadgeTypePasswordSave: + case kBadgeTypePasswordSave: _actionIdentifier = PopupMenuActionShowSavePasswordOptions; _title = l10n_util::GetNSString( IDS_IOS_PASSWORD_MANAGER_SAVE_PASSWORD_TITLE); break; - case BadgeType::kBadgeTypePasswordUpdate: + case kBadgeTypePasswordUpdate: _actionIdentifier = PopupMenuActionShowUpdatePasswordOptions; _title = l10n_util::GetNSString( IDS_IOS_PASSWORD_MANAGER_UPDATE_PASSWORD_TITLE); break; - case BadgeType::kBadgeTypeSaveAddressProfile: + case kBadgeTypeSaveAddressProfile: _actionIdentifier = PopupMenuActionShowSaveAddressProfileOptions; - _title = @"Save Address"; + _title = + l10n_util::GetNSString(IDS_IOS_AUTOFILL_SAVE_ADDRESS_PROMPT_TITLE); break; - case BadgeType::kBadgeTypeSaveCard: + case kBadgeTypeSaveCard: _actionIdentifier = PopupMenuActionShowSaveCardOptions; _title = l10n_util::GetNSString(IDS_IOS_AUTOFILL_SAVE_CARD); break; - case BadgeType::kBadgeTypeTranslate: + case kBadgeTypeTranslate: _actionIdentifier = PopupMenuActionShowTranslateOptions; _title = l10n_util::GetNSString(IDS_IOS_TRANSLATE_INFOBAR_MODAL_TITLE); break; - case BadgeType::kBadgeTypeAddToReadingList: + case kBadgeTypeAddToReadingList: _actionIdentifier = PopupMenuActionAddToReadingListOptions; _title = l10n_util::GetNSString(IDS_IOS_READING_LIST_MESSAGES_MODAL_TITLE); break; - case BadgeType::kBadgeTypePermissionsCamera: + case kBadgeTypePermissionsCamera: // Falls through. - case BadgeType::kBadgeTypePermissionsMicrophone: + case kBadgeTypePermissionsMicrophone: _actionIdentifier = PopupMenuActionShowPermissionsOptions; _title = l10n_util::GetNSString( IDS_IOS_PERMISSIONS_INFOBAR_OVERFLOW_POPUP_TITLE); break; - case BadgeType::kBadgeTypeIncognito: + case kBadgeTypeIncognito: NOTREACHED() << "A BadgePopupMenuItem should not be an Incognito badge"; break; - case BadgeType::kBadgeTypeOverflow: + case kBadgeTypeOverflow: NOTREACHED() << "A BadgePopupMenuItem should not be an overflow badge"; break; - case BadgeType::kBadgeTypeNone: + case kBadgeTypeNone: NOTREACHED() << "A badge should not have kBadgeTypeNone"; break; }
diff --git a/ios/chrome/browser/ui/badges/badge_static_item.mm b/ios/chrome/browser/ui/badges/badge_static_item.mm index c44ef4a..53beb16 100644 --- a/ios/chrome/browser/ui/badges/badge_static_item.mm +++ b/ios/chrome/browser/ui/badges/badge_static_item.mm
@@ -31,7 +31,7 @@ _badgeType = badgeType; _tappable = NO; _badgeState = BadgeStateNone; - _fullScreen = badgeType == BadgeType::kBadgeTypeIncognito; + _fullScreen = badgeType == kBadgeTypeIncognito; } return self; }
diff --git a/ios/chrome/browser/ui/badges/badge_type.h b/ios/chrome/browser/ui/badges/badge_type.h index 29f0b67..d435842 100644 --- a/ios/chrome/browser/ui/badges/badge_type.h +++ b/ios/chrome/browser/ui/badges/badge_type.h
@@ -5,8 +5,10 @@ #ifndef IOS_CHROME_BROWSER_UI_BADGES_BADGE_TYPE_H_ #define IOS_CHROME_BROWSER_UI_BADGES_BADGE_TYPE_H_ +#import <Foundation/Foundation.h> + // Badge types. -enum class BadgeType { +typedef NS_ENUM(NSUInteger, BadgeType) { // Badge type for no badge. This is to allow other features to distinguish // when a badge is necessary or not. Setting a BadgeModel type to // kBadgeTypeNone might result in a crash.
diff --git a/ios/chrome/browser/ui/badges/badge_type_util.cc b/ios/chrome/browser/ui/badges/badge_type_util.mm similarity index 66% rename from ios/chrome/browser/ui/badges/badge_type_util.cc rename to ios/chrome/browser/ui/badges/badge_type_util.mm index 24388c3..219c973 100644 --- a/ios/chrome/browser/ui/badges/badge_type_util.cc +++ b/ios/chrome/browser/ui/badges/badge_type_util.mm
@@ -5,49 +5,53 @@ #include "ios/chrome/browser/ui/badges/badge_type_util.h" #include <ostream> - #include "base/notreached.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + BadgeType BadgeTypeForInfobarType(InfobarType infobar_type) { switch (infobar_type) { case InfobarType::kInfobarTypePasswordSave: - return BadgeType::kBadgeTypePasswordSave; + return kBadgeTypePasswordSave; case InfobarType::kInfobarTypePasswordUpdate: - return BadgeType::kBadgeTypePasswordUpdate; + return kBadgeTypePasswordUpdate; case InfobarType::kInfobarTypeSaveAutofillAddressProfile: - return BadgeType::kBadgeTypeSaveAddressProfile; + return kBadgeTypeSaveAddressProfile; case InfobarType::kInfobarTypeSaveCard: - return BadgeType::kBadgeTypeSaveCard; + return kBadgeTypeSaveCard; case InfobarType::kInfobarTypeTranslate: - return BadgeType::kBadgeTypeTranslate; + return kBadgeTypeTranslate; case InfobarType::kInfobarTypeAddToReadingList: - return BadgeType::kBadgeTypeAddToReadingList; + return kBadgeTypeAddToReadingList; case InfobarType::kInfobarTypePermissions: // Default value; actual value would depend on the value of // GetStatesForAllPermissions() of the currently active WebState, and be // overridden when used. - return BadgeType::kBadgeTypePermissionsCamera; + return kBadgeTypePermissionsCamera; default: - return BadgeType::kBadgeTypeNone; + return kBadgeTypeNone; } } InfobarType InfobarTypeForBadgeType(BadgeType badge_type) { switch (badge_type) { - case BadgeType::kBadgeTypePasswordSave: + case kBadgeTypePasswordSave: return InfobarType::kInfobarTypePasswordSave; - case BadgeType::kBadgeTypePasswordUpdate: + case kBadgeTypePasswordUpdate: return InfobarType::kInfobarTypePasswordUpdate; - case BadgeType::kBadgeTypeSaveAddressProfile: + case kBadgeTypeSaveAddressProfile: return InfobarType::kInfobarTypeSaveAutofillAddressProfile; - case BadgeType::kBadgeTypeSaveCard: + case kBadgeTypeSaveCard: return InfobarType::kInfobarTypeSaveCard; - case BadgeType::kBadgeTypeTranslate: + case kBadgeTypeTranslate: return InfobarType::kInfobarTypeTranslate; - case BadgeType::kBadgeTypeAddToReadingList: + case kBadgeTypeAddToReadingList: return InfobarType::kInfobarTypeAddToReadingList; - case BadgeType::kBadgeTypePermissionsCamera: - case BadgeType::kBadgeTypePermissionsMicrophone: + case kBadgeTypePermissionsCamera: + // Falls through. + case kBadgeTypePermissionsMicrophone: return InfobarType::kInfobarTypePermissions; default: NOTREACHED() << "Unsupported badge type.";
diff --git a/ios/chrome/browser/ui/badges/badges_histograms.h b/ios/chrome/browser/ui/badges/badges_histograms.h index 279806d..7bdb3c6 100644 --- a/ios/chrome/browser/ui/badges/badges_histograms.h +++ b/ios/chrome/browser/ui/badges/badges_histograms.h
@@ -10,6 +10,8 @@ // Values for the Mobile.Messages.OverflowRow.Tapped histogram. Entries should // not be renumbered and numeric values should never be reused. +// Please also update MobileMessagesInfobarType enum in +// tools/metrics/histograms/enums.xml enum class MobileMessagesInfobarType { Confirm = 0, SavePassword = 1, @@ -17,8 +19,9 @@ SaveCard = 3, Translate = 4, Permissions = 5, + AutofillSaveAddressProfile = 6, // Highest enumerator. Recommended by Histogram metrics best practices. - kMaxValue = Permissions, + kMaxValue = AutofillSaveAddressProfile, }; #endif // IOS_CHROME_BROWSER_UI_BADGES_BADGES_HISTOGRAMS_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm index 909fa07..6caa27ad 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -564,6 +564,11 @@ // Tests that tapping the fake omnibox moves the collection. - (void)testTapFakeOmniboxScroll { + // Disable the test on iOS 15.3 due to build failure. + // TODO(crbug.com/1306515): enable the test with fix. + if (@available(iOS 15.3, *)) { + EARL_GREY_TEST_DISABLED(@"Test disabled on iOS 15.3."); + } // Get the collection and its layout. UICollectionView* collectionView = [NewTabPageAppInterface collectionView]; @@ -598,6 +603,11 @@ // Tests that tapping the fake omnibox then unfocusing it moves the collection // back to where it was. - (void)testTapFakeOmniboxScrollScrolled { + // Disable the test on iOS 15.3 due to build failure. + // TODO(crbug.com/1306515): enable the test with fix. + if (@available(iOS 15.3, *)) { + EARL_GREY_TEST_DISABLED(@"Test disabled on iOS 15.3."); + } // Get the collection and its layout. UICollectionView* collectionView = [NewTabPageAppInterface collectionView];
diff --git a/ios/chrome/browser/ui/popup_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/BUILD.gn index 916ea98..9a92a6a4 100644 --- a/ios/chrome/browser/ui/popup_menu/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/BUILD.gn
@@ -104,6 +104,7 @@ "//ios/chrome/common/ui/colors", "//ios/components/webui:url_constants", "//ios/public/provider/chrome/browser", + "//ios/public/provider/chrome/browser/follow", "//ios/public/provider/chrome/browser/text_zoom:text_zoom_api", "//ios/public/provider/chrome/browser/user_feedback", "//ios/web",
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm index d842543c..f389ac4d 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -42,6 +42,8 @@ #import "ios/chrome/browser/web/web_navigation_browser_agent.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" +#import "ios/public/provider/chrome/browser/chrome_browser_provider.h" +#import "ios/public/provider/chrome/browser/follow/follow_provider.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -287,12 +289,17 @@ overlayPresenter; self.overflowMenuMediator.browserPolicyConnector = GetApplicationContext()->GetBrowserPolicyConnector(); - self.overflowMenuMediator.followActionState = - IsWebChannelsEnabled() - ? GetFollowActionState( - self.browser->GetWebStateList()->GetActiveWebState(), - self.browser->GetBrowserState()) - : FollowActionStateHidden; + + if (IsWebChannelsEnabled()) { + self.overflowMenuMediator.followActionState = GetFollowActionState( + self.browser->GetWebStateList()->GetActiveWebState(), + self.browser->GetBrowserState()); + ios::GetChromeBrowserProvider() + .GetFollowProvider() + ->SetFollowEventDelegate(self.browser); + } else { + self.overflowMenuMediator.followActionState = FollowActionStateHidden; + } self.contentBlockerMediator.consumer = self.overflowMenuMediator;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm index e2cc26b..9235bcdc 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -240,7 +240,8 @@ @selector(testOpenTabsHeaderVisibleInSearchModeWhenSearchBarIsNotEmpty), @selector(testSuggestedActionsVisibleInSearchModeWhenSearchBarIsNotEmpty), @selector(testSearchSuggestedActionsDisplaysCorrectHistoryMatchesCount), - @selector(testSearchSuggestedActionsSectionContentInRegularGrid)}; + @selector(testSearchSuggestedActionsSectionContentInRegularGrid), + @selector(testSuggestedActionsNotAvailableInIncognitoPageSearchMode)}; for (SEL test : searchTests) { if ([self isRunningTest:test]) { config.features_enabled.push_back(kTabsSearch); @@ -1598,6 +1599,33 @@ assertWithMatcher:grey_nil()]; } +// Tests that suggested actions section does not appear in search mode for +// incognito page. +- (void)testSuggestedActionsNotAvailableInIncognitoPageSearchMode { + [self loadTestURLsInNewIncognitoTabs]; + [ChromeEarlGrey showTabSwitcher]; + + // Enter search mode. + [[EarlGrey selectElementWithMatcher:TabGridSearchTabsButton()] + performAction:grey_tap()]; + + // Upon entry, the search bar is empty. Verify that the suggested actions + // section doesn't exist. + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSectionHeader()] + assertWithMatcher:grey_nil()]; + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSection()] + assertWithMatcher:grey_nil()]; + + // Searching with a query should not show suggested actions section. + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_typeText(@"page 2\n")]; + [[EarlGrey selectElementWithMatcher:SearchSuggestedActionsSectionHeader()] + assertWithMatcher:grey_nil()]; + [[self scrollDownViewMatcher:chrome_test_util::IncognitoTabGrid() + toSelectMatcher:SearchSuggestedActionsSection()] + assertWithMatcher:grey_nil()]; +} + // Tests that the search suggested actions section has the right rows in the // regular grid. - (void)testSearchSuggestedActionsSectionContentInRegularGrid { @@ -1697,7 +1725,6 @@ // Tests that selecting an open tab search result in incognito mode will // correctly open the expected tab. - (void)testSearchIncognitoOpenTabsSelectResult { - [ChromeEarlGrey openNewIncognitoTab]; [self loadTestURLsInNewIncognitoTabs]; [ChromeEarlGrey showTabSwitcher]; @@ -1840,6 +1867,7 @@ } - (void)loadTestURLsInNewIncognitoTabs { + [ChromeEarlGrey openNewIncognitoTab]; [ChromeEarlGrey loadURL:_URL1]; [ChromeEarlGrey waitForWebStateContainingText:kResponse1];
diff --git a/ios/public/provider/chrome/browser/follow/follow_provider.h b/ios/public/provider/chrome/browser/follow/follow_provider.h index 37cfbd45..7cb0658 100644 --- a/ios/public/provider/chrome/browser/follow/follow_provider.h +++ b/ios/public/provider/chrome/browser/follow/follow_provider.h
@@ -9,6 +9,7 @@ @class FollowSiteInfo; @class FollowedWebChannel; +class Browser; // FollowProvider provides and updates the following status of websites and // provides information related to these. @@ -32,6 +33,10 @@ // Updates the following status of |site| to |state|. virtual void UpdateFollowStatus(FollowSiteInfo* site, bool state); + + // Sets the follow event delegate to discover feed with |browser|. + // This method must be called before any follow action needs to be handled. + virtual void SetFollowEventDelegate(Browser* browser); }; #endif // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_FOLLOW_FOLLOW_PROVIDER_H_
diff --git a/ios/public/provider/chrome/browser/follow/follow_provider.mm b/ios/public/provider/chrome/browser/follow/follow_provider.mm index f7a81ac9..dd042a1ad 100644 --- a/ios/public/provider/chrome/browser/follow/follow_provider.mm +++ b/ios/public/provider/chrome/browser/follow/follow_provider.mm
@@ -21,3 +21,5 @@ } void FollowProvider::UpdateFollowStatus(FollowSiteInfo* site, bool state) {} + +void FollowProvider::SetFollowEventDelegate(Browser* browser) {}
diff --git a/ios/showcase/badges/OWNERS b/ios/showcase/badges/OWNERS new file mode 100644 index 0000000..e4cb6a98 --- /dev/null +++ b/ios/showcase/badges/OWNERS
@@ -0,0 +1 @@ +ginnyhuang@chromium.org
diff --git a/ios/showcase/badges/sc_badge_coordinator.mm b/ios/showcase/badges/sc_badge_coordinator.mm index 5ce9369..ffd7a22 100644 --- a/ios/showcase/badges/sc_badge_coordinator.mm +++ b/ios/showcase/badges/sc_badge_coordinator.mm
@@ -79,30 +79,30 @@ self.title = @"Badges"; AddNamedGuidesToView(@[ kBadgeOverflowMenuGuide ], self.view); - BadgeStaticItem* incognitoItem = [[BadgeStaticItem alloc] - initWithBadgeType:BadgeType::kBadgeTypeIncognito]; - BadgeTappableItem* passwordBadgeItem = [[BadgeTappableItem alloc] - initWithBadgeType:BadgeType::kBadgeTypePasswordSave]; + BadgeStaticItem* incognitoItem = + [[BadgeStaticItem alloc] initWithBadgeType:kBadgeTypeIncognito]; + BadgeTappableItem* passwordBadgeItem = + [[BadgeTappableItem alloc] initWithBadgeType:kBadgeTypePasswordSave]; passwordBadgeItem.badgeState = BadgeStateRead; [self.consumer setupWithDisplayedBadge:passwordBadgeItem fullScreenBadge:incognitoItem]; } - (void)showAcceptedDisplayedBadge { - BadgeStaticItem* incognitoItem = [[BadgeStaticItem alloc] - initWithBadgeType:BadgeType::kBadgeTypeIncognito]; - BadgeTappableItem* passwordBadgeItem = [[BadgeTappableItem alloc] - initWithBadgeType:BadgeType::kBadgeTypePasswordSave]; + BadgeStaticItem* incognitoItem = + [[BadgeStaticItem alloc] initWithBadgeType:kBadgeTypeIncognito]; + BadgeTappableItem* passwordBadgeItem = + [[BadgeTappableItem alloc] initWithBadgeType:kBadgeTypePasswordSave]; passwordBadgeItem.badgeState = BadgeStateRead | BadgeStateAccepted; [self.consumer setupWithDisplayedBadge:passwordBadgeItem fullScreenBadge:incognitoItem]; } - (void)addSecondBadge:(id)sender { - BadgeStaticItem* incognitoItem = [[BadgeStaticItem alloc] - initWithBadgeType:BadgeType::kBadgeTypeIncognito]; - BadgeTappableItem* displayedBadge = [[BadgeTappableItem alloc] - initWithBadgeType:BadgeType::kBadgeTypeOverflow]; + BadgeStaticItem* incognitoItem = + [[BadgeStaticItem alloc] initWithBadgeType:kBadgeTypeIncognito]; + BadgeTappableItem* displayedBadge = + [[BadgeTappableItem alloc] initWithBadgeType:kBadgeTypeOverflow]; [self.consumer setupWithDisplayedBadge:displayedBadge fullScreenBadge:incognitoItem]; [self.consumer markDisplayedBadgeAsRead:NO]; @@ -158,8 +158,8 @@ self.badgePopupMenuCoordinator = [[BadgePopupMenuCoordinator alloc] initWithBaseViewController:self.containerViewController browser:nil]; - NSArray* badgeItems = @[ [[BadgeTappableItem alloc] - initWithBadgeType:BadgeType::kBadgeTypePasswordSave] ]; + NSArray* badgeItems = + @[ [[BadgeTappableItem alloc] initWithBadgeType:kBadgeTypePasswordSave] ]; [self.badgePopupMenuCoordinator setBadgeItemsToShow:badgeItems]; [self.badgePopupMenuCoordinator start]; [self.consumer markDisplayedBadgeAsRead:YES];
diff --git a/media/gpu/mac/vt_video_decode_accelerator_mac.cc b/media/gpu/mac/vt_video_decode_accelerator_mac.cc index 13a393d..eba1691 100644 --- a/media/gpu/mac/vt_video_decode_accelerator_mac.cc +++ b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
@@ -1345,6 +1345,11 @@ return; } seen_pps_[pps_id].assign(nalu.data, nalu.data + nalu.size); + // Pass PPS as data to the platform decoder, it helps in cases + // when there are more than one PPS, Video Toolbox is smart enough + // to find and recognize them there. + nalus.push_back(nalu); + data_size += kNALUHeaderLength + nalu.size; break; }
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc index 9b28dd3..564c753 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -508,25 +508,25 @@ } void CopyRowsToNV12Buffer(int first_row, - int y_rows, - int uv_rows, - int y_bytes_per_row, - int uv_bytes_per_row, + int rows_y, + int rows_uv, + int bytes_per_row_y, + int bytes_per_row_uv, const VideoFrame* source_frame, uint8_t* dest_y, int dest_stride_y, uint8_t* dest_uv, int dest_stride_uv) { TRACE_EVENT2("media", "CopyRowsToNV12Buffer", "bytes_per_row", - y_bytes_per_row, "rows", y_rows); + bytes_per_row_y, "rows", rows_y); if (!dest_y || !dest_uv) return; DCHECK_NE(dest_stride_y, 0); DCHECK_NE(dest_stride_uv, 0); - DCHECK_LE(y_bytes_per_row, std::abs(dest_stride_y)); - DCHECK_LE(uv_bytes_per_row, std::abs(dest_stride_uv)); + DCHECK_LE(bytes_per_row_y, std::abs(dest_stride_y)); + DCHECK_LE(bytes_per_row_uv, std::abs(dest_stride_uv)); DCHECK_EQ(0, first_row % 2); DCHECK(source_frame->format() == PIXEL_FORMAT_I420 || source_frame->format() == PIXEL_FORMAT_YV12 || @@ -536,13 +536,13 @@ first_row * source_frame->stride(VideoFrame::kYPlane), source_frame->stride(VideoFrame::kYPlane), dest_y + first_row * dest_stride_y, dest_stride_y, - y_bytes_per_row, y_rows); + bytes_per_row_y, rows_y); libyuv::CopyPlane( source_frame->visible_data(VideoFrame::kUVPlane) + first_row / 2 * source_frame->stride(VideoFrame::kUVPlane), source_frame->stride(VideoFrame::kUVPlane), dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv, - uv_bytes_per_row, uv_rows); + bytes_per_row_uv, rows_uv); return; } @@ -558,8 +558,8 @@ first_row / 2 * source_frame->stride(VideoFrame::kVPlane), source_frame->stride(VideoFrame::kVPlane), dest_y + first_row * dest_stride_y, dest_stride_y, - dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv, y_bytes_per_row, - y_rows); + dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv, bytes_per_row_y, + rows_y); } void CopyRowsToRGB10Buffer(bool is_argb, @@ -1015,36 +1015,36 @@ break; case GpuVideoAcceleratorFactories::OutputFormat::NV12_SINGLE_GMB: { - const size_t y_rows_to_copy = VideoFrame::Rows( + const size_t rows_to_copy_y = VideoFrame::Rows( VideoFrame::kYPlane, VideoFormat(output_format), rows_to_copy); - const size_t uv_rows_to_copy = VideoFrame::Rows( + const size_t rows_to_copy_uv = VideoFrame::Rows( VideoFrame::kUVPlane, VideoFormat(output_format), rows_to_copy); - const size_t y_bytes_per_row = VideoFrame::RowBytes( + const size_t bytes_per_row_y = VideoFrame::RowBytes( VideoFrame::kYPlane, VideoFormat(output_format), coded_size.width()); - const size_t uv_bytes_per_row = VideoFrame::RowBytes( + const size_t bytes_per_row_uv = VideoFrame::RowBytes( VideoFrame::kUVPlane, VideoFormat(output_format), coded_size.width()); CopyRowsToNV12Buffer( - row, y_rows_to_copy, uv_rows_to_copy, y_bytes_per_row, - uv_bytes_per_row, video_frame, + row, rows_to_copy_y, rows_to_copy_uv, bytes_per_row_y, + bytes_per_row_uv, video_frame, static_cast<uint8_t*>(buffer->memory(0)), buffer->stride(0), static_cast<uint8_t*>(buffer->memory(1)), buffer->stride(1)); break; } case GpuVideoAcceleratorFactories::OutputFormat::NV12_DUAL_GMB: { - const size_t y_rows_to_copy = VideoFrame::Rows( + const size_t rows_to_copy_y = VideoFrame::Rows( VideoFrame::kYPlane, VideoFormat(output_format), rows_to_copy); - const size_t uv_rows_to_copy = VideoFrame::Rows( + const size_t rows_to_copy_uv = VideoFrame::Rows( VideoFrame::kUVPlane, VideoFormat(output_format), rows_to_copy); - const size_t y_bytes_per_row = VideoFrame::RowBytes( + const size_t bytes_per_row_y = VideoFrame::RowBytes( VideoFrame::kYPlane, VideoFormat(output_format), coded_size.width()); - const size_t uv_bytes_per_row = VideoFrame::RowBytes( + const size_t bytes_per_row_uv = VideoFrame::RowBytes( VideoFrame::kUVPlane, VideoFormat(output_format), coded_size.width()); gfx::GpuMemoryBuffer* buffer2 = frame_resources->plane_resources[1].gpu_memory_buffer.get(); CopyRowsToNV12Buffer( - row, y_rows_to_copy, uv_rows_to_copy, y_bytes_per_row, - uv_bytes_per_row, video_frame, + row, rows_to_copy_y, rows_to_copy_uv, bytes_per_row_y, + bytes_per_row_uv, video_frame, static_cast<uint8_t*>(buffer->memory(0)), buffer->stride(0), static_cast<uint8_t*>(buffer2->memory(0)), buffer2->stride(0)); break;
diff --git a/net/BUILD.gn b/net/BUILD.gn index b329352d..5b4ce09 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -672,6 +672,7 @@ "log/net_log_capture_mode.h", "log/net_log_entry.cc", "log/net_log_entry.h", + "log/net_log_event_type.cc", "log/net_log_event_type.h", "log/net_log_event_type_list.h", "log/net_log_source.cc",
diff --git a/net/log/net_log.cc b/net/log/net_log.cc index f81d83d..e053527 100644 --- a/net/log/net_log.cc +++ b/net/log/net_log.cc
@@ -181,24 +181,10 @@ } // static -const char* NetLog::EventTypeToString(NetLogEventType event) { - switch (event) { -#define EVENT_TYPE(label) \ - case NetLogEventType::label: \ - return #label; -#include "net/log/net_log_event_type_list.h" -#undef EVENT_TYPE - default: - NOTREACHED(); - return nullptr; - } -} - -// static base::Value NetLog::GetEventTypesAsValue() { base::Value dict(base::Value::Type::DICTIONARY); for (int i = 0; i < static_cast<int>(NetLogEventType::COUNT); ++i) { - dict.SetIntKey(EventTypeToString(static_cast<NetLogEventType>(i)), i); + dict.SetIntKey(NetLogEventTypeToString(static_cast<NetLogEventType>(i)), i); } return dict; }
diff --git a/net/log/net_log.h b/net/log/net_log.h index 427bf17..9a6fc19 100644 --- a/net/log/net_log.h +++ b/net/log/net_log.h
@@ -334,9 +334,6 @@ // timestamps are desired, but is suitable for e.g. expiration times. static std::string TimeToString(const base::Time& time); - // Returns a C-String symbolic name for |event_type|. - static const char* EventTypeToString(NetLogEventType event_type); - // Returns a dictionary that maps event type symbolic names to their enum // values. static base::Value GetEventTypesAsValue();
diff --git a/net/log/net_log_event_type.cc b/net/log/net_log_event_type.cc new file mode 100644 index 0000000..069b3dca --- /dev/null +++ b/net/log/net_log_event_type.cc
@@ -0,0 +1,28 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/log/net_log_event_type.h" + +#include "base/notreached.h" + +namespace net { + +const char* NetLogEventTypeToString(NetLogEventType type) { + switch (type) { +#define EVENT_TYPE(label) \ + case NetLogEventType::label: \ + return #label; +#include "net/log/net_log_event_type_list.h" +#undef EVENT_TYPE + default: + NOTREACHED(); + return nullptr; + } +} + +std::ostream& operator<<(std::ostream& os, NetLogEventType type) { + return os << NetLogEventTypeToString(type); +} + +} // namespace net
diff --git a/net/log/net_log_event_type.h b/net/log/net_log_event_type.h index d9d4bf6..1a58d67 100644 --- a/net/log/net_log_event_type.h +++ b/net/log/net_log_event_type.h
@@ -5,6 +5,10 @@ #ifndef NET_LOG_NET_LOG_EVENT_TYPE_H_ #define NET_LOG_NET_LOG_EVENT_TYPE_H_ +#include <ostream> + +#include "net/base/net_export.h" + namespace net { enum class NetLogEventType { @@ -14,6 +18,12 @@ COUNT }; +// Returns a C-String symbolic name for |type|. +NET_EXPORT const char* NetLogEventTypeToString(NetLogEventType type); + +// For convenience in tests. +NET_EXPORT std::ostream& operator<<(std::ostream& os, NetLogEventType type); + // The 'phase' of an event trace (whether it marks the beginning or end // of an event.). enum class NetLogEventPhase {
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index 0e73ffd86..9d76112 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -4025,6 +4025,22 @@ // } EVENT_TYPE(CORS_PREFLIGHT_RESULT) +// This event is logged when PreflightController detects a failed CORS +// preflight. +// +// It contains the following parameters: +// { +// "error: <A string representing the network error for the failure. +// "ERR_FAILED" for CORS errors.>, +// "cors-error": <Optional. An integer representing the more granular reason +// for the CORS error, if any. Values map to +// `network::mojom::CorsError`.>, +// "failed-parameter": <Optional, absent if `cors-error` is absent. A string +// representing the parameter that failed validation, +// e.g. a forbidden header.>, +// } +EVENT_TYPE(CORS_PREFLIGHT_ERROR) + // This event identifies the NetLogSource() for a URLRequest of the preflight // request. EVENT_TYPE(CORS_PREFLIGHT_URL_REQUEST)
diff --git a/net/log/test_net_log_util.cc b/net/log/test_net_log_util.cc index a165437..8559c92 100644 --- a/net/log/test_net_log_util.cc +++ b/net/log/test_net_log_util.cc
@@ -6,7 +6,7 @@ #include <cstddef> -#include "net/log/net_log.h" +#include "net/log/net_log_entry.h" namespace net { @@ -40,8 +40,8 @@ const NetLogEntry& entry = entries[index]; if (expected_event != entry.type) { return ::testing::AssertionFailure() - << "Actual event: " << NetLog::EventTypeToString(entry.type) - << ". Expected event: " << NetLog::EventTypeToString(expected_event) + << "Actual event: " << NetLogEventTypeToString(entry.type) + << ". Expected event: " << NetLogEventTypeToString(expected_event) << "."; } if (expected_phase != entry.phase) {
diff --git a/net/log/test_net_log_util.h b/net/log/test_net_log_util.h index 60d0055b..9caef59f 100644 --- a/net/log/test_net_log_util.h +++ b/net/log/test_net_log_util.h
@@ -6,6 +6,8 @@ #define NET_LOG_TEST_NET_LOG_UTIL_H_ #include <stddef.h> +#include <string> +#include <vector> #include "base/strings/string_piece.h" #include "net/log/net_log_event_type.h"
diff --git a/net/log/trace_net_log_observer.cc b/net/log/trace_net_log_observer.cc index 543d861..b2998b25 100644 --- a/net/log/trace_net_log_observer.cc +++ b/net/log/trace_net_log_observer.cc
@@ -59,7 +59,7 @@ switch (entry.phase) { case NetLogEventPhase::BEGIN: TRACE_EVENT_NESTABLE_ASYNC_BEGIN2( - kNetLogTracingCategory, NetLog::EventTypeToString(entry.type), + kNetLogTracingCategory, NetLogEventTypeToString(entry.type), entry.source.id, "source_type", NetLog::SourceTypeToString(entry.source.type), "params", std::unique_ptr<base::trace_event::ConvertableToTraceFormat>( @@ -67,7 +67,7 @@ break; case NetLogEventPhase::END: TRACE_EVENT_NESTABLE_ASYNC_END2( - kNetLogTracingCategory, NetLog::EventTypeToString(entry.type), + kNetLogTracingCategory, NetLogEventTypeToString(entry.type), entry.source.id, "source_type", NetLog::SourceTypeToString(entry.source.type), "params", std::unique_ptr<base::trace_event::ConvertableToTraceFormat>( @@ -75,7 +75,7 @@ break; case NetLogEventPhase::NONE: TRACE_EVENT_NESTABLE_ASYNC_INSTANT2( - kNetLogTracingCategory, NetLog::EventTypeToString(entry.type), + kNetLogTracingCategory, NetLogEventTypeToString(entry.type), entry.source.id, "source_type", NetLog::SourceTypeToString(entry.source.type), "params", std::unique_ptr<base::trace_event::ConvertableToTraceFormat>(
diff --git a/net/log/trace_net_log_observer_unittest.cc b/net/log/trace_net_log_observer_unittest.cc index 15ecb779..2083e27 100644 --- a/net/log/trace_net_log_observer_unittest.cc +++ b/net/log/trace_net_log_observer_unittest.cc
@@ -261,7 +261,7 @@ EXPECT_EQ(base::StringPrintf("0x%x", entries[0].source.id), actual_item1.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT), actual_item1.phase); - EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::CANCELLED), + EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::CANCELLED), actual_item1.name); EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type), actual_item1.source_type); @@ -270,7 +270,7 @@ EXPECT_EQ(base::StringPrintf("0x%x", entries[1].source.id), actual_item2.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN), actual_item2.phase); - EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::URL_REQUEST_START_JOB), + EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::URL_REQUEST_START_JOB), actual_item2.name); EXPECT_EQ(NetLog::SourceTypeToString(entries[1].source.type), actual_item2.source_type); @@ -279,7 +279,7 @@ EXPECT_EQ(base::StringPrintf("0x%x", entries[2].source.id), actual_item3.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_END), actual_item3.phase); - EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::REQUEST_ALIVE), + EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::REQUEST_ALIVE), actual_item3.name); EXPECT_EQ(NetLog::SourceTypeToString(entries[2].source.type), actual_item3.source_type); @@ -311,7 +311,7 @@ EXPECT_EQ(base::StringPrintf("0x%x", entries[0].source.id), actual_item1.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT), actual_item1.phase); - EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::CANCELLED), + EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::CANCELLED), actual_item1.name); EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type), actual_item1.source_type); @@ -320,7 +320,7 @@ EXPECT_EQ(base::StringPrintf("0x%x", entries[2].source.id), actual_item2.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT), actual_item2.phase); - EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::URL_REQUEST_START_JOB), + EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::URL_REQUEST_START_JOB), actual_item2.name); EXPECT_EQ(NetLog::SourceTypeToString(entries[2].source.type), actual_item2.source_type); @@ -348,7 +348,7 @@ EXPECT_EQ(base::StringPrintf("0x%x", entries[0].source.id), actual_item1.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT), actual_item1.phase); - EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::CANCELLED), + EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::CANCELLED), actual_item1.name); EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type), actual_item1.source_type); @@ -432,7 +432,7 @@ EXPECT_EQ(base::StringPrintf("0x%x", entries[0].source.id), actual_item1.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT), actual_item1.phase); - EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::CANCELLED), + EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::CANCELLED), actual_item1.name); EXPECT_EQ(NetLog::SourceTypeToString(entries[0].source.type), actual_item1.source_type); @@ -441,7 +441,7 @@ EXPECT_EQ(base::StringPrintf("0x%x", entries[1].source.id), actual_item2.id); EXPECT_EQ(std::string(1, TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT), actual_item2.phase); - EXPECT_EQ(NetLog::EventTypeToString(NetLogEventType::REQUEST_ALIVE), + EXPECT_EQ(NetLogEventTypeToString(NetLogEventType::REQUEST_ALIVE), actual_item2.name); EXPECT_EQ(NetLog::SourceTypeToString(entries[1].source.type), actual_item2.source_type);
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 12e7e517..0b38995 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -5377,7 +5377,7 @@ NetLogEventType::NETWORK_DELEGATE_HEADERS_RECEIVED, }; for (NetLogEventType event : kExpectedEvents) { - SCOPED_TRACE(NetLog::EventTypeToString(event)); + SCOPED_TRACE(NetLogEventTypeToString(event)); log_position = ExpectLogContainsSomewhereAfter( entries, log_position + 1, event, NetLogEventPhase::BEGIN); @@ -5430,7 +5430,7 @@ NetLogEventType::NETWORK_DELEGATE_HEADERS_RECEIVED, }; for (NetLogEventType event : kExpectedEvents) { - SCOPED_TRACE(NetLog::EventTypeToString(event)); + SCOPED_TRACE(NetLogEventTypeToString(event)); log_position = ExpectLogContainsSomewhereAfter( entries, log_position + 1, event, NetLogEventPhase::BEGIN); @@ -5450,7 +5450,7 @@ // The NetworkDelegate logged information in the same three events as before. for (NetLogEventType event : kExpectedEvents) { - SCOPED_TRACE(NetLog::EventTypeToString(event)); + SCOPED_TRACE(NetLogEventTypeToString(event)); log_position = ExpectLogContainsSomewhereAfter( entries, log_position + 1, event, NetLogEventPhase::BEGIN); @@ -5552,7 +5552,7 @@ NetLogEventType::URL_REQUEST_DELEGATE_RESPONSE_STARTED, }; for (NetLogEventType event : kExpectedEvents) { - SCOPED_TRACE(NetLog::EventTypeToString(event)); + SCOPED_TRACE(NetLogEventTypeToString(event)); log_position = ExpectLogContainsSomewhereAfter(entries, log_position, event, NetLogEventPhase::BEGIN); @@ -5612,7 +5612,7 @@ NetLogEventType::URL_REQUEST_DELEGATE_RESPONSE_STARTED, }; for (NetLogEventType event : kExpectedEvents) { - SCOPED_TRACE(NetLog::EventTypeToString(event)); + SCOPED_TRACE(NetLogEventTypeToString(event)); log_position = ExpectLogContainsSomewhereAfter( entries, log_position, event, NetLogEventPhase::BEGIN);
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc index 2e8b7e0..9c04f5e 100644 --- a/services/network/cors/cors_url_loader.cc +++ b/services/network/cors/cors_url_loader.cc
@@ -4,6 +4,9 @@ #include "services/network/cors/cors_url_loader.h" +#include <sstream> +#include <utility> + #include "base/bind.h" #include "base/containers/contains.h" #include "base/containers/flat_set.h" @@ -123,6 +126,23 @@ return dict; } +// Returns net log params for the `CORS_PREFLIGHT_ERROR` event type. +base::Value::Dict NetLogPreflightErrorParams( + int net_error, + const absl::optional<CorsErrorStatus>& status) { + base::Value::Dict dict; + + dict.Set("error", net::ErrorToShortString(net_error)); + if (status) { + dict.Set("cors-error", static_cast<int>(status->cors_error)); + if (!status->failed_parameter.empty()) { + dict.Set("failed-parameter", status->failed_parameter); + } + } + + return dict; +} + // Returns the response tainting value // (https://fetch.spec.whatwg.org/#concept-request-response-tainting) for a // request and the CORS flag, as specified in @@ -744,6 +764,10 @@ return absl::nullopt; } + net_log_.AddEvent(net::NetLogEventType::CORS_PREFLIGHT_ERROR, [&] { + return base::Value(NetLogPreflightErrorParams(net_error, status)); + }); + // `kInvalidResponse` is never returned by the preflight controller, so we use // it to record the case where there was a net error and no CORS error. auto histogram_error = mojom::CorsError::kInvalidResponse;
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc index d9b797b6..03266ff4f 100644 --- a/services/network/cors/cors_url_loader_unittest.cc +++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -60,11 +60,15 @@ namespace { +using ::testing::Contains; using ::testing::ElementsAre; +using ::testing::Eq; using ::testing::IsEmpty; +using ::testing::IsNull; using ::testing::IsSupersetOf; using ::testing::Optional; using ::testing::Pair; +using ::testing::Pointee; const uint32_t kRendererProcessId = 573; @@ -79,6 +83,29 @@ return base::Bucket(static_cast<base::HistogramBase::Sample>(error), count); } +// Returns a view of the types of the given entries, in the exact same order. +std::vector<net::NetLogEventType> GetTypesOfNetLogEntries( + const std::vector<net::NetLogEntry>& entries) { + std::vector<net::NetLogEventType> types; + for (const auto& entry : entries) { + types.push_back(entry.type); + } + return types; +} + +// Returns a pointer to the first entry in `entries` with the given `type`. +// Returns nullptr if none can be found. +const net::NetLogEntry* FindEntryByType( + const std::vector<net::NetLogEntry>& entries, + net::NetLogEventType type) { + for (const auto& entry : entries) { + if (entry.type == type) { + return &entry; + } + } + return nullptr; +} + class TestURLLoaderFactory : public mojom::URLLoaderFactory { public: TestURLLoaderFactory() {} @@ -476,13 +503,14 @@ std::vector<net::NetLogEntry> GetEntries() const { std::vector<net::NetLogEntry> entries, filtered; entries = net_log_observer_.GetEntries(); - for (const auto& entry : entries) { + for (auto& entry : entries) { if (entry.type == net::NetLogEventType::CORS_REQUEST || entry.type == net::NetLogEventType::CHECK_CORS_PREFLIGHT_REQUIRED || entry.type == net::NetLogEventType::CHECK_CORS_PREFLIGHT_CACHE || entry.type == net::NetLogEventType::CORS_PREFLIGHT_RESULT || - entry.type == net::NetLogEventType::CORS_PREFLIGHT_CACHED_RESULT) { - filtered.push_back(entry.Clone()); + entry.type == net::NetLogEventType::CORS_PREFLIGHT_CACHED_RESULT || + entry.type == net::NetLogEventType::CORS_PREFLIGHT_ERROR) { + filtered.push_back(std::move(entry)); } } return filtered; @@ -2906,6 +2934,110 @@ ADD_FAILURE() << "Log entry not found."; } +TEST_F(CorsURLLoaderTest, NetLogPreflightMissingAllowOrigin) { + auto initiator = url::Origin::Create(GURL("https://foo.example")); + ResetFactory(initiator, mojom::kBrowserProcessId); + + ResourceRequest request; + request.method = "PUT"; + request.mode = mojom::RequestMode::kCors; + request.url = GURL("https://example.com/"); + request.request_initiator = initiator; + + CreateLoaderAndStart(request); + RunUntilCreateLoaderAndStartCalled(); + NotifyLoaderClientOnReceiveResponse(); + NotifyLoaderClientOnComplete(net::OK); + RunUntilComplete(); + + std::vector<net::NetLogEntry> entries = GetEntries(); + std::vector<net::NetLogEventType> types = GetTypesOfNetLogEntries(entries); + EXPECT_THAT(types, + Contains(net::NetLogEventType::CORS_PREFLIGHT_RESULT).Times(0)); + ASSERT_THAT(types, + Contains(net::NetLogEventType::CORS_PREFLIGHT_ERROR).Times(1)); + + const net::NetLogEntry* entry = + FindEntryByType(entries, net::NetLogEventType::CORS_PREFLIGHT_ERROR); + const base::Value::Dict* params = entry->params.GetIfDict(); + ASSERT_TRUE(params); + EXPECT_THAT(params->FindString("error"), Pointee(Eq("ERR_FAILED"))); + EXPECT_THAT(params->FindInt("cors-error"), + Optional(Eq(static_cast<int>( + mojom::CorsError::kPreflightMissingAllowOriginHeader)))); + EXPECT_THAT(params->FindString("failed-parameter"), IsNull()); +} + +TEST_F(CorsURLLoaderTest, NetLogPreflightMethodDisallowed) { + auto initiator = url::Origin::Create(GURL("https://foo.example")); + ResetFactory(initiator, mojom::kBrowserProcessId); + + ResourceRequest request; + request.method = "PUT"; + request.mode = mojom::RequestMode::kCors; + request.url = GURL("https://example.com/"); + request.request_initiator = initiator; + + CreateLoaderAndStart(request); + RunUntilCreateLoaderAndStartCalled(); + NotifyLoaderClientOnReceiveResponse({ + {"Access-Control-Allow-Origin", "https://foo.example"}, + {"Access-Control-Allow-Methods", "GET"}, + {"Access-Control-Allow-Credentials", "true"}, + }); + NotifyLoaderClientOnComplete(net::OK); + RunUntilComplete(); + + std::vector<net::NetLogEntry> entries = GetEntries(); + std::vector<net::NetLogEventType> types = GetTypesOfNetLogEntries(entries); + ASSERT_THAT(types, + Contains(net::NetLogEventType::CORS_PREFLIGHT_RESULT).Times(1)); + ASSERT_THAT(types, + Contains(net::NetLogEventType::CORS_PREFLIGHT_ERROR).Times(1)); + + const net::NetLogEntry* entry = + FindEntryByType(entries, net::NetLogEventType::CORS_PREFLIGHT_RESULT); + ASSERT_EQ(entry->params.type(), base::Value::Type::DICT); + EXPECT_THAT( + entry->params.GetDict().FindString("access-control-allow-methods"), + Pointee(Eq("GET"))); + + entry = FindEntryByType(entries, net::NetLogEventType::CORS_PREFLIGHT_ERROR); + const base::Value::Dict* params = entry->params.GetIfDict(); + ASSERT_TRUE(params); + EXPECT_THAT(params->FindString("error"), Pointee(Eq("ERR_FAILED"))); + EXPECT_THAT(params->FindInt("cors-error"), + Optional(Eq(static_cast<int>( + mojom::CorsError::kMethodDisallowedByPreflightResponse)))); + EXPECT_THAT(params->FindString("failed-parameter"), Pointee(Eq("PUT"))); +} + +TEST_F(CorsURLLoaderTest, NetLogPreflightNetError) { + auto initiator = url::Origin::Create(GURL("https://foo.example")); + ResetFactory(initiator, mojom::kBrowserProcessId); + + ResourceRequest request; + request.method = "PUT"; + request.mode = mojom::RequestMode::kCors; + request.url = GURL("https://example.com/"); + request.request_initiator = initiator; + + CreateLoaderAndStart(request); + RunUntilCreateLoaderAndStartCalled(); + NotifyLoaderClientOnComplete(net::ERR_INVALID_ARGUMENT); + RunUntilComplete(); + + std::vector<net::NetLogEntry> entries = GetEntries(); + const auto type = net::NetLogEventType::CORS_PREFLIGHT_ERROR; + ASSERT_THAT(GetTypesOfNetLogEntries(entries), Contains(type).Times(1)); + + const net::NetLogEntry* entry = FindEntryByType(entries, type); + const base::Value::Dict* params = entry->params.GetIfDict(); + EXPECT_THAT(params->FindString("error"), Pointee(Eq("ERR_INVALID_ARGUMENT"))); + EXPECT_THAT(params->FindInt("cors-error"), Eq(absl::nullopt)); + EXPECT_THAT(params->FindString("failed-parameter"), IsNull()); +} + TEST_F(CorsURLLoaderTest, PreflightMissingAllowOrigin) { auto initiator = url::Origin::Create(GURL("https://foo.example")); ResetFactory(initiator, mojom::kBrowserProcessId);
diff --git a/services/network/cors/preflight_controller.cc b/services/network/cors/preflight_controller.cc index e6073a60..cfe2046 100644 --- a/services/network/cors/preflight_controller.cc +++ b/services/network/cors/preflight_controller.cc
@@ -338,15 +338,15 @@ } absl::optional<CorsErrorStatus> CheckPreflightResult( - PreflightResult* result, + const PreflightResult& result, const ResourceRequest& original_request, NonWildcardRequestHeadersSupport non_wildcard_request_headers_support) { absl::optional<CorsErrorStatus> status = - result->EnsureAllowedCrossOriginMethod(original_request.method); + result.EnsureAllowedCrossOriginMethod(original_request.method); if (status) return status; - return result->EnsureAllowedCrossOriginHeaders( + return result.EnsureAllowedCrossOriginHeaders( original_request.headers, original_request.is_revalidating, non_wildcard_request_headers_support); } @@ -471,9 +471,8 @@ // Preflight succeeded. Check `original_request_` with `result`. DCHECK(!detected_error_status); - detected_error_status = - CheckPreflightResult(result.get(), original_request_, - non_wildcard_request_headers_support_); + detected_error_status = CheckPreflightResult( + *result, original_request_, non_wildcard_request_headers_support_); has_authorization_covered_by_wildcard = result->HasAuthorizationCoveredByWildcard(original_request_.headers); }
diff --git a/services/network/cors/preflight_result.cc b/services/network/cors/preflight_result.cc index 2d6386b..f78671da 100644 --- a/services/network/cors/preflight_result.cc +++ b/services/network/cors/preflight_result.cc
@@ -102,6 +102,12 @@ return true; } +// Joins the strings in the given `set ` with commas. +std::string JoinSet(const base::flat_set<std::string>& set) { + std::vector<base::StringPiece> values(set.begin(), set.end()); + return base::JoinString(values, ","); +} + } // namespace // static @@ -270,14 +276,10 @@ !headers_.contains(kAuthorization); } -base::Value PreflightResult::NetLogParams() { +base::Value PreflightResult::NetLogParams() const { base::Value dict(base::Value::Type::DICTIONARY); - std::vector<std::string> methods(methods_.begin(), methods_.end()); - std::vector<std::string> headers(headers_.begin(), headers_.end()); - dict.SetStringKey("access-control-allow-methods", - base::JoinString(methods, ",")); - dict.SetStringKey("access-control-allow-headers", - base::JoinString(headers, ",")); + dict.SetStringKey("access-control-allow-methods", JoinSet(methods_)); + dict.SetStringKey("access-control-allow-headers", JoinSet(headers_)); return dict; }
diff --git a/services/network/cors/preflight_result.h b/services/network/cors/preflight_result.h index 5e08b5a8..fedb8bf 100644 --- a/services/network/cors/preflight_result.h +++ b/services/network/cors/preflight_result.h
@@ -95,11 +95,12 @@ bool HasAuthorizationCoveredByWildcard( const net::HttpRequestHeaders& headers) const; - // Refers the cache expiry time. + // Returns the cache expiry time. base::TimeTicks absolute_expiry_time() const { return absolute_expiry_time_; } - // Create a param for NetLog. - base::Value NetLogParams(); + // Returns params for the `CORS_PREFLIGHT_RESULT` and + // `CORS_PREFLIGHT_CACHED_RESULT` net log events. + base::Value NetLogParams() const; protected: explicit PreflightResult(const mojom::CredentialsMode credentials_mode);
diff --git a/sql/database.h b/sql/database.h index 2bc45a94..7482260 100644 --- a/sql/database.h +++ b/sql/database.h
@@ -232,7 +232,8 @@ // The callback will never be called after the Database instance is destroyed. using ErrorCallback = base::RepeatingCallback<void(int, Statement*)>; void set_error_callback(ErrorCallback callback) { - DCHECK(error_callback_.is_null() || callback.is_null()) + DCHECK(!callback.is_null()) << "Use reset_error_callback() explicitly"; + DCHECK(error_callback_.is_null()) << "Overwriting previously set error callback"; error_callback_ = std::move(callback); }
diff --git a/sql/error_metrics.cc b/sql/error_metrics.cc index 1724582..aadc386c 100644 --- a/sql/error_metrics.cc +++ b/sql/error_metrics.cc
@@ -5,12 +5,14 @@ #include "sql/error_metrics.h" #include <ostream> // Needed to compile NOTREACHED() with operator <<. +#include <set> #include <utility> #include "base/check_op.h" #include "base/metrics/histogram_functions.h" #include "base/notreached.h" #include "base/ranges/algorithm.h" +#include "base/strings/string_piece.h" #include "third_party/sqlite/sqlite3.h" namespace sql { @@ -26,6 +28,7 @@ {SQLITE_INTERNAL, SqliteLoggedResultCode::kUnusedSqlite}, {SQLITE_PERM, SqliteLoggedResultCode::kPermission}, {SQLITE_ABORT, SqliteLoggedResultCode::kAbort}, + {SQLITE_BUSY, SqliteLoggedResultCode::kBusy}, // Chrome features shouldn't execute conflicting statements concurrently. {SQLITE_LOCKED, SqliteLoggedResultCode::kUnusedChrome}, @@ -122,7 +125,7 @@ #endif // Chrome does not use blocking Posix advisory file lock requests. - {SQLITE_ERROR_SNAPSHOT, SqliteLoggedResultCode::kUnusedChrome}, + {SQLITE_BUSY_TIMEOUT, SqliteLoggedResultCode::kUnusedChrome}, #ifdef SQLITE_ENABLE_SETLK_TIMEOUT #error "This code assumes that Chrome does not use #endif @@ -256,4 +259,55 @@ base::UmaHistogramEnumeration(histogram_name, logged_code); } +void CheckSqliteLoggedResultCodeForTesting() { + // Ensure that error codes are alphabetical. + const auto* unordered_it = base::ranges::adjacent_find( + kResultCodeMapping, + [](const std::pair<int, SqliteLoggedResultCode>& lhs, + const std::pair<int, SqliteLoggedResultCode>& rhs) { + return lhs >= rhs; + }); + DCHECK_EQ(unordered_it, base::ranges::end(kResultCodeMapping)) + << "Mapping ordering broken at {" << unordered_it->first << ", " + << static_cast<int>(unordered_it->second) << "}"; + + std::set<int> sqlite_result_codes; + for (auto& mapping_entry : kResultCodeMapping) + sqlite_result_codes.insert(mapping_entry.first); + + // SQLite doesn't have special messages for extended errors. + // At the time of this writing, sqlite3_errstr() has a string table for + // primary result codes, and uses it for extended error codes as well. + // + // So, we can only use sqlite3_errstr() to check for holes in the primary + // message table. + for (int result_code = 0; result_code <= 256; ++result_code) { + if (sqlite_result_codes.count(result_code) != 0) + continue; + + const char* error_message = sqlite3_errstr(result_code); + + static constexpr base::StringPiece kUnknownErrorMessage("unknown error"); + DCHECK_EQ(kUnknownErrorMessage.compare(error_message), 0) + << "Unmapped SQLite result code: " << result_code + << " SQLite message: " << error_message; + } + + // Number of #defines in https://www.sqlite.org/c3ref/c_abort.html + // + // This number is also stated at + // https://www.sqlite.org/rescode.html#primary_result_code_list + static constexpr int kPrimaryResultCodes = 31; + + // Number of #defines in https://www.sqlite.org/c3ref/c_abort_rollback.html + // + // This number is also stated at + // https://www.sqlite.org/rescode.html#extended_result_code_list + static constexpr int kExtendedResultCodes = 74; + + DCHECK_EQ(std::size(kResultCodeMapping), + size_t{kPrimaryResultCodes + kExtendedResultCodes}) + << "Mapping table has incorrect number of entries"; +} + } // namespace sql
diff --git a/sql/error_metrics.h b/sql/error_metrics.h index 300c262e..980439a 100644 --- a/sql/error_metrics.h +++ b/sql/error_metrics.h
@@ -218,6 +218,12 @@ COMPONENT_EXPORT(SQL) SqliteLoggedResultCode CreateSqliteLoggedResultCode(int sqlite_result_code); +// Called by unit tests. +// +// DCHECKs the representation invariants of the mapping table used to convert +// SQLite result codes to logging-friendly values. +COMPONENT_EXPORT(SQL) void CheckSqliteLoggedResultCodeForTesting(); + } // namespace sql #endif // SQL_ERROR_METRICS_H_
diff --git a/sql/error_metrics_unittest.cc b/sql/error_metrics_unittest.cc index 75f92bb..63350bc 100644 --- a/sql/error_metrics_unittest.cc +++ b/sql/error_metrics_unittest.cc
@@ -62,21 +62,13 @@ #endif } -// TODO(crbug.com/1306382): Fails when dcheck_always_on = false. -#if !DCHECK_IS_ON() -#define MAYBE_CreateSqliteLoggedResultCode_ChromeBugError \ - DISABLED_CreateSqliteLoggedResultCode_ChromeBugError -#else -#define MAYBE_CreateSqliteLoggedResultCode_ChromeBugError \ - CreateSqliteLoggedResultCode_ChromeBugError -#endif // DCHECK_IS_ON() -TEST(ErrorMetricsTest, MAYBE_CreateSqliteLoggedResultCode_ChromeBugError) { +TEST(ErrorMetricsTest, CreateSqliteLoggedResultCode_ChromeBugError) { #if DCHECK_IS_ON() EXPECT_DCHECK_DEATH_WITH( CreateSqliteLoggedResultCode(SQLITE_NOTFOUND), "SQLite reported code that should never show up in Chrome: 12"); #else - EXPECT_EQ(SqliteLoggedResultCode::kUnusedSqlite, + EXPECT_EQ(SqliteLoggedResultCode::kUnusedChrome, CreateSqliteLoggedResultCode(SQLITE_NOTFOUND)); #endif } @@ -105,6 +97,10 @@ SqliteLoggedResultCode::kCorruptIndex, 1); } +TEST(ErrorMetricsTest, CheckMapping) { + CheckSqliteLoggedResultCodeForTesting(); +} + } // namespace } // namespace sql
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 64bade6..9ff8668 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5801,7 +5801,7 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4944.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4946.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "isolate_profile_data": true, @@ -5809,14 +5809,14 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 101.0.4944.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 101.0.4946.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v101.0.4944.0", - "revision": "version:101.0.4944.0" + "location": "lacros_version_skew_tests_v101.0.4946.0", + "revision": "version:101.0.4946.0" } ], "dimension_sets": [ @@ -5943,7 +5943,7 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4944.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4946.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "isolate_profile_data": true, @@ -5951,14 +5951,14 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 101.0.4944.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 101.0.4946.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v101.0.4944.0", - "revision": "version:101.0.4944.0" + "location": "lacros_version_skew_tests_v101.0.4946.0", + "revision": "version:101.0.4946.0" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 7a6489d..1460351 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -85096,7 +85096,7 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4944.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4946.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "isolate_profile_data": true, @@ -85104,14 +85104,14 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 101.0.4944.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 101.0.4946.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v101.0.4944.0", - "revision": "version:101.0.4944.0" + "location": "lacros_version_skew_tests_v101.0.4946.0", + "revision": "version:101.0.4946.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -85213,7 +85213,7 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4944.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4946.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "isolate_profile_data": true, @@ -85221,14 +85221,14 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 101.0.4944.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 101.0.4946.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v101.0.4944.0", - "revision": "version:101.0.4944.0" + "location": "lacros_version_skew_tests_v101.0.4946.0", + "revision": "version:101.0.4946.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -86595,21 +86595,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4944.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4946.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 101.0.4944.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 101.0.4946.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v101.0.4944.0", - "revision": "version:101.0.4944.0" + "location": "lacros_version_skew_tests_v101.0.4946.0", + "revision": "version:101.0.4946.0" } ], "dimension_sets": [ @@ -86737,21 +86737,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4944.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4946.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 101.0.4944.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 101.0.4946.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v101.0.4944.0", - "revision": "version:101.0.4944.0" + "location": "lacros_version_skew_tests_v101.0.4946.0", + "revision": "version:101.0.4946.0" } ], "dimension_sets": [ @@ -88292,21 +88292,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4944.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4946.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 101.0.4944.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 101.0.4946.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v101.0.4944.0", - "revision": "version:101.0.4944.0" + "location": "lacros_version_skew_tests_v101.0.4946.0", + "revision": "version:101.0.4946.0" } ], "dimension_sets": [ @@ -88434,21 +88434,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4944.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4946.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 101.0.4944.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 101.0.4946.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v101.0.4944.0", - "revision": "version:101.0.4944.0" + "location": "lacros_version_skew_tests_v101.0.4946.0", + "revision": "version:101.0.4946.0" } ], "dimension_sets": [ @@ -89185,21 +89185,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4944.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4946.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 101.0.4944.0", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 101.0.4946.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v101.0.4944.0", - "revision": "version:101.0.4944.0" + "location": "lacros_version_skew_tests_v101.0.4946.0", + "revision": "version:101.0.4946.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -89281,21 +89281,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4944.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4946.0/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 101.0.4944.0", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 101.0.4946.0", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v101.0.4944.0", - "revision": "version:101.0.4944.0" + "location": "lacros_version_skew_tests_v101.0.4946.0", + "revision": "version:101.0.4946.0" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/testing/buildbot/chromium.rust.json b/testing/buildbot/chromium.rust.json index a3d05ad..261cb22 100644 --- a/testing/buildbot/chromium.rust.json +++ b/testing/buildbot/chromium.rust.json
@@ -1,6 +1,84 @@ { "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {}, "AAAAA2 See generate_buildbot_json.py to make changes": {}, + "android-rust-arm-dbg": { + "additional_compile_targets": [ + "mojo_rust", + "rust_build_tests" + ], + "gtest_tests": [ + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "base_unittests", + "test_id_prefix": "ninja://base:base_unittests/" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "rust_gtest_interop_unittests", + "test_id_prefix": "ninja://testing/rust_gtest_interop:rust_gtest_interop_unittests/" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "test_cpp_including_rust_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "test_cpp_including_rust_unittests", + "test_id_prefix": "ninja://build/rust/tests/test_cpp_including_rust:test_cpp_including_rust_unittests/" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "test_serde_jsonrc", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "device_os": "MMB29Q" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "test_serde_jsonrc", + "test_id_prefix": "ninja://build/rust/tests/test_serde_jsonrc:test_serde_jsonrc/" + } + ] + }, "android-rust-arm-rel": { "additional_compile_targets": [ "mojo_rust", @@ -168,6 +246,95 @@ } ] }, + "linux-rust-x64-dbg": { + "additional_compile_targets": [ + "mojo_rust", + "mojo_rust_tests", + "rust_build_tests" + ], + "gtest_tests": [ + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "base_unittests", + "test_id_prefix": "ninja://base:base_unittests/" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "rust_gtest_interop_unittests", + "test_id_prefix": "ninja://testing/rust_gtest_interop:rust_gtest_interop_unittests/" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "test_cpp_including_rust_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "test_cpp_including_rust_unittests", + "test_id_prefix": "ninja://build/rust/tests/test_cpp_including_rust:test_cpp_including_rust_unittests/" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "test_serde_jsonrc", + "swarming": { + "can_use_on_swarming_builders": true, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "test_serde_jsonrc", + "test_id_prefix": "ninja://build/rust/tests/test_serde_jsonrc:test_serde_jsonrc/" + } + ], + "isolated_scripts": [ + { + "isolate_name": "build_rust_tests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "build_rust_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "build_rust_tests", + "test_id_prefix": "ninja://build/rust/tests:build_rust_tests/" + }, + { + "isolate_name": "mojo_rust_tests", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "mojo_rust_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "mojo_rust_tests", + "test_id_prefix": "ninja://mojo/public/rust:mojo_rust_tests/" + } + ] + }, "linux-rust-x64-rel": { "additional_compile_targets": [ "mojo_rust",
diff --git a/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter b/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter index 5632132..b3a7453 100644 --- a/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter +++ b/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter
@@ -88,9 +88,9 @@ -InitialEnrollmentTest.* -InterruptedAutoStartEnrollmentTest.* -InvalidPendingScreenTest.* +-KioskConsumerTest.* -KioskEnrollmentTest.* -KioskEnterpriseTest.* --KioskHiddenWebUITest.* -KioskTest.* -KioskUpdateTest.* -KioskVirtualKeyboardTest.*
diff --git a/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter b/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter index ebdff59e..14ede5a 100644 --- a/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter +++ b/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter
@@ -88,9 +88,9 @@ InitialEnrollmentTest.* InterruptedAutoStartEnrollmentTest.* InvalidPendingScreenTest.* +KioskConsumerTest.* KioskEnrollmentTest.* KioskEnterpriseTest.* -KioskHiddenWebUITest.* KioskTest.* KioskUpdateTest.* KioskVirtualKeyboardTest.*
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 0383ff0..8779701 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -28,16 +28,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4944.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v101.0.4946.0/test_ash_chrome', '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter', ], - 'identifier': 'Lacros version skew testing ash 101.0.4944.0', + 'identifier': 'Lacros version skew testing ash 101.0.4946.0', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v101.0.4944.0', - 'revision': 'version:101.0.4944.0', + 'location': 'lacros_version_skew_tests_v101.0.4946.0', + 'revision': 'version:101.0.4946.0', }, ], },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index c6ac3ca..8d8ce75c 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -5526,6 +5526,19 @@ 'name': 'chromium.rust', 'mixins': ['chromium-tester-service-account'], 'machines': { + 'android-rust-arm-dbg': { + 'additional_compile_targets': [ + 'mojo_rust', + 'rust_build_tests', + ], + 'mixins': [ 'marshmallow' ], + 'test_suites': { + 'gtest_tests': 'rust_gtests', + # Currently `can_build_rust_unit_tests` is false on Android (because + # `rustc_can_link` is false). + # TODO(https://crbug.com/1260120): Cover `rust_native_tests` here. + }, + }, 'android-rust-arm-rel': { 'additional_compile_targets': [ 'mojo_rust', @@ -5550,6 +5563,17 @@ 'isolated_scripts': 'rust_native_tests', }, }, + 'linux-rust-x64-dbg' : { + 'additional_compile_targets': [ + 'mojo_rust', + 'mojo_rust_tests', + 'rust_build_tests', + ], + 'test_suites': { + 'gtest_tests': 'rust_gtests', + 'isolated_scripts': 'rust_native_tests', + }, + }, 'linux-rust-x64-rel' : { 'additional_compile_targets': [ 'mojo_rust',
diff --git a/testing/rust_gtest_interop/rust_gtest_interop.cc b/testing/rust_gtest_interop/rust_gtest_interop.cc index 126080d95..f75e2b8 100644 --- a/testing/rust_gtest_interop/rust_gtest_interop.cc +++ b/testing/rust_gtest_interop/rust_gtest_interop.cc
@@ -10,8 +10,8 @@ namespace { -// The C++ test fixture used for all Rust unit tests. It provides nothing except -// the test body which calls thr Rust function. +// The default C++ test fixture used for Rust unit tests. It provides nothing +// except the test body which calls the Rust function. class RustTest : public testing::Test { public: explicit RustTest(void (&test_fn)()) : test_fn_(test_fn) {} @@ -23,12 +23,17 @@ } // namespace -void rust_gtest_add_test(void (*test_fn)(), +GtestFactory rust_gtest_default_factory() { + return [](void (*f)()) -> testing::Test* { return new RustTest(*f); }; +} + +void rust_gtest_add_test(GtestFactory gtest_factory, + void (*test_function)(), const char* test_suite_name, const char* test_name, const char* file, int32_t line) { - auto factory = [=]() -> testing::Test* { return new RustTest(*test_fn); }; + auto factory = [=]() { return gtest_factory(test_function); }; testing::RegisterTest(test_suite_name, test_name, nullptr, nullptr, file, line, factory); }
diff --git a/testing/rust_gtest_interop/rust_gtest_interop.h b/testing/rust_gtest_interop/rust_gtest_interop.h index 14d8cbe0..0b44a44 100644 --- a/testing/rust_gtest_interop/rust_gtest_interop.h +++ b/testing/rust_gtest_interop/rust_gtest_interop.h
@@ -9,8 +9,21 @@ #include "third_party/rust/cxx/v1/crate/include/cxx.h" +namespace testing { +class Test; +} + namespace rust_gtest_interop { +// The factory function which will construct a testing::Test subclass that runs +// the given function pointer as the test body. The factory function exists to +// allow choosing different subclasses of testing::Test. +using GtestFactory = testing::Test* (*)(void (*)()); + +// Returns a factory that will run the test function. Used for any Rust tests +// that don't need a specific C++ testing::Test subclass. +GtestFactory rust_gtest_default_factory(); + // Register a test to be run via GTest. This must be called before main(), as // there's no calls from C++ into Rust to collect tests. Any function given to // this function will be included in the set of tests run by the RUN_ALL_TESTS() @@ -22,7 +35,8 @@ // // SAFETY: This function makes copies of the strings so the pointers do not need // to outlive the function call. -void rust_gtest_add_test(void (*test_fn)(), +void rust_gtest_add_test(GtestFactory gtest_factory, + void (*test_function)(), const char* test_suite_name, const char* test_name, const char* file,
diff --git a/testing/rust_gtest_interop/rust_gtest_interop.rs b/testing/rust_gtest_interop/rust_gtest_interop.rs index 817288d..5353617 100644 --- a/testing/rust_gtest_interop/rust_gtest_interop.rs +++ b/testing/rust_gtest_interop/rust_gtest_interop.rs
@@ -81,38 +81,86 @@ } } - extern "C" { - /// The C++ mangled name for rust_gtest_interop::rust_gtest_add_test(). This comes from - /// `objdump -t` on the C++ object file. - /// - /// TODO(danakj): We do this by hand because cxx doesn't support passing raw function - /// pointers nor passing `*const c_char`: https://github.com/dtolnay/cxx/issues/1011 and - /// https://github.com/dtolnay/cxx/issues/1015. - fn _ZN18rust_gtest_interop19rust_gtest_add_testEPFvvEPKcS3_S3_i( - func: extern "C" fn(), - test_suite_name: *const std::os::raw::c_char, - test_name: *const std::os::raw::c_char, - file: *const std::os::raw::c_char, - line: i32, - ); + /// Used in the function pointer return type of rust_gtest_default_factory() in order to keep + /// some type safety while erasing the C++ rust_gtest_interop::GtestFactory's type. + #[non_exhaustive] + #[repr(C)] + struct GTestFactoryPtr(usize); + + /// Wrapper that calls C++ rust_gtest_default_factory(). + /// + /// The function returns a function pointer to a C++ type that Rust doesn't know about, since + /// we're not using generated C++ bindings. So we just represent the function pointer as a + /// `GTestFactoryPtr (*)()`. The function pointer only exists to be passed to + /// rust_gtest_add_test(), and Rust code must not call it since the actual signature is lost. + /// + /// # Safety + /// + /// Rust must not call the returned function pointer, the only thing Rust can do with it is pass + /// it to rust_gtest_add_test(). + /// + /// TODO(danakj): We do this by hand because cxx doesn't support function pointers + /// (https://github.com/dtolnay/cxx/issues/1011). We could wrap the function pointer in a + /// struct, but then we have to pass it in UniquePtr a function pointer with 'static lifetime. + /// We do this instead of introducing multiple levels of extra abstractions (a struct, + /// unique_ptr) and leaking heap memory. + unsafe fn rust_gtest_default_factory() -> extern "C" fn() -> GTestFactoryPtr { + extern "C" { + /// The C++ mangled name for rust_gtest_interop::rust_gtest_default_factory(). This + /// comes from `objdump -t` on the C++ object file. + fn _ZN18rust_gtest_interop26rust_gtest_default_factoryEv() + -> extern "C" fn() -> GTestFactoryPtr; + } + + _ZN18rust_gtest_interop26rust_gtest_default_factoryEv() } + /// Wrapper that calls C++ rust_gtest_add_test(). - fn rust_add_test( + /// + /// Note that the `factory` parameter is actually a C++ function pointer, of type + /// rust_gtest_interop::GtestFactory. However the function pointer includes C++ types Rust + /// doesn't know about and we are not using a C++ bindings generator to know about them. So we + /// cheat and just call it a `GTestFactoryPtr (*)()`. + /// + /// # Safety + /// + /// The `factory` function pointer can only be a pointer returned from + /// rust_gtest_default_factory(), or some other similar function that returns a C++ + /// `rust_gtest_interop::GtestFactory`. It is not actually a `GTestFactoryPtr (*)()`, so + /// other function pointers would be invalid. + /// + /// TODO(danakj): We do this by hand because cxx doesn't support passing raw function pointers + /// nor passing `*const c_char`: https://github.com/dtolnay/cxx/issues/1011 and + /// https://github.com/dtolnay/cxx/issues/1015. + unsafe fn rust_gtest_add_test( + factory: extern "C" fn() -> GTestFactoryPtr, func: extern "C" fn(), test_suite_name: *const std::os::raw::c_char, test_name: *const std::os::raw::c_char, file: *const std::os::raw::c_char, line: i32, ) { - unsafe { - _ZN18rust_gtest_interop19rust_gtest_add_testEPFvvEPKcS3_S3_i( - func, - test_suite_name, - test_name, - file, - line, - ) + extern "C" { + /// The C++ mangled name for rust_gtest_interop::rust_gtest_add_test(). This comes from + /// `objdump -t` on the C++ object file. + fn _ZN18rust_gtest_interop19rust_gtest_add_testEPFPN7testing4TestEPFvvEES4_PKcS8_S8_i( + factory: extern "C" fn() -> GTestFactoryPtr, + func: extern "C" fn(), + test_suite_name: *const std::os::raw::c_char, + test_name: *const std::os::raw::c_char, + file: *const std::os::raw::c_char, + line: i32, + ); } + + _ZN18rust_gtest_interop19rust_gtest_add_testEPFPN7testing4TestEPFvvEES4_PKcS8_S8_i( + factory, + func, + test_suite_name, + test_name, + file, + line, + ) } /// Information used to register a function pointer as a test with the C++ Gtest framework. @@ -131,13 +179,19 @@ /// thread, before main() is run. It may not panic, or call anything that may panic. pub fn register_test(r: TestRegistration) { let line = r.line.try_into().unwrap_or(-1); - rust_add_test( - r.func, - r.test_suite_name.as_ptr(), - r.test_name.as_ptr(), - r.file.as_ptr(), - line, - ); + // SAFETY: The `factory` parameter to rust_gtest_add_test() must be a type-erased C++ + // GtestFactory, which is what rust_gtest_default_factory() returns. + unsafe { + let factory = rust_gtest_default_factory(); + rust_gtest_add_test( + factory, + r.func, + r.test_suite_name.as_ptr(), + r.test_name.as_ptr(), + r.file.as_ptr(), + line, + ) + }; } }
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 0f70de4..4f899a5a 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2468,23 +2468,6 @@ ] } ], - "DesktopBookmarksBarAppShortcut": [ - { - "platforms": [ - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "AppsShortcutDefaultOff" - ] - } - ] - } - ], "DesktopNtpModules": [ { "platforms": [ @@ -6220,6 +6203,21 @@ ] } ], + "SmartLockUIRevamp": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_20220214", + "enable_features": [ + "SmartLockUIRevamp" + ] + } + ] + } + ], "SnoozeIPH": [ { "platforms": [
diff --git a/third_party/blink/public/mojom/mediastream/media_stream.mojom b/third_party/blink/public/mojom/mediastream/media_stream.mojom index f6441e8f..753b1db 100644 --- a/third_party/blink/public/mojom/mediastream/media_stream.mojom +++ b/third_party/blink/public/mojom/mediastream/media_stream.mojom
@@ -121,6 +121,13 @@ bool request_pan_tilt_zoom_permission; }; +// Results returned by a successful GetOpenDevice call. +struct GetOpenDeviceResponse { + string label; + MediaStreamDevice device; + bool pan_tilt_zoom_allowed; +}; + // Per-frame renderer-side interface that receives device stopped/change // notifications or pause requests from the browser process. interface MediaStreamDeviceObserver { @@ -212,6 +219,16 @@ mojo_base.mojom.Token crop_id, uint32 crop_version) => (media.mojom.CropRequestResult crop_result); + + // Get a MediaStreamDevice metadata object which refers to the same flow of + // media backing an existing MediaStreamDevice. + // + // This allows for example transferring of MediaStreamTracks between + // contexts: the receiving context calls GetOpenDevice with the session id + // of the MediaStreamDevice created by the original context. + // Response is null if and only if result != OK. + GetOpenDevice(mojo_base.mojom.UnguessableToken session_id) + => (MediaStreamRequestResult result, GetOpenDeviceResponse? response); }; // Browser-side interface that is used by the renderer process to notify the
diff --git a/third_party/blink/renderer/core/css/build.gni b/third_party/blink/renderer/core/css/build.gni index 4000f3a..ce29f22 100644 --- a/third_party/blink/renderer/core/css/build.gni +++ b/third_party/blink/renderer/core/css/build.gni
@@ -499,6 +499,7 @@ "parser/sizes_math_function_parser.h", "part_names.cc", "part_names.h", + "pending_sheet_type.h", "properties/computed_style_utils.cc", "properties/computed_style_utils.h", "properties/css_bitset.h",
diff --git a/third_party/blink/renderer/core/css/pending_sheet_type.h b/third_party/blink/renderer/core/css/pending_sheet_type.h new file mode 100644 index 0000000..96a1bab --- /dev/null +++ b/third_party/blink/renderer/core/css/pending_sheet_type.h
@@ -0,0 +1,16 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PENDING_SHEET_TYPE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PENDING_SHEET_TYPE_H_ + +#include <stdint.h> + +namespace blink { + +enum class PendingSheetType { kNone, kNonBlocking, kBlocking }; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PENDING_SHEET_TYPE_H_
diff --git a/third_party/blink/renderer/core/css/style_element.cc b/third_party/blink/renderer/core/css/style_element.cc index 200140f..8871ade 100644 --- a/third_party/blink/renderer/core/css/style_element.cc +++ b/third_party/blink/renderer/core/css/style_element.cc
@@ -31,6 +31,7 @@ #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/html/blocking_attribute.h" #include "third_party/blink/renderer/core/html/html_style_element.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/svg/svg_style_element.h" @@ -49,7 +50,8 @@ : created_by_parser_(created_by_parser), loading_(false), registered_as_candidate_(false), - start_position_(TextPosition::BelowRangePosition()) { + start_position_(TextPosition::BelowRangePosition()), + pending_sheet_type_(PendingSheetType::kNone) { if (created_by_parser && document && document->GetScriptableDocumentParser() && !document->IsInDocumentWrite()) { @@ -115,8 +117,11 @@ if (sheet_->IsLoading()) { DCHECK(IsSameObject(owner_element)); - owner_element.GetDocument().GetStyleEngine().RemovePendingSheet( - owner_element); + if (pending_sheet_type_ == PendingSheetType::kBlocking) { + owner_element.GetDocument().GetStyleEngine().RemovePendingSheet( + owner_element); + } + pending_sheet_type_ = PendingSheetType::kNone; } sheet_.Release()->ClearOwnerNode(); @@ -155,17 +160,27 @@ if (IsCSS(element, type) && passes_content_security_policy_checks) { scoped_refptr<MediaQuerySet> media_queries; const AtomicString& media_string = media(); + bool media_query_matches = true; if (!media_string.IsEmpty()) { media_queries = MediaQuerySet::Create(media_string, element.GetExecutionContext()); + if (LocalFrame* frame = document.GetFrame()) { + MediaQueryEvaluator evaluator(frame); + media_query_matches = evaluator.Eval(*media_queries); + } } + // TODO(crbug.com/1271296): Should be blocking only when created by parser + // or has `blocking="render"`, but created_by_parser_ flag is flipped to + // false in FinishParsingChildren(), which causes test failures. + pending_sheet_type_ = media_query_matches ? PendingSheetType::kBlocking + : PendingSheetType::kNonBlocking; loading_ = true; TextPosition start_position = start_position_ == TextPosition::BelowRangePosition() ? TextPosition::MinimumPosition() : start_position_; - new_sheet = - document.GetStyleEngine().CreateSheet(element, text, start_position); + new_sheet = document.GetStyleEngine().CreateSheet( + element, text, start_position, pending_sheet_type_); new_sheet->SetMediaQueries(media_queries); loading_ = false; } @@ -192,12 +207,16 @@ return false; DCHECK(IsSameObject(*sheet_->ownerNode())); - document.GetStyleEngine().RemovePendingSheet(*sheet_->ownerNode()); + if (pending_sheet_type_ == PendingSheetType::kBlocking) + document.GetStyleEngine().RemovePendingSheet(*sheet_->ownerNode()); + pending_sheet_type_ = PendingSheetType::kNone; return true; } void StyleElement::SetToPendingState(Document& document, Element& element) { DCHECK(IsSameObject(element)); + DCHECK_LT(pending_sheet_type_, PendingSheetType::kBlocking); + pending_sheet_type_ = PendingSheetType::kBlocking; document.GetStyleEngine().AddPendingSheet(element); }
diff --git a/third_party/blink/renderer/core/css/style_element.h b/third_party/blink/renderer/core/css/style_element.h index 11f910a..4ffa573 100644 --- a/third_party/blink/renderer/core/css/style_element.h +++ b/third_party/blink/renderer/core/css/style_element.h
@@ -22,10 +22,12 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_ELEMENT_H_ #include "third_party/blink/renderer/core/css/css_style_sheet.h" +#include "third_party/blink/renderer/core/css/pending_sheet_type.h" #include "third_party/blink/renderer/platform/wtf/text/text_position.h" namespace blink { +class BlockingAttribute; class ContainerNode; class Document; class Element; @@ -42,6 +44,7 @@ virtual const AtomicString& type() const = 0; virtual const AtomicString& media() const = 0; + virtual BlockingAttribute* blocking() const = 0; // Returns whether |this| and |node| are the same object. Helps us verify // parameter validity in certain member functions with an Element parameter @@ -70,6 +73,7 @@ bool loading_ : 1; bool registered_as_candidate_ : 1; TextPosition start_position_; + PendingSheetType pending_sheet_type_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index 21da7da0..bb120804 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -739,11 +739,13 @@ CSSStyleSheet* StyleEngine::CreateSheet(Element& element, const String& text, - TextPosition start_position) { + TextPosition start_position, + PendingSheetType type) { DCHECK(element.GetDocument() == GetDocument()); CSSStyleSheet* style_sheet = nullptr; - AddPendingSheet(element); + if (type == PendingSheetType::kBlocking) + AddPendingSheet(element); AtomicString text_content(text);
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index 7e2059c..725d98b 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -44,6 +44,7 @@ #include "third_party/blink/renderer/core/css/invalidation/pending_invalidations.h" #include "third_party/blink/renderer/core/css/invalidation/style_invalidator.h" #include "third_party/blink/renderer/core/css/layout_tree_rebuild_root.h" +#include "third_party/blink/renderer/core/css/pending_sheet_type.h" #include "third_party/blink/renderer/core/css/rule_feature_set.h" #include "third_party/blink/renderer/core/css/style_invalidation_root.h" #include "third_party/blink/renderer/core/css/style_recalc_root.h" @@ -351,7 +352,8 @@ CSSStyleSheet* CreateSheet(Element&, const String& text, - WTF::TextPosition start_position); + WTF::TextPosition start_position, + PendingSheetType type); void CollectFeaturesTo(RuleFeatureSet& features);
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 7f95472..06b9cf2 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -777,14 +777,14 @@ String sheet_text("div {}"); TextPosition min_pos = TextPosition::MinimumPosition(); - CSSStyleSheet* sheet1 = - GetStyleEngine().CreateSheet(*element, sheet_text, min_pos); + CSSStyleSheet* sheet1 = GetStyleEngine().CreateSheet( + *element, sheet_text, min_pos, PendingSheetType::kNonBlocking); // Check that the first sheet is not using a cached StyleSheetContents. EXPECT_FALSE(sheet1->Contents()->IsUsedFromTextCache()); - CSSStyleSheet* sheet2 = - GetStyleEngine().CreateSheet(*element, sheet_text, min_pos); + CSSStyleSheet* sheet2 = GetStyleEngine().CreateSheet( + *element, sheet_text, min_pos, PendingSheetType::kNonBlocking); // Check that the second sheet uses the cached StyleSheetContents for the // first. @@ -801,7 +801,8 @@ element = MakeGarbageCollected<HTMLStyleElement>(GetDocument(), CreateElementFlags()); - sheet1 = GetStyleEngine().CreateSheet(*element, sheet_text, min_pos); + sheet1 = GetStyleEngine().CreateSheet(*element, sheet_text, min_pos, + PendingSheetType::kNonBlocking); // Check that we did not use a cached StyleSheetContents after the garbage // collection.
diff --git a/third_party/blink/renderer/core/html/html_style_element.h b/third_party/blink/renderer/core/html/html_style_element.h index f2e6e84..c1c7459 100644 --- a/third_party/blink/renderer/core/html/html_style_element.h +++ b/third_party/blink/renderer/core/html/html_style_element.h
@@ -44,7 +44,7 @@ bool disabled() const; void setDisabled(bool); - BlockingAttribute& blocking() const { return *blocking_attribute_; } + BlockingAttribute* blocking() const override { return blocking_attribute_; } void Trace(Visitor*) const override;
diff --git a/third_party/blink/renderer/core/html/link_style.cc b/third_party/blink/renderer/core/html/link_style.cc index 9f48335..ddcb2da2 100644 --- a/third_party/blink/renderer/core/html/link_style.cc +++ b/third_party/blink/renderer/core/html/link_style.cc
@@ -37,7 +37,7 @@ LinkStyle::LinkStyle(HTMLLinkElement* owner) : LinkResource(owner), disabled_state_(kUnset), - pending_sheet_type_(kNone), + pending_sheet_type_(PendingSheetType::kNone), render_blocking_behavior_(RenderBlockingBehavior::kUnset), loading_(false), fired_load_(false), @@ -151,8 +151,8 @@ } void LinkStyle::SetToPendingState() { - DCHECK_LT(pending_sheet_type_, kBlocking); - AddPendingSheet(kBlocking); + DCHECK_LT(pending_sheet_type_, PendingSheetType::kBlocking); + AddPendingSheet(PendingSheetType::kBlocking); } void LinkStyle::ClearSheet() { @@ -174,7 +174,7 @@ return; pending_sheet_type_ = type; - if (pending_sheet_type_ == kNonBlocking) + if (pending_sheet_type_ == PendingSheetType::kNonBlocking) return; GetDocument().GetStyleEngine().AddPendingSheet(*owner_); } @@ -182,11 +182,11 @@ void LinkStyle::RemovePendingSheet() { DCHECK(owner_); PendingSheetType type = pending_sheet_type_; - pending_sheet_type_ = kNone; + pending_sheet_type_ = PendingSheetType::kNone; - if (type == kNone) + if (type == PendingSheetType::kNone) return; - if (type == kNonBlocking) { + if (type == PendingSheetType::kNonBlocking) { // Tell StyleEngine to re-compute styleSheets of this owner_'s treescope. GetDocument().GetStyleEngine().ModifiedStyleSheetCandidateNode(*owner_); return; @@ -215,7 +215,7 @@ // Check #2: An alternate sheet becomes enabled while it is still loading. if (owner_->RelAttribute().IsAlternate() && disabled_state_ == kEnabledViaScript) - AddPendingSheet(kBlocking); + AddPendingSheet(PendingSheetType::kBlocking); // Check #3: A main sheet becomes enabled while it was still loading and // after it was disabled via script. It takes really terrible code to make @@ -224,7 +224,7 @@ // only 3 sheets. :) if (!owner_->RelAttribute().IsAlternate() && disabled_state_ == kEnabledViaScript && old_disabled_state == kDisabled) - AddPendingSheet(kBlocking); + AddPendingSheet(PendingSheetType::kBlocking); // If the sheet is already loading just bail. return; @@ -285,7 +285,8 @@ (RuntimeEnabledFeatures::BlockingAttributeEnabled() && owner_->blocking().IsRenderBlocking())); - AddPendingSheet(render_blocking ? kBlocking : kNonBlocking); + AddPendingSheet(render_blocking ? PendingSheetType::kBlocking + : PendingSheetType::kNonBlocking); // Load stylesheets that are not needed for the layout immediately with low // priority. When the link element is created by scripts, load the
diff --git a/third_party/blink/renderer/core/html/link_style.h b/third_party/blink/renderer/core/html/link_style.h index 65d52b0..af256d2 100644 --- a/third_party/blink/renderer/core/html/link_style.h +++ b/third_party/blink/renderer/core/html/link_style.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LINK_STYLE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LINK_STYLE_H_ +#include "third_party/blink/renderer/core/css/pending_sheet_type.h" #include "third_party/blink/renderer/core/css/style_engine.h" #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/html/link_resource.h" @@ -65,8 +66,6 @@ enum DisabledState { kUnset, kEnabledViaScript, kDisabled }; - enum PendingSheetType { kNone, kNonBlocking, kBlocking }; - void ClearSheet(); void AddPendingSheet(PendingSheetType); void RemovePendingSheet();
diff --git a/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc b/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc index d132278..907fd4e 100644 --- a/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc +++ b/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
@@ -297,6 +297,10 @@ const String& id, const CanvasContextCreationAttributesCore& attributes) { DCHECK_EQ(execution_context, GetTopExecutionContext()); + + if (execution_context->IsContextDestroyed()) + return nullptr; + CanvasRenderingContext::CanvasRenderingAPI rendering_api = CanvasRenderingContext::RenderingAPIFromId(id, execution_context);
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index dfee14d..837811a 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -824,13 +824,12 @@ return nullptr; } -void PaintLayer::SetNeedsCompositingInputsUpdate(bool mark_ancestor_flags) { +void PaintLayer::SetNeedsCompositingInputsUpdate() { // TODO(chrishtr): These are a bit of a heavy hammer, because not all // things which require compositing inputs update require a descendant- // dependent flags update. Reduce call sites after CAP launch allows /// removal of CompositingInputsUpdater. - if (mark_ancestor_flags) - MarkAncestorChainForFlagsUpdate(kNeedsDescendantDependentUpdate); + MarkAncestorChainForFlagsUpdate(kNeedsDescendantDependentUpdate); } void PaintLayer::SetNeedsVisualOverflowRecalc() {
diff --git a/third_party/blink/renderer/core/paint/paint_layer.h b/third_party/blink/renderer/core/paint/paint_layer.h index 8ba80ac..66fb0654 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.h +++ b/third_party/blink/renderer/core/paint/paint_layer.h
@@ -520,7 +520,7 @@ return needs_visual_overflow_recalc_; } void SetNeedsVisualOverflowRecalc(); - void SetNeedsCompositingInputsUpdate(bool mark_ancestor_flags = true); + void SetNeedsCompositingInputsUpdate(); void UpdateAncestorScrollContainerLayer( const PaintLayer* ancestor_scroll_container_layer) {
diff --git a/third_party/blink/renderer/core/svg/svg_style_element.h b/third_party/blink/renderer/core/svg/svg_style_element.h index f6d7401..0383df44 100644 --- a/third_party/blink/renderer/core/svg/svg_style_element.h +++ b/third_party/blink/renderer/core/svg/svg_style_element.h
@@ -45,6 +45,8 @@ const AtomicString& media() const override; void setMedia(const AtomicString&); + BlockingAttribute* blocking() const override { return nullptr; } + String title() const override; void setTitle(const AtomicString&);
diff --git a/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h b/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h index 670bca61..1acf7e7 100644 --- a/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h +++ b/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h
@@ -59,6 +59,8 @@ uint32_t, CropCallback)); #endif + MOCK_METHOD2(GetOpenDevice, + void(const base::UnguessableToken&, GetOpenDeviceCallback)); void ResetSessionId() { session_id_ = base::UnguessableToken::Create(); } void DoNotRunCallback() { do_not_run_cb_ = true; }
diff --git a/third_party/blink/renderer/modules/subapps/sub_apps.cc b/third_party/blink/renderer/modules/subapps/sub_apps.cc index 54c7cce..8002bd9 100644 --- a/third_party/blink/renderer/modules/subapps/sub_apps.cc +++ b/third_party/blink/renderer/modules/subapps/sub_apps.cc
@@ -72,7 +72,9 @@ // static const char SubApps::kSupplementName[] = "SubApps"; -SubApps::SubApps(Navigator& navigator) : Supplement<Navigator>(navigator) {} +SubApps::SubApps(Navigator& navigator) + : Supplement<Navigator>(navigator), + service_(navigator.GetExecutionContext()) {} // static SubApps* SubApps::subApps(Navigator& navigator) { @@ -87,21 +89,27 @@ void SubApps::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); Supplement<Navigator>::Trace(visitor); + visitor->Trace(service_); } -mojo::Remote<mojom::blink::SubAppsService>& SubApps::GetService() { +HeapMojoRemote<mojom::blink::SubAppsService>& SubApps::GetService() { if (!service_.is_bound()) { - GetSupplementable() - ->GetExecutionContext() - ->GetBrowserInterfaceBroker() - .GetInterface(service_.BindNewPipeAndPassReceiver()); + auto* context = GetSupplementable()->GetExecutionContext(); + context->GetBrowserInterfaceBroker().GetInterface( + service_.BindNewPipeAndPassReceiver( + context->GetTaskRunner(TaskType::kMiscPlatformAPI))); // In case the other endpoint gets disconnected, we want to reset our end of // the pipe as well so that we don't remain connected to a half-open pipe. - service_.reset_on_disconnect(); + service_.set_disconnect_handler( + WTF::Bind(&SubApps::OnConnectionError, WrapWeakPersistent(this))); } return service_; } +void SubApps::OnConnectionError() { + service_.reset(); +} + ScriptPromise SubApps::add(ScriptState* script_state, const String& install_url, ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/modules/subapps/sub_apps.h b/third_party/blink/renderer/modules/subapps/sub_apps.h index c19e362..66dda28 100644 --- a/third_party/blink/renderer/modules/subapps/sub_apps.h +++ b/third_party/blink/renderer/modules/subapps/sub_apps.h
@@ -5,9 +5,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SUBAPPS_SUB_APPS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SUBAPPS_SUB_APPS_H_ -#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/subapps/sub_apps_service.mojom-blink.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" #include "third_party/blink/renderer/platform/supplementable.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -37,10 +37,11 @@ ScriptPromise list(ScriptState*, ExceptionState&); private: - mojo::Remote<mojom::blink::SubAppsService>& GetService(); + HeapMojoRemote<mojom::blink::SubAppsService>& GetService(); + void OnConnectionError(); bool CheckPreconditionsMaybeThrow(ExceptionState&); - mojo::Remote<mojom::blink::SubAppsService> service_; + HeapMojoRemote<mojom::blink::SubAppsService> service_; }; } // namespace blink
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 81b671e..ff9e74b3 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3377,6 +3377,8 @@ crbug.com/626703 [ Win ] virtual/partitioned-cookies/http/tests/inspector-protocol/network/disabled-cache-navigation.js [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Mac11-arm64 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html [ Timeout ] +crbug.com/626703 [ Mac10.15 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-value-010.https.html [ Failure ] crbug.com/626703 [ Mac10.12 ] virtual/fenced-frame-mparch/wpt_internal/fenced_frame/maxframes.https.html [ Timeout ] crbug.com/626703 [ Mac10.12 ] virtual/portals/external/wpt/portals/history/history-manipulation-inside-portal-with-subframes.html [ Timeout ] crbug.com/626703 [ Mac10.12 ] virtual/portals/wpt_internal/portals/create-many-portals.html [ Timeout ] @@ -7544,9 +7546,6 @@ # Need implementation of blocking=render on link headers crbug.com/1271296 virtual/no-forced-frame-updates/external/wpt/html/dom/render-blocking/header-inserted-preload-link.tentative.html [ Skip ] -# Need to unblock scripts on style elements when media doesn't match -crbug.com/1296736 external/wpt/html/semantics/document-metadata/interactions-of-styling-and-scripting/style-element-media-not-match-does-not-block-script.html [ Failure ] - # Sheriff 2022-02-07 crbug.com/1289759 [ Linux ] http/tests/loading/slow-parsing-subframe.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/WebGPUExpectations b/third_party/blink/web_tests/WebGPUExpectations index 03995769..82e89019 100644 --- a/third_party/blink/web_tests/WebGPUExpectations +++ b/third_party/blink/web_tests/WebGPUExpectations
@@ -41,7 +41,7 @@ [ Win ] wpt_internal/webgpu/cts.https.html?q=webgpu:web_platform,copyToTexture,ImageBitmap:from_ImageData:* [ Slow ] [ Win ] wpt_internal/webgpu/cts.https.html?q=webgpu:api,operation,rendering,draw:arguments:* [ Slow ] [ Win ] wpt_internal/webgpu/cts.https.html?q=webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_only:* [ Slow ] -# [ Mac ] wpt_internal/webgpu/cts.https.html?q=webgpu:api,operation,command_buffer,image_copy:rowsPerImage_and_bytesPerRow_depth_stencil:* [ Slow ] +[ Mac ] wpt_internal/webgpu/cts.https.html?q=webgpu:api,operation,command_buffer,image_copy:rowsPerImage_and_bytesPerRow_depth_stencil:* [ Slow ] # Intel only. Really slow and killed by the GPU watchdog? crbug.com/dawn/1046 [ Mac ] wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,robust_access_vertex:vertex_buffer_access:indexed=false;indirect=true;drawCallTestParameter="firstVertex";type="float32x4";* [ Slow Crash ] crbug.com/dawn/1046 [ Mac ] wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,robust_access_vertex:vertex_buffer_access:indexed=false;indirect=true;drawCallTestParameter="instanceCount";type="float32x4";* [ Slow Crash ] @@ -163,13 +163,6 @@ # Replace depth-clamp feature with depth-clip crbug.com/dawn/1178 wpt_internal/webgpu/cts.https.html?q=webgpu:api,operation,rendering,depth_clip_clamp:* [ Failure ] -# crbug.com/dawn/1281 -# Temporary. Failing a loadOp/storeOp validation error in Dawn. -# https://dawn-review.googlesource.com/c/dawn/+/82540 -wpt_internal/webgpu/cts.https.html?q=webgpu:api,validation,attachment_compatibility:render_pass_and_bundle,depth_format:* [ Failure ] -wpt_internal/webgpu/cts.https.html?q=webgpu:api,operation,command_buffer,image_copy:rowsPerImage_and_bytesPerRow_depth_stencil:* [ Skip ] # Skipped because it conflicted with a Slow expectation. -wpt_internal/webgpu/cts.https.html?q=webgpu:api,operation,command_buffer,image_copy:offsets_and_sizes_copy_depth_stencil:* [ Failure ] - # Our automated build does not support mp4 currently (fails on Linux, Mac, and Win Intel) wpt_internal/webgpu/cts.https.html?q=webgpu:web_platform,external_texture,video:importExternalTexture,sample:videoSource="red-green.mp4" [ Failure ]
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version index 809cf8e9..57450c9 100644 --- a/third_party/blink/web_tests/external/Version +++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@ -Version: 6bce541b6701e2517f5ddcd447e29d875bd8c822 +Version: 5f5ec4cff46e14ef86c249bbf24b63d35e6611ff
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 2b6d060..0b12f36 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
@@ -156547,6 +156547,32 @@ {} ] ], + "replaced-aspect-ratio-intrinsic-size-001.html": [ + "8c1f213dec9b200ad874e449aca38deb46d6bd91", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], + "replaced-aspect-ratio-intrinsic-size-002.html": [ + "daf6f36022d9cbda58fe7d758863617c5acf646f", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "replaced-aspect-ratio-stretch-fit-001.html": [ "0653c8284a4ad029f5fb6d21f706559a24e5bf72", [ @@ -247276,10 +247302,6 @@ "9d1fbaaf47b97cb82dc3003ffd2d46268100774e", [] ], - "idlharness-expected.txt": [ - "fda5da9e18277deb767a4abaf1479863dbac771b", - [] - ], "js": { "CSS-supports-CSSStyleDeclaration-expected.txt": [ "2e621a2f0ec3509e414ecdf7693d621c4de5c361", @@ -306126,7 +306148,7 @@ [] ], "css-conditional.idl": [ - "16f25583be97cfce8d4178fa68f43518e51195d2", + "d87f305fddf9e7c3f0151d51a595ae7140dce908", [] ], "css-counter-styles.idl": [ @@ -307214,7 +307236,7 @@ "early-hints": { "resources": { "early-hints-helpers.sub.js": [ - "72cebf9540ca0240a3360feb1cb5ce47e8b5838d", + "5c1b2198eaee880fe6cd0a97684619788fd07b8c", [] ], "early-hints-test-loader.h2.py": [ @@ -307226,7 +307248,7 @@ [] ], "empty.js.headers": [ - "175cdf80464a658981a55d09d788dee26bf1e1a0", + "74b688d1dcefad4376e4176eb4c023aecea1a632", [] ], "fetch-and-record-js.h2.py": [ @@ -307238,7 +307260,19 @@ [] ], "preload-initiator-type.html": [ - "39b0db0f89534c1f012985f9e7e86b715dccf6a9", + "0fdeb2b9037be8785880f71045a9facbc85fb394", + [] + ], + "redirect-cross-origin.html": [ + "39b37f81300bd722381de0b47e2d998a7c976574", + [] + ], + "redirect-same-origin.html": [ + "6a2246a2acd8cd0b035c04d9b18be7bff82811e0", + [] + ], + "redirect-with-early-hints.h2.py": [ + "e501d85a6b5c22469bec8133b846a9ff445e4f0d", [] ], "referrer-policy-test-loader.h2.py": [ @@ -307246,7 +307280,7 @@ [] ], "referrer-policy-test.html": [ - "af4f393d56f13ce62e9a436d60f97eb3749f40f7", + "d0389c2e11cce36ae0ed0ddee454809e7360b539", [] ], "utils.py": [ @@ -460411,6 +460445,15 @@ {} ] ], + "modal-dialog-selection.html": [ + "ab8dc4fd9842aaa6509a0bcae22df0b305fc3c6b", + [ + null, + { + "testdriver": true + } + ] + ], "multiple-centered-dialogs.html": [ "f9a62c5503c62aa019e6345a9080e0097af75faa", [ @@ -473200,6 +473243,42 @@ } ] ], + "redirect-cross-origin.h2.window.js": [ + "548759b19cc8441f3defbf6b412cce5e7b224179", + [ + "loading/early-hints/redirect-cross-origin.h2.window.html", + { + "script_metadata": [ + [ + "script", + "/common/utils.js" + ], + [ + "script", + "resources/early-hints-helpers.sub.js" + ] + ] + } + ] + ], + "redirect-same-origin.h2.window.js": [ + "88d64f399a77f975cc11ebc380e400b801fc06b3", + [ + "loading/early-hints/redirect-same-origin.h2.window.html", + { + "script_metadata": [ + [ + "script", + "/common/utils.js" + ], + [ + "script", + "resources/early-hints-helpers.sub.js" + ] + ] + } + ] + ], "referrer-policy-no-referrer.h2.window.js": [ "10f2c2c4bcda67541489dd1dd1a14426568d61a3", [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-conditional/idlharness-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-conditional/idlharness-expected.txt deleted file mode 100644 index fda5da9e..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-conditional/idlharness-expected.txt +++ /dev/null
@@ -1,44 +0,0 @@ -This is a testharness.js-based test. -PASS idl_test setup -PASS idl_test validation -PASS Partial interface CSSRule: original interface defined -PASS Partial interface CSSRule: member names are unique -PASS Partial namespace CSS: original namespace defined -PASS Partial namespace CSS: member names are unique -PASS CSSConditionRule interface: existence and properties of interface object -PASS CSSConditionRule interface object length -PASS CSSConditionRule interface object name -PASS CSSConditionRule interface: existence and properties of interface prototype object -PASS CSSConditionRule interface: existence and properties of interface prototype object's "constructor" property -PASS CSSConditionRule interface: existence and properties of interface prototype object's @@unscopables property -FAIL CSSConditionRule interface: attribute conditionText assert_equals: setter must be function for PutForwards, Replaceable, or non-readonly attributes expected "function" but got "undefined" -PASS CSSMediaRule interface: existence and properties of interface object -PASS CSSMediaRule interface object length -PASS CSSMediaRule interface object name -PASS CSSMediaRule interface: existence and properties of interface prototype object -PASS CSSMediaRule interface: existence and properties of interface prototype object's "constructor" property -PASS CSSMediaRule interface: existence and properties of interface prototype object's @@unscopables property -PASS CSSMediaRule interface: attribute media -PASS CSSMediaRule must be primary interface of cssMediaRule -PASS Stringification of cssMediaRule -PASS CSSMediaRule interface: cssMediaRule must inherit property "media" with the proper type -PASS CSSConditionRule interface: cssMediaRule must inherit property "conditionText" with the proper type -PASS CSSRule interface: cssMediaRule must inherit property "SUPPORTS_RULE" with the proper type -PASS CSSSupportsRule interface: existence and properties of interface object -PASS CSSSupportsRule interface object length -PASS CSSSupportsRule interface object name -PASS CSSSupportsRule interface: existence and properties of interface prototype object -PASS CSSSupportsRule interface: existence and properties of interface prototype object's "constructor" property -PASS CSSSupportsRule interface: existence and properties of interface prototype object's @@unscopables property -PASS CSSSupportsRule must be primary interface of cssSupportsRule -PASS Stringification of cssSupportsRule -PASS CSSConditionRule interface: cssSupportsRule must inherit property "conditionText" with the proper type -PASS CSSRule interface: cssSupportsRule must inherit property "SUPPORTS_RULE" with the proper type -PASS CSSRule interface: constant SUPPORTS_RULE on interface object -PASS CSSRule interface: constant SUPPORTS_RULE on interface prototype object -PASS CSSRule interface: cssRule must inherit property "SUPPORTS_RULE" with the proper type -PASS CSS namespace: operation escape(CSSOMString) -PASS CSS namespace: operation supports(CSSOMString, CSSOMString) -PASS CSS namespace: operation supports(CSSOMString) -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/css-conditional.idl b/third_party/blink/web_tests/external/wpt/interfaces/css-conditional.idl index 16f25583..d87f305 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/css-conditional.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/css-conditional.idl
@@ -9,7 +9,7 @@ [Exposed=Window] interface CSSConditionRule : CSSGroupingRule { - attribute CSSOMString conditionText; + readonly attribute CSSOMString conditionText; }; [Exposed=Window]
diff --git a/third_party/blink/web_tests/fast/canvas-api/OffscreenCanvas-getContext-executionContext-detached.html b/third_party/blink/web_tests/fast/canvas-api/OffscreenCanvas-getContext-executionContext-detached.html new file mode 100644 index 0000000..97d7de8 --- /dev/null +++ b/third_party/blink/web_tests/fast/canvas-api/OffscreenCanvas-getContext-executionContext-detached.html
@@ -0,0 +1,18 @@ +<html> +<body> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +test(function() { + function go() { + var iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + var offc = new iframe.contentWindow.OffscreenCanvas(69,69); + iframe.remove(); + var context = offc.getContext("2d"); + } + window.onload = go; +}, "Verify that calling getContext on an OffscreenCanvas whose parent iframe has been remove does not crash."); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/service-worker-interception-late-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/service-worker-interception-late-expected.txt index dbcc877..4787d80 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/service-worker-interception-late-expected.txt +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/service-worker-interception-late-expected.txt
@@ -5,4 +5,6 @@ [renderer] Request to http://127.0.0.1:8000/inspector-protocol/fetch/resources/empty.html, type: XHR [renderer] Request to http://127.0.0.1:8000/inspector-protocol/fetch/resources/fetch-data.txt, type: XHR Response after interception enabled: overriden response body +Stopped service worker +Disconnected from service worker
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/service-worker-interception-late.js b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/service-worker-interception-late.js index aa439be..4f3db6f 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/service-worker-interception-late.js +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/service-worker-interception-late.js
@@ -9,7 +9,6 @@ {autoAttach: true, waitForDebuggerOnStart: false, flatten: true}); dp.Target.onAttachedToTarget(async event => { serviceWorkerSession = session.createChild(event.params.sessionId); - }); await dp.ServiceWorker.enable(); @@ -23,9 +22,10 @@ const result = await dp.ServiceWorker.onceWorkerVersionUpdated(); versions = result.params.versions; } while (!versions.length || versions[0].status !== phase); + return versions[0]; } - await waitForServiceWorkerPhase("installing"); + const version = await waitForServiceWorkerPhase("installing"); const url = 'fetch-data.txt'; let content = await session.evaluateAsync(`fetch("${url}").then(r => r.text())`); @@ -63,5 +63,14 @@ content = await session.evaluateAsync(`fetch("${url}").then(r => r.text())`); testRunner.log(`Response after interception enabled: ${content}`); + // Stop worker and wait till it stopped, to make sure worker shutdown + // is covered (see https://crbug.com/1306006). + dp.ServiceWorker.stopWorker({versionId: version.versionId}); + await dp.ServiceWorker.onceWorkerVersionUpdated( + e => e.params.versions.length && e.params.versions[0].runningStatus === "stopped"), + + testRunner.log("Stopped service worker"); + await serviceWorkerSession.disconnect(); + testRunner.log("Disconnected from service worker"); testRunner.completeTest(); })
diff --git a/third_party/node/clean_json_attrs.py b/third_party/node/clean_json_attrs.py index 0ee0026..d5ea48c38 100755 --- a/third_party/node/clean_json_attrs.py +++ b/third_party/node/clean_json_attrs.py
@@ -13,7 +13,7 @@ removed = False - for key, val in json_dict.items(): + for key, val in list(json_dict.items()): if isinstance(val, dict): if _remove_attrs(val, attr_pattern): removed = True
diff --git a/third_party/webgpu-cts/ts_sources.txt b/third_party/webgpu-cts/ts_sources.txt index 3473f28..a1f4cb2 100644 --- a/third_party/webgpu-cts/ts_sources.txt +++ b/third_party/webgpu-cts/ts_sources.txt
@@ -54,8 +54,8 @@ src/stress/listing.ts src/webgpu/constants.ts src/stress/adapter/device_allocation.spec.ts +src/webgpu/util/constants.ts src/webgpu/util/conversion.ts -src/webgpu/shader/execution/builtin/builtin.ts src/webgpu/util/math.ts src/webgpu/util/unions.ts src/webgpu/util/texture/base.ts @@ -248,6 +248,8 @@ src/webgpu/idl/constants/flags.spec.ts src/webgpu/shader/types.ts src/webgpu/shader/values.ts +src/webgpu/util/compare.ts +src/webgpu/shader/execution/expression.ts src/webgpu/shader/execution/robust_access.spec.ts src/webgpu/shader/execution/robust_access_vertex.spec.ts src/webgpu/shader/execution/zero_init.spec.ts
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.h b/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.h index ccc21b1..465b358 100644 --- a/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.h +++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.h
@@ -682,6 +682,7 @@ virtual HRESULT STDMETHODCALLTYPE Update( /* [string][in] */ const WCHAR *app_id, + /* [string][in] */ const WCHAR *install_data_index, /* [in] */ BOOL same_version_update_allowed, /* [in] */ IUpdaterObserver *observer) = 0; @@ -733,6 +734,7 @@ HRESULT ( STDMETHODCALLTYPE *Update )( IUpdater * This, /* [string][in] */ const WCHAR *app_id, + /* [string][in] */ const WCHAR *install_data_index, /* [in] */ BOOL same_version_update_allowed, /* [in] */ IUpdaterObserver *observer); @@ -775,8 +777,8 @@ #define IUpdater_RunPeriodicTasks(This,callback) \ ( (This)->lpVtbl -> RunPeriodicTasks(This,callback) ) -#define IUpdater_Update(This,app_id,same_version_update_allowed,observer) \ - ( (This)->lpVtbl -> Update(This,app_id,same_version_update_allowed,observer) ) +#define IUpdater_Update(This,app_id,install_data_index,same_version_update_allowed,observer) \ + ( (This)->lpVtbl -> Update(This,app_id,install_data_index,same_version_update_allowed,observer) ) #define IUpdater_UpdateAll(This,observer) \ ( (This)->lpVtbl -> UpdateAll(This,observer) )
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.tlb b/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.tlb index 584f330f..725177697 100644 --- a/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.tlb +++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.tlb Binary files differ
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl_p.c b/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl_p.c index 246d3df..e55c3b1d 100644 --- a/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl_p.c +++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl_p.c
@@ -47,7 +47,7 @@ #include "updater_idl.h" #define TYPE_FORMAT_STRING_SIZE 145 -#define PROC_FORMAT_STRING_SIZE 805 +#define PROC_FORMAT_STRING_SIZE 811 #define EXPR_FORMAT_STRING_SIZE 1 #define TRANSMIT_AS_TABLE_SIZE 0 #define WIRE_MARSHAL_TABLE_SIZE 1 @@ -768,23 +768,23 @@ 0x6c, /* Old Flags: object, Oi2 */ /* 708 */ NdrFcLong( 0x0 ), /* 0 */ /* 712 */ NdrFcShort( 0x7 ), /* 7 */ -/* 714 */ NdrFcShort( 0x28 ), /* ARM64 Stack size/offset = 40 */ +/* 714 */ NdrFcShort( 0x30 ), /* ARM64 Stack size/offset = 48 */ /* 716 */ NdrFcShort( 0x8 ), /* 8 */ /* 718 */ NdrFcShort( 0x8 ), /* 8 */ /* 720 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ - 0x4, /* 4 */ + 0x5, /* 5 */ /* 722 */ 0x10, /* 16 */ 0x1, /* Ext Flags: new corr desc, */ /* 724 */ NdrFcShort( 0x0 ), /* 0 */ /* 726 */ NdrFcShort( 0x0 ), /* 0 */ /* 728 */ NdrFcShort( 0x0 ), /* 0 */ -/* 730 */ NdrFcShort( 0x4 ), /* 4 */ -/* 732 */ 0x4, /* 4 */ +/* 730 */ NdrFcShort( 0x5 ), /* 5 */ +/* 732 */ 0x5, /* 5 */ 0x80, /* 128 */ /* 734 */ 0x81, /* 129 */ 0x82, /* 130 */ /* 736 */ 0x83, /* 131 */ - 0x0, /* 0 */ + 0x84, /* 132 */ /* Parameter app_id */ @@ -792,59 +792,65 @@ /* 740 */ NdrFcShort( 0x8 ), /* ARM64 Stack size/offset = 8 */ /* 742 */ NdrFcShort( 0x58 ), /* Type Offset=88 */ + /* Parameter install_data_index */ + +/* 744 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */ +/* 746 */ NdrFcShort( 0x10 ), /* ARM64 Stack size/offset = 16 */ +/* 748 */ NdrFcShort( 0x58 ), /* Type Offset=88 */ + /* Parameter same_version_update_allowed */ -/* 744 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ -/* 746 */ NdrFcShort( 0x10 ), /* ARM64 Stack size/offset = 16 */ -/* 748 */ 0x8, /* FC_LONG */ +/* 750 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ +/* 752 */ NdrFcShort( 0x18 ), /* ARM64 Stack size/offset = 24 */ +/* 754 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Parameter observer */ -/* 750 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ -/* 752 */ NdrFcShort( 0x18 ), /* ARM64 Stack size/offset = 24 */ -/* 754 */ NdrFcShort( 0x7e ), /* Type Offset=126 */ +/* 756 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ +/* 758 */ NdrFcShort( 0x20 ), /* ARM64 Stack size/offset = 32 */ +/* 760 */ NdrFcShort( 0x7e ), /* Type Offset=126 */ /* Return value */ -/* 756 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ -/* 758 */ NdrFcShort( 0x20 ), /* ARM64 Stack size/offset = 32 */ -/* 760 */ 0x8, /* FC_LONG */ +/* 762 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 764 */ NdrFcShort( 0x28 ), /* ARM64 Stack size/offset = 40 */ +/* 766 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Procedure UpdateAll */ -/* 762 */ 0x33, /* FC_AUTO_HANDLE */ +/* 768 */ 0x33, /* FC_AUTO_HANDLE */ 0x6c, /* Old Flags: object, Oi2 */ -/* 764 */ NdrFcLong( 0x0 ), /* 0 */ -/* 768 */ NdrFcShort( 0x8 ), /* 8 */ -/* 770 */ NdrFcShort( 0x18 ), /* ARM64 Stack size/offset = 24 */ -/* 772 */ NdrFcShort( 0x0 ), /* 0 */ +/* 770 */ NdrFcLong( 0x0 ), /* 0 */ /* 774 */ NdrFcShort( 0x8 ), /* 8 */ -/* 776 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ +/* 776 */ NdrFcShort( 0x18 ), /* ARM64 Stack size/offset = 24 */ +/* 778 */ NdrFcShort( 0x0 ), /* 0 */ +/* 780 */ NdrFcShort( 0x8 ), /* 8 */ +/* 782 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ 0x2, /* 2 */ -/* 778 */ 0xe, /* 14 */ +/* 784 */ 0xe, /* 14 */ 0x1, /* Ext Flags: new corr desc, */ -/* 780 */ NdrFcShort( 0x0 ), /* 0 */ -/* 782 */ NdrFcShort( 0x0 ), /* 0 */ -/* 784 */ NdrFcShort( 0x0 ), /* 0 */ -/* 786 */ NdrFcShort( 0x2 ), /* 2 */ -/* 788 */ 0x2, /* 2 */ +/* 786 */ NdrFcShort( 0x0 ), /* 0 */ +/* 788 */ NdrFcShort( 0x0 ), /* 0 */ +/* 790 */ NdrFcShort( 0x0 ), /* 0 */ +/* 792 */ NdrFcShort( 0x2 ), /* 2 */ +/* 794 */ 0x2, /* 2 */ 0x80, /* 128 */ -/* 790 */ 0x81, /* 129 */ +/* 796 */ 0x81, /* 129 */ 0x0, /* 0 */ /* Parameter observer */ -/* 792 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ -/* 794 */ NdrFcShort( 0x8 ), /* ARM64 Stack size/offset = 8 */ -/* 796 */ NdrFcShort( 0x7e ), /* Type Offset=126 */ +/* 798 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ +/* 800 */ NdrFcShort( 0x8 ), /* ARM64 Stack size/offset = 8 */ +/* 802 */ NdrFcShort( 0x7e ), /* Type Offset=126 */ /* Return value */ -/* 798 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ -/* 800 */ NdrFcShort( 0x10 ), /* ARM64 Stack size/offset = 16 */ -/* 802 */ 0x8, /* FC_LONG */ +/* 804 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 806 */ NdrFcShort( 0x10 ), /* ARM64 Stack size/offset = 16 */ +/* 808 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ 0x0 @@ -1274,7 +1280,7 @@ 588, 664, 706, - 762 + 768 }; static const MIDL_STUBLESS_PROXY_INFO IUpdater_ProxyInfo =
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.h b/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.h index 9733925..c73126d 100644 --- a/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.h +++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.h
@@ -682,6 +682,7 @@ virtual HRESULT STDMETHODCALLTYPE Update( /* [string][in] */ const WCHAR *app_id, + /* [string][in] */ const WCHAR *install_data_index, /* [in] */ BOOL same_version_update_allowed, /* [in] */ IUpdaterObserver *observer) = 0; @@ -733,6 +734,7 @@ HRESULT ( STDMETHODCALLTYPE *Update )( IUpdater * This, /* [string][in] */ const WCHAR *app_id, + /* [string][in] */ const WCHAR *install_data_index, /* [in] */ BOOL same_version_update_allowed, /* [in] */ IUpdaterObserver *observer); @@ -775,8 +777,8 @@ #define IUpdater_RunPeriodicTasks(This,callback) \ ( (This)->lpVtbl -> RunPeriodicTasks(This,callback) ) -#define IUpdater_Update(This,app_id,same_version_update_allowed,observer) \ - ( (This)->lpVtbl -> Update(This,app_id,same_version_update_allowed,observer) ) +#define IUpdater_Update(This,app_id,install_data_index,same_version_update_allowed,observer) \ + ( (This)->lpVtbl -> Update(This,app_id,install_data_index,same_version_update_allowed,observer) ) #define IUpdater_UpdateAll(This,observer) \ ( (This)->lpVtbl -> UpdateAll(This,observer) )
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.tlb b/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.tlb index 584f330f..725177697 100644 --- a/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.tlb +++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.tlb Binary files differ
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl_p.c b/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl_p.c index 770f5bb..09976330 100644 --- a/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl_p.c +++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl_p.c
@@ -47,7 +47,7 @@ #include "updater_idl.h" #define TYPE_FORMAT_STRING_SIZE 145 -#define PROC_FORMAT_STRING_SIZE 727 +#define PROC_FORMAT_STRING_SIZE 733 #define EXPR_FORMAT_STRING_SIZE 1 #define TRANSMIT_AS_TABLE_SIZE 0 #define WIRE_MARSHAL_TABLE_SIZE 1 @@ -700,11 +700,11 @@ 0x6c, /* Old Flags: object, Oi2 */ /* 640 */ NdrFcLong( 0x0 ), /* 0 */ /* 644 */ NdrFcShort( 0x7 ), /* 7 */ -/* 646 */ NdrFcShort( 0x28 ), /* X64 Stack size/offset = 40 */ +/* 646 */ NdrFcShort( 0x30 ), /* X64 Stack size/offset = 48 */ /* 648 */ NdrFcShort( 0x8 ), /* 8 */ /* 650 */ NdrFcShort( 0x8 ), /* 8 */ /* 652 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ - 0x4, /* 4 */ + 0x5, /* 5 */ /* 654 */ 0xa, /* 10 */ 0x1, /* Ext Flags: new corr desc, */ /* 656 */ NdrFcShort( 0x0 ), /* 0 */ @@ -718,55 +718,61 @@ /* 666 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */ /* 668 */ NdrFcShort( 0x58 ), /* Type Offset=88 */ + /* Parameter install_data_index */ + +/* 670 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */ +/* 672 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */ +/* 674 */ NdrFcShort( 0x58 ), /* Type Offset=88 */ + /* Parameter same_version_update_allowed */ -/* 670 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ -/* 672 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */ -/* 674 */ 0x8, /* FC_LONG */ +/* 676 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ +/* 678 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */ +/* 680 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Parameter observer */ -/* 676 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ -/* 678 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */ -/* 680 */ NdrFcShort( 0x7e ), /* Type Offset=126 */ +/* 682 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ +/* 684 */ NdrFcShort( 0x20 ), /* X64 Stack size/offset = 32 */ +/* 686 */ NdrFcShort( 0x7e ), /* Type Offset=126 */ /* Return value */ -/* 682 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ -/* 684 */ NdrFcShort( 0x20 ), /* X64 Stack size/offset = 32 */ -/* 686 */ 0x8, /* FC_LONG */ +/* 688 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 690 */ NdrFcShort( 0x28 ), /* X64 Stack size/offset = 40 */ +/* 692 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Procedure UpdateAll */ -/* 688 */ 0x33, /* FC_AUTO_HANDLE */ +/* 694 */ 0x33, /* FC_AUTO_HANDLE */ 0x6c, /* Old Flags: object, Oi2 */ -/* 690 */ NdrFcLong( 0x0 ), /* 0 */ -/* 694 */ NdrFcShort( 0x8 ), /* 8 */ -/* 696 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */ -/* 698 */ NdrFcShort( 0x0 ), /* 0 */ +/* 696 */ NdrFcLong( 0x0 ), /* 0 */ /* 700 */ NdrFcShort( 0x8 ), /* 8 */ -/* 702 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ +/* 702 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */ +/* 704 */ NdrFcShort( 0x0 ), /* 0 */ +/* 706 */ NdrFcShort( 0x8 ), /* 8 */ +/* 708 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ 0x2, /* 2 */ -/* 704 */ 0xa, /* 10 */ +/* 710 */ 0xa, /* 10 */ 0x1, /* Ext Flags: new corr desc, */ -/* 706 */ NdrFcShort( 0x0 ), /* 0 */ -/* 708 */ NdrFcShort( 0x0 ), /* 0 */ -/* 710 */ NdrFcShort( 0x0 ), /* 0 */ /* 712 */ NdrFcShort( 0x0 ), /* 0 */ +/* 714 */ NdrFcShort( 0x0 ), /* 0 */ +/* 716 */ NdrFcShort( 0x0 ), /* 0 */ +/* 718 */ NdrFcShort( 0x0 ), /* 0 */ /* Parameter observer */ -/* 714 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ -/* 716 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */ -/* 718 */ NdrFcShort( 0x7e ), /* Type Offset=126 */ +/* 720 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ +/* 722 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */ +/* 724 */ NdrFcShort( 0x7e ), /* Type Offset=126 */ /* Return value */ -/* 720 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ -/* 722 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */ -/* 724 */ 0x8, /* FC_LONG */ +/* 726 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 728 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */ +/* 730 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ 0x0 @@ -1196,7 +1202,7 @@ 532, 600, 638, - 688 + 694 }; static const MIDL_STUBLESS_PROXY_INFO IUpdater_ProxyInfo =
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.h b/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.h index 699f0cf2..5770af15 100644 --- a/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.h +++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.h
@@ -682,6 +682,7 @@ virtual HRESULT STDMETHODCALLTYPE Update( /* [string][in] */ const WCHAR *app_id, + /* [string][in] */ const WCHAR *install_data_index, /* [in] */ BOOL same_version_update_allowed, /* [in] */ IUpdaterObserver *observer) = 0; @@ -733,6 +734,7 @@ HRESULT ( STDMETHODCALLTYPE *Update )( IUpdater * This, /* [string][in] */ const WCHAR *app_id, + /* [string][in] */ const WCHAR *install_data_index, /* [in] */ BOOL same_version_update_allowed, /* [in] */ IUpdaterObserver *observer); @@ -775,8 +777,8 @@ #define IUpdater_RunPeriodicTasks(This,callback) \ ( (This)->lpVtbl -> RunPeriodicTasks(This,callback) ) -#define IUpdater_Update(This,app_id,same_version_update_allowed,observer) \ - ( (This)->lpVtbl -> Update(This,app_id,same_version_update_allowed,observer) ) +#define IUpdater_Update(This,app_id,install_data_index,same_version_update_allowed,observer) \ + ( (This)->lpVtbl -> Update(This,app_id,install_data_index,same_version_update_allowed,observer) ) #define IUpdater_UpdateAll(This,observer) \ ( (This)->lpVtbl -> UpdateAll(This,observer) )
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.tlb b/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.tlb index 33a56d60..95c7dd6 100644 --- a/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.tlb +++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.tlb Binary files differ
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl_p.c b/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl_p.c index b0e6006..d7521b6b2 100644 --- a/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl_p.c +++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl_p.c
@@ -50,7 +50,7 @@ #include "updater_idl.h" #define TYPE_FORMAT_STRING_SIZE 145 -#define PROC_FORMAT_STRING_SIZE 691 +#define PROC_FORMAT_STRING_SIZE 697 #define EXPR_FORMAT_STRING_SIZE 1 #define TRANSMIT_AS_TABLE_SIZE 0 #define WIRE_MARSHAL_TABLE_SIZE 1 @@ -695,11 +695,11 @@ 0x6c, /* Old Flags: object, Oi2 */ /* 608 */ NdrFcLong( 0x0 ), /* 0 */ /* 612 */ NdrFcShort( 0x7 ), /* 7 */ -/* 614 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */ +/* 614 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */ /* 616 */ NdrFcShort( 0x8 ), /* 8 */ /* 618 */ NdrFcShort( 0x8 ), /* 8 */ /* 620 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ - 0x4, /* 4 */ + 0x5, /* 5 */ /* 622 */ 0x8, /* 8 */ 0x1, /* Ext Flags: new corr desc, */ /* 624 */ NdrFcShort( 0x0 ), /* 0 */ @@ -712,54 +712,60 @@ /* 632 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ /* 634 */ NdrFcShort( 0x58 ), /* Type Offset=88 */ + /* Parameter install_data_index */ + +/* 636 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */ +/* 638 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 640 */ NdrFcShort( 0x58 ), /* Type Offset=88 */ + /* Parameter same_version_update_allowed */ -/* 636 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ -/* 638 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ -/* 640 */ 0x8, /* FC_LONG */ +/* 642 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ +/* 644 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 646 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Parameter observer */ -/* 642 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ -/* 644 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ -/* 646 */ NdrFcShort( 0x7e ), /* Type Offset=126 */ +/* 648 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ +/* 650 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 652 */ NdrFcShort( 0x7e ), /* Type Offset=126 */ /* Return value */ -/* 648 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ -/* 650 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ -/* 652 */ 0x8, /* FC_LONG */ +/* 654 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 656 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */ +/* 658 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Procedure UpdateAll */ -/* 654 */ 0x33, /* FC_AUTO_HANDLE */ +/* 660 */ 0x33, /* FC_AUTO_HANDLE */ 0x6c, /* Old Flags: object, Oi2 */ -/* 656 */ NdrFcLong( 0x0 ), /* 0 */ -/* 660 */ NdrFcShort( 0x8 ), /* 8 */ -/* 662 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ -/* 664 */ NdrFcShort( 0x0 ), /* 0 */ +/* 662 */ NdrFcLong( 0x0 ), /* 0 */ /* 666 */ NdrFcShort( 0x8 ), /* 8 */ -/* 668 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ +/* 668 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 670 */ NdrFcShort( 0x0 ), /* 0 */ +/* 672 */ NdrFcShort( 0x8 ), /* 8 */ +/* 674 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ 0x2, /* 2 */ -/* 670 */ 0x8, /* 8 */ +/* 676 */ 0x8, /* 8 */ 0x1, /* Ext Flags: new corr desc, */ -/* 672 */ NdrFcShort( 0x0 ), /* 0 */ -/* 674 */ NdrFcShort( 0x0 ), /* 0 */ -/* 676 */ NdrFcShort( 0x0 ), /* 0 */ +/* 678 */ NdrFcShort( 0x0 ), /* 0 */ +/* 680 */ NdrFcShort( 0x0 ), /* 0 */ +/* 682 */ NdrFcShort( 0x0 ), /* 0 */ /* Parameter observer */ -/* 678 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ -/* 680 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ -/* 682 */ NdrFcShort( 0x7e ), /* Type Offset=126 */ +/* 684 */ NdrFcShort( 0xb ), /* Flags: must size, must free, in, */ +/* 686 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 688 */ NdrFcShort( 0x7e ), /* Type Offset=126 */ /* Return value */ -/* 684 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ -/* 686 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ -/* 688 */ 0x8, /* FC_LONG */ +/* 690 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 692 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 694 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ 0x0 @@ -1189,7 +1195,7 @@ 504, 570, 606, - 654 + 660 }; static const MIDL_STUBLESS_PROXY_INFO IUpdater_ProxyInfo =
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py index 6e450f7d..a68eb85 100755 --- a/tools/clang/scripts/build.py +++ b/tools/clang/scripts/build.py
@@ -443,6 +443,8 @@ sys.exit(1) +# TODO(https://crbug.com/1286289): remove once Chrome targets don't rely on +# libstdc++.so existing in the clang package. def CopyLibstdcpp(args, build_dir): if not args.gcc_toolchain: return @@ -453,33 +455,8 @@ ], universal_newlines=True).rstrip() - # Copy libstdc++.so.6 into the build dir so that the built binaries can find - # it. Binaries get their rpath set to $origin/../lib/. For clang, lld, - # etc. that live in the bin/ directory, this means they expect to find the .so - # in their neighbouring lib/ dir. - # For unit tests we pass -Wl,-rpath to the linker pointing to the lib64 dir - # in the gcc toolchain, via LLVM_LOCAL_RPATH below. - # The two fuzzer tests are weird in that they copy the fuzzer binary from bin/ - # into the test tree under a different name. To make the relative rpath in - # them work, copy libstdc++ to the copied location for now. - # There is also a compiler-rt test that copies llvm-symbolizer out of bin/. - # TODO(thakis): Instead, make the upstream lit.local.cfg.py for these 2 tests - # check if the binary contains an rpath and if so disable the tests. - for d in ['lib', - 'test/tools/llvm-isel-fuzzer/lib', - 'test/tools/llvm-opt-fuzzer/lib']: - EnsureDirExists(os.path.join(build_dir, d)) - CopyFile(libstdcpp, os.path.join(build_dir, d)) - - sanitizer_common_tests = os.path.join(build_dir, - 'projects/compiler-rt/test/sanitizer_common') - if os.path.exists(sanitizer_common_tests): - for d in ['asan-i386-Linux', 'asan-x86_64-Linux', 'lsan-i386-Linux', - 'lsan-x86_64-Linux', 'msan-x86_64-Linux', 'tsan-x86_64-Linux', - 'ubsan-i386-Linux', 'ubsan-x86_64-Linux']: - libpath = os.path.join(sanitizer_common_tests, d, 'Output', 'lib') - EnsureDirExists(libpath) - CopyFile(libstdcpp, libpath) + EnsureDirExists(os.path.join(build_dir, 'lib')) + CopyFile(libstdcpp, os.path.join(build_dir, 'lib')) def gn_arg(v): @@ -683,7 +660,16 @@ print('Invalid --gcc-toolchain: ' + args.gcc_toolchain) return 1 base_cmake_args += [ - '-DLLVM_LOCAL_RPATH=' + os.path.join(args.gcc_toolchain, 'lib64') + '-DLLVM_STATIC_LINK_CXX_STDLIB=ON', + # Force compiler-rt tests to use our gcc toolchain + # because the one on the host may be too old. + # Even with -static-libstdc++ the compiler-rt tests add -lstdc++ + # which adds a DT_NEEDED to libstdc++.so so we need to add RPATHs + # to the gcc toolchain. + '-DCOMPILER_RT_TEST_COMPILER_CFLAGS=--gcc-toolchain=' + + args.gcc_toolchain + ' -Wl,-rpath,' + + os.path.join(args.gcc_toolchain, 'lib64') + ' -Wl,-rpath,' + + os.path.join(args.gcc_toolchain, 'lib32') ] if sys.platform == 'darwin': @@ -695,15 +681,6 @@ '-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF', ]) - if args.gcc_toolchain: - # Force compiler-rt tests to use our gcc toolchain (including libstdc++.so) - # because the one on the host may be too old. - base_cmake_args.append( - '-DCOMPILER_RT_TEST_COMPILER_CFLAGS=--gcc-toolchain=' + - args.gcc_toolchain + ' -Wl,-rpath,' + - os.path.join(args.gcc_toolchain, 'lib64') + ' -Wl,-rpath,' + - os.path.join(args.gcc_toolchain, 'lib32')) - if sys.platform == 'win32': base_cmake_args.append('-DLLVM_USE_CRT_RELEASE=MT') # TODO(crbug.com/1292528): We need Visual Studio 19.27 or later. @@ -799,8 +776,6 @@ if lld is not None: bootstrap_args.append('-DCMAKE_LINKER=' + lld) RunCommand(['cmake'] + bootstrap_args + [os.path.join(LLVM_DIR, 'llvm')], msvc_arch='x64') - CopyLibstdcpp(args, LLVM_BOOTSTRAP_DIR) - CopyLibstdcpp(args, LLVM_BOOTSTRAP_INSTALL_DIR) RunCommand(['ninja'], msvc_arch='x64') if args.run_tests: test_targets = ['check-all'] @@ -861,7 +836,6 @@ RunCommand(['cmake'] + instrument_args + [os.path.join(LLVM_DIR, 'llvm')], msvc_arch='x64') - CopyLibstdcpp(args, LLVM_INSTRUMENTED_DIR) RunCommand(['ninja'], msvc_arch='x64') print('Instrumented compiler built.')
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index d22944d8..ceeeedc 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -36,7 +36,7 @@ # Reverting problematic clang rolls is safe, though. # This is the output of `git describe` and is usable as a commit-ish. CLANG_REVISION = 'llvmorg-15-init-3677-g8133778d' -CLANG_SUB_REVISION = 1 +CLANG_SUB_REVISION = 4 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION) RELEASE_VERSION = '15.0.0'
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index f34920061..069f1c7 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -637,7 +637,9 @@ }, 'chromium.rust': { + 'linux-rust-x64-dbg': 'debug_bot_rust_linux_x64', 'linux-rust-x64-rel': 'release_rust_linux_x64', + 'android-rust-arm-dbg': 'debug_bot_rust_android_arm_reclient', 'android-rust-arm-rel': 'release_rust_android_arm_reclient', }, @@ -1200,8 +1202,10 @@ }, 'tryserver.chromium.rust': { + 'linux-rust-x64-dbg': 'debug_bot_rust_linux_x64', 'linux-rust-x64-rel': 'release_rust_linux_x64', 'linux-rust-intree-x64-rel': 'release_rust_intree_linux_x64', + 'android-rust-arm-dbg': 'debug_bot_rust_android_arm', 'android-rust-arm-rel': 'release_rust_android_arm', }, @@ -2307,6 +2311,18 @@ 'debug_bot', 'paeverywhere', 'x64', ], + 'debug_bot_rust_android_arm': [ + 'debug_bot', 'enable_rust', 'android', 'arm', + ], + + 'debug_bot_rust_android_arm_reclient': [ + 'debug_bot_reclient', 'enable_rust', 'android', 'arm', + ], + + 'debug_bot_rust_linux_x64': [ + 'debug_bot', 'enable_rust', 'x64', + ], + 'debug_bot_x86': [ 'debug_bot', 'x86', ],
diff --git a/tools/mb/mb_config_expectations/chromium.rust.json b/tools/mb/mb_config_expectations/chromium.rust.json index b9ca679..d7cf8ada 100644 --- a/tools/mb/mb_config_expectations/chromium.rust.json +++ b/tools/mb/mb_config_expectations/chromium.rust.json
@@ -1,4 +1,18 @@ { + "android-rust-arm-dbg": { + "gn_args": { + "enable_rust": true, + "ffmpeg_branding": "Chrome", + "is_component_build": true, + "is_debug": true, + "proprietary_codecs": true, + "symbol_level": 1, + "target_cpu": "arm", + "target_os": "android", + "use_rbe": true, + "use_remoteexec": true + } + }, "android-rust-arm-rel": { "gn_args": { "blink_enable_generated_code_formatting": false, @@ -15,6 +29,16 @@ "use_remoteexec": true } }, + "linux-rust-x64-dbg": { + "gn_args": { + "enable_rust": true, + "is_component_build": true, + "is_debug": true, + "symbol_level": 1, + "target_cpu": "x64", + "use_goma": true + } + }, "linux-rust-x64-rel": { "gn_args": { "blink_enable_generated_code_formatting": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.rust.json b/tools/mb/mb_config_expectations/tryserver.chromium.rust.json index 707054f..bacb51c 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.rust.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.rust.json
@@ -1,4 +1,17 @@ { + "android-rust-arm-dbg": { + "gn_args": { + "enable_rust": true, + "ffmpeg_branding": "Chrome", + "is_component_build": true, + "is_debug": true, + "proprietary_codecs": true, + "symbol_level": 1, + "target_cpu": "arm", + "target_os": "android", + "use_goma": true + } + }, "android-rust-arm-rel": { "gn_args": { "blink_enable_generated_code_formatting": false, @@ -27,6 +40,16 @@ "use_goma": true } }, + "linux-rust-x64-dbg": { + "gn_args": { + "enable_rust": true, + "is_component_build": true, + "is_debug": true, + "symbol_level": 1, + "target_cpu": "x64", + "use_goma": true + } + }, "linux-rust-x64-rel": { "gn_args": { "blink_enable_generated_code_formatting": false,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index ea7925e..c8e8ea1 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -8619,6 +8619,7 @@ <int value="269" label="RFH_UNLOAD_HANDLER_NOT_ALLOWED_IN_FENCED_FRAME"/> <int value="270" label="RFH_BEFOREUNLOAD_HANDLER_NOT_ALLOWED_IN_FENCED_FRAME"/> + <int value="271" label="MSDH_GET_OPEN_DEVICE_USE_WITHOUT_FEATURE"/> </enum> <enum name="BadMessageReasonExtensions"> @@ -21895,6 +21896,9 @@ <int value="7" label="Unable to upload new signing key to server after maximum retries and failed to restore old key"/> + <int value="8" + label="Unable to store the signing key due to signing key file + permissions failure."/> </enum> <enum name="DevToolsAction"> @@ -51782,6 +51786,7 @@ <int value="-1972312724" label="OfflinePagesLoadSignalCollecting:enabled"/> <int value="-1972219399" label="NTPSaveToOffline:enabled"/> <int value="-1971086581" label="print-scaling"/> + <int value="-1970672551" label="CanvasContextLostInBackground:disabled"/> <int value="-1969636234" label="OmniboxRefinedFocusState:disabled"/> <int value="-1966445414" label="StylusBatteryStatus:disabled"/> <int value="-1965587041" label="omnibox-tab-switch-suggestions"/> @@ -57616,6 +57621,7 @@ <int value="2059322877" label="new-avatar-menu"/> <int value="2063091429" label="OfflinePagesSharing:enabled"/> <int value="2063420769" label="SharedHighlightingV2:disabled"/> + <int value="2065833330" label="CanvasContextLostInBackground:enabled"/> <int value="2066015302" label="QueryTiles:disabled"/> <int value="2066508701" label="WebViewOriginTrials:disabled"/> <int value="2067634730" label="LsdPermissionPrompt:disabled"/> @@ -61379,6 +61385,8 @@ <int value="2" label="Update Password"/> <int value="3" label="Save Card"/> <int value="4" label="Translate"/> + <int value="5" label="Permissions"/> + <int value="6" label="Autofill Save Address Profile"/> </enum> <enum name="MobileMessagesModalEvent">
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml index a83ecc83..cd395dd4 100644 --- a/tools/metrics/histograms/metadata/arc/histograms.xml +++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -102,9 +102,9 @@ </summary> </histogram> -<histogram name="Arc.AndroidBootTime" units="ms" expires_after="2022-04-24"> - <owner>elijahtaylor@google.com</owner> - <owner>shihuis@google.com</owner> +<histogram name="Arc.AndroidBootTime" units="ms" expires_after="2022-12-24"> + <owner>yusukes@google.com</owner> + <owner>khmel@google.com</owner> <summary>The time elapsed for booting up the ARC instance.</summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 2e831b23..9f74e93 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -2470,17 +2470,6 @@ </token> </histogram> -<histogram name="Ash.NumberOfVisibleWindowsInPrimaryDisplay" units="Windows" - expires_after="2022-04-24"> - <owner>jamescook@chromium.org</owner> - <summary> - An upper bound on the number of windows visible to the user on the primary - display. Determined by processing the windows in increasing z-order and - counting all non-minimized windows until a maximized or fullscreen window is - processed. This metric is logged periodically every 30 minutes. - </summary> -</histogram> - <histogram base="true" name="Ash.Overview.AnimationSmoothness.Close" units="%" expires_after="2023-04-10"> <!-- Name completed by histogram_suffixes
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml index c6afb73..cfbcdc5 100644 --- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -7381,21 +7381,6 @@ <affected-histogram name="PerformanceHints.Observer.HintForURLResult"/> </histogram_suffixes> -<histogram_suffixes name="PerformanceMonitor" separator="."> - <suffix name="BrowserProcess" label=""/> - <suffix name="GPUProcess" label=""/> - <suffix name="NetworkProcess" label=""/> - <suffix name="PluginProcess" label=""/> - <suffix name="PPAPIProcess" label=""/> - <suffix name="RendererExtensionEventProcess" label=""/> - <suffix name="RendererExtensionPersistentProcess" label=""/> - <suffix name="RendererProcess" label=""/> - <suffix name="Total" label=""/> - <suffix name="UtilityProcess" label=""/> - <suffix name="WorkerProcess" label=""/> - <affected-histogram name="PerformanceMonitor.AverageCPU"/> -</histogram_suffixes> - <histogram_suffixes name="PermissionRequestGesture" separator="."> <suffix name="Gesture" label="With user gesture"/> <suffix name="NoGesture" label="Without user gesture"/>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index e4fbdd9b..2ec77651 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -6303,18 +6303,6 @@ <summary>The scheme of the URL showing a JavaScript dialog.</summary> </histogram> -<histogram name="Keyboard.ShortcutViewer.StartupTime" units="ms" - expires_after="2022-04-24"> - <owner>jamescook@chromium.org</owner> - <owner>msw@chromium.org</owner> - <owner>wutao@chromium.org</owner> - <summary> - Time delay between the user gesture that triggered the keyboard shortcut - viewer dialog (e.g. pressing Ctrl-Alt-/) and the dialog widget being shown, - including layout time for the views::Views. - </summary> -</histogram> - <histogram name="Kiosk.Extensions.InstallDuration" units="ms" expires_after="2022-09-01"> <owner>yixie@chromium.org</owner> @@ -8755,425 +8743,6 @@ </summary> </histogram> -<histogram name="PerformanceMonitor.AverageCPU" units="PercentCPUUsage" - expires_after="2021-10-30"> - <obsolete> - Replaced in 2021-03 by PerformanceMonitor.AverageCPU2, which reports this - value in permyriad (1/10000) instead of percent and changes the upper bound - of the histogram. - </obsolete> - <owner>fdoray@chromium.org</owner> - <owner>oysteine@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - Average CPU utilization of a process, read out at each two-minute interval. - The utilization is in the 0-100% range per CPU, which is then summed up. - I.e. a quadcore system fully loaded would read as 400%. - </summary> -</histogram> - -<histogram name="PerformanceMonitor.AverageCPU2.Total{UsageScenario}" - units="1/100 %" expires_after="2022-11-30"> - <owner>fdoray@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - See definitioin of PerformanceClass.AverageCPU2.ProcessName. This is - recorded for {UsageScenario} (see go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - -<histogram name="PerformanceMonitor.AverageCPU2.{ProcessName}" units="1/100 %" - expires_after="2022-11-30"> - <owner>fdoray@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - Average CPU utilization of process type {ProcessName}, read out at each - two-minute interval. The utilization is in the 0-100% range per CPU, which - is then summed up and multiplied by 100. The histogram is capped at 20000 - (equivalent to 2 cores fully loaded). I.e. 4 cores busy at 25% each will - read as 25 * 4 * 100 = 10000. - - NOTE: This metric has one signigicant limitation, it doesn't report the CPU - usage of processes that terminate before the end of the interval. This means - that short lived processes will rarely be included in the data. Furthermore, - we know that short-lived processes are very common (see - Renderer.ProcessLifetime). A future version of this metric will address this - limitation. - </summary> - <token key="ProcessName" variants="ProcessName"/> -</histogram> - -<histogram name="PerformanceMonitor.AverageDisk" units="BytesPerSecond" - expires_after="M85"> - <obsolete> - Removed 04/2021. Not needed for current investigations. - </obsolete> - <owner>etienneb@chromium.org</owner> - <owner>oysteine@chromium.org</owner> - <summary> - Average disk utilization of a process, recorded at every two-minute - interval. The amount of data transferred (Total I/O bytes per second) for a - given process. - - NOTE: This metric has one signigicant limitation, it doesn't report the CPU - usage of processes that terminate before the end of the interval. This means - that short lived processes will rarely be included in the data. Furthermore, - we know that short-lived processes are very common (see - Renderer.ProcessLifetime). A future version of this metric will address this - limitation. - </summary> -</histogram> - -<histogram name="PerformanceMonitor.EnergyImpact.Total{UsageScenario}" - units="ScaledUnits" expires_after="2022-11-30"> - <owner>olivierli@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - See definition of PerformanceMonitor.EnergyImpact.ProcessName. This is - recorded for {UsageScenario} (see go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - -<histogram name="PerformanceMonitor.EnergyImpact.{ProcessName}" - units="ScaledUnits" expires_after="2022-11-30"> - <owner>olivierli@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - (Mac only) A synthetic power use estimate, as displayed in macOS Activity - Monitor and the battery menu. This incorporates CPU utilization, idle - wakeups, IO, and task QoS level using per-machine-model weights. Divide by - 100 to match Activity Monitor's scale. Recorded every two minutes. - - NOTE: This metric has one signigicant limitation, it doesn't report the CPU - usage of processes that terminate before the end of the interval. This means - that short lived processes will rarely be included in the data. Furthermore, - we know that short-lived processes are very common (see - Renderer.ProcessLifetime). A future version of this metric will address this - limitation. - </summary> - <token key="ProcessName" variants="ProcessName"/> -</histogram> - -<histogram name="PerformanceMonitor.HighCPU" enum="BooleanHit" - expires_after="M85"> - <obsolete> - Removed 04/2021. PerformanceMonitor.AverageCPU2 has the same data with more - granularity. - </obsolete> - <owner>oysteine@chromium.org</owner> - <summary> - The number of times a process has continuously stayed above a certain - threshold of CPU utilization over a certain time period (currently set to - two minutes). - </summary> -</histogram> - -<histogram name="PerformanceMonitor.IdleWakeups.Total{UsageScenario}" - units="WakeupsPerSecond" expires_after="2022-11-30"> - <owner>olivierli@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - See definition of PerformanceMonitor.IdleWakeups.ProcessName. This is - recorded for {UsageScenario} (see go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - -<histogram name="PerformanceMonitor.IdleWakeups.{ProcessName}" - units="WakeupsPerSecond" expires_after="2022-11-30"> - <owner>olivierli@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - The average CPU idle wakeups per second, sampled every two minutes. - - NOTE: This metric has one signigicant limitation, it doesn't report the CPU - usage of processes that terminate before the end of the interval. This means - that short lived processes will rarely be included in the data. Furthermore, - we know that short-lived processes are very common (see - Renderer.ProcessLifetime). A future version of this metric will address this - limitation. - </summary> - <token key="ProcessName" variants="ProcessName"/> -</histogram> - -<histogram - name="PerformanceMonitor.PackageExitIdleWakeups.Total{UsageScenario}" - units="WakeupsPerSecond" expires_after="2022-11-30"> - <owner>olivierli@chromium.org</owner> - <owner>catan-team@chromium.orgg</owner> - <summary> - See definition of PerformanceMonitor.PackageExitIdleWakeups.ProcessName. - This is recorded for {UsageScenario} (see go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - -<histogram name="PerformanceMonitor.PackageExitIdleWakeups.{ProcessName}" - units="WakeupsPerSecond" expires_after="2022-11-30"> - <owner>olivierli@chromium.org</owner> - <owner>catan-team@chromium.orgg</owner> - <summary> - (Mac only) The average package exit idle wakeups per second, sampled every - two minutes. This is a subset of wakeups that indicate that the processor - complex was taken out of low-power state. For more info, see the - powermetrics man page on macOS. - - NOTE: This metric has one signigicant limitation, it doesn't report the CPU - usage of processes that terminate before the end of the interval. This means - that short lived processes will rarely be included in the data. Furthermore, - we know that short-lived processes are very common (see - Renderer.ProcessLifetime). A future version of this metric will address this - limitation. - </summary> - <token key="ProcessName" variants="ProcessName"/> -</histogram> - -<histogram name="PerformanceMonitor.ResourceCoalition.Availability" - enum="CoalitionIDAvailability" expires_after="2022-11-30"> - <owner>fdoray@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - Details about whether or not it's possible to get coalition resource usage - data on the system. Only on macOS, recorded once at startup. - </summary> -</histogram> - -<histogram - name="PerformanceMonitor.ResourceCoalition.BytesReadPerSecond2{UsageScenario}" - units="BytesPerSecond" expires_after="2022-11-30"> - <owner>fdoray@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - The IO reads reported by the resource coalition mechanism on macOS. The data - is reported as the rate per second during this interval with a byte - granularity. This is recorded for {UsageScenario} (see - go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - -<histogram - name="PerformanceMonitor.ResourceCoalition.BytesWrittenPerSecond2{UsageScenario}" - units="BytesPerSecond" expires_after="2022-11-30"> - <owner>fdoray@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - The IO writes reported by the resource coalition mechanism on macOS. The - data is reported as the rate per second during this interval with a byte - granularity. This is recorded for {UsageScenario} (see - go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - -<histogram name="PerformanceMonitor.ResourceCoalition.CPUTime" - units="hundredth of percent" expires_after="2022-11-30"> - <obsolete> - Deprecated in 07/2021 because the computation was wrong. Replaced by - PerformanceMonitor.ResourceCoalition.CPUTime2. - </obsolete> - <owner>sebmarchand@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - Average CPU utilization reported by the resource coalition mechanism on - macOS. Read out at each two-minute interval. The utilization is in the - 0-100% range per CPU, which is then summed up and multiplied by 100. The - histogram is capped at 20000 (equivalent to 2 cores fully loaded). I.e. 4 - cores busy at 25% each will read as 25 * 4 * 100 = 10000. - </summary> -</histogram> - -<histogram - name="PerformanceMonitor.ResourceCoalition.CPUTime2_10sec{UsageScenario10sec}" - units="1/100 %" expires_after="2022-11-30"> - <owner>fdoray@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - Average CPU utilization reported by the resource coalition mechanism on - macOS. The utilization is in the 0-100% range per CPU, which is then summed - up and multiplied by 100. The histogram is capped at 20000 (equivalent to 2 - cores fully loaded). I.e. 4 cores busy at 25% each will read as 25 * 4 * 100 - = 10000. This is recorded for {UsageScenario10sec} (see - go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario10sec" variants="UsageScenario10sec"/> -</histogram> - -<histogram name="PerformanceMonitor.ResourceCoalition.CPUTime2{UsageScenario}" - units="1/100 %" expires_after="2022-11-30"> - <owner>fdoray@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - Average CPU utilization reported by the resource coalition mechanism on - macOS. The utilization is in the 0-100% range per CPU, which is then summed - up and multiplied by 100. The histogram is capped at 20000 (equivalent to 2 - cores fully loaded). I.e. 4 cores busy at 25% each will read as 25 * 4 * 100 - = 10000. This is recorded for {UsageScenario} (see - go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - -<histogram name="PerformanceMonitor.ResourceCoalition.Energy" - units="milliwatts" expires_after="2022-11-30"> - <obsolete> - Deprecated in 07/2021 because the name of the metric was wrong. Replaced by - PerformanceMonitor.ResourceCoalition.Power. - </obsolete> - <owner>sebmarchand@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - The energy usage reported by the resource coalition mechanism on macOS. - Reported every 2 minutes. Only available on devices with an ARM CPU. - </summary> -</histogram> - -<histogram - name="PerformanceMonitor.ResourceCoalition.EnergyImpact{UsageScenario}" - units="centi-EnergyImpact" expires_after="2022-11-30"> - <owner>siggi@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - (Mac only) A synthetic power use estimate, as displayed in macOS Activity - Monitor and the battery menu. This incorporates CPU utilization, idle - wakeups, IO, and task QoS level using per-machine-model weights. Divide by - 100 to match Activity Monitor's scale. Only available on macs with an Intel - CPU. - - This EnergyImpact score is computed from the usage reported by the resource - coalition mechanism on macOS. It accounts for the resource usage of all - Chrome processes no matter how short-lived, as well as XPC services running - on Chrome's behalf. - - This is recorded for {UsageScenario} (see go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - -<histogram name="PerformanceMonitor.ResourceCoalition.GPUTime" - units="hundredth of percent" expires_after="2022-11-30"> - <obsolete> - Deprecated in 07/2021 because the computation was wrong. Replaced by - PerformanceMonitor.ResourceCoalition.GPUTime2. - </obsolete> - <owner>sebmarchand@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - Average GPU utilization reported by the resource coalition mechanism on - macOS. Read out at each two-minute interval. The utilization is in the - 0-100% range and is multiplied by 100. The histogram is capped at 10000 - (equivalent to the GPU being used 100% of the time). - </summary> -</histogram> - -<histogram name="PerformanceMonitor.ResourceCoalition.GPUTime2{UsageScenario}" - units="1/100 %" expires_after="2022-11-30"> - <owner>fdoray@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - Average GPU utilization reported by the resource coalition mechanism on - macOS. The utilization is in the 0-100% range and is multiplied by 100. The - histogram is capped at 10000 (equivalent to the GPU being used 100% of the - time). This is recorded for {UsageScenario} (see - go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - -<histogram - name="PerformanceMonitor.ResourceCoalition.InterruptWakeupsPerSecond{UsageScenario}" - units="milliWakeupsPerSecond" expires_after="2022-11-30"> - <owner>fdoray@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - The interrupt wakeup rate reported by the resource coalition mechanism on - macOS. The data is reported as the rate per second during this interval with - a milliwakeup granularity. This is recorded for {UsageScenario} (see - go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - -<histogram - name="PerformanceMonitor.ResourceCoalition.PlatformIdleWakeupsPerSecond{UsageScenario}" - units="milliWakeupsPerSecond" expires_after="2022-11-30"> - <owner>fdoray@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - The platform idle wakeup rate reported by the resource coalition mechanism - on macOS. The data is reported as the rate per second during this interval - with a milliwakeup granularity. This is recorded for {UsageScenario} (see - go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - -<histogram name="PerformanceMonitor.ResourceCoalition.Power2{UsageScenario}" - units="milliwatts" expires_after="2022-11-30"> - <owner>fdoray@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - The power usage reported by the resource coalition mechanism on macOS. Only - reported on devices with an ARM CPU. This is recorded for {UsageScenario} - (see go/chrome_power_use_per_scenario). - </summary> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - -<histogram - name="PerformanceMonitor.ResourceCoalition.QoSLevel.{QoSLevel}{UsageScenario}" - units="1/100 %" expires_after="2022-11-30"> - <owner>fdoray@chromium.org</owner> - <owner>catan-team@chromium.org</owner> - <summary> - Average CPU time spent in a given QoS level, as reported by the resource - coalition mechanism on macOS. The utilization is in the 0-100% range and is - multiplied by 100. The histogram is capped at 10000 (equivalent to the GPU - being used 100% of the time). This is recorded for {UsageScenario} (see - go/chrome_power_use_per_scenario). - </summary> - <token key="QoSLevel"> - <variant name="Background"/> - <variant name="Default"/> - <variant name="Legacy"/> - <variant name="Maintenance"/> - <variant name="UserInitiated"/> - <variant name="UserInteractive"/> - <variant name="Utility"/> - </token> -<!-- Usage scenario variant defined in tools/metrics/histograms/metadata/power/histograms.xml --> - - <token key="UsageScenario" variants="UsageScenario"/> -</histogram> - <histogram name="PeriodicBackgroundSync.Event.BatchSize" units="events" expires_after="2022-07-31"> <owner>nator@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml index 072b188c..a3460fe7 100644 --- a/tools/metrics/histograms/metadata/password/histograms.xml +++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -993,6 +993,9 @@ <histogram name="PasswordManager.BulkCheck.LeaksFoundOnErrorOrCanceled" units="credentials" expires_after="2022-04-24"> + <obsolete> + Removed in M101. + </obsolete> <owner>vasilii@chromium.org</owner> <owner>vsemeniuk@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/permissions/histograms.xml b/tools/metrics/histograms/metadata/permissions/histograms.xml index 6f9d9813..24adaeb 100644 --- a/tools/metrics/histograms/metadata/permissions/histograms.xml +++ b/tools/metrics/histograms/metadata/permissions/histograms.xml
@@ -137,7 +137,7 @@ </histogram> <histogram name="Permissions.AutoBlocker.EmbargoStatus" - enum="PermissionEmbargoStatus" expires_after="2022-04-24"> + enum="PermissionEmbargoStatus" expires_after="2022-10-24"> <owner>engedy@chromium.org</owner> <owner>src/components/permissions/PERMISSIONS_OWNERS</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml index bb0f4814..600bafed 100644 --- a/tools/metrics/histograms/metadata/power/histograms.xml +++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -26,9 +26,6 @@ <!-- Variants describing the usage scenario for a 2 minutes interval. Consider updating UsageScenario10Sec when updating this. - - Used in tools/metrics/histograms/metadata/others/histograms.xml - When changing this variant changes need to verified against histograms there. --> <variant name="" summary="2 minutes runtime intervals"/> @@ -85,9 +82,6 @@ <!-- Variants describing the usage scenario for a 10 seconds intervals. Contains more variants than "UsageScenario". - - Used in tools/metrics/histograms/metadata/others/histograms.xml - When changing this variant changes need to verified against histograms there. --> <variant name="" summary="10 seconds runtime intervals"/> @@ -140,6 +134,345 @@ but there was in the last 2 minutes"/> </variants> +<histogram name="PerformanceMonitor.AverageCPU2.Total{UsageScenario}" + units="1/100 %" expires_after="2022-11-30"> + <owner>fdoray@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + See definitioin of PerformanceClass.AverageCPU2.ProcessName. This is + recorded for {UsageScenario} (see go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + +<histogram name="PerformanceMonitor.AverageCPU2.{ProcessName}" units="1/100 %" + expires_after="2022-11-30"> + <owner>fdoray@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + Average CPU utilization of process type {ProcessName}, read out at each + two-minute interval. The utilization is in the 0-100% range per CPU, which + is then summed up and multiplied by 100. The histogram is capped at 20000 + (equivalent to 2 cores fully loaded). I.e. 4 cores busy at 25% each will + read as 25 * 4 * 100 = 10000. + + NOTE: This metric has one signigicant limitation, it doesn't report the CPU + usage of processes that terminate before the end of the interval. This means + that short lived processes will rarely be included in the data. Furthermore, + we know that short-lived processes are very common (see + Renderer.ProcessLifetime). A future version of this metric will address this + limitation. + </summary> + <token key="ProcessName" variants="ProcessName"/> +</histogram> + +<histogram name="PerformanceMonitor.EnergyImpact.Total{UsageScenario}" + units="ScaledUnits" expires_after="2022-11-30"> + <owner>olivierli@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + See definition of PerformanceMonitor.EnergyImpact.ProcessName. This is + recorded for {UsageScenario} (see go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + +<histogram name="PerformanceMonitor.EnergyImpact.{ProcessName}" + units="ScaledUnits" expires_after="2022-11-30"> + <owner>olivierli@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + (Mac only) A synthetic power use estimate, as displayed in macOS Activity + Monitor and the battery menu. This incorporates CPU utilization, idle + wakeups, IO, and task QoS level using per-machine-model weights. Divide by + 100 to match Activity Monitor's scale. Recorded every two minutes. + + NOTE: This metric has one signigicant limitation, it doesn't report the CPU + usage of processes that terminate before the end of the interval. This means + that short lived processes will rarely be included in the data. Furthermore, + we know that short-lived processes are very common (see + Renderer.ProcessLifetime). A future version of this metric will address this + limitation. + </summary> + <token key="ProcessName" variants="ProcessName"/> +</histogram> + +<histogram name="PerformanceMonitor.IdleWakeups.Total{UsageScenario}" + units="WakeupsPerSecond" expires_after="2022-11-30"> + <owner>olivierli@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + See definition of PerformanceMonitor.IdleWakeups.ProcessName. This is + recorded for {UsageScenario} (see go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + +<histogram name="PerformanceMonitor.IdleWakeups.{ProcessName}" + units="WakeupsPerSecond" expires_after="2022-11-30"> + <owner>olivierli@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + The average CPU idle wakeups per second, sampled every two minutes. + + NOTE: This metric has one signigicant limitation, it doesn't report the CPU + usage of processes that terminate before the end of the interval. This means + that short lived processes will rarely be included in the data. Furthermore, + we know that short-lived processes are very common (see + Renderer.ProcessLifetime). A future version of this metric will address this + limitation. + </summary> + <token key="ProcessName" variants="ProcessName"/> +</histogram> + +<histogram + name="PerformanceMonitor.PackageExitIdleWakeups.Total{UsageScenario}" + units="WakeupsPerSecond" expires_after="2022-11-30"> + <owner>olivierli@chromium.org</owner> + <owner>catan-team@chromium.orgg</owner> + <summary> + See definition of PerformanceMonitor.PackageExitIdleWakeups.ProcessName. + This is recorded for {UsageScenario} (see go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + +<histogram name="PerformanceMonitor.PackageExitIdleWakeups.{ProcessName}" + units="WakeupsPerSecond" expires_after="2022-11-30"> + <owner>olivierli@chromium.org</owner> + <owner>catan-team@chromium.orgg</owner> + <summary> + (Mac only) The average package exit idle wakeups per second, sampled every + two minutes. This is a subset of wakeups that indicate that the processor + complex was taken out of low-power state. For more info, see the + powermetrics man page on macOS. + + NOTE: This metric has one signigicant limitation, it doesn't report the CPU + usage of processes that terminate before the end of the interval. This means + that short lived processes will rarely be included in the data. Furthermore, + we know that short-lived processes are very common (see + Renderer.ProcessLifetime). A future version of this metric will address this + limitation. + </summary> + <token key="ProcessName" variants="ProcessName"/> +</histogram> + +<histogram name="PerformanceMonitor.ResourceCoalition.Availability" + enum="CoalitionIDAvailability" expires_after="2022-11-30"> + <owner>fdoray@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + Details about whether or not it's possible to get coalition resource usage + data on the system. Only on macOS, recorded once at startup. + </summary> +</histogram> + +<histogram + name="PerformanceMonitor.ResourceCoalition.BytesReadPerSecond2{UsageScenario}" + units="BytesPerSecond" expires_after="2022-11-30"> + <owner>fdoray@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + The IO reads reported by the resource coalition mechanism on macOS. The data + is reported as the rate per second during this interval with a byte + granularity. This is recorded for {UsageScenario} (see + go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + +<histogram + name="PerformanceMonitor.ResourceCoalition.BytesWrittenPerSecond2{UsageScenario}" + units="BytesPerSecond" expires_after="2022-11-30"> + <owner>fdoray@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + The IO writes reported by the resource coalition mechanism on macOS. The + data is reported as the rate per second during this interval with a byte + granularity. This is recorded for {UsageScenario} (see + go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + +<histogram name="PerformanceMonitor.ResourceCoalition.CPUTime" + units="hundredth of percent" expires_after="2022-11-30"> + <obsolete> + Deprecated in 07/2021 because the computation was wrong. Replaced by + PerformanceMonitor.ResourceCoalition.CPUTime2. + </obsolete> + <owner>sebmarchand@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + Average CPU utilization reported by the resource coalition mechanism on + macOS. Read out at each two-minute interval. The utilization is in the + 0-100% range per CPU, which is then summed up and multiplied by 100. The + histogram is capped at 20000 (equivalent to 2 cores fully loaded). I.e. 4 + cores busy at 25% each will read as 25 * 4 * 100 = 10000. + </summary> +</histogram> + +<histogram + name="PerformanceMonitor.ResourceCoalition.CPUTime2_10sec{UsageScenario10sec}" + units="1/100 %" expires_after="2022-11-30"> + <owner>fdoray@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + Average CPU utilization reported by the resource coalition mechanism on + macOS. The utilization is in the 0-100% range per CPU, which is then summed + up and multiplied by 100. The histogram is capped at 20000 (equivalent to 2 + cores fully loaded). I.e. 4 cores busy at 25% each will read as 25 * 4 * 100 + = 10000. This is recorded for {UsageScenario10sec} (see + go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario10sec" variants="UsageScenario10sec"/> +</histogram> + +<histogram name="PerformanceMonitor.ResourceCoalition.CPUTime2{UsageScenario}" + units="1/100 %" expires_after="2022-11-30"> + <owner>fdoray@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + Average CPU utilization reported by the resource coalition mechanism on + macOS. The utilization is in the 0-100% range per CPU, which is then summed + up and multiplied by 100. The histogram is capped at 20000 (equivalent to 2 + cores fully loaded). I.e. 4 cores busy at 25% each will read as 25 * 4 * 100 + = 10000. This is recorded for {UsageScenario} (see + go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + +<histogram name="PerformanceMonitor.ResourceCoalition.Energy" + units="milliwatts" expires_after="2022-11-30"> + <obsolete> + Deprecated in 07/2021 because the name of the metric was wrong. Replaced by + PerformanceMonitor.ResourceCoalition.Power. + </obsolete> + <owner>sebmarchand@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + The energy usage reported by the resource coalition mechanism on macOS. + Reported every 2 minutes. Only available on devices with an ARM CPU. + </summary> +</histogram> + +<histogram + name="PerformanceMonitor.ResourceCoalition.EnergyImpact{UsageScenario}" + units="centi-EnergyImpact" expires_after="2022-11-30"> + <owner>siggi@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + (Mac only) A synthetic power use estimate, as displayed in macOS Activity + Monitor and the battery menu. This incorporates CPU utilization, idle + wakeups, IO, and task QoS level using per-machine-model weights. Divide by + 100 to match Activity Monitor's scale. Only available on macs with an Intel + CPU. + + This EnergyImpact score is computed from the usage reported by the resource + coalition mechanism on macOS. It accounts for the resource usage of all + Chrome processes no matter how short-lived, as well as XPC services running + on Chrome's behalf. + + This is recorded for {UsageScenario} (see go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + +<histogram name="PerformanceMonitor.ResourceCoalition.GPUTime" + units="hundredth of percent" expires_after="2022-11-30"> + <obsolete> + Deprecated in 07/2021 because the computation was wrong. Replaced by + PerformanceMonitor.ResourceCoalition.GPUTime2. + </obsolete> + <owner>sebmarchand@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + Average GPU utilization reported by the resource coalition mechanism on + macOS. Read out at each two-minute interval. The utilization is in the + 0-100% range and is multiplied by 100. The histogram is capped at 10000 + (equivalent to the GPU being used 100% of the time). + </summary> +</histogram> + +<histogram name="PerformanceMonitor.ResourceCoalition.GPUTime2{UsageScenario}" + units="1/100 %" expires_after="2022-11-30"> + <owner>fdoray@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + Average GPU utilization reported by the resource coalition mechanism on + macOS. The utilization is in the 0-100% range and is multiplied by 100. The + histogram is capped at 10000 (equivalent to the GPU being used 100% of the + time). This is recorded for {UsageScenario} (see + go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + +<histogram + name="PerformanceMonitor.ResourceCoalition.InterruptWakeupsPerSecond{UsageScenario}" + units="milliWakeupsPerSecond" expires_after="2022-11-30"> + <owner>fdoray@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + The interrupt wakeup rate reported by the resource coalition mechanism on + macOS. The data is reported as the rate per second during this interval with + a milliwakeup granularity. This is recorded for {UsageScenario} (see + go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + +<histogram + name="PerformanceMonitor.ResourceCoalition.PlatformIdleWakeupsPerSecond{UsageScenario}" + units="milliWakeupsPerSecond" expires_after="2022-11-30"> + <owner>fdoray@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + The platform idle wakeup rate reported by the resource coalition mechanism + on macOS. The data is reported as the rate per second during this interval + with a milliwakeup granularity. This is recorded for {UsageScenario} (see + go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + +<histogram name="PerformanceMonitor.ResourceCoalition.Power2{UsageScenario}" + units="milliwatts" expires_after="2022-11-30"> + <owner>fdoray@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + The power usage reported by the resource coalition mechanism on macOS. Only + reported on devices with an ARM CPU. This is recorded for {UsageScenario} + (see go/chrome_power_use_per_scenario). + </summary> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + +<histogram + name="PerformanceMonitor.ResourceCoalition.QoSLevel.{QoSLevel}{UsageScenario}" + units="1/100 %" expires_after="2022-11-30"> + <owner>fdoray@chromium.org</owner> + <owner>catan-team@chromium.org</owner> + <summary> + Average CPU time spent in a given QoS level, as reported by the resource + coalition mechanism on macOS. The utilization is in the 0-100% range and is + multiplied by 100. The histogram is capped at 10000 (equivalent to the GPU + being used 100% of the time). This is recorded for {UsageScenario} (see + go/chrome_power_use_per_scenario). + </summary> + <token key="QoSLevel"> + <variant name="Background"/> + <variant name="Default"/> + <variant name="Legacy"/> + <variant name="Maintenance"/> + <variant name="UserInitiated"/> + <variant name="UserInteractive"/> + <variant name="Utility"/> + </token> + <token key="UsageScenario" variants="UsageScenario"/> +</histogram> + <histogram name="Power.ApproxCpuTimeSecondsPerCoreTypeAndFrequency" units="50 MHz" expires_after="2022-08-28"> <obsolete>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index 8b3e159..0c44681 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -548,7 +548,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Paste.BytesPerSeconds" units="bytes" - expires_after="2022-04-24"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary> @@ -570,7 +570,7 @@ </histogram> <histogram name="SafeBrowsing.DeepScan.Paste.Duration" units="ms" - expires_after="2022-05-01"> + expires_after="2023-02-01"> <owner>domfc@chromium.org</owner> <owner>webprotect-team@google.com</owner> <summary>
diff --git a/tools/perf/core/bot_platforms.py b/tools/perf/core/bot_platforms.py index 242f841..bf8865b4 100644 --- a/tools/perf/core/bot_platforms.py +++ b/tools/perf/core/bot_platforms.py
@@ -661,7 +661,8 @@ _FUCHSIA_ATLAS_PERF_FYI_BENCHMARK_CONFIGS, 1, 'fuchsia', - is_fyi=True) + is_fyi=True, + executables=FUCHSIA_EXEC_CONFIGS['atlas']) # Calibration bots LINUX_PERF_CALIBRATION = PerfPlatform(
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 281eeda..fa1b597a 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,16 +5,16 @@ "remote_path": "perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "win": { - "hash": "6a87f3d6ab9205abf31d28f5367b04a7bc89217e", - "remote_path": "perfetto_binaries/trace_processor_shell/win/bce4286eebf41c7e7f6689684dea989c0b010fe1/trace_processor_shell.exe" + "hash": "7da27714c4ea778f83e3b05cd083ae5e7cace7a2", + "remote_path": "perfetto_binaries/trace_processor_shell/win/981be5ab5ba9674eded95ed5493811a061d7ed2a/trace_processor_shell.exe" }, "linux_arm": { "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893", "remote_path": "perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "mac": { - "hash": "b7b68e705f9e64650b588326af40c038a6a33f5b", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/bce4286eebf41c7e7f6689684dea989c0b010fe1/trace_processor_shell" + "hash": "5520efee30c243deda3278e696dc2b15f1f591a5", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/bc7a9c2bb682f97e2c5666bf19ec0a742c26ae26/trace_processor_shell" }, "mac_arm64": { "hash": "c0397e87456ad6c6a7aa0133e5b81c97adbab4ab", @@ -22,7 +22,7 @@ }, "linux": { "hash": "182bc90682ca7a54b10ae45fdd6a7a40e17a2334", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/981be5ab5ba9674eded95ed5493811a061d7ed2a/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/linux/06dab69bb9dcb7063a20820348d47cb60c9fc970/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/perf/core/shard_maps/fuchsia-perf-atlas-fyi_map.json b/tools/perf/core/shard_maps/fuchsia-perf-atlas-fyi_map.json index 130d400..8f95e74 100644 --- a/tools/perf/core/shard_maps/fuchsia-perf-atlas-fyi_map.json +++ b/tools/perf/core/shard_maps/fuchsia-perf-atlas-fyi_map.json
@@ -4,14 +4,26 @@ "system_health.common_desktop": { "abridged": false } + }, + "executables": { + "base_perftests": { + "path": "bin/run_base_perftests", + "arguments": [ + "--test-launcher-jobs=1", + "--test-launcher-retry-limit=0", + "-d", + "--os-check=update", + "--system-image-dir=../../third_party/fuchsia-sdk/images-internal/chromebook-x64-release/sucrose_eng" + ] + } } }, "extra_infos": { - "num_stories": 82, - "predicted_min_shard_time": 879.0, + "num_stories": 83, + "predicted_min_shard_time": 4033.0, "predicted_min_shard_index": 0, - "predicted_max_shard_time": 879.0, + "predicted_max_shard_time": 4033.0, "predicted_max_shard_index": 0, - "shard #0": 879.0 + "shard #0": 4033.0 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/timing_data/fuchsia-perf-atlas-fyi_timing.json b/tools/perf/core/shard_maps/timing_data/fuchsia-perf-atlas-fyi_timing.json index c3c17d8..e177bf7f 100644 --- a/tools/perf/core/shard_maps/timing_data/fuchsia-perf-atlas-fyi_timing.json +++ b/tools/perf/core/shard_maps/timing_data/fuchsia-perf-atlas-fyi_timing.json
@@ -1,62 +1,334 @@ [ { - "duration": "3.0", + "duration": "39.0", + "name": "system_health.common_desktop/browse:media:googleplaystore:2021" + }, + { + "duration": "77.0", + "name": "system_health.common_desktop/browse:media:imgur" + }, + { + "duration": "96.0", + "name": "system_health.common_desktop/browse:media:pinterest:2018" + }, + { + "duration": "65.0", + "name": "system_health.common_desktop/browse:media:tumblr:2018" + }, + { + "duration": "9.0", "name": "system_health.common_desktop/browse:media:youtube:2019" }, { - "duration": "3.0", + "duration": "72.0", + "name": "system_health.common_desktop/browse:media:youtubetv:2019" + }, + { + "duration": "78.0", + "name": "system_health.common_desktop/browse:media:youtubetv_watch:2020" + }, + { + "duration": "55.0", + "name": "system_health.common_desktop/browse:news:cnn:2021" + }, + { + "duration": "55.0", + "name": "system_health.common_desktop/browse:news:flipboard:2020" + }, + { + "duration": "60.0", + "name": "system_health.common_desktop/browse:news:hackernews:2020" + }, + { + "duration": "79.0", + "name": "system_health.common_desktop/browse:news:nytimes:2020" + }, + { + "duration": "69.0", + "name": "system_health.common_desktop/browse:news:reddit:2020" + }, + { + "duration": "53.0", + "name": "system_health.common_desktop/browse:search:google:2020" + }, + { + "duration": "38.0", + "name": "system_health.common_desktop/browse:search:google_india:2021" + }, + { + "duration": "72.0", + "name": "system_health.common_desktop/browse:social:facebook_infinite_scroll:2018" + }, + { + "duration": "62.0", + "name": "system_health.common_desktop/browse:social:tumblr_infinite_scroll:2018" + }, + { + "duration": "56.0", + "name": "system_health.common_desktop/browse:social:twitter:2018" + }, + { + "duration": "68.0", + "name": "system_health.common_desktop/browse:social:twitter_infinite_scroll:2018" + }, + { + "duration": "63.0", + "name": "system_health.common_desktop/browse:tech:discourse_infinite_scroll:2018" + }, + { + "duration": "84.0", + "name": "system_health.common_desktop/browse:tools:autocad:2021" + }, + { + "duration": "43.0", + "name": "system_health.common_desktop/browse:tools:docs_scrolling" + }, + { + "duration": "9.0", "name": "system_health.common_desktop/browse:tools:earth:2020" }, { - "duration": "3.0", + "duration": "10.0", "name": "system_health.common_desktop/browse:tools:gmail-compose:2020" }, { - "duration": "3.0", + "duration": "9.0", "name": "system_health.common_desktop/browse:tools:gmail-labelclick:2020" }, { - "duration": "3.0", + "duration": "41.0", + "name": "system_health.common_desktop/browse:tools:gmail-openconversation:2020" + }, + { + "duration": "9.0", "name": "system_health.common_desktop/browse:tools:gmail-search:2020" }, { - "duration": "3.0", + "duration": "80.0", + "name": "system_health.common_desktop/browse:tools:maps:2019" + }, + { + "duration": "9.0", "name": "system_health.common_desktop/browse:tools:photoshop:2021" }, { - "duration": "3.0", + "duration": "9.0", "name": "system_health.common_desktop/browse:tools:photoshop_warm:2021" }, { - "duration": "3.0", + "duration": "9.0", "name": "system_health.common_desktop/browse:tools:sheets:2019" }, { - "duration": "3.0", + "duration": "10.0", "name": "system_health.common_desktop/browse_accessibility:media:youtube" }, { + "duration": "33.0", + "name": "system_health.common_desktop/browse_accessibility:tech:codesearch:2018" + }, + { "duration": "23.0", + "name": "system_health.common_desktop/load:chrome:blank" + }, + { + "duration": "25.0", + "name": "system_health.common_desktop/load:games:alphabetty:2018" + }, + { + "duration": "23.0", + "name": "system_health.common_desktop/load:games:bubbles:2020" + }, + { + "duration": "22.0", + "name": "system_health.common_desktop/load:games:lazors" + }, + { + "duration": "26.0", + "name": "system_health.common_desktop/load:games:miniclip:2018" + }, + { + "duration": "28.0", + "name": "system_health.common_desktop/load:games:spychase:2018" + }, + { + "duration": "26.0", "name": "system_health.common_desktop/load:media:9gag" }, { - "duration": "19.0", + "duration": "23.0", + "name": "system_health.common_desktop/load:media:dailymotion:2019" + }, + { + "duration": "25.0", + "name": "system_health.common_desktop/load:media:facebook_feed:desktop:2020" + }, + { + "duration": "25.0", + "name": "system_health.common_desktop/load:media:facebook_photos:2018" + }, + { + "duration": "27.0", + "name": "system_health.common_desktop/load:media:facebook_photos:desktop:2020" + }, + { + "duration": "25.0", + "name": "system_health.common_desktop/load:media:flickr:2018" + }, + { + "duration": "23.0", + "name": "system_health.common_desktop/load:media:google_images:2018" + }, + { + "duration": "25.0", + "name": "system_health.common_desktop/load:media:imgur:2018" + }, + { + "duration": "26.0", + "name": "system_health.common_desktop/load:media:soundcloud:2018" + }, + { + "duration": "24.0", + "name": "system_health.common_desktop/load:media:youtube:2018" + }, + { + "duration": "22.0", + "name": "system_health.common_desktop/load:media:youtubelivingroom:2020" + }, + { + "duration": "25.0", + "name": "system_health.common_desktop/load:news:bbc:2018" + }, + { + "duration": "26.0", + "name": "system_health.common_desktop/load:news:cnn:2020" + }, + { + "duration": "23.0", "name": "system_health.common_desktop/load:news:flipboard" }, { - "duration": "3.0", + "duration": "22.0", + "name": "system_health.common_desktop/load:news:hackernews:2018" + }, + { + "duration": "28.0", + "name": "system_health.common_desktop/load:news:nytimes:2018" + }, + { + "duration": "25.0", + "name": "system_health.common_desktop/load:news:qq:2018" + }, + { + "duration": "27.0", + "name": "system_health.common_desktop/load:news:reddit:2018" + }, + { + "duration": "24.0", + "name": "system_health.common_desktop/load:news:wikipedia:2018" + }, + { + "duration": "24.0", + "name": "system_health.common_desktop/load:search:amazon:2018" + }, + { + "duration": "24.0", + "name": "system_health.common_desktop/load:search:baidu:2018" + }, + { + "duration": "23.0", + "name": "system_health.common_desktop/load:search:ebay:2018" + }, + { + "duration": "25.0", + "name": "system_health.common_desktop/load:search:flipkart:2018" + }, + { + "duration": "25.0", + "name": "system_health.common_desktop/load:search:google:2018" + }, + { + "duration": "24.0", + "name": "system_health.common_desktop/load:search:taobao:2018" + }, + { + "duration": "23.0", + "name": "system_health.common_desktop/load:search:yahoo:2018" + }, + { + "duration": "24.0", + "name": "system_health.common_desktop/load:search:yandex:2018" + }, + { + "duration": "24.0", + "name": "system_health.common_desktop/load:social:instagram:2018" + }, + { + "duration": "26.0", + "name": "system_health.common_desktop/load:social:pinterest:2019" + }, + { + "duration": "25.0", + "name": "system_health.common_desktop/load:social:vk:2018" + }, + { + "duration": "9.0", "name": "system_health.common_desktop/load:tools:chat:2020" }, { - "duration": "3.0", + "duration": "76.0", + "name": "system_health.common_desktop/load:tools:docs:2019" + }, + { + "duration": "25.0", + "name": "system_health.common_desktop/load:tools:drive:2019" + }, + { + "duration": "10.0", "name": "system_health.common_desktop/load:tools:gmail:2019" }, { - "duration": "131.0", + "duration": "25.0", + "name": "system_health.common_desktop/load:tools:stackoverflow:2018" + }, + { + "duration": "25.0", + "name": "system_health.common_desktop/load:tools:weather:2019" + }, + { + "duration": "26.0", + "name": "system_health.common_desktop/load_accessibility:media:wikipedia:2018" + }, + { + "duration": "24.0", + "name": "system_health.common_desktop/load_accessibility:shopping:amazon:2018" + }, + { + "duration": "136.0", + "name": "system_health.common_desktop/long_running:tools:gmail-background" + }, + { + "duration": "136.0", "name": "system_health.common_desktop/long_running:tools:gmail-foreground" }, { - "duration": "3.0", + "duration": "10.0", "name": "system_health.common_desktop/multitab:misc:typical24" + }, + { + "duration": "126.0", + "name": "system_health.common_desktop/multitab:misc:typical24:2018" + }, + { + "duration": "49.0", + "name": "system_health.common_desktop/play:media:google_play_music" + }, + { + "duration": "50.0", + "name": "system_health.common_desktop/play:media:soundcloud:2018" + }, + { + "duration": "900.0", + "name": "base_perftests/_gtest_" } ] \ No newline at end of file
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index c440a3fc..020c874 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -2,10 +2,10 @@ # Instructions of how to use this file: # https://chromium.googlesource.com/chromium/src/+/main/docs/speed/bot_health_sheriffing/how_to_disable_a_story.md # tags: [ android chromeos chromeos-local chromeos-remote -# linux mac mac-10.12 mac-10.13 mac-arm64 mac-x86_64 win win10 win7 win-laptop +# linux mac mac-10.12 mac-10.13 mac-arm64 mac-x86_64 win win10 win-laptop # sierra highsierra android-marshmallow android-lollipop android-nougat android-oreo android-pie android-10 # android-kitkat ubuntu fuchsia fuchsia-board-astro fuchsia-board-sherlock fuchsia-chrome ] -# tags: [ android-go android-low-end android-nexus-5 android-nexus-5x android-nexus-6 +# tags: [ android-go android-low-end android-nexus-6 # android-pixel-2 android-pixel-4 desktop mobile android-pixel-4a ] # tags: [ android-not-webview android-webview android-webview-google android-chromium # reference release debug exact release-x64 debug-x64 android-weblayer ] @@ -13,81 +13,38 @@ # conflicts_allowed: True # Benchmark: blink_perf.accessibility -crbug.com/1114112 [ android-nexus-5x android-webview ] blink_perf.accessibility/build-table.html [ Skip ] -crbug.com/1226849 [ android-nexus-5x android-webview ] blink_perf.accessibility/line-breaks.html [ Skip ] crbug.com/1234000 [ android-pixel-2 ] blink_perf.accessibility/line-breaks.html [ Skip ] -crbug.com/1266142 [ android-nexus-5x android-webview ] blink_perf.accessibility/many-nodes-toggle-content-visibility-auto.html [ Skip ] -crbug.com/1266142 [ android-nexus-5x android-webview ] blink_perf.accessibility/many-nodes-toggle-content-visibility-hidden.html [ Skip ] -crbug.com/1290813 [ android-nexus-5x ] blink_perf.accessibility/many-nodes-toggle-display-none.html [ Skip ] # Benchmark: blink_perf.bindings -crbug.com/882881 [ android-nexus-5 ] blink_perf.bindings/structured-clone-json-deserialize.html [ Skip ] -crbug.com/910207 [ android-nexus-5x ] blink_perf.bindings/structured-clone-json-deserialize.html [ Skip ] -crbug.com/882881 [ android-nexus-5 ] blink_perf.bindings/structured-clone-json-serialize.html [ Skip ] -crbug.com/910207 [ android-nexus-5x ] blink_perf.bindings/structured-clone-json-serialize.html [ Skip ] -crbug.com/882881 [ android-nexus-5 ] blink_perf.bindings/structured-clone-long-string-deserialize.html [ Skip ] -crbug.com/910207 [ android-nexus-5x ] blink_perf.bindings/structured-clone-long-string-deserialize.html [ Skip ] crbug.com/931780 [ android-webview ] blink_perf.bindings/structured-clone-long-string-serialize.html [ Skip ] crbug.com/893209 [ android-webview ] blink_perf.bindings/structured-clone-long-string-deserialize.html [ Skip ] -crbug.com/882881 [ android-nexus-5 ] blink_perf.bindings/structured-clone-long-string-serialize.html [ Skip ] -crbug.com/910207 [ android-nexus-5x ] blink_perf.bindings/structured-clone-long-string-serialize.html [ Skip ] -crbug.com/882881 [ android-nexus-5 ] blink_perf.bindings/worker-structured-clone-json-roundtrip.html [ Skip ] -crbug.com/910207 [ android-nexus-5x ] blink_perf.bindings/worker-structured-clone-json-roundtrip.html [ Skip ] -crbug.com/882881 [ android-nexus-5 ] blink_perf.bindings/worker-structured-clone-json-to-worker.html [ Skip ] -crbug.com/882881 [ android-nexus-5x ] blink_perf.bindings/worker-structured-clone-json-to-worker.html [ Skip ] -crbug.com/882881 [ android-nexus-5 ] blink_perf.bindings/worker-structured-clone-json-from-worker.html [ Skip ] -crbug.com/882881 [ android-nexus-5x ] blink_perf.bindings/worker-structured-clone-json-from-worker.html [ Skip ] crbug.com/865400 [ android-pixel-2 ] blink_perf.bindings/structured-clone-long-string-deserialize.html [ Skip ] crbug.com/865400 [ android-pixel-2 ] blink_perf.bindings/structured-clone-long-string-serialize.html [ Skip ] -# Benchmark: blink_perf.css -crbug.com/891878 [ android-nexus-5x android-webview ] blink_perf.css/CustomPropertiesVarAlias.html [ Skip ] - # Benchmark: blink_perf.events -crbug.com/963945 [ android-nexus-5x android-webview ] blink_perf.events/EventsDispatchingInDeeplyNestedV1ShadowTrees.html [ Skip ] -crbug.com/963945 [ android-nexus-5x android-webview ] blink_perf.events/EventsDispatchingInV1ShadowTrees.html [ Skip ] crbug.com/963945 [ android-pixel-2 ] blink_perf.events/EventsDispatchingInDeeplyNestedV1ShadowTrees.html [ Skip ] crbug.com/963945 [ android-pixel-2 ] blink_perf.events/EventsDispatchingInV1ShadowTrees.html [ Skip ] # Benchmark: blink_perf.layout crbug.com/551950 [ android-low-end ] blink_perf.layout/* [ Skip ] -crbug.com/832686 [ android-nexus-5 ] blink_perf.layout/subtree-detaching.html [ Skip ] -crbug.com/910207 [ android-nexus-5x ] blink_perf.layout/subtree-detaching.html [ Skip ] crbug.com/966921 [ android ] blink_perf.layout/line-layout-fit-content.html [ Skip ] crbug.com/966921 [ android ] blink_perf.layout/line-layout-fit-content-break-word.html [ Skip ] # Benchmark: blink_perf.paint crbug.com/574483 [ android-low-end ] blink_perf.paint/* [ Skip ] -crbug.com/799540 [ android-nexus-5 ] blink_perf.paint/* [ Skip ] -crbug.com/910207 [ android-nexus-5x ] blink_perf.paint/* [ Skip ] crbug.com/859979 [ android-webview ] blink_perf.paint/paint-offset-changes.html [ Skip ] crbug.com/901493 [ android-nexus-6 android-webview ] blink_perf.paint/* [ Skip ] crbug.com/1000460 [ android-pixel-2 ] blink_perf.paint/color-changes.html [ Skip ] # Benchmark: blink_perf.parser -crbug.com/966913 [ android-nexus-5x android-webview ] blink_perf.parser/query-selector-all-class-deep.html [ Skip ] -crbug.com/966913 [ android-nexus-5x android-webview ] blink_perf.parser/query-selector-all-deep.html [ Skip ] -crbug.com/966913 [ android-nexus-5x android-webview ] blink_perf.parser/query-selector-all-id-deep.html [ Skip ] crbug.com/966613 [ android-pixel-2 ] blink_perf.parser/query-selector-all-class-deep.html [ Skip ] crbug.com/966613 [ android-pixel-2 ] blink_perf.parser/query-selector-all-deep.html [ Skip ] crbug.com/966613 [ android-pixel-2 ] blink_perf.parser/query-selector-all-id-deep.html [ Skip ] -# Benchmark: blink_perf.shadow_dom -crbug.com/702319 [ android-nexus-5x ] blink_perf.shadow_dom/* [ Skip ] - # Benchmark: blink_perf.svg -crbug.com/736817 [ android-nexus-5x ] blink_perf.svg/SvgCubics.html [ Skip ] -crbug.com/736817 [ android-nexus-5x ] blink_perf.svg/Debian.html [ Skip ] -crbug.com/736817 [ android-nexus-5x ] blink_perf.svg/HarveyRayner.html [ Skip ] -crbug.com/736817 [ android-nexus-5x ] blink_perf.svg/CrawFishGanson.html [ Skip ] -crbug.com/736817 [ android-nexus-5x ] blink_perf.svg/Worldcup.html [ Skip ] -crbug.com/736817 [ android-nexus-5x ] blink_perf.svg/FlowerFromMyGarden.html [ Skip ] -crbug.com/736817 [ android-nexus-5x ] blink_perf.svg/SvgNestedUse.html [ Skip ] crbug.com/846061 [ win ] blink_perf.svg/SierpinskiCarpet.html [ Skip ] crbug.com/846061 [ mac ] blink_perf.svg/SierpinskiCarpet.html [ Skip ] crbug.com/850293 blink_perf.svg/Cowboy_transform.html [ Skip ] -crbug.com/894147 [ android-nexus-5 ] blink_perf.svg/SierpinskiCarpet.html [ Skip ] -crbug.com/894147 [ android-nexus-5x ] blink_perf.svg/SierpinskiCarpet.html [ Skip ] crbug.com/1023792 [ android ] blink_perf.svg/SierpinskiCarpet.html [ Skip ] # Benchmark: desktop_ui @@ -105,7 +62,6 @@ crbug.com/1050065 [ android-pixel-2 ] dromaeo/http://dromaeo.com?dom-modify [ Skip ] # Benchmark: jetstream -crbug.com/830600 [ android-nexus-5x android-webview ] jetstream/JetStream [ Skip ] crbug.com/1009843 [ android ] jetstream/JetStream [ Skip ] # Benchmark: loading.desktop @@ -117,7 +73,6 @@ crbug.com/876636 [ chromeos ] loading.desktop/TheOnion_cold [ Skip ] crbug.com/876636 [ chromeos ] loading.desktop/TheOnion_warm [ Skip ] crbug.com/876636 [ win10 ] loading.desktop/TheOnion_warm [ Skip ] -crbug.com/876636 [ win7 ] loading.desktop/TheOnion_warm [ Skip ] crbug.com/876636 [ chromeos ] loading.desktop/AllRecipes_cold [ Skip ] crbug.com/876636 [ chromeos ] loading.desktop/AllRecipes_warm [ Skip ] crbug.com/879833 [ mac-10.12 ] loading.desktop/AllRecipes_cold [ Skip ] @@ -129,10 +84,6 @@ # Benchmark: loading.mobile crbug.com/656861 loading.mobile/G1 [ Skip ] -crbug.com/857108 [ android-nexus-5 ] loading.mobile/G1_3g [ Skip ] -crbug.com/910207 [ android-nexus-5x ] loading.mobile/G1_3g [ Skip ] -[ android-nexus-5x ] loading.mobile/Hongkiat [ Skip ] -[ android-nexus-5x ] loading.mobile/Dramaq [ Skip ] crbug.com/859597 loading.mobile/Bradesco_3g [ Skip ] crbug.com/859597 loading.mobile/Dailymotion_3g [ Skip ] crbug.com/859597 loading.mobile/Dawn_3g [ Skip ] @@ -151,24 +102,6 @@ crbug.com/942631 loading.mobile/VoiceMemos_warm [ Skip ] crbug.com/942631 loading.mobile/VoiceMemos_hot_3g [ Skip ] crbug.com/942631 loading.mobile/VoiceMemos_warm_3g [ Skip ] -crbug.com/859597 [ android-nexus-5 ] loading.mobile/FlipBoard_cold_3g [ Skip ] -crbug.com/862663 [ android-nexus-5 ] loading.mobile/GoogleBrazil_3g [ Skip ] -crbug.com/910207 [ android-nexus-5x ] loading.mobile/GoogleBrazil_3g [ Skip ] -crbug.com/862663 [ android-nexus-5 ] loading.mobile/GoogleIndonesia_3g [ Skip ] -crbug.com/862663 [ android-nexus-5 ] loading.mobile/GoogleRedirectToGoogleJapan_3g [ Skip ] -crbug.com/910207 [ android-nexus-5x ] loading.mobile/GoogleRedirectToGoogleJapan_3g [ Skip ] -crbug.com/859597 [ android-nexus-5x ] loading.mobile/FlipBoard_cold_3g [ Skip ] -crbug.com/859597 [ android-nexus-5 ] loading.mobile/Hongkiat_3g [ Skip ] -crbug.com/859597 [ android-nexus-5x ] loading.mobile/Hongkiat_3g [ Skip ] -crbug.com/859597 [ android-nexus-5x android-webview ] loading.mobile/Hongkiat_3g [ Skip ] -crbug.com/896088 [ android-nexus-5 ] loading.mobile/TribunNews_3g [ Skip ] -crbug.com/859597 [ android-nexus-5x ] loading.mobile/TribunNews_3g [ Skip ] -crbug.com/859597 [ android-nexus-5x android-webview ] loading.mobile/TribunNews_3g [ Skip ] -crbug.com/859597 [ android-nexus-5x ] loading.mobile/GoogleIndonesia_3g [ Skip ] -crbug.com/859597 [ android-nexus-5x ] loading.mobile/QQNews_3g [ Skip ] -crbug.com/859597 [ android-nexus-5x ] loading.mobile/Youtube_3g [ Skip ] -crbug.com/859597 [ android-nexus-5x android-webview ] loading.mobile/GoogleBrazil_3g [ Skip ] -crbug.com/867103 [ android-nexus-5x android-webview ] loading.mobile/FlipBoard_warm_3g [ Skip ] crbug.com/873032 [ android-webview ] loading.mobile/GoogleRedirectToGoogleJapan_3g [ Skip ] crbug.com/873033 [ android-not-webview ] loading.mobile/FlipKart_warm_3g [ Skip ] crbug.com/676612 [ android-nexus-6 android-webview ] loading.mobile/FlipBoard_cold_3g [ Skip ] @@ -194,7 +127,6 @@ crbug.com/865400 [ android-pixel-2 android-webview ] loading.mobile/Hongkiat_3g [ Skip ] crbug.com/865400 [ android-pixel-2 android-webview ] loading.mobile/OLX_3g [ Skip ] crbug.com/865400 [ android-pixel-2 android-webview ] loading.mobile/VoiceMemos_cold_3g [ Skip ] -crbug.com/919191 [ android-nexus-5x android-webview ] loading.mobile/OLX_3g [ Skip ] # Benchmark: media.desktop crbug.com/1114681 [ win-laptop ] media.desktop/video.html?src=smpte_3840x2160_60fps_vp9.webm&seek [ Skip ] @@ -211,7 +143,6 @@ crbug.com/1202988 [ fuchsia-board-sherlock ] media.mobile/video.html?src=foodmarket_720p30fps.mp4 [ Skip ] # Benchmark: power.desktop -crbug.com/1036360 [ win7 ] power.desktop/abcnews [ Skip ] crbug.com/1082094 [ win10 ] power.desktop/abcnews [ Skip ] # Benchmark: power.mobile @@ -238,11 +169,8 @@ crbug.com/785485 [ android-webview ] rendering.mobile/kevs_3d [ Skip ] crbug.com/785286 [ android-webview ] rendering.mobile/smash_cat [ Skip ] crbug.com/785286 [ android-webview ] rendering.mobile/effect_games [ Skip ] -crbug.com/364248 [ android-nexus-5 ] rendering.mobile/geo_apis [ Skip ] -crbug.com/910207 [ android-nexus-5x ] rendering.mobile/geo_apis [ Skip ] crbug.com/825234 [ android-webview ] rendering.mobile/bouncing_balls_shadow [ Skip ] crbug.com/755556 [ android ] rendering.mobile/balls_css_key_frame_animations_composited_transform [ Skip ] -crbug.com/840964 [ android-nexus-5x ] rendering.mobile/web_animations_many_keyframes [ Skip ] crbug.com/653993 [ android-webview ] rendering.mobile/maps_perf_test [ Skip ] crbug.com/785473 [ android-webview ] rendering.mobile/canvas_20000_pixels_per_second [ Skip ] crbug.com/785473 [ android-webview ] rendering.mobile/canvas_40000_pixels_per_second [ Skip ] @@ -254,22 +182,14 @@ crbug.com/461127 rendering.mobile/famo_us_twitter_demo [ Skip ] crbug.com/850295 rendering.mobile/aquarium_20k [ Skip ] crbug.com/873013 [ android-webview ] rendering.mobile/yahoo_answers_mobile_2018 [ Skip ] -crbug.com/893197 [ android-nexus-5x ] rendering.mobile/yahoo_answers_mobile_2018 [ Skip ] crbug.com/865400 [ android-pixel-2 ] rendering.mobile/yahoo_answers_mobile_2018 [ Skip ] -crbug.com/874935 [ android-nexus-5 ] rendering.mobile/yahoo_news_2018 [ Skip ] -crbug.com/910207 [ android-nexus-5x ] rendering.mobile/yahoo_news_2018 [ Skip ] crbug.com/901526 rendering.mobile/microsoft_fireflies [ Skip ] crbug.com/924400 [ android-nexus-6 android-webview ] rendering.mobile/canvas_animation_no_clear [ Skip ] -crbug.com/949366 [ android-nexus-5x android-webview ] rendering.mobile/google_news_mobile_2018 [ Skip ] crbug.com/954948 [ android-webview ] rendering.mobile/cnn_mobile_pinch_2018 [ Skip ] crbug.com/966637 [ android-pixel-2 android-webview ] rendering.mobile/google_news_mobile_2018 [ Skip ] crbug.com/967809 [ android-webview ] rendering.mobile/microsoft_video_city [ Skip ] crbug.com/1017244 [ mobile ] rendering.mobile/youtube_2018 [ Skip ] -crbug.com/1036357 [ android-nexus-5 ] rendering.mobile/idle_power_blank [ Skip ] -crbug.com/1036357 [ android-nexus-5 ] rendering.mobile/balls_svg_animations [ Skip ] crbug.com/1116469 [ android-webview ] rendering.mobile/webgl_to_texture [ Skip ] -crbug.com/1124237 [ android-nexus-5x android-webview ] rendering.mobile/toBlob_duration.html [ Skip ] -crbug.com/1150490 [ android-nexus-5x android-webview ] rendering.mobile/microgame_fps [ Skip ] crbug.com/1153607 [ android-pixel-2 ] rendering.mobile/many_images [ Skip ] crbug.com/1178690 [ android-webview ] rendering.mobile/wsj_mobile_2018 [ Skip ] crbug.com/1193722 [ android-pixel-2 android-webview ] rendering.mobile/espn_pathological_2018 [ Skip ] @@ -335,17 +255,11 @@ crbug.com/815193 [ android ] rasterize_and_record_micro.top_25/file://static_top_25/wikipedia.html [ Skip ] crbug.com/873011 [ android-webview ] rasterize_and_record_micro.top_25/file://static_top_25/yahoonews.html [ Skip ] crbug.com/865400 [ android-pixel-2 ] rasterize_and_record_micro.top_25/file://static_top_25/yahoonews.html [ Skip ] -crbug.com/865400 [ android-nexus-5 ] rasterize_and_record_micro.top_25/file://static_top_25/yahoonews.html [ Skip ] -crbug.com/865400 [ android-nexus-5x ] rasterize_and_record_micro.top_25/file://static_top_25/yahoonews.html [ Skip ] -crbug.com/892223 [ android-nexus-5 ] rasterize_and_record_micro.top_25/file://static_top_25/yahoogames.html [ Skip ] -crbug.com/910207 [ android-nexus-5x ] rasterize_and_record_micro.top_25/file://static_top_25/yahoogames.html [ Skip ] crbug.com/875878 [ android-nexus-6 android-webview ] rasterize_and_record_micro.top_25/file://static_top_25/yahoogames.html [ Skip ] crbug.com/1228228 [ android-webview ] rasterize_and_record_micro.top_25/file://static_top_25/gmail.html [ Skip ] crbug.com/1228228 [ mac-10.12 ] rasterize_and_record_micro.top_25/file://static_top_25/gmail.html [ Skip ] # Benchmark: startup.mobile -crbug.com/948789 [ android-nexus-5 ] startup.mobile/maps_pwa:with_http_cache [ Skip ] -crbug.com/948789 [ android-nexus-5x ] startup.mobile/maps_pwa:with_http_cache [ Skip ] crbug.com/1030735 [ android-weblayer ] startup.mobile/maps_pwa:with_http_cache [ Skip ] crbug.com/1059717 [ android-pixel-2 ] startup.mobile/maps_pwa:with_http_cache [ Skip ] @@ -360,7 +274,6 @@ crbug.com/1008093 [ linux ] system_health.common_desktop/multitab:misc:typical24:2018 [ Skip ] crbug.com/1008093 [ mac ] system_health.common_desktop/multitab:misc:typical24 [ Skip ] crbug.com/1008093 [ mac ] system_health.common_desktop/multitab:misc:typical24:2018 [ Skip ] -crbug.com/931185 [ win7 ] system_health.common_desktop/browse:media:youtubetv:2019 [ Skip ] crbug.com/1008028 [ desktop ] system_health.common_desktop/browse:news:hackernews:2020 [ Skip ] crbug.com/1009838 [ mac ] system_health.common_desktop/browse:tools:maps:2019 [ Skip ] crbug.com/1008001 [ win ] system_health.common_desktop/browse:tools:sheets:2019 [ Skip ] @@ -368,7 +281,6 @@ crbug.com/1023366 [ desktop ] system_health.common_desktop/browse:media:youtube:2019 [ Skip ] crbug.com/1259608 [ desktop ] system_health.common_desktop/load:media:imgur:2018 [ Skip ] crbug.com/1042632 [ win ] system_health.common_desktop/load:tools:gmail:2019 [ Skip ] -crbug.com/1050068 [ win7 ] system_health.common_desktop/load:media:9gag [ Skip ] crbug.com/1044682 [ desktop ] system_health.common_desktop/browse:tools:gmail-labelclick:2020 [ Skip ] crbug.com/1044682 [ desktop ] system_health.common_desktop/browse:tools:gmail-openconversation:2020 [ Skip ] crbug.com/1044682 [ desktop ] system_health.common_desktop/browse:tools:gmail-search:2020 [ Skip ] @@ -458,9 +370,7 @@ crbug.com/869118 [ linux ] system_health.memory_desktop/long_running:tools:gmail-background [ Skip ] crbug.com/899887 [ linux ] system_health.memory_desktop/browse:social:facebook_infinite_scroll:2018 [ Skip ] crbug.com/924330 [ linux ] system_health.memory_desktop/browse:media:pinterest:2018 [ Skip ] -crbug.com/1088447 [ win7 ] system_health.memory_desktop/browse:tech:discourse_infinite_scroll:2018 [ Skip ] crbug.com/874803 [ win10 ] system_health.memory_desktop/multitab:misc:typical24 [ Skip ] -crbug.com/944978 [ win7 ] system_health.memory_desktop/multitab:misc:typical24 [ Skip ] crbug.com/934270 [ win ] system_health.memory_desktop/multitab:misc:typical24:2018 [ Skip ] crbug.com/942952 [ chromeos ] system_health.memory_desktop/browse:news:hackernews:2020 [ Skip ] crbug.com/959418 [ chromeos ] system_health.memory_desktop/long_running:tools:gmail-background [ Skip ] @@ -473,7 +383,6 @@ crbug.com/1017346 [ desktop ] system_health.memory_desktop/browse:media:youtube:2019 [ Skip ] crbug.com/1042632 [ win ] system_health.memory_desktop/load:tools:gmail:2019 [ Skip ] crbug.com/1042632 [ win ] system_health.memory_desktop/browse:social:tumblr_infinite_scroll:2018 [ Skip ] -crbug.com/956191 [ win7 ] system_health.memory_desktop/browse:news:nytimes:2020 [ Skip ] crbug.com/1097065 [ linux ] system_health.memory_desktop/load:social:vk:2018 [ Skip ] crbug.com/1097065 [ linux ] system_health.memory_desktop/browse_accessibility:tech:codesearch:2018 [ Skip ] crbug.com/1114120 [ win ] system_health.memory_desktop/browse:social:twitter_infinite_scroll:2018 [ Skip ] @@ -574,12 +483,10 @@ crbug.com/883320 [ android-go ] system_health.memory_mobile/browse:news:cnn:2021 [ Skip ] crbug.com/1064658 [ android ] system_health.memory_mobile/browse:tech:discourse_infinite_scroll:2018 [ Skip ] crbug.com/923527 [ android-webview ] system_health.memory_mobile/load:media:soundcloud:2018 [ Skip ] -crbug.com/1017661 [ android-nexus-5x ] system_health.memory_mobile/browse:social:facebook_infinite_scroll:2018 [ Skip ] crbug.com/1036143 [ android-pixel-2 ] system_health.memory_mobile/browse:chrome:omnibox:2019 [ Skip ] crbug.com/1036141 [ android-webview ] system_health.memory_mobile/browse:shopping:lazada:2019 [ Skip ] crbug.com/1044956 [ android-pixel-2 ] system_health.memory_mobile/background:tools:gmail:2019 [ Skip ] crbug.com/1049984 [ android-go android-webview ] system_health.memory_mobile/browse:social:instagram:2019 [ Skip ] -crbug.com/1097719 [ android-nexus-5x android-webview ] system_health.memory_mobile/browse:social:instagram:2019 [ Skip ] crbug.com/1112337 [ android ] system_health.memory_mobile/browse:news:cricbuzz:2019 [ Skip ] crbug.com/1113921 [ android-go ] system_health.memory_mobile/load:tools:dropbox:2019 [ Skip ] crbug.com/1139057 [ mobile ] system_health.memory_mobile/browse:social:facebook:2019 [ Skip ] @@ -607,7 +514,6 @@ crbug.com/1009838 [ mac ] v8.browsing_desktop/browse:tools:maps:2019 [ Skip ] crbug.com/1009838 [ chromeos ] v8.browsing_desktop/browse:tools:maps:2019 [ Skip ] crbug.com/1023366 [ desktop ] v8.browsing_desktop/browse:media:youtube:2019 [ Skip ] -crbug.com/1044653 [ win7 ] v8.browsing_desktop/browse:media:youtubetv:2019 [ Skip ] crbug.com/1057975 [ mac ] v8.browsing_desktop/browse:tools:maps:2019 [ Skip ] crbug.com/1100138 [ desktop ] v8.browsing_desktop/browse:tools:gmail-labelclick:2020 [ Skip ] crbug.com/1100138 [ desktop ] v8.browsing_desktop/browse:tools:gmail-openconversation:2020 [ Skip ] @@ -642,7 +548,6 @@ crbug.com/1009838 [ mac ] v8.browsing_desktop-future/browse:tools:maps:2019 [ Skip ] crbug.com/1009838 [ chromeos ] v8.browsing_desktop-future/browse:tools:maps:2019 [ Skip ] crbug.com/1023366 [ desktop ] v8.browsing_desktop-future/browse:media:youtube:2019 [ Skip ] -crbug.com/1044653 [ win7 ] v8.browsing_desktop-future/browse:media:youtubetv:2019 [ Skip ] crbug.com/1057975 [ mac ] v8.browsing_desktop-future/browse:tools:maps:2019 [ Skip ] crbug.com/1100138 [ desktop ] v8.browsing_desktop-future/browse:tools:gmail-labelclick:2020 [ Skip ] crbug.com/1100138 [ desktop ] v8.browsing_desktop-future/browse:tools:gmail-openconversation:2020 [ Skip ] @@ -675,7 +580,6 @@ crbug.com/1036141 [ android-webview ] v8.browsing_mobile/browse:shopping:lazada:2019 [ Skip ] crbug.com/1036143 [ android-pixel-2 ] v8.browsing_mobile/browse:chrome:omnibox:2019 [ Skip ] crbug.com/1064658 [ android ] v8.browsing_mobile/browse:tech:discourse_infinite_scroll:2018 [ Skip ] -crbug.com/1088419 [ android-nexus-5x android-webview ] v8.browsing_mobile/browse:media:imgur:2019 [ Skip ] crbug.com/1112337 [ android ] v8.browsing_mobile/browse:news:cricbuzz:2019 [ Skip ] crbug.com/1139057 [ mobile ] v8.browsing_mobile/browse:social:facebook:2019 [ Skip ] crbug.com/1143740 [ android-pixel-2 android-webview ] v8.browsing_mobile/browse:media:imgur:2019 [ Skip ] @@ -696,7 +600,6 @@ crbug.com/1036141 [ android-webview ] v8.browsing_mobile-future/browse:shopping:lazada:2019 [ Skip ] crbug.com/1036143 [ android-pixel-2 ] v8.browsing_mobile-future/browse:chrome:omnibox:2019 [ Skip ] crbug.com/1064658 [ android ] v8.browsing_mobile-future/browse:tech:discourse_infinite_scroll:2018 [ Skip ] -crbug.com/1088419 [ android-nexus-5x android-webview ] v8.browsing_mobile-future/browse:media:imgur:2019 [ Skip ] crbug.com/1112337 [ android ] v8.browsing_mobile-future/browse:news:cricbuzz:2019 [ Skip ] crbug.com/1139057 [ mobile ] v8.browsing_mobile-future/browse:social:facebook:2019 [ Skip ] crbug.com/1143740 [ android-pixel-2 android-webview ] v8.browsing_mobile-future/browse:media:imgur:2019 [ Skip ]
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 12e31e53..c189a4d9 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -49,7 +49,7 @@ <item id="client_download_request" added_in_milestone="62" content_hash_code="04bc89c5" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc" /> <item id="content_hash_verification_job" added_in_milestone="62" content_hash_code="079fc9db" os_list="linux,windows,chromeos" file_path="extensions/browser/content_hash_fetcher.cc" /> <item id="content_suggestion_get_favicon" added_in_milestone="62" content_hash_code="0800f6e5" os_list="linux,windows,chromeos,android" file_path="components/ntp_snippets/content_suggestions_service.cc" /> - <item id="conversion_measurement_report" added_in_milestone="84" content_hash_code="07884f7e" os_list="linux,windows,chromeos,android" file_path="content/browser/attribution_reporting/attribution_report_network_sender.cc" /> + <item id="conversion_measurement_report" added_in_milestone="84" content_hash_code="07884f7e" os_list="linux,windows,android" file_path="content/browser/attribution_reporting/attribution_report_network_sender.cc" /> <item id="credenential_avatar" added_in_milestone="62" content_hash_code="06bcc86b" os_list="linux,windows,chromeos,android" file_path="chrome/browser/ui/passwords/account_avatar_fetcher.cc" /> <item id="cros_recovery_image_download" added_in_milestone="62" content_hash_code="00a7d792" os_list="linux,windows,chromeos" file_path="chrome/browser/extensions/api/image_writer_private/write_from_url_operation.cc" /> <item id="desktop_screenshot_save" added_in_milestone="94" content_hash_code="019480c9" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble.cc" /> @@ -125,7 +125,7 @@ <item id="indexed_db_internals_handler" added_in_milestone="62" content_hash_code="0384abe6" os_list="linux,windows,chromeos,android" file_path="content/browser/indexed_db/indexed_db_internals_ui.cc" /> <item id="interest_feedv2_image_send" added_in_milestone="86" content_hash_code="06687258" os_list="linux,windows,chromeos,android" file_path="components/feed/core/v2/image_fetcher.cc" /> <item id="interest_feedv2_send" added_in_milestone="83" content_hash_code="02f676af" os_list="linux,windows,chromeos,android" file_path="components/feed/core/v2/feed_network_impl.cc" /> - <item id="interest_group_update_fetcher" added_in_milestone="94" content_hash_code="0272b26d" os_list="linux,windows,android,chromeos" file_path="content/browser/interest_group/interest_group_update_manager.cc" /> + <item id="interest_group_update_fetcher" added_in_milestone="94" content_hash_code="0272b26d" os_list="linux,windows,android" file_path="content/browser/interest_group/interest_group_update_manager.cc" /> <item id="intranet_redirect_detector" added_in_milestone="62" content_hash_code="03b26f7b" os_list="linux,windows,chromeos" file_path="chrome/browser/intranet_redirect_detector.cc" /> <item id="javascript_report_error" added_in_milestone="87" content_hash_code="006e4e54" os_list="linux" file_path="chrome/browser/error_reporting/chrome_js_error_report_processor_nonchromeos.cc" /> <item id="lib_address_input" added_in_milestone="62" content_hash_code="0374aae8" os_list="linux,windows,chromeos,android" file_path="third_party/libaddressinput/chromium/chrome_metadata_source.cc" /> @@ -163,7 +163,7 @@ <item id="openscreen_message" added_in_milestone="83" content_hash_code="076a1faf" os_list="linux,windows,chromeos,android" file_path="components/openscreen_platform/udp_socket.cc" /> <item id="openscreen_tls_message" added_in_milestone="83" content_hash_code="00f4022a" os_list="linux,windows,chromeos,android" file_path="components/openscreen_platform/tls_connection_factory.cc" /> <item id="optimization_guide_model" added_in_milestone="79" content_hash_code="01ee6e67" os_list="linux,windows,chromeos,android" file_path="components/optimization_guide/core/prediction_model_fetcher_impl.cc" /> - <item id="optimization_guide_model_download" added_in_milestone="88" content_hash_code="05d71d9b" os_list="linux,windows,chromeos,android" file_path="components/optimization_guide/core/prediction_model_download_manager.cc" /> + <item id="optimization_guide_model_download" added_in_milestone="88" content_hash_code="05d71d9b" os_list="linux,windows,android" file_path="components/optimization_guide/core/prediction_model_download_manager.cc" /> <item id="origin_policy_loader" added_in_milestone="69" content_hash_code="07fd1eaf" os_list="linux,windows,chromeos,android" file_path="services/network/origin_policy/origin_policy_fetcher.cc" /> <item id="parallel_download_job" added_in_milestone="62" content_hash_code="064736f3" os_list="linux,windows,chromeos,android" file_path="components/download/internal/common/parallel_download_job.cc" /> <item id="password_protection_request" added_in_milestone="62" content_hash_code="01869413" os_list="linux,windows,chromeos,android" file_path="components/safe_browsing/core/browser/password_protection/password_protection_request.cc" /> @@ -291,8 +291,6 @@ <item id="ambient_photo_cache" added_in_milestone="98" content_hash_code="07dbf21e" os_list="chromeos" file_path="ash/ambient/ambient_photo_cache.cc" /> <item id="ambient_photo_controller" added_in_milestone="98" content_hash_code="03284b8a" os_list="chromeos" file_path="ash/ambient/ambient_photo_controller.cc" /> <item id="image_downloader" added_in_milestone="98" content_hash_code="05b52680" os_list="chromeos" file_path="ash/assistant/assistant_controller_impl.cc" /> - <item id="fast_pair_footprints_request" added_in_milestone="98" type="partial" second_id="oauth2_api_call_flow" content_hash_code="01d3d58d" os_list="chromeos" semantics_fields="1,2,3,4,5" policy_fields="-1,3,5" file_path="ash/quick_pair/repository/fast_pair/footprints_fetcher.cc" /> - <item id="fast_pair" added_in_milestone="99" content_hash_code="060b214f" os_list="chromeos" file_path="ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.cc" /> <item id="kiosk_app_icon" added_in_milestone="98" content_hash_code="04f02fef" os_list="chromeos" file_path="chrome/browser/ash/app_mode/web_app/web_kiosk_app_data.cc" /> <item id="arc_auth_code_fetcher" added_in_milestone="98" content_hash_code="057519ca" os_list="chromeos" file_path="chrome/browser/ash/arc/auth/arc_background_auth_code_fetcher.cc" /> <item id="customization_wallpaper_downloader" added_in_milestone="98" content_hash_code="03ee8364" os_list="chromeos" file_path="chrome/browser/ash/customization/customization_wallpaper_downloader.cc" /> @@ -312,7 +310,7 @@ <item id="launcher_item_suggest" added_in_milestone="98" content_hash_code="04a4041e" os_list="chromeos" file_path="chrome/browser/ui/app_list/search/files/item_suggest_cache.cc" /> <item id="ambient_client" added_in_milestone="98" content_hash_code="062d821f" os_list="chromeos" file_path="chrome/browser/ui/ash/ambient/ambient_client_impl.cc" /> <item id="calendar_get_events" added_in_milestone="98" content_hash_code="0108842a" os_list="chromeos" file_path="chrome/browser/ui/ash/calendar/calendar_keyed_service.cc" /> - <item id="side_search_availability_test" added_in_milestone="98" content_hash_code="04410970" os_list="chromeos" file_path="chrome/browser/ui/side_search/side_search_tab_contents_helper.cc" /> + <item id="side_search_availability_test" added_in_milestone="98" content_hash_code="04b1ffa5" os_list="chromeos,linux,windows" file_path="chrome/browser/ui/side_search/side_search_tab_contents_helper.cc" /> <item id="edu_account_login_profile_image_fetcher" added_in_milestone="98" content_hash_code="0689301c" os_list="chromeos" file_path="chrome/browser/ui/webui/chromeos/edu_account_login_handler_chromeos.cc" /> <item id="management_ui_customer_logo" added_in_milestone="98" content_hash_code="01a17a58" os_list="chromeos" file_path="chrome/browser/ui/webui/management/management_ui_handler_chromeos.cc" /> <item id="gaia_reauth_token_fetcher" added_in_milestone="98" content_hash_code="04ff463d" os_list="chromeos" file_path="chrome/browser/ash/login/gaia_reauth_token_fetcher.cc" /> @@ -360,4 +358,5 @@ <item id="sct_auditing_hashdance" added_in_milestone="100" content_hash_code="00ea07d2" os_list="linux,windows,android,chromeos" file_path="chrome/browser/ssl/sct_reporting_service.cc" /> <item id="pull_template_request" added_in_milestone="101" content_hash_code="06335b4a" os_list="android" file_path="components/content_creation/notes/core/templates/template_fetcher.cc" /> <item id="webapk_create_for_service" added_in_milestone="101" content_hash_code="00107cfb" os_list="android" file_path="chrome/browser/android/webapk/webapk_installer.cc" /> + <item id="wallpaper_google_photos_enabled" added_in_milestone="101" content_hash_code="0264e793" os_list="chromeos" file_path="chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc" /> </annotations>
diff --git a/tools/traffic_annotation/summary/grouping.xml b/tools/traffic_annotation/summary/grouping.xml index 7447e61..7ba954dc 100644 --- a/tools/traffic_annotation/summary/grouping.xml +++ b/tools/traffic_annotation/summary/grouping.xml
@@ -67,8 +67,6 @@ <traffic_annotation unique_id="chromebook_mail_api"/> <traffic_annotation unique_id="customization_wallpaper_downloader"/> <traffic_annotation unique_id="edu_account_login_profile_image_fetcher"/> - <traffic_annotation unique_id="fast_pair"/> - <traffic_annotation unique_id="fast_pair_footprints_request"/> <traffic_annotation unique_id="fast_pair_image_decoder"/> <traffic_annotation unique_id="fast_pair_device_metadata_fetcher"/> <traffic_annotation unique_id="fwupd_firmware_update"/> @@ -95,6 +93,7 @@ <traffic_annotation unique_id="wallpaper_fetcher"/> <traffic_annotation unique_id="wallpaper_google_photos_albums"/> <traffic_annotation unique_id="wallpaper_google_photos_count"/> + <traffic_annotation unique_id="wallpaper_google_photos_enabled"/> <traffic_annotation unique_id="wallpaper_google_photos_photos"/> </sender> <!-- ChromeOS-specific features -->
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc index c507113..87170d6 100644 --- a/ui/accessibility/ax_role_properties.cc +++ b/ui/accessibility/ax_role_properties.cc
@@ -903,6 +903,15 @@ } } +bool IsWindow(ax::mojom::Role role) { + switch (role) { + case ax::mojom::Role::kWindow: + return true; + default: + return false; + } +} + bool ShouldHaveReadonlyStateByDefault(const ax::mojom::Role role) { switch (role) { case ax::mojom::Role::kArticle:
diff --git a/ui/accessibility/ax_role_properties.h b/ui/accessibility/ax_role_properties.h index ec4ded7..8585cf04 100644 --- a/ui/accessibility/ax_role_properties.h +++ b/ui/accessibility/ax_role_properties.h
@@ -214,6 +214,9 @@ // objects. See the method definition for more details. AX_BASE_EXPORT bool IsUIAEmbeddedObject(ax::mojom::Role role); +// Returns true if the provided role represents a window. +AX_BASE_EXPORT bool IsWindow(const ax::mojom::Role role); + // Returns true if the node should be read only by default AX_BASE_EXPORT bool ShouldHaveReadonlyStateByDefault( const ax::mojom::Role role);
diff --git a/ui/accessibility/platform/ax_platform_node_cocoa.mm b/ui/accessibility/platform/ax_platform_node_cocoa.mm index d5c5492d..d7c4d1b 100644 --- a/ui/accessibility/platform/ax_platform_node_cocoa.mm +++ b/ui/accessibility/platform/ax_platform_node_cocoa.mm
@@ -500,8 +500,12 @@ break; } - // VoiceOver computes the wrong description for a link. + // No label for windows. ax::mojom::Role role = _node->GetRole(); + if (ui::IsWindow(role)) + return false; + + // VoiceOver computes the wrong description for a link. if (ui::IsLink(role)) return true; @@ -1474,10 +1478,7 @@ } - (NSString*)AXTitle { - if (ui::IsNameExposedInAXValueForRole(_node->GetRole())) - return @""; - - return [self getName]; + return [self accessibilityTitle]; } - (id)AXTitleUIElement { @@ -1638,7 +1639,7 @@ - (NSString*)description { return [NSString stringWithFormat:@"%@ - %@ (%@)", [super description], - [self AXTitle], [self AXRole]]; + [self accessibilityTitle], [self AXRole]]; } // @@ -1737,7 +1738,29 @@ } - (NSString*)accessibilityTitle { - return [self AXTitle]; + if (![self instanceActive]) + return nil; + + if (ui::IsNameExposedInAXValueForRole(_node->GetRole())) + return @""; + + if ([self isNameFromLabel]) + return @""; + + // If we're exposing the title in TitleUIElement, don't also redundantly + // expose it in AXDescription. + if ([self titleUIElement]) + return @""; + + // On macOS cell titles are empty if they came from content. + ax::mojom::NameFrom nameFrom = _node->GetNameFrom(); + if (nameFrom == ax::mojom::NameFrom::kContents) { + NSString* role = [self accessibilityRole]; + if ([role isEqualToString:NSAccessibilityCellRole]) + return @""; + } + + return [self getName]; } - (id)accessibilityValue {
diff --git a/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm b/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm index 40ce4c1..2194a81 100644 --- a/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm +++ b/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm
@@ -78,6 +78,7 @@ NSAccessibilityPopupValueAttribute, NSAccessibilityRequiredAttributeChrome, NSAccessibilityRoleDescriptionAttribute, + NSAccessibilityTitleAttribute, NSAccessibilityTitleUIElementAttribute, NSAccessibilityURLAttribute, NSAccessibilityVisitedAttribute},
diff --git a/ui/gfx/animation/tween.cc b/ui/gfx/animation/tween.cc index 926c30fc..9e0a711 100644 --- a/ui/gfx/animation/tween.cc +++ b/ui/gfx/animation/tween.cc
@@ -118,6 +118,9 @@ case ACCEL_0_100_DECEL_80: return gfx::CubicBezier(0, 1, 0.2, 1).Solve(state); + + case ACCEL_5_70_DECEL_90: + return gfx::CubicBezier(0.05, 0.7, 0.1, 1).Solve(state); } NOTREACHED(); @@ -164,8 +167,8 @@ BlendColorComponents(SkColorGetB(start), SkColorGetB(target), start_a, target_a, blended_a, value); - return SkColorSetARGB( - FloatToColorByte(blended_a), blended_r, blended_g, blended_b); + return SkColorSetARGB(FloatToColorByte(blended_a), blended_r, blended_g, + blended_b); } // static
diff --git a/ui/gfx/animation/tween.h b/ui/gfx/animation/tween.h index 45d86cd..f9c8a13 100644 --- a/ui/gfx/animation/tween.h +++ b/ui/gfx/animation/tween.h
@@ -94,6 +94,9 @@ ACCEL_0_100_DECEL_80, // Variant of ACCEL_0_80_DECEL_80 which drops in // value even faster. + + ACCEL_5_70_DECEL_90, // Start at peak velocity and very soft + // deceleration. }; Tween(const Tween&) = delete;
diff --git a/ui/gfx/switches.cc b/ui/gfx/switches.cc index 67a798b..0e8044c 100644 --- a/ui/gfx/switches.cc +++ b/ui/gfx/switches.cc
@@ -47,6 +47,12 @@ }; const base::Feature kOddWidthMultiPlanarBuffers{ - "OddWidthMultiPlanarBuffers", base::FEATURE_DISABLED_BY_DEFAULT}; + "OddWidthMultiPlanarBuffers", +#if BUILDFLAG(IS_MAC) + base::FEATURE_ENABLED_BY_DEFAULT +#else + base::FEATURE_DISABLED_BY_DEFAULT +#endif +}; } // namespace features
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.cc b/ui/views/controls/tabbed_pane/tabbed_pane.cc index 85c6cab9..eb25f02 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -138,6 +138,7 @@ void Tab::GetAccessibleNodeData(ui::AXNodeData* data) { data->role = ax::mojom::Role::kTab; data->SetName(title_->GetText()); + data->SetNameFrom(ax::mojom::NameFrom::kContents); data->AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, selected()); }
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index a7ee067..168f63d 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -960,6 +960,8 @@ node_data->role = ax::mojom::Role::kTextField; node_data->SetName(accessible_name_); + node_data->SetNameFrom(ax::mojom::NameFrom::kContents); + // Editable state indicates support of editable interface, and is always set // for a textfield, even if disabled or readonly. node_data->AddState(ax::mojom::State::kEditable);
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabCallbackTest.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabCallbackTest.java index 5795a38..a316ed8 100644 --- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabCallbackTest.java +++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabCallbackTest.java
@@ -7,6 +7,7 @@ import android.net.Uri; import android.os.Build; import android.support.test.InstrumentationRegistry; +import android.view.View; import androidx.test.filters.SmallTest; @@ -423,4 +424,43 @@ ScrollNotificationType.DIRECTION_CHANGED_UP, (int) notificationTypes[0]); Assert.assertTrue(scrollRatio[0] < 0.5); } + + @Test + @SmallTest + @MinWebLayerVersion(101) + public void testOnVerticalOverscroll() throws TimeoutException { + InstrumentationActivity activity = mActivityTestRule.launchShellWithUrl("about:blank"); + + float overscrollY[] = new float[1]; + CallbackHelper callbackHelper = new CallbackHelper(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + Tab tab = activity.getTab(); + TabCallback callback = new TabCallback() { + @Override + public void onVerticalOverscroll(float accumulatedOverscrollY) { + overscrollY[0] = accumulatedOverscrollY; + callbackHelper.notifyCalled(); + tab.unregisterTabCallback(this); + } + }; + tab.registerTabCallback(callback); + }); + + View decorView[] = new View[1]; + int dimension[] = new int[2]; + TestThreadUtils.runOnUiThreadBlocking(() -> { + decorView[0] = activity.getWindow().getDecorView(); + dimension[0] = decorView[0].getWidth(); + dimension[1] = decorView[0].getHeight(); + }); + + int x = dimension[0] / 2; + int fromY = dimension[1] / 3; + int toY = dimension[1] / 3 * 2; + + TestTouchUtils.dragCompleteView(InstrumentationRegistry.getInstrumentation(), decorView[0], + /*fromX=*/x, /*toX=*/x, fromY, toY, /*stepCount=*/10); + callbackHelper.waitForFirst(); + Assert.assertThat(overscrollY[0], Matchers.lessThan(0f)); + } }
diff --git a/weblayer/browser/java/BUILD.gn b/weblayer/browser/java/BUILD.gn index eb8a818..d738792 100644 --- a/weblayer/browser/java/BUILD.gn +++ b/weblayer/browser/java/BUILD.gn
@@ -44,7 +44,7 @@ "//components/browser_ui/settings/android:java_resources", "//components/browser_ui/site_settings/android:java_resources", "//components/browser_ui/strings/android:browser_ui_strings_grd", - "//components/browser_ui/styles/android:java_resources", + "//components/browser_ui/theme/android:java_resources", "//components/infobars/android:java_resources", "//components/omnibox/browser:java_resources", "//components/page_info/android:java_resources",
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java index 7aad242..c49a5862 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
@@ -50,6 +50,7 @@ import org.chromium.components.webapps.AddToHomescreenCoordinator; import org.chromium.components.webapps.AppBannerManager; import org.chromium.content_public.browser.GestureListenerManager; +import org.chromium.content_public.browser.GestureStateListener; import org.chromium.content_public.browser.GestureStateListenerWithScroll; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationHandle; @@ -314,6 +315,20 @@ mMediaSessionHelper = new MediaSessionHelper( mWebContents, MediaSessionManager.createMediaSessionHelperDelegate(this)); + + GestureListenerManager.fromWebContents(mWebContents) + .addListener(new GestureStateListener() { + @Override + public void didOverscroll( + float accumulatedOverscrollX, float accumulatedOverscrollY) { + if (WebLayerFactoryImpl.getClientMajorVersion() < 101) return; + try { + mClient.onVerticalOverscroll(accumulatedOverscrollY); + } catch (RemoteException e) { + throw new APICallException(e); + } + } + }); } private void doInitAfterSettingContainerView() {
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl index 21bf2d7..c09baf4e 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl +++ b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl
@@ -47,4 +47,7 @@ in IObjectWrapper linkText, in IObjectWrapper titleOrAltText, in IObjectWrapper srcUrl, in boolean isImage, in boolean isVideo, in boolean canDownload, in IContextMenuParams contextMenuParams) = 13; + + // Added in M101. + void onVerticalOverscroll(float accumulatedOverscrollY) = 14; }
diff --git a/weblayer/public/java/org/chromium/weblayer/Tab.java b/weblayer/public/java/org/chromium/weblayer/Tab.java index c503d97..c3d37fd 100644 --- a/weblayer/public/java/org/chromium/weblayer/Tab.java +++ b/weblayer/public/java/org/chromium/weblayer/Tab.java
@@ -972,6 +972,14 @@ mActionModeCallback.onActionItemClicked(actionModeItemType, selectedString); } } + + @Override + public void onVerticalOverscroll(float accumulatedOverscrollY) { + StrictModeWorkaround.apply(); + for (TabCallback callback : mCallbacks) { + callback.onVerticalOverscroll(accumulatedOverscrollY); + } + } } private static final class ErrorPageCallbackClientImpl extends IErrorPageCallbackClient.Stub {
diff --git a/weblayer/public/java/org/chromium/weblayer/TabCallback.java b/weblayer/public/java/org/chromium/weblayer/TabCallback.java index 724d289..58756765 100644 --- a/weblayer/public/java/org/chromium/weblayer/TabCallback.java +++ b/weblayer/public/java/org/chromium/weblayer/TabCallback.java
@@ -72,4 +72,21 @@ */ public void onScrollNotification( @ScrollNotificationType int notificationType, float currentScrollRatio) {} + + /** + * Notification for vertical overscroll. This happens when user tries to touch scroll beyond + * the scroll bounds, or when a fling animation hits scroll bounds. + * A few caveats when using this callback: + * * This should be considered independent and unordered with respect to other scroll callbacks + * such as `onScrollNotification` or `ScrollOffsetCallback.onVerticalScrollOffsetChanged`. + * Client should not assume a certain order between this and other scroll notifications. + * * The value is accumulated scroll, so the magnitude of the value only goes up for a single + * overscroll gesture. However this is not enough to distinguish between two overscroll + * gestures and client must listen to touch events to make such distinction. Similarly there + * is no "end overscroll" event, and client is expected to listen to touch events as well. + * Added in M101. + * @param accumulatedOverscrollY negative for when trying to scroll beyond offset 0, positive + * for when trying to scroll beyond bottom scroll bounds. + */ + public void onVerticalOverscroll(float accumulatedOverscrollY) {} }