diff --git a/AUTHORS b/AUTHORS index 1b9ad99c..6df3e36 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -508,6 +508,7 @@ Guobin Wu <wuguobin.1229@bytedance.com> Gurpreet Kaur <k.gurpreet@samsung.com> Gustav Tiger <gustav.tiger@sonymobile.com> +Gustavo Martin <gusmartin@google.com> Gyuyoung Kim <gyuyoung.kim@navercorp.com> Gzob Qq <gzobqq@gmail.com> Habib Virji <habib.virji@samsung.com>
diff --git a/DEPS b/DEPS index a328d00..f0c7fff0 100644 --- a/DEPS +++ b/DEPS
@@ -291,7 +291,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'src_internal_revision': '5460c98a4b486ab3baedaa8a7251467c9cb09532', + 'src_internal_revision': 'e80ad25a3bbf0c883f0a2649187857d38c710529', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. @@ -303,7 +303,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'dd6a1a2c2346cabb0a8ce54140c3471c3f1ca18e', + 'angle_revision': 'bc9ff5e6c934f04e060ea9754a9156f1bf3ad107', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -339,7 +339,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling breakpad # and whatever else without interference from each other. - 'breakpad_revision': '7c56a01c1437ecdbe1d02c724573ca378947f82b', + 'breakpad_revision': 'ff252ff6faf5e3a52dc4955aab0d84831697dc94', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -379,7 +379,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': '26ab7701c3537b32486490fb6dcb26eab6e149ef', + 'devtools_frontend_revision': 'a9fee9cd133c82bb62a79f27e037f67526dbfdfb', # 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. @@ -515,7 +515,7 @@ # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. - 'libcxx_revision': 'ac9e4860cadb33ec5185084ed7c6345eca5fa50c', + 'libcxx_revision': 'ed0f32ee7a8d9481bfd26cfa6f5940b9f296f371', # GN CIPD package version. 'gn_version': 'git_revision:05e031634869be95570643bfad014c6dcbfc1a5c', @@ -1178,7 +1178,7 @@ 'packages': [ { 'package': 'chromium/chrome/android/orderfiles/arm', - 'version': 'aIM4eRVIIbhE_gbgYl9dnLBw7Zw-rOav2rEhriHnUEUC', + 'version': 'N1evYBm-OAI7VMNX-X3cG9WEAEJD9d9AaKmzbx4P2MEC', }, ], 'condition': 'checkout_android', @@ -1233,7 +1233,7 @@ 'packages': [ { 'package': 'chromium/third_party/updater/chrome_linux64', - 'version': 'ytJ0UbU9gMLUMLRQlmqQpGpOy1dYswI3rOJ0ILnIFbUC', + 'version': 'version:2@140.0.7273.0', }, ], }, @@ -1592,7 +1592,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '6ba3341efc52c965dd551f0fd5b16df1e5097d39', + '2c5256966ea2fdf7cf1e7ca7363eff4e495e7db3', 'condition': 'checkout_android and checkout_src_internal', }, @@ -2349,7 +2349,7 @@ Var('chromium_git') + '/external/libaddressinput.git' + '@' + '2610f7b1043d6784ada41392fc9392d1ea09ea07', 'src/third_party/libaom/source/libaom': - Var('aomedia_git') + '/aom.git' + '@' + 'a48eee7fd280967ce00308a48285f11fb03be464', + Var('aomedia_git') + '/aom.git' + '@' + 'f6055d0dc007d24e39e8d6a4a268216d67608b56', 'src/third_party/crabbyavif/src': Var('chromium_git') + '/external/github.com/webmproject/CrabbyAvif.git' + '@' + Var('crabbyavif_revision'), @@ -2612,7 +2612,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('chromium_git') + '/external/github.com/google/perfetto.git' + '@' + '40f166cc9df71dd893f0b589b69b3e6d53171855', + Var('chromium_git') + '/external/github.com/google/perfetto.git' + '@' + 'c26b918af62b7375d8089dd7c7ca7f5fbe9c111b', 'src/base/tracing/test/data': { 'bucket': 'perfetto', @@ -3116,7 +3116,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'OIv20ijjJFk7Bq8243oFQ07T9JGEg05ouZIaO-1dSk0C', + 'version': 'WD-hMS8wvD10CwUeTRPohDFmi61rxMQqC7Jq0DofwDAC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -3127,7 +3127,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'I3005yUkYGZ64jnBlNssGhmnKkvlCQaSerxdJSYFNEUC', + 'version': 'cCRwecHqnXVwdkTQW9xkx6h2ehIsYJot20iU-17-t0IC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -3187,7 +3187,7 @@ 'packages': [ { 'package': 'chromium/third_party/android_deps/autorolled', - 'version': 'HFSxY6DOr4aw0AehTYaIuMWkEwn9BWcDnnQcf7xQNj8C', + 'version': 'VGZvOZmD2nlVRmHIj_PzRsR3SJ82hc8hKLtfghTgHkAC', }, ], 'condition': 'checkout_android and non_git_source', @@ -3746,7 +3746,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - 'c07b97cf7d062f9164993da5913b2613f152a425', + '590133c247d87e501608f31c698216719413be5f', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc index fa86b11..f894ad1 100644 --- a/ash/constants/ash_switches.cc +++ b/ash/constants/ash_switches.cc
@@ -476,6 +476,10 @@ // Disables volume adjust sound. const char kDisableVolumeAdjustSound[] = "disable-volume-adjust-sound"; +// Disables the Welcome Recap feature for factory testing. +const char kDisableWelcomeRecapForFactoryTest[] = + "disable-welcome-recap-for-factory-testing"; + // DEPRECATED. Please use --arc-availability=officially-supported. // Enables starting the ARC instance upon session start. const char kEnableArc[] = "enable-arc";
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h index 983a20a5..2af2b89 100644 --- a/ash/constants/ash_switches.h +++ b/ash/constants/ash_switches.h
@@ -154,6 +154,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kDisablePerUserTimezone[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kDisableRollbackOption[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kDisableVolumeAdjustSound[]; +COMPONENT_EXPORT(ASH_CONSTANTS) +extern const char kDisableWelcomeRecapForFactoryTest[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kEnableArc[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kEnableArcVm[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kEnableArcVmDlc[];
diff --git a/ash/multi_user/multi_user_window_manager_impl.cc b/ash/multi_user/multi_user_window_manager_impl.cc index 431581e..7d2346df 100644 --- a/ash/multi_user/multi_user_window_manager_impl.cc +++ b/ash/multi_user/multi_user_window_manager_impl.cc
@@ -100,9 +100,7 @@ MultiUserWindowManagerImpl::WindowEntry::~WindowEntry() = default; -MultiUserWindowManagerImpl::MultiUserWindowManagerImpl( - const AccountId& account_id) - : current_account_id_(account_id) { +MultiUserWindowManagerImpl::MultiUserWindowManagerImpl() { g_instance = this; Shell::Get()->session_controller()->AddObserver(this); } @@ -162,15 +160,17 @@ // transfer it to the current user. const bool show_for_current_user = window->GetProperty(aura::client::kCreatedByUserGesture); - if (show_for_current_user) - window_entry->set_show_for_user(current_account_id_); + if (show_for_current_user) { + window_entry->set_show_for_user(*current_account_id_); + } // Add all transient children to our set of windows. Note that the function // will add the children but not the owner to the transient children map. AddTransientOwnerRecursive(window, window); - if (!IsWindowOnDesktopOfUser(window, current_account_id_)) + if (!IsWindowOnDesktopOfUser(window, *current_account_id_)) { SetWindowVisibility(window, false); + } } void MultiUserWindowManagerImpl::ShowWindowForUser( @@ -225,7 +225,8 @@ } const AccountId& MultiUserWindowManagerImpl::CurrentAccountId() const { - return current_account_id_; + CHECK(current_account_id_.has_value()); + return *current_account_id_; } void MultiUserWindowManagerImpl::AddObserver( @@ -238,6 +239,11 @@ observers_.RemoveObserver(observer); } +void MultiUserWindowManagerImpl::SetPrimaryUser(const AccountId& account_id) { + // Emulate as if primary user, which was already logged in, is logged in now. + OnActiveUserSessionChanged(account_id); +} + bool MultiUserWindowManagerImpl::IsWindowOnDesktopOfUser( aura::Window* window, const AccountId& account_id) const { @@ -258,25 +264,25 @@ void MultiUserWindowManagerImpl::OnActiveUserSessionChanged( const AccountId& account_id) { - // MultiUserWindowManagerImpl is created with an account before the change has - // potentially made it to SessionController. This means - // MultiUserWindowManagerImpl may be notified of a switch to the current user. - // Ignore this. Ignoring this is especially important in tests, which may be - // impacted by running the animation (when the animation closes, observers are - // notified, which may have side effects in downstream code). - if (account_id == current_account_id_) - return; + CHECK(current_account_id_ != account_id); + bool for_primary_user = !current_account_id_.has_value(); // This needs to be set before the animation starts. current_account_id_ = account_id; + if (for_primary_user) { + // For primary user activation, it is not transition from another user + // so we do not run animation. + return; + } + // Here to avoid a very nasty race condition, we must destruct any previously // created animation before creating a new one. Otherwise, the newly // constructed will hide all windows of the old user in the first step of the // animation only to be reshown again by the destructor of the old animation. animation_.reset(); animation_ = std::make_unique<UserSwitchAnimator>( - this, current_account_id_, GetAdjustedAnimationTime(kUserFadeTime)); + this, *current_account_id_, GetAdjustedAnimationTime(kUserFadeTime)); // Call RequestCaptureState here instead of having MediaClient observe // ActiveUserChanged because it must happen after @@ -327,15 +333,18 @@ if (suppress_visibility_changes_) return; + CHECK(current_account_id_.has_value()); + // Don't allow to make the window visible if it shouldn't be. - if (visible && !IsWindowOnDesktopOfUser(window, current_account_id_)) { + if (visible && !IsWindowOnDesktopOfUser(window, *current_account_id_)) { SetWindowVisibility(window, false); return; } aura::Window* owned_parent = GetOwningWindowInTransientChain(window); if (owned_parent && owned_parent != window && visible && - !IsWindowOnDesktopOfUser(owned_parent, current_account_id_)) + !IsWindowOnDesktopOfUser(owned_parent, *current_account_id_)) { SetWindowVisibility(window, false); + } } void MultiUserWindowManagerImpl::OnTransientChildAdded( @@ -384,7 +393,8 @@ } const AccountId& MultiUserWindowManagerImpl::GetCurrentUserForTest() const { - return current_account_id_; + CHECK(current_account_id_.has_value()); + return *current_account_id_; } bool MultiUserWindowManagerImpl::ShowWindowForUserIntern( @@ -507,8 +517,9 @@ // Hide the window if it should not be shown. Note that this hide operation // will hide recursively this and all children - but we have already collected // their initial view state. - if (!IsWindowOnDesktopOfUser(owned_parent, current_account_id_)) + if (!IsWindowOnDesktopOfUser(owned_parent, *current_account_id_)) { SetWindowVisibility(window, false, kAnimationTime); + } } void MultiUserWindowManagerImpl::RemoveTransientOwnerRecursive( @@ -568,9 +579,8 @@ } // static -std::unique_ptr<MultiUserWindowManager> MultiUserWindowManager::Create( - const AccountId& account_id) { - return std::make_unique<MultiUserWindowManagerImpl>(account_id); +std::unique_ptr<MultiUserWindowManager> MultiUserWindowManager::Create() { + return std::make_unique<MultiUserWindowManagerImpl>(); } } // namespace ash
diff --git a/ash/multi_user/multi_user_window_manager_impl.h b/ash/multi_user/multi_user_window_manager_impl.h index f3d28484..21efcc0 100644 --- a/ash/multi_user/multi_user_window_manager_impl.h +++ b/ash/multi_user/multi_user_window_manager_impl.h
@@ -61,7 +61,7 @@ ANIMATION_SPEED_DISABLED // Unit tests which do not require animations. }; - explicit MultiUserWindowManagerImpl(const AccountId& account_id); + MultiUserWindowManagerImpl(); MultiUserWindowManagerImpl(const MultiUserWindowManagerImpl&) = delete; MultiUserWindowManagerImpl& operator=(const MultiUserWindowManagerImpl&) = @@ -84,6 +84,7 @@ const AccountId& CurrentAccountId() const override; void AddObserver(MultiUserWindowManagerObserver* observer) override; void RemoveObserver(MultiUserWindowManagerObserver* observer) override; + void SetPrimaryUser(const AccountId& account_id) override; // SessionObserver: void OnActiveUserSessionChanged(const AccountId& account_id) override; @@ -221,7 +222,7 @@ // The currently selected active user. It is used to find the proper // visibility state in various cases. The state is stored here instead of // being read from the user manager to be in sync while a switch occurs. - AccountId current_account_id_; + std::optional<AccountId> current_account_id_; // Suppress changes to the visibility flag while we are changing it ourselves. bool suppress_visibility_changes_ = false;
diff --git a/ash/public/cpp/multi_user_window_manager.h b/ash/public/cpp/multi_user_window_manager.h index a09ac2ec..391d608 100644 --- a/ash/public/cpp/multi_user_window_manager.h +++ b/ash/public/cpp/multi_user_window_manager.h
@@ -24,8 +24,7 @@ // of windows based on the active user. class ASH_EXPORT MultiUserWindowManager { public: - static std::unique_ptr<MultiUserWindowManager> Create( - const AccountId& account_id); + static std::unique_ptr<MultiUserWindowManager> Create(); virtual ~MultiUserWindowManager() = default; @@ -65,8 +64,13 @@ // Unregisters `observer` from the instance. virtual void RemoveObserver(MultiUserWindowManagerObserver* observer) = 0; + // Notifies this instance about the primary user. + // TODO(crbug.com/425160398): This is short term work around for the + // transition period, so to be removed soon. + virtual void SetPrimaryUser(const AccountId& account_id) = 0; + protected: - MultiUserWindowManager() {} + MultiUserWindowManager() = default; }; } // namespace ash
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc index 446f323..7acf681 100644 --- a/ash/wm/desks/desks_unittests.cc +++ b/ash/wm/desks/desks_unittests.cc
@@ -4874,7 +4874,8 @@ void SimulateUser1Login() { auto account_id = SimulateUserLogin({kUser1Email}, std::nullopt, std::move(owned_user_1_prefs_)); - multi_user_window_manager_ = MultiUserWindowManager::Create(account_id); + multi_user_window_manager_ = MultiUserWindowManager::Create(); + multi_user_window_manager_->SetPrimaryUser(account_id); MultiUserWindowManagerImpl::Get()->SetAnimationSpeedForTest( MultiUserWindowManagerImpl::ANIMATION_SPEED_DISABLED); GetSessionControllerClient()->SetSessionState(
diff --git a/ash/wm/desks/templates/saved_desk_unittest.cc b/ash/wm/desks/templates/saved_desk_unittest.cc index 741ee33..75d572b 100644 --- a/ash/wm/desks/templates/saved_desk_unittest.cc +++ b/ash/wm/desks/templates/saved_desk_unittest.cc
@@ -418,8 +418,8 @@ // this would lead to flaky tests. saved_desk_test_helper()->WaitForDeskModels(); account_id_test_ = AccountId::FromUserEmail("test_user"); - multi_user_window_manager_ = - MultiUserWindowManager::Create(account_id_test_); + multi_user_window_manager_ = MultiUserWindowManager::Create(); + multi_user_window_manager_->SetPrimaryUser(account_id_test_); } void TearDown() override {
diff --git a/ash/wm/window_cycle/window_cycle_controller_unittest.cc b/ash/wm/window_cycle/window_cycle_controller_unittest.cc index c691be9a..74de4c9a 100644 --- a/ash/wm/window_cycle/window_cycle_controller_unittest.cc +++ b/ash/wm/window_cycle/window_cycle_controller_unittest.cc
@@ -3247,13 +3247,17 @@ } void SimulateUserLogin(const AccountId& account_id) { + AshTestBase::SimulateUserLogin(account_id); + // TODO(crbug.com/425160398): Currently on the production, + // MultiUserWindowManager is created after primary user login. + // We should move the initialization. if (!multi_user_window_manager_) { - multi_user_window_manager_ = MultiUserWindowManager::Create(account_id); + multi_user_window_manager_ = MultiUserWindowManager::Create(); + multi_user_window_manager_->SetPrimaryUser(account_id); CHECK(MultiUserWindowManagerImpl::Get()); MultiUserWindowManagerImpl::Get()->SetAnimationSpeedForTest( MultiUserWindowManagerImpl::ANIMATION_SPEED_DISABLED); } - AshTestBase::SimulateUserLogin(account_id); } const aura::Window::Windows GetWindows(WindowCycleController* controller) {
diff --git a/base/i18n/icu_util.cc b/base/i18n/icu_util.cc index 3a9b90a2..a52dcbe8 100644 --- a/base/i18n/icu_util.cc +++ b/base/i18n/icu_util.cc
@@ -176,7 +176,8 @@ return; } #endif // !BUILDFLAG(IS_APPLE) - File file(data_path, File::FLAG_OPEN | File::FLAG_READ); + File file(data_path, + File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WIN_SHARE_DELETE); if (file.IsValid()) { // TODO(brucedawson): http://crbug.com/445616. g_debug_icu_pf_last_error = 0;
diff --git a/base/message_loop/message_pump_default.cc b/base/message_loop/message_pump_default.cc index f61747c9..ee1e3357 100644 --- a/base/message_loop/message_pump_default.cc +++ b/base/message_loop/message_pump_default.cc
@@ -70,8 +70,6 @@ event_.Wait(); } } else { - TRACE_EVENT(TRACE_DISABLED_BY_DEFAULT("base"), "TimeWait", "delay_ms", - next_work_info.remaining_delay().InMilliseconds()); // Not handling shorter sleeps to keep the code as simple as possible. if (ShouldBusyLoop() && next_work_info.remaining_delay() > max_busy_loop_time_) {
diff --git a/build/chromeos/test_runner.py b/build/chromeos/test_runner.py index dd27ab2d..500e9f9 100755 --- a/build/chromeos/test_runner.py +++ b/build/chromeos/test_runner.py
@@ -840,8 +840,6 @@ # of args. # TODO(crbug.com/40567963): Make the GN-dependent deps controllable via cmd # line args. - if not env.get('GN_ARGS'): - env['GN_ARGS'] = 'enable_nacl = true' if not env.get('USE'): env['USE'] = 'highdpi' return env
diff --git a/build/mcp_servers/.vpython3 b/build/mcp_servers/.vpython3 index 431b674..7a04dc9 100644 --- a/build/mcp_servers/.vpython3 +++ b/build/mcp_servers/.vpython3
@@ -61,6 +61,10 @@ version: "version:8.0.3" > wheel: < + name: "infra/python/wheels/colorama-py2_py3" + version: "version:0.4.1" +> +wheel: < name: "infra/python/wheels/h11-py3" version: "version:0.16.0" > @@ -85,7 +89,7 @@ version: "version:2.11.7" > wheel: < - name: "infra/python/wheels/pydantic_core-py3" + name: "infra/python/wheels/pydantic_core/${vpython_platform}" version: "version:2.33.2" > wheel: <
diff --git a/build/mcp_servers/PRESUBMIT.py b/build/mcp_servers/PRESUBMIT.py new file mode 100644 index 0000000..827fe56e --- /dev/null +++ b/build/mcp_servers/PRESUBMIT.py
@@ -0,0 +1,45 @@ +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Presubmit script for //build/mcp_servers. + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts +for more details about the presubmit API built into depot_tools. +""" + +PRESUBMIT_VERSION = '2.0.0' + + +def _GetChromiumSrcPath(input_api): + """Returns the path to the Chromium src directory.""" + return input_api.os_path.realpath( + input_api.os_path.join(input_api.PresubmitLocalPath(), '..', '..')) + + +def CheckUnittests(input_api, output_api): + """Runs all unittests in the directory and subdirectories.""" + return input_api.canned_checks.RunUnitTestsInDirectory( + input_api, + output_api, + input_api.PresubmitLocalPath(), + [r'^.+_unittest\.py$'], + ) + + +def CheckPylint(input_api, output_api): + """Runs pylint on all directory content and subdirectories.""" + chromium_src_path = _GetChromiumSrcPath(input_api) + extra_path_components = [ + ('build', ), + ] + extra_paths = [ + input_api.os_path.join(chromium_src_path, *component) + for component in extra_path_components + ] + pylint_checks = input_api.canned_checks.GetPylint( + input_api, + output_api, + extra_paths_list=extra_paths, + pylintrc='pylintrc', + version='3.2') + return input_api.RunTests(pylint_checks)
diff --git a/build/mcp_servers/build_information.py b/build/mcp_servers/build_information.py index ee0b9eb..ca21b0f 100755 --- a/build/mcp_servers/build_information.py +++ b/build/mcp_servers/build_information.py
@@ -11,7 +11,10 @@ import re import sys +# vpython-provided modules +# pylint: disable=import-error from mcp.server import fastmcp +# pylint: enable=import-error # pylint: disable=wrong-import-position sys.path.insert(0, @@ -65,12 +68,12 @@ """Retrieves the operating system used by the current host. The return value is directly comparable with the target_os GN arg, except in the case of 'unknown'.""" - platform = sys.platform - if platform in ('linux', 'cygwin'): + current_platform = sys.platform + if current_platform in ('linux', 'cygwin'): return ValidOs.LINUX - if platform == 'win32': + if current_platform == 'win32': return ValidOs.WIN - if platform == 'darwin': + if current_platform == 'darwin': return ValidOs.MAC return ValidOs.UNKNOWN @@ -82,27 +85,19 @@ value is directly comparable with the target_cpu GN arg, except in the case of 'unknown'.""" arch = _get_host_architecture() - if arch == Architecture.UNKNOWN: - return ValidArch.UNKNOWN bits = _get_host_bits() - if bits == Bitness.UNKNOWN: - return ValidArch.UNKNOWN - if arch == Architecture.INTEL: - if bits == Bitness.THIRTY_TWO: + match (arch, bits): + case (Architecture.INTEL, Bitness.THIRTY_TWO): return ValidArch.X86 - if bits == Bitness.SIXTY_FOUR: + case (Architecture.INTEL, Bitness.SIXTY_FOUR): return ValidArch.X64 - return ValidArch.UNKNOWN - - if arch == Architecture.ARM: - if bits == Bitness.THIRTY_TWO: + case (Architecture.ARM, Bitness.THIRTY_TWO): return ValidArch.ARM - if bits == Bitness.SIXTY_FOUR: + case (Architecture.ARM, Bitness.SIXTY_FOUR): return ValidArch.ARM64 - return ValidArch.UNKNOWN - - return ValidArch.UNKNOWN + case _: + return ValidArch.UNKNOWN def _get_host_architecture() -> Architecture:
diff --git a/build/mcp_servers/build_information_unittest.py b/build/mcp_servers/build_information_unittest.py index 07c3e669..83431b8 100755 --- a/build/mcp_servers/build_information_unittest.py +++ b/build/mcp_servers/build_information_unittest.py
@@ -4,12 +4,17 @@ # found in the LICENSE file. """Unittests for build_information.py.""" +# pylint: disable=protected-access + import os import sys import unittest from unittest import mock +# vpython-provided modules +# pylint: disable=import-error from pyfakefs import fake_filesystem_unittest +# pylint: enable=import-error # pylint: disable=wrong-import-position sys.path.insert(0, @@ -269,8 +274,8 @@ mock_get_arch.return_value = build_information.ValidArch.X64 mock_get_valid_dirs.return_value = ['out/Release'] - result = build_information.get_valid_build_directories_for_current_host( - ) + result = ( + build_information.get_valid_build_directories_for_current_host()) mock_get_valid_dirs.assert_called_once_with('linux', 'x64') self.assertEqual(result, ['out/Release']) @@ -282,8 +287,8 @@ mock_get_os.return_value = build_information.ValidOs.UNKNOWN mock_get_arch.return_value = build_information.ValidArch.X64 - result = build_information.get_valid_build_directories_for_current_host( - ) + result = ( + build_information.get_valid_build_directories_for_current_host()) self.assertEqual(result, []) @mock.patch('mcp_servers.build_information.get_host_arch') @@ -293,8 +298,8 @@ mock_get_os.return_value = build_information.ValidOs.LINUX mock_get_arch.return_value = build_information.ValidArch.UNKNOWN - result = build_information.get_valid_build_directories_for_current_host( - ) + result = ( + build_information.get_valid_build_directories_for_current_host()) self.assertEqual(result, [])
diff --git a/build/mcp_servers/pylintrc b/build/mcp_servers/pylintrc new file mode 100644 index 0000000..be149199 --- /dev/null +++ b/build/mcp_servers/pylintrc
@@ -0,0 +1,251 @@ +[MAIN] + +# Pickle collected data for later comparisons. +persistent=yes + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + pylint_quotes, + pylint.extensions.no_self_use + +# Configure quote preferences. +string-quote = single-avoid-escape +triple-quote = double +docstring-quote = double + +[MESSAGES CONTROL] + +# Disable the message, report, category or checker with the given id(s). +disable=duplicate-code, + fixme, + invalid-name, + locally-disabled, + locally-enabled, + missing-docstring, + too-few-public-methods, + too-many-instance-attributes, + +# Pylint, or at least v1.5.6, does not properly handle adding comments between +# lines of disable= entries, nor does it allow multiple disable= lines, so +# we can't comment inline about why any of the above can't be removed. Thus, +# that information is here. + +# duplicate-code +# There is a bug in Pylint that prevents duplicate-code from being disabled for +# blocks of code, see https://github.com/PyCQA/pylint/issues/214. Since +# duplicate-code causes parts of the harness_script strings to be detected as +# duplicates, and there isn't a good solution to actually fix that, we need to +# keep this disabled until a fix is implemented and the Pylint version we use is +# upgraded. + +# fixme +# This complains about TODOs, which are perfectly valid to have. + +# invalid-name +# The default regular expressions for name validation don't like the conventions +# many Chromium Python files use, namely the use of upper camel case for method +# names. The regular expressions could be updated to handle this properly, but +# that would likely be part of a repo-wide linter update. + +# locally-disabled/locally-enabled +# There are valid cases where we want to selectively enable/disable lint errors +# in a particular file/scope, e.g. allowing protected access in unittests. + +# missing-docstring +# Docstrings are important, and proper use of them should be enforced. However, +# requiring a docstring on *every* method and class is overkill, as many are +# self-documenting due to being short and well-named. + +# too-few-public-methods +# This is supposedly to catch "functions disguised as classes", but we have +# never had issues with that. We do, however, use a handful of struct-like +# classes, which this complains about. + +# too-many-instance-attributes +# Only ends up complaining about struct-like classes. So, like +# too-few-public-methods, leave disabled instead of disabling on a per-class +# basis. + +# Other notes + +# too-many-arguments +# This one is borderline. There are legitimate cases of having too many +# arguments, but it also tends to flag cases that can't be fixed more often +# than fixable issues. There also doesn't appear to be an easy way to bump up +# the limit, as 5 is pretty small. + + +[REPORTS] + +# Set the output format. Available formats are text, parseable, colorized, msvs +# (visual studio) and html +output-format=text + +# Put messages in a separate file for each module / package specified on the +# command line instead of printing them on stdout. Reports (if any) will be +# written in a file name "pylint_global.[txt|html]". +files-output=no + +# Tells whether to display a full report or only the messages +# CHANGED: +reports=no + +# Activate the evaluation score. +score=no + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + + +[VARIABLES] + +# A regular expression matching the beginning of the name of dummy variables +# (i.e. not used). +dummy-variables-rgx=_|dummy + + +[TYPECHECK] + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# List of classes names for which member attributes should not be checked +# (useful for classes with attributes dynamically set). +ignored-classes=SQLObject, + twisted.internet.reactor, + hashlib, + google.appengine.api.memcache + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E0201 when accessed. Python regular +# expressions are accepted. +generated-members=REQUEST, + acl_users, + aq_parent, + multiprocessing.managers.SyncManager + + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=79 + +# Maximum number of lines in a module +max-module-lines=1000 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + + +[BASIC] + +# List of builtins function names that should not be used, separated by a comma +bad-functions=map, + filter, + apply, + input + +# Regular expression which should only match correct module names +module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Regular expression which should only match correct module level names +const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ + +# Regular expression which should only match correct class names +class-rgx=[A-Z_][a-zA-Z0-9]+$ + +# Regular expression which should only match correct function names +function-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct method names +method-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct instance attribute names +attr-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct argument names +argument-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct variable names +variable-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct list comprehension / +# generator expression variable names +inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ + +# Good variable names which should always be accepted, separated by a comma +good-names=i,j,k,ex,Run,_ + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo,bar,baz,toto,tutu,tata + +# Regular expression which should only match functions or classes name which do +# not require a docstring +no-docstring-rgx=__.*__ + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.* + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of branch for function / method body +max-branchs=12 + +# Maximum number of statements in function / method body +max-statements=50 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__,__new__,setUp + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + + +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub, + string, + TERMIOS, + Bastion, + rexec + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=Exception
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni index 0b349da..c691869 100644 --- a/buildtools/deps_revisions.gni +++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@ declare_args() { # Used to cause full rebuilds on libc++ rolls. This should be kept in sync # with the libcxx_revision var in //DEPS. - libcxx_revision = "ac9e4860cadb33ec5185084ed7c6345eca5fa50c" + libcxx_revision = "ed0f32ee7a8d9481bfd26cfa6f5940b9f296f371" }
diff --git a/chrome/android/expectations/monochrome_32_64_public_bundle__base.AndroidManifest.expected b/chrome/android/expectations/monochrome_32_64_public_bundle__base.AndroidManifest.expected index 678312b..4b09ac3 100644 --- a/chrome/android/expectations/monochrome_32_64_public_bundle__base.AndroidManifest.expected +++ b/chrome/android/expectations/monochrome_32_64_public_bundle__base.AndroidManifest.expected
@@ -298,7 +298,6 @@ <meta-data android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> - <meta-data android:name="com.google.firebase.components:com.google.firebase.ktx.FirebaseCommonLegacyRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> </service> # DIFF-ANCHOR: 7e26656b
diff --git a/chrome/android/expectations/monochrome_32_public_bundle__base.AndroidManifest.expected b/chrome/android/expectations/monochrome_32_public_bundle__base.AndroidManifest.expected index 9a1ff6c..5d276b0 100644 --- a/chrome/android/expectations/monochrome_32_public_bundle__base.AndroidManifest.expected +++ b/chrome/android/expectations/monochrome_32_public_bundle__base.AndroidManifest.expected
@@ -297,7 +297,6 @@ <meta-data android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> - <meta-data android:name="com.google.firebase.components:com.google.firebase.ktx.FirebaseCommonLegacyRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> </service> # DIFF-ANCHOR: 7e26656b
diff --git a/chrome/android/expectations/monochrome_64_32_public_bundle.proguard_flags.expected b/chrome/android/expectations/monochrome_64_32_public_bundle.proguard_flags.expected index 4ccdc96..ac4725b 100644 --- a/chrome/android/expectations/monochrome_64_32_public_bundle.proguard_flags.expected +++ b/chrome/android/expectations/monochrome_64_32_public_bundle.proguard_flags.expected
@@ -551,6 +551,18 @@ <methods>; } +# File: obj/third_party/androidx/androidx_datastore_datastore_core_android_java/proguard.txt +# make sure r8 can remove the fake counter that is only in the code to handle the +# robolectric tests. +-assumenosideeffects class androidx.datastore.core.SharedCounter$Factory { + private boolean isDalvik() return true; +} + +# File: obj/third_party/androidx/androidx_datastore_datastore_preferences_core_android_java/proguard.txt +-keepclassmembers class * extends androidx.datastore.preferences.protobuf.GeneratedMessageLite { + <fields>; +} + # File: obj/third_party/androidx/androidx_fragment_fragment_java/proguard.txt # Copyright (C) 2020 The Android Open Source Project # @@ -874,17 +886,28 @@ -dontwarn com.google.firebase.components.Component$Instantiation -dontwarn com.google.firebase.components.Component$ComponentType --keep class * implements com.google.firebase.components.ComponentRegistrar +-keep class * implements com.google.firebase.components.ComponentRegistrar { void <init>(); } -keep,allowshrinking interface com.google.firebase.components.ComponentRegistrar # File: obj/third_party/android_deps/google_play_services_auth_base_java/proguard.txt # We keep all fields for every generated proto file as the runtime uses # reflection over them that ProGuard cannot detect. Without this keep # rule, fields may be removed that would cause runtime failures. --keepclassmembers class * extends com.google.android.gms.internal.auth.zzew { +-keepclassmembers class * extends com.google.android.gms.internal.auth.zzaay { <fields>; } +# Checkdiscard flags for the auth frp client. Add these flags to ensure +# no accidental API leakage. +# This file is only applied when making the SDK, and is not forwarded to end developers. +-checkdiscard class com.google.android.gms.auth.frp.FrpClient { + public *** FrpClient; + public *** isChallengeSupported(); + public *** isChallengeRequired(); +} + +-dontwarn dalvik.system.VMStack + # File: obj/third_party/android_deps/google_play_services_base_java/proguard.txt # b/35135904 Ensure that proguard will not strip the mResultGuardian. -keepclassmembers class com.google.android.gms.common.api.internal.BasePendingResult {
diff --git a/chrome/android/expectations/monochrome_64_32_public_bundle__base.AndroidManifest.expected b/chrome/android/expectations/monochrome_64_32_public_bundle__base.AndroidManifest.expected index c2e2571e..4c49fe52 100644 --- a/chrome/android/expectations/monochrome_64_32_public_bundle__base.AndroidManifest.expected +++ b/chrome/android/expectations/monochrome_64_32_public_bundle__base.AndroidManifest.expected
@@ -297,7 +297,6 @@ <meta-data android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> - <meta-data android:name="com.google.firebase.components:com.google.firebase.ktx.FirebaseCommonLegacyRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> </service> # DIFF-ANCHOR: 7e26656b
diff --git a/chrome/android/expectations/monochrome_64_32_public_bundle__chrome.AndroidManifest.expected b/chrome/android/expectations/monochrome_64_32_public_bundle__chrome.AndroidManifest.expected index f6d4458..41f6f99 100644 --- a/chrome/android/expectations/monochrome_64_32_public_bundle__chrome.AndroidManifest.expected +++ b/chrome/android/expectations/monochrome_64_32_public_bundle__chrome.AndroidManifest.expected
@@ -352,7 +352,7 @@ android:clearTaskOnLaunch="true" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize|uiMode" android:excludeFromRecents="true" - android:exported="false" + android:exported="true" android:hardwareAccelerated="false" android:label="Search" android:launchMode="singleTask"
diff --git a/chrome/android/expectations/monochrome_64_public_bundle__base.AndroidManifest.expected b/chrome/android/expectations/monochrome_64_public_bundle__base.AndroidManifest.expected index d3ad4ab0..5a529faf 100644 --- a/chrome/android/expectations/monochrome_64_public_bundle__base.AndroidManifest.expected +++ b/chrome/android/expectations/monochrome_64_public_bundle__base.AndroidManifest.expected
@@ -297,7 +297,6 @@ <meta-data android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> - <meta-data android:name="com.google.firebase.components:com.google.firebase.ktx.FirebaseCommonLegacyRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> </service> # DIFF-ANCHOR: 7e26656b
diff --git a/chrome/android/expectations/trichrome_chrome_32_64_bundle__base.AndroidManifest.expected b/chrome/android/expectations/trichrome_chrome_32_64_bundle__base.AndroidManifest.expected index 796c7f3e..f3d4d34 100644 --- a/chrome/android/expectations/trichrome_chrome_32_64_bundle__base.AndroidManifest.expected +++ b/chrome/android/expectations/trichrome_chrome_32_64_bundle__base.AndroidManifest.expected
@@ -207,7 +207,6 @@ <meta-data android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> - <meta-data android:name="com.google.firebase.components:com.google.firebase.ktx.FirebaseCommonLegacyRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> </service> # DIFF-ANCHOR: 7e26656b
diff --git a/chrome/android/expectations/trichrome_chrome_32_bundle__base.AndroidManifest.expected b/chrome/android/expectations/trichrome_chrome_32_bundle__base.AndroidManifest.expected index bc913ef..19194112 100644 --- a/chrome/android/expectations/trichrome_chrome_32_bundle__base.AndroidManifest.expected +++ b/chrome/android/expectations/trichrome_chrome_32_bundle__base.AndroidManifest.expected
@@ -207,7 +207,6 @@ <meta-data android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> - <meta-data android:name="com.google.firebase.components:com.google.firebase.ktx.FirebaseCommonLegacyRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> </service> # DIFF-ANCHOR: 7e26656b
diff --git a/chrome/android/expectations/trichrome_chrome_64_32_bundle__base.AndroidManifest.expected b/chrome/android/expectations/trichrome_chrome_64_32_bundle__base.AndroidManifest.expected index 5ce5110c..1b4fccc 100644 --- a/chrome/android/expectations/trichrome_chrome_64_32_bundle__base.AndroidManifest.expected +++ b/chrome/android/expectations/trichrome_chrome_64_32_bundle__base.AndroidManifest.expected
@@ -207,7 +207,6 @@ <meta-data android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> - <meta-data android:name="com.google.firebase.components:com.google.firebase.ktx.FirebaseCommonLegacyRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> </service> # DIFF-ANCHOR: 7e26656b
diff --git a/chrome/android/expectations/trichrome_chrome_64_bundle__base.AndroidManifest.expected b/chrome/android/expectations/trichrome_chrome_64_bundle__base.AndroidManifest.expected index 3dd0e3a..c839e7d 100644 --- a/chrome/android/expectations/trichrome_chrome_64_bundle__base.AndroidManifest.expected +++ b/chrome/android/expectations/trichrome_chrome_64_bundle__base.AndroidManifest.expected
@@ -207,7 +207,6 @@ <meta-data android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> - <meta-data android:name="com.google.firebase.components:com.google.firebase.ktx.FirebaseCommonLegacyRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingKtxRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> <meta-data android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar" android:value="com.google.firebase.components.ComponentRegistrar"/> </service> # DIFF-ANCHOR: 7e26656b
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java index 5b4b5f4..f8d3fb4 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java
@@ -56,6 +56,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabHidingType; import org.chromium.chrome.browser.tab.TabObserver; +import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabClosingSource; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; @@ -220,7 +221,7 @@ mTabModelObserver = new TabModelSelectorTabModelObserver(mActivity.getTabModelSelector()) { @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { ensureObserverRegistered(tab); refreshTabs(); }
diff --git a/chrome/android/features/tab_ui/java/res/layout/archived_tabs_auto_delete_promo.xml b/chrome/android/features/tab_ui/java/res/layout/archived_tabs_auto_delete_promo.xml index 53ed9ad..01a6a2e 100644 --- a/chrome/android/features/tab_ui/java/res/layout/archived_tabs_auto_delete_promo.xml +++ b/chrome/android/features/tab_ui/java/res/layout/archived_tabs_auto_delete_promo.xml
@@ -57,14 +57,15 @@ android:id="@+id/promo_title_text" android:layout_width="match_parent" android:layout_height="28dp" - android:textAppearance="@style/TextAppearance.TextLarge.Primary" + android:textAppearance="@style/TextAppearance.Headline" android:gravity="center_horizontal|top" android:text="@string/archived_tabs_auto_delete_promo_title"/> <ScrollView android:id="@+id/promo_description_scrollview" android:layout_width="match_parent" - android:layout_height="60dp" - android:layout_marginBottom="28dp" + android:layout_height="41dp" + android:layout_marginTop="16dp" + android:layout_marginBottom="24dp" android:scrollbars="none" android:fadeScrollbars="false" android:maxHeight="120dp"> @@ -72,7 +73,7 @@ android:id="@+id/promo_description_text" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="@style/TextAppearance.TextSmall.Secondary" + android:textAppearance="@style/TextAppearance.TextMedium.Secondary" android:lineSpacingExtra="4dp" android:gravity="center_horizontal|top"/> </ScrollView>
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java index 1a04e14..499b07b 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java
@@ -374,7 +374,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { if (!isVisible()) return; // When this grid dialog is opened via the tab switcher there is a
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java index 4dc5415..51b688d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java
@@ -50,6 +50,7 @@ import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter; import org.chromium.ui.recyclerview.widget.ItemTouchHelper2; +import java.util.ArrayList; import java.util.List; /** @@ -722,8 +723,10 @@ Tab hoveredCard = filter.getRepresentativeTabAt(hoveredCardIndex); if (selectedCard == null) return; if (hoveredCard == null) return; - boolean willMergingCreateNewGroup = - filter.willMergingCreateNewGroup(List.of(selectedCard, hoveredCard)); + List<Tab> tabsToMerge = new ArrayList<>(); + tabsToMerge.addAll(filter.getRelatedTabList(selectedCard.getId())); + tabsToMerge.addAll(filter.getRelatedTabList(hoveredCard.getId())); + boolean willMergingCreateNewGroup = filter.willMergingCreateNewGroup(tabsToMerge); filter.mergeTabsToGroup(selectedCard.getId(), hoveredCard.getId()); if (willMergingCreateNewGroup) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListEditorLegacyGroupAction.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListEditorLegacyGroupAction.java index b0ea625cc..fe3eedb 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListEditorLegacyGroupAction.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListEditorLegacyGroupAction.java
@@ -138,11 +138,7 @@ sortedTabs.add(tab); } - List<Tab> tabsToMerge = new ArrayList<>(); - tabsToMerge.addAll(sortedTabs); - tabsToMerge.add(destinationTab); - boolean willMergingCreateNewGroup = - tabGroupModelFilter.willMergingCreateNewGroup(tabsToMerge); + boolean willMergingCreateNewGroup = tabGroupModelFilter.willMergingCreateNewGroup(tabs); tabGroupModelFilter.mergeListOfTabsToGroup(sortedTabs, destinationTab, /* notify= */ true); if (willMergingCreateNewGroup) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index a6d667b9..ad6a5b60 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -1011,7 +1011,7 @@ mTabModelObserver = new TabModelObserver() { @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { assert mShowingTabs; mNextTabId = Tab.INVALID_TAB_ID;
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 90efa49..c586a7f6 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -957,7 +957,7 @@ <activity android:name="org.chromium.chrome.browser.searchwidget.SearchActivity" android:theme="@style/Theme.Chromium.SearchActivity" android:label="Search" - android:exported="false" + android:exported="true" android:launchMode="singleTask" android:taskAffinity="" android:clearTaskOnLaunch="true"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 5440a25..45080fd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -917,7 +917,7 @@ rootViewSupplier::get, incognitoSupplier, adaptOnOverviewColorAlphaChange(), - mXrSceneCoreSessionManagerSupplier.get()); + getXrSpaceModeObservableSupplier()); return hubLayoutDependencyHolder; } @@ -990,7 +990,7 @@ mRootUiCoordinator.getDataSharingTabManager(), mRootUiCoordinator.getBottomSheetController(), mRootUiCoordinator.getShareDelegateSupplier(), - getXrSpaceModeObservableSupplier(), + mXrSceneCoreSessionManagerSupplier.get(), mRootUiCoordinator.getTopControlsStacker()); mLayoutStateProviderSupplier.set(mLayoutManager); } @@ -1184,17 +1184,6 @@ } private void onTabSwitcherClicked() { - var xrSceneCoreSessionManager = mXrSceneCoreSessionManagerSupplier.get(); - if (xrSceneCoreSessionManager != null) { - // Do nothing if space mode switch is already started. - xrSceneCoreSessionManager.startSpaceModeChange( - true, this::onTabSwitcherClickedInternal); - } else { - onTabSwitcherClickedInternal(); - } - } - - private void onTabSwitcherClickedInternal() { Profile profile = mTabModelProfileSupplier.get(); if (profile != null) { TrackerFactory.getTrackerForProfile(profile) @@ -1611,13 +1600,8 @@ // Request switching to Home Space mode on XR. var xrSceneCoreSessionManager = mXrSceneCoreSessionManagerSupplier.get(); if (xrSceneCoreSessionManager != null) { - boolean isFsm = - xrSceneCoreSessionManager.getXrSpaceModeObservableSupplier().get(); - if (isFsm) { - xrSceneCoreSessionManager.startSpaceModeChange( - /* fsmModeRequested= */ false, - () -> xrSceneCoreSessionManager.finishSpaceModeChange()); - } + xrSceneCoreSessionManager.requestSpaceModeChange( + /* requestFullSpaceMode= */ false); } hideOverview(/* animate= */ true); } @@ -4559,8 +4543,6 @@ XrSceneCoreSessionManager xrSceneCoreSessionManager = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - // TODO(crbug.com/422134376): To detect "Android XR" query OS instead of device's - // properties. if (XrUtils.isXrDevice()) { xrSceneCoreSessionManager = new XrSceneCoreSessionManagerImpl(this); xrSceneCoreSessionManager
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/TabUsageTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/TabUsageTracker.java index 15a3b3f..21728b49 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/TabUsageTracker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/TabUsageTracker.java
@@ -17,6 +17,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelUtils; @@ -132,7 +133,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { mTabsUsed.add(tab.getId()); } };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/UndoRefocusHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/UndoRefocusHelper.java index f089d2d..aaae3ef7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/UndoRefocusHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/UndoRefocusHelper.java
@@ -125,7 +125,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { // Undoing a selected tab closure, after manually switching tabs shouldn't // switch focus to the reopened tab. if (type == TabSelectionType.FROM_USER
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java index 845d407..207554f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -208,6 +208,7 @@ import org.chromium.components.browser_ui.widget.gesture.SwipeGestureListener.SwipeHandler; import org.chromium.components.browser_ui.widget.textbubble.TextBubbleBackPressHandler; import org.chromium.components.cached_flags.CachedFlagsSafeMode; +import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.embedder_support.util.UrlUtilities; import org.chromium.components.feature_engagement.EventConstants; @@ -2371,13 +2372,19 @@ getActivityTab()); } - private void openReaderMode() { - Tab currentTab = getActivityTab(); + private void onReaderModeMenuItemClick(Tab currentTab) { ReaderModeManager readerModeManager = currentTab.getUserDataHost().getUserData(ReaderModeManager.class); if (readerModeManager == null) return; - - readerModeManager.activateReaderMode(); + if (DomDistillerUrlUtils.isDistilledPage(currentTab.getUrl())) { + // Hide Reading Mode menu option is visible. + readerModeManager.hideReaderMode(); + RecordUserAction.record("MobileMenuHideReaderMode"); + } else { + // Show Reading Mode menu option is visible. + readerModeManager.activateReaderMode(); + RecordUserAction.record("MobileMenuShowReaderMode"); + } } /** @@ -2641,8 +2648,7 @@ } if (id == R.id.reader_mode_menu_id) { - openReaderMode(); - RecordUserAction.record("MobileMenuReaderMode"); + onReaderModeMenuItemClick(currentTab); return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/iban/AutofillSaveIbanBottomSheetMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/iban/AutofillSaveIbanBottomSheetMediator.java index 5a46b65..63f6e46 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/iban/AutofillSaveIbanBottomSheetMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/iban/AutofillSaveIbanBottomSheetMediator.java
@@ -12,6 +12,7 @@ import org.chromium.chrome.browser.layouts.LayoutStateProvider.LayoutStateObserver; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.components.autofill.SaveIbanPromptOffer; @@ -143,7 +144,7 @@ // TabModelObserver. @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { // While the bottom sheet scrim covers the omnibox UI, a new tab can be created in other // ways such as by opening a link from another app. In this case we want to hide the bottom // sheet rather than keeping the bottom sheet open while this tab loads behind the scrim.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/save_card/AutofillSaveCardBottomSheetLifecycle.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/save_card/AutofillSaveCardBottomSheetLifecycle.java index abc3279..57b9af4f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/save_card/AutofillSaveCardBottomSheetLifecycle.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/save_card/AutofillSaveCardBottomSheetLifecycle.java
@@ -10,6 +10,7 @@ import org.chromium.chrome.browser.layouts.LayoutStateProvider; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; @@ -106,7 +107,7 @@ // Implements TabModelObserver for TabModel. @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { if (lastId != tab.getId()) { finish(mDelegate::onIgnored); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillCardBenefitsFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillCardBenefitsFragment.java index a60b10b..fc56f71 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillCardBenefitsFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillCardBenefitsFragment.java
@@ -156,29 +156,30 @@ } private void createPreferencesForCardBenefitTerms() { - HashSet<Pair<String, String>> issuersAndProductDescriptions = new HashSet<>(); + HashSet<Pair<String, String>> benefitSourcesAndProductDescriptions = new HashSet<>(); // List the card for product terms redirect if: // 1. The card is eligible for benefits. // 2. The card has a valid product term url. - // 3. Same issuer and card product combination is not listed before. + // 3. Same benefit source and card product combination is not listed before. for (CreditCard card : mPersonalDataManager.getCreditCardsForSettings()) { - Pair<String, String> issuerAndProductDescriptionPair = - Pair.create(card.getIssuerId(), card.getProductDescription()); + Pair<String, String> benefitSourceAndProductDescriptionPair = + Pair.create(card.getBenefitSource(), card.getProductDescription()); if (!mPersonalDataManager.isCardEligibleForBenefits(card.getGUID()) - || issuersAndProductDescriptions.contains(issuerAndProductDescriptionPair) + || benefitSourcesAndProductDescriptions.contains( + benefitSourceAndProductDescriptionPair) || GURL.isEmptyOrInvalid(card.getProductTermsUrl())) { continue; } - issuersAndProductDescriptions.add(issuerAndProductDescriptionPair); + benefitSourcesAndProductDescriptions.add(benefitSourceAndProductDescriptionPair); // Add a preference for the credit card. ChromeBasePreference cardPref = new ChromeBasePreference(getStyledContext()); cardPref.setDividerAllowedAbove(false); cardPref.setDividerAllowedBelow(false); - cardPref.setTitle(issuerAndProductDescriptionPair.second); + cardPref.setTitle(benefitSourceAndProductDescriptionPair.second); cardPref.setSummary(R.string.autofill_settings_page_card_benefits_issuer_term_text); cardPref.setKey(PREF_KEY_CARD_BENEFIT_TERM);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/vcn/AutofillVcnEnrollBottomSheetProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/vcn/AutofillVcnEnrollBottomSheetProperties.java index 6907d3b..81b15cc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/vcn/AutofillVcnEnrollBottomSheetProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/vcn/AutofillVcnEnrollBottomSheetProperties.java
@@ -27,7 +27,7 @@ @NullMarked /*package*/ abstract class AutofillVcnEnrollBottomSheetProperties { /** Opens links. */ - static interface LinkOpener { + interface LinkOpener { /** * Opens a link and records the metric for opening it. *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java index 85fb843..0f10951 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
@@ -11,6 +11,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.chromium.base.Log; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.Supplier; @@ -22,6 +23,7 @@ import org.chromium.chrome.browser.data_sharing.DataSharingTabManager; import org.chromium.chrome.browser.device.DeviceClassManager; import org.chromium.chrome.browser.hub.HubLayoutDependencyHolder; +import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.multiwindow.MultiInstanceManager; import org.chromium.chrome.browser.share.ShareDelegate; @@ -39,9 +41,11 @@ import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.dragdrop.DragAndDropDelegate; import org.chromium.ui.resources.dynamics.DynamicResourceLoader; +import org.chromium.ui.xr.scenecore.XrSceneCoreSessionManager; /** LayoutManagerChromeTablet is the specialization of LayoutManagerChrome for the tablet. */ public class LayoutManagerChromeTablet extends LayoutManagerChrome { + private static final String TAG = "LayoutManagerChrome"; // Tab Strip private StripLayoutHelperManager mTabStripLayoutHelperManager; @@ -55,6 +59,7 @@ protected ObservableSupplierImpl<LayerTitleCache> mLayerTitleCacheSupplier = new ObservableSupplierImpl<>(); private final ObservableSupplier<Integer> mTabStripHeightSupplier; + private final @Nullable XrSceneCoreSessionManager mXrSceneCoreSessionManager; /** * Creates an instance of a LayoutManagerChromePhone. @@ -80,8 +85,8 @@ * @param dataSharingTabManager The {@link DataSharingTabManager} for shared groups. * @param bottomSheetController The {@link BottomSheetController} used to show bottom sheets. * @param shareDelegateSupplier Supplies {@link ShareDelegate} to share tab URLs. - * @param xrSpaceModeObservableSupplier Supplies current XR space mode status. True for XR full - * space mode, false otherwise. + * @param xrSceneCoreSessionManager The {@link XrSceneCoreSessionManager} to switch between + * space modes on XR. * @param topControlsStacker The {@link TopControlsStacker} for the owner of this instance. */ public LayoutManagerChromeTablet( @@ -106,7 +111,7 @@ DataSharingTabManager dataSharingTabManager, @NonNull BottomSheetController bottomSheetController, @NonNull Supplier<ShareDelegate> shareDelegateSupplier, - @Nullable ObservableSupplier<Boolean> xrSpaceModeObservableSupplier, + @Nullable XrSceneCoreSessionManager xrSceneCoreSessionManager, TopControlsStacker topControlsStacker) { super( host, @@ -116,6 +121,13 @@ tabContentManagerSupplier, topUiThemeColorProvider, hubLayoutDependencyHolder); + + mXrSceneCoreSessionManager = xrSceneCoreSessionManager; + ObservableSupplier<Boolean> xrSpaceModeObservableSupplier = + mXrSceneCoreSessionManager != null + ? mXrSceneCoreSessionManager.getXrSpaceModeObservableSupplier() + : null; + mTabStripLayoutHelperManager = new StripLayoutHelperManager( host.getContext(), @@ -225,4 +237,45 @@ public boolean hasTabletUi() { return true; } + + @Override + public void showLayout(@LayoutType int layoutType, boolean animate) { + // The Tab Switcher should always appear in the Full Space mode on XR. + if (mXrSceneCoreSessionManager != null + && layoutType == LayoutType.TAB_SWITCHER + && !mXrSceneCoreSessionManager.isXrFullSpaceMode()) { + boolean spaceModeChangeStarted = + mXrSceneCoreSessionManager.requestSpaceModeChange( + /* requestFullSpaceMode= */ true, + () -> super.showLayout(layoutType, animate)); + if (spaceModeChangeStarted) { + // The layout will be shown after the XR space mode is changed. + return; + } else { + Log.w(TAG, "Unable to show the Tab Switcher in Full Space mode on XR."); + } + } + super.showLayout(layoutType, animate); + } + + @Override + protected void startShowing(Layout layout, boolean animate) { + super.startShowing(layout, animate); + if (mXrSceneCoreSessionManager != null && isTabSwitcher(layout)) { + mXrSceneCoreSessionManager.setMainPanelVisibility(true); + } + } + + @Override + public void doneHiding() { + if (mXrSceneCoreSessionManager != null && isTabSwitcher(getActiveLayout())) { + mXrSceneCoreSessionManager.requestSpaceModeChange(/* requestFullSpaceMode= */ false); + mXrSceneCoreSessionManager.setMainPanelVisibility(false); + } + super.doneHiding(); + } + + private boolean isTabSwitcher(Layout layout) { + return layout != null && layout.getLayoutType() == LayoutType.TAB_SWITCHER; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java index 2b5e56b..5cb01793 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java
@@ -235,7 +235,7 @@ mTabModelSelectorTabModelObserver = new TabModelSelectorTabModelObserver(tabModelSelector) { @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { if (!mIsShowing) return; setStaticTab(tab);
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 390cbdf1..2ab9762 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
@@ -752,6 +752,12 @@ assumeNonNull(provider).addObserver(mDistillabilityObserver); } + // Navigates away from reader mode. This is intended for in-app distillation, not for CCT. + public void hideReaderMode() { + mTab.goBack(); + RecordUserAction.record("MobileReaderModeHidden"); + } + /** * Returns whether reader mode should trigger through messages. This happens for CCTs and * incognito tabs.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonController.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonController.java index bd3418f..af2b420 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonController.java
@@ -137,17 +137,17 @@ Tab currentTab = mActiveTabSupplier.get(); if (currentTab == null) return; - // Note: Hidden behind feature flag. - if (DomDistillerFeatures.sReaderModeDistillInApp.isEnabled() - && DomDistillerUrlUtils.isDistilledPage(currentTab.getUrl())) { - currentTab.goBack(); - return; - } - ReaderModeManager readerModeManager = currentTab.getUserDataHost().getUserData(ReaderModeManager.class); if (readerModeManager == null) return; + // Note: Hidden behind feature flag. + if (DomDistillerFeatures.sReaderModeDistillInApp.isEnabled() + && DomDistillerUrlUtils.isDistilledPage(currentTab.getUrl())) { + readerModeManager.hideReaderMode(); + return; + } + readerModeManager.activateReaderMode(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/hub/HubLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/hub/HubLayout.java index d1f53556..22d0216 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/hub/HubLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/hub/HubLayout.java
@@ -9,6 +9,8 @@ import static org.chromium.chrome.browser.hub.HubAnimationConstants.HUB_LAYOUT_FADE_DURATION_MS; import static org.chromium.chrome.browser.hub.HubAnimationConstants.HUB_LAYOUT_TIMEOUT_MS; import static org.chromium.chrome.browser.hub.HubAnimationConstants.HUB_LAYOUT_TRANSLATE_DURATION_MS; +import static org.chromium.chrome.browser.hub.HubAnimationConstants.HUB_LAYOUT_XR_FADE_IN_DELAY_MS; +import static org.chromium.chrome.browser.hub.HubAnimationConstants.HUB_LAYOUT_XR_FADE_OUT_DELAY_MS; import android.content.Context; import android.graphics.Bitmap; @@ -28,7 +30,6 @@ import org.chromium.base.Callback; import org.chromium.base.Promise; -import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.supplier.ObservableSupplier; @@ -69,7 +70,6 @@ import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.base.LocalizationUtils; import org.chromium.ui.resources.ResourceManager; -import org.chromium.ui.xr.scenecore.XrSceneCoreSessionManager; import java.util.Collections; import java.util.function.DoubleConsumer; @@ -86,8 +86,6 @@ */ @NullMarked public class HubLayout extends Layout implements HubLayoutController, AppHeaderObserver { - private static final int START_HIDING_DELAY_XR_FULL_SPACE_MODE_MS = 250; - /** * Implementation of {@link HubLayoutAnimationListener} that updates an {@link * ObservableSupplier<Boolean>} to reflect the animation state. @@ -130,6 +128,7 @@ private final DoubleConsumer mOnToolbarAlphaChange; private final HubShowPaneHelper mHubShowPaneHelper; private final @Nullable DesktopWindowStateManager mDesktopWindowStateManager; + private final Supplier<Boolean> mXrFullSpaceModeSupplier; /** * The previous {@link LayoutType}, valid between {@link #show(long, boolean)} and {@link @@ -153,8 +152,6 @@ private @Nullable HubLayoutAnimationRunner mCurrentAnimationRunner; - private @Nullable XrSceneCoreSessionManager mXrSessionManager; - /** * Create the {@link Layout} to show the Hub on. * @@ -217,14 +214,13 @@ mHubShowPaneHelper = mHubManager.getHubShowPaneHelper(); mScrimController = dependencyHolder.getScrimController(); mOnToolbarAlphaChange = dependencyHolder.getOnOverviewAlphaChange(); + mXrFullSpaceModeSupplier = dependencyHolder.getXrFullSpaceModeSupplier(); mTabModelSelector = tabModelSelectorSupplier.get(); mDesktopWindowStateManager = desktopWindowStateManager; if (mDesktopWindowStateManager != null) { mDesktopWindowStateManager.addObserver(this); maybeUpdateLayout(); } - - mXrSessionManager = dependencyHolder.getXrSceneCoreSessionManager(); } @Override @@ -244,15 +240,7 @@ public void selectTabAndHideHubLayout(@TabId int tabId) { assumeNonNull(mTabModelSelector); TabModelUtils.selectTabById(mTabModelSelector, tabId, TabSelectionType.FROM_USER); - - // TODO(crbug.com/422175353): Put delay of starting HubLayout->StaticLayout - // transition in FadeHubLayoutAnimationFactory on Android XR. - if (isActivityInXrFullSpaceModeNow()) { - ThreadUtils.postOnUiThreadDelayed( - this::startHiding, START_HIDING_DELAY_XR_FULL_SPACE_MODE_MS); - } else { - startHiding(); - } + startHiding(); } @Override @@ -288,7 +276,6 @@ if (mDesktopWindowStateManager != null) { mDesktopWindowStateManager.removeObserver(this); } - mXrSessionManager = null; } @Override @@ -319,10 +306,9 @@ @Override public void show(long time, boolean animate) { + final boolean isXrFullSpaceMode = mXrFullSpaceModeSupplier.get(); if (isStartingToShow()) return; - if (mXrSessionManager != null - && animate - && !ChromeFeatureList.sShowTabListAnimations.isEnabled()) { + if (isXrFullSpaceMode && animate && !ChromeFeatureList.sShowTabListAnimations.isEnabled()) { animate = false; } @@ -337,8 +323,7 @@ if (previousLayoutType == LayoutType.BROWSING) { final Tab currentTab = mTabModelSelector.getCurrentTab(); createLayoutTabForTabId(getIdForTab(currentTab)); - mCurrentSceneLayer = - isActivityInXrFullSpaceModeNow() ? mEmptySceneLayer : mTabSceneLayer; + mCurrentSceneLayer = isXrFullSpaceMode ? mEmptySceneLayer : mTabSceneLayer; captureTabThumbnail(currentTab, bitmapPromise); } else { mCurrentSceneLayer = mEmptySceneLayer; @@ -352,6 +337,10 @@ HubContainerView containerView = mHubController.getContainerView(); HubLayoutAnimatorProvider animatorProvider = createShowAnimatorProvider(containerView); + // Delay animation on XR to allow FSM transitions to complete. + if (isXrFullSpaceMode) { + delayAnimation(animatorProvider, HUB_LAYOUT_XR_FADE_IN_DELAY_MS); + } Callback<@Nullable Bitmap> thumbnailCallback = animatorProvider.getThumbnailCallback(); if (thumbnailCallback != null) { @@ -364,15 +353,6 @@ mCurrentAnimationRunner.addListener( new HubLayoutAnimationListenerImpl(mIsAnimatingSupplier) { @Override - public void onStart() { - super.onStart(); - // Show HubLayout (in XR full space mode) when animation starts. - if (isActivityInXrFullSpaceModeNow()) { - mXrSessionManager.finishSpaceModeChange(); - } - } - - @Override public void onEnd(boolean wasForcedToFinish) { super.onEnd(wasForcedToFinish); doneShowing(); @@ -436,6 +416,7 @@ // Since we are hiding this is no-longer fully shown. mFullyShown = false; + final boolean isXrFullSpaceMode = mXrFullSpaceModeSupplier.get(); // Use the EXPAND_NEW_TAB animation if it is already prepared. if (getCurrentAnimationType() == HubLayoutAnimationType.EXPAND_NEW_TAB) { @@ -453,14 +434,13 @@ int tabId = mTabModelSelector.getCurrentTabId(); @LayoutType int nextLayoutType = mLayoutStateProvider.getNextLayoutType(); - if (nextLayoutType == LayoutType.BROWSING) { + if (nextLayoutType == LayoutType.BROWSING && !isXrFullSpaceMode) { // During fade and translate animations the composited scene layer is visible. At // the end of the animation a composited tab will be fully visible. To ensure // continuity during the animation create and show the mTabSceneLayer with the // LayoutTab for the tabId that will be shown once the animation finishes. createLayoutTabForTabId(tabId); - mCurrentSceneLayer = - isActivityInXrFullSpaceModeNow() ? mEmptySceneLayer : mTabSceneLayer; + mCurrentSceneLayer = mTabSceneLayer; } else { mCurrentSceneLayer = mEmptySceneLayer; } @@ -468,6 +448,10 @@ HubContainerView containerView = mHubController.getContainerView(); HubLayoutAnimatorProvider animatorProvider = createHideAnimatorProvider(containerView); + // Delay animation on XR to allow tab selection animation to finish. + if (isXrFullSpaceMode) { + delayAnimation(animatorProvider, HUB_LAYOUT_XR_FADE_OUT_DELAY_MS); + } Callback<@Nullable Bitmap> thumbnailCallback = animatorProvider.getThumbnailCallback(); if (thumbnailCallback != null) { @@ -488,15 +472,6 @@ public void onEnd(boolean wasForcedToFinish) { super.onEnd(wasForcedToFinish); doneHiding(); - - if (isActivityInXrFullSpaceModeNow()) { - mXrSessionManager.startSpaceModeChange( - false, - () -> { - assumeNonNull(mXrSessionManager); - mXrSessionManager.finishSpaceModeChange(); - }); - } } }); maybeAddPaneAnimationListener(mCurrentAnimationRunner); @@ -714,7 +689,7 @@ // Fixes being able to click the toolbar through the Hub on LFF devices see b/337616153. // This is not always `true` because it results in a visible flicker when exiting the Hub // into an NTP when using the expand animation. - return mFullyShown || isActivityInXrFullSpaceModeNow(); + return mFullyShown || mXrFullSpaceModeSupplier.get(); } @Override @@ -739,10 +714,9 @@ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) HubLayoutAnimatorProvider createShowAnimatorProvider(HubContainerView containerView) { @Nullable Pane pane = mPaneManager.getFocusedPaneSupplier().get(); - final boolean isFullSpaceModeOnAndroidXR = isActivityInXrFullSpaceModeNow(); + final boolean isXrFullSpaceMode = mXrFullSpaceModeSupplier.get(); - if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(getContext()) - && !isFullSpaceModeOnAndroidXR) { + if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(getContext()) && !isXrFullSpaceMode) { return TranslateHubLayoutAnimationFactory.createTranslateUpAnimatorProvider( mHubController.getHubColorMixer(), containerView, @@ -759,17 +733,16 @@ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) HubLayoutAnimatorProvider createHideAnimatorProvider(HubContainerView containerView) { @Nullable Pane pane = mPaneManager.getFocusedPaneSupplier().get(); - final boolean isFullSpaceModeOnAndroidXR = isActivityInXrFullSpaceModeNow(); + final boolean isXrFullSpaceMode = mXrFullSpaceModeSupplier.get(); - if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(getContext()) - && !isFullSpaceModeOnAndroidXR) { + if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(getContext()) && !isXrFullSpaceMode) { return TranslateHubLayoutAnimationFactory.createTranslateDownAnimatorProvider( mHubController.getHubColorMixer(), containerView, mScrimController, HUB_LAYOUT_TRANSLATE_DURATION_MS, getContainerYOffset()); - } else if (pane == null || isFullSpaceModeOnAndroidXR) { + } else if (pane == null || isXrFullSpaceMode) { return FadeHubLayoutAnimationFactory.createFadeOutAnimatorProvider( containerView, HUB_LAYOUT_FADE_DURATION_MS, mOnToolbarAlphaChange); } @@ -831,6 +804,12 @@ mCurrentAnimationRunner.runWithWaitForAnimatorTimeout(HUB_LAYOUT_TIMEOUT_MS); } + private void delayAnimation(HubLayoutAnimatorProvider animatorProvider, long delay) { + animatorProvider + .getAnimatorSupplier() + .onAvailable((animator) -> animator.getAnimatorSet().setStartDelay(delay)); + } + @EnsuresNonNull("mTabSceneLayer") private void ensureSceneLayersExist() { if (mTabSceneLayer == null) { @@ -961,12 +940,6 @@ } } - @EnsuresNonNullIf("mXrSessionManager") - private boolean isActivityInXrFullSpaceModeNow() { - return mXrSessionManager != null - && mXrSessionManager.getXrSpaceModeObservableSupplier().get(); - } - public HubController getHubControllerForTesting() { return mHubController; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/hub/HubLayoutUnitTest.java b/chrome/android/java/src/org/chromium/chrome/browser/hub/HubLayoutUnitTest.java index 2de701f..11380000 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/hub/HubLayoutUnitTest.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/hub/HubLayoutUnitTest.java
@@ -330,7 +330,7 @@ rootViewSupplier, mScrimController, mOnAlphaChange, - /* xrSceneCoreSessionManager= */ null); + /* xrFullSpaceModeSupplier= */ null); mTabModelSelectorSupplier = () -> mTabModelSelector; mHubLayout = @@ -747,7 +747,7 @@ rootViewSupplier, mScrimController, mOnAlphaChange, - /* xrSceneCoreSessionManager= */ null); + /* xrFullSpaceModeSupplier= */ null); mHubLayout = new HubLayout( mActivity,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java b/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java index 8e1c6dc..2d29da8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java
@@ -62,6 +62,7 @@ import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabObserver; +import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab_group_sync.TabGroupSyncFeatures; import org.chromium.chrome.browser.tab_group_sync.TabGroupSyncServiceFactory; import org.chromium.chrome.browser.tabmodel.TabClosingSource; @@ -723,7 +724,7 @@ mTabModelObserver = new TabModelSelectorTabModelObserver(selector) { @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { // We will check if |mActiveTab| is the same as the selected |tab| to avoid // a superfluous update to an instance's stored active tab info that // remains unchanged.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java index 08d3260..88ec554 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/AutoFetchNotifier.java
@@ -65,7 +65,7 @@ /** Interface for testing. */ @VisibleForTesting - public static interface TestHooks { + public interface TestHooks { public void inProgressNotificationShown(Intent cancelButtonIntent, Intent deleteIntent); public void completeNotificationShown(Intent clickIntent, Intent deleteIntent);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java index 7d03060..4eebcc5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java
@@ -668,9 +668,10 @@ * top of WebContents' counterpart methods. This interface is designed to ensure these extra * steps have been taken into account. */ - public static interface OfflinePageLoadUrlDelegate { + public interface OfflinePageLoadUrlDelegate { /** * Load the url of the given {@link LoadUrlParam} in WebContents. + * * @param params The LoadUrlParams that has specified which url to load. */ /* package */ void loadUrl(LoadUrlParams params);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/DialogControllerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/DialogControllerImpl.java index 0d8bd2f..7b51c80 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/DialogControllerImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/DialogControllerImpl.java
@@ -26,7 +26,7 @@ private final AlertDialogFactory mAlertDialogFactory; /** A interface for creating alert dialogs. */ - /* package */ static interface AlertDialogFactory { + /* package */ interface AlertDialogFactory { /** * Returns a new dialog builder. Mocked in tests. *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java index 77a61893..fd418c4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java
@@ -29,7 +29,7 @@ @NullMarked public class ServiceWorkerPaymentAppBridge { /** The interface for checking whether there is an installed SW payment app. */ - public static interface HasServiceWorkerPaymentAppsCallback { + public interface HasServiceWorkerPaymentAppsCallback { /** * Called to return checking result. * @@ -39,7 +39,7 @@ } /** The interface for getting all installed SW payment apps' information. */ - public static interface GetServiceWorkerPaymentAppsInfoCallback { + public interface GetServiceWorkerPaymentAppsInfoCallback { /** * Called to return installed SW payment apps' information. *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java index 04800a0..d274a69 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java
@@ -64,6 +64,7 @@ import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.components.browser_ui.accessibility.PageZoomCoordinator; import org.chromium.components.dom_distiller.core.DomDistillerFeatures; +import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.embedder_support.util.UrlUtilities; import org.chromium.components.user_prefs.UserPrefs; @@ -313,8 +314,8 @@ observeAndMaybeAddReadAloud(modelList, currentTab); // Reader mode - if (DomDistillerFeatures.showAlwaysOnEntryPoint()) { - modelList.add(buildReaderModeItem()); + if (shouldShowReaderModeItem(currentTab)) { + modelList.add(buildReaderModeItem(currentTab)); } // Open with ... @@ -673,13 +674,19 @@ shouldShowIconBeforeItem() ? R.drawable.sharing_print : 0)); } - private MVCListAdapter.ListItem buildReaderModeItem() { - assert DomDistillerFeatures.showAlwaysOnEntryPoint(); + private boolean shouldShowReaderModeItem(@Nullable Tab currentTab) { + return currentTab != null && DomDistillerFeatures.showAlwaysOnEntryPoint(); + } + + private MVCListAdapter.ListItem buildReaderModeItem(Tab currentTab) { + assert shouldShowReaderModeItem(currentTab); return new MVCListAdapter.ListItem( AppMenuHandler.AppMenuItemType.STANDARD, buildModelForStandardMenuItem( R.id.reader_mode_menu_id, - R.string.show_reading_mode_text, + DomDistillerUrlUtils.isDistilledPage(currentTab.getUrl()) + ? R.string.hide_reading_mode_text + : R.string.show_reading_mode_text, shouldShowIconBeforeItem() ? R.drawable.ic_reader_mode_24dp : 0)); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabCollectionTabModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabCollectionTabModelImpl.java index 5a3b3199..d74b7e0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabCollectionTabModelImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabCollectionTabModelImpl.java
@@ -44,6 +44,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; /** @@ -364,9 +365,7 @@ if (tab == null) return; int currentIndex = indexOf(tab); - if (currentIndex == TabList.INVALID_TAB_INDEX || currentIndex == newIndex) { - return; - } + if (currentIndex == TabList.INVALID_TAB_INDEX || currentIndex == newIndex) return; // Clamp negative values here to ensure the tab moves to index 0 if negative. The size_t // cast in C++ otherwise results in the tab going to the end of the list which is not @@ -739,7 +738,19 @@ public int representativeIndexOf(@Nullable Tab tab) { // TODO(crbug.com/428692223): Revisit the performance of this method by doing it in C++. if (tab == null) return TabList.INVALID_TAB_INDEX; - return getRepresentativeTabList().indexOf(tab); + Token tabGroupId = tab.getTabGroupId(); + boolean isTabGroup = tabGroupId != null; + + List<Tab> representativeTabList = getRepresentativeTabList(); + for (int i = 0; i < representativeTabList.size(); i++) { + Tab representativeTab = representativeTabList.get(i); + if (representativeTab == tab + || (isTabGroup + && Objects.equals(tabGroupId, representativeTab.getTabGroupId()))) { + return i; + } + } + return TabList.INVALID_TAB_INDEX; } @Override @@ -810,9 +821,28 @@ if (tab == null) return; Token tabGroupId = tab.getTabGroupId(); - if (tabGroupId == null) return; + if (tabGroupId != null) { + moveGroupToIndex(tabGroupId, newIndex); + return; + } - moveGroupToIndex(tabGroupId, newIndex); + // TODO(crbug.com/433947821): TabListMediator uses this API for individual tab reordering + // and expects to get a notification that a group has moved. However, this is not a group. + // We should consider refactoring TabListMediator to use a different API for individual tab + // reordering (or also listen to didMoveTab()). + int curIndex = indexOf(tab); + int finalIndex = + moveTabInternal( + tab, + curIndex, + newIndex, + /* newTabGroupId= */ null, + /* isPinned= */ tab.getIsPinned()); + if (finalIndex != curIndex) { + for (TabGroupModelFilterObserver observer : mTabGroupObservers) { + observer.didMoveTabGroup(tab, finalIndex, curIndex); + } + } } @Override @@ -1477,7 +1507,7 @@ */ private boolean wasLastTabInGroupAndNotifyDidMoveTabOutOfGroup( Tab tab, Token oldTabGroupId, int finalIndex) { - int prevFilterIndex = getFirstTabIndexInGroup(oldTabGroupId); + int prevFilterIndex = representativeIndexOf(getLastShownTabForGroup(oldTabGroupId)); boolean isLastTabInGroup = prevFilterIndex == TabList.INVALID_TAB_INDEX; if (isLastTabInGroup) { prevFilterIndex = finalIndex; @@ -1488,13 +1518,6 @@ return isLastTabInGroup; } - private int getFirstTabIndexInGroup(Token tabGroupId) { - // TODO(crbug.com/428692223): Optimize this by requesting it from the collection. - List<Tab> tabsInGroup = getTabsInGroup(tabGroupId); - if (tabsInGroup.isEmpty()) return TabList.INVALID_TAB_INDEX; - return indexOf(tabsInGroup.get(0)); - } - private @Nullable Tab getLastShownTabForGroup(Token tabGroupId) { return TabCollectionTabModelImplJni.get() .getLastShownTabForGroup(mNativeTabCollectionTabModelImplPtr, tabGroupId);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java index 317fb01..3e6a4003 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
@@ -45,6 +45,7 @@ import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabIdManager; import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab.TabState; import org.chromium.chrome.browser.tab.TabStateAttributes; import org.chromium.chrome.browser.tab.TabStateExtractor; @@ -225,7 +226,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { saveTabListAsynchronously(); } @@ -253,7 +254,7 @@ } /** Callback interface to use while reading the persisted TabModelSelector info from disk. */ - public static interface OnTabStateReadCallback { + public interface OnTabStateReadCallback { /** * To be called as the details about a persisted Tab are read from the TabModelSelector's * persisted data.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkSyncService.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkSyncService.java index 0fc3014..8229fdf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkSyncService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkSyncService.java
@@ -30,7 +30,7 @@ private static final long UNIX_OFFSET_MICROS = 11644473600000000L; /** Called with update result. */ - public static interface PwaRestorableListCallback { + public interface PwaRestorableListCallback { @CalledByNative("PwaRestorableListCallback") public void onRestorableAppsAvailable( boolean success,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java index ad0dd82..70aa6738 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java
@@ -122,7 +122,7 @@ private Handler mUpdateFailureHandler; /** Called with update result. */ - public static interface WebApkUpdateCallback { + public interface WebApkUpdateCallback { @CalledByNative("WebApkUpdateCallback") public void onResultFromNative(@WebApkInstallResult int result, boolean relaxUpdates); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/xr/scenecore/XrSceneCoreSessionManagerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/xr/scenecore/XrSceneCoreSessionManagerImpl.java index 35a0d747..a902049 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/xr/scenecore/XrSceneCoreSessionManagerImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/xr/scenecore/XrSceneCoreSessionManagerImpl.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.browser.xr.scenecore; -import static org.chromium.build.NullUtil.assumeNonNull; - import android.annotation.SuppressLint; import android.app.Activity; import android.os.Build; @@ -17,7 +15,6 @@ import androidx.xr.runtime.internal.Dimensions; import androidx.xr.scenecore.impl.JxrPlatformAdapterAxr; -import org.chromium.base.CallbackController; import org.chromium.base.ThreadUtils; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; @@ -35,29 +32,26 @@ @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) @NullMarked public class XrSceneCoreSessionManagerImpl implements XrSceneCoreSessionManager { - // TODO(crbug.com/422151641): Figure out how to get rid of timing delay and use event - // or callback instead, when switching XR space modes. - // The delay is based on observations to let UI redraw before XR space mode switching. - private static final int XR_MODE_UI_UPDATE_DELAY_MS = 250; private JxrPlatformAdapterAxr mJxrPlatformAdapter; private Activity mActivity; - private CallbackController mCallbackController = new CallbackController(); // If not null, a request to change XR space mode is in progress. - private @Nullable Boolean mIsFsmRequested; + private @Nullable Boolean mIsFullSpaceModeRequested; private @Nullable Runnable mXrModeSwitchCallback; - private final ObservableSupplierImpl<Boolean> mIsFullSpaceModeNowSupplier = - new ObservableSupplierImpl<>(false); // Home space mode on startup. + private final ObservableSupplierImpl<Boolean> mIsFullSpaceModeNowSupplier; private final ActivitySpace.OnBoundsChangedListener mBoundsChangedListener = this::boundsChangeCallback; public XrSceneCoreSessionManagerImpl(Activity activity) { - // TODO(crbug.com/422134376): To detect "Android XR" query OS instead of device's - // properties. assert XrUtils.isXrDevice(); mActivity = activity; mJxrPlatformAdapter = createJxrPlatformAdapter(mActivity); mJxrPlatformAdapter.getActivitySpace().addOnBoundsChangedListener(mBoundsChangedListener); + + // Initialize the supplier with the current mode. + boolean isXrFullSpaceMode = + mJxrPlatformAdapter.getActivitySpace().getBounds().width == Float.POSITIVE_INFINITY; + mIsFullSpaceModeNowSupplier = new ObservableSupplierImpl<>(isXrFullSpaceMode); } private JxrPlatformAdapterAxr createJxrPlatformAdapter(Activity activity) { @@ -69,48 +63,43 @@ @MainThread @Override - public boolean startSpaceModeChange(boolean fsmModeRequested, Runnable completedCallback) { - return trySpaceModeChange(fsmModeRequested, completedCallback); + public boolean requestSpaceModeChange( + boolean requestFullSpaceMode, Runnable completedCallback) { + return requestSpaceModeChangeInternal(requestFullSpaceMode, completedCallback); } @MainThread @Override - public boolean requestSpaceModeChange(boolean fsmModeRequested) { - return trySpaceModeChange(fsmModeRequested, /* completedCallback= */ null); + public boolean requestSpaceModeChange(boolean requestFullSpaceMode) { + return requestSpaceModeChangeInternal(requestFullSpaceMode, /* completedCallback= */ null); } @MainThread - private boolean trySpaceModeChange( - boolean fsmModeRequested, @Nullable Runnable completedCallback) { + private boolean requestSpaceModeChangeInternal( + boolean requestFullSpaceMode, @Nullable Runnable completedCallback) { ThreadUtils.assertOnUiThread(); if (!ThreadUtils.runningOnUiThread()) return false; // Decline if the request to change XR space mode is being processed. - if (mIsFsmRequested != null) { + if (mIsFullSpaceModeRequested != null) { return false; } // Do nothing if the activity doesn't have focus or the requested XR // space mode is already set. - if (!mActivity.hasWindowFocus() - || assumeNonNull(mIsFullSpaceModeNowSupplier.get()).equals(fsmModeRequested)) { + if (!mActivity.hasWindowFocus() || requestFullSpaceMode == isXrFullSpaceMode()) { return false; } - // Hide the main panel only if callback is requested. - // The main panel will be set visible by {@link - // XrSceneCoreSessionManagerImpl#finishSpaceModeChange}. - if (completedCallback != null) { - mIsFsmRequested = fsmModeRequested; - mXrModeSwitchCallback = completedCallback; - mJxrPlatformAdapter.getMainPanelEntity().setHidden(true); - } + mIsFullSpaceModeRequested = requestFullSpaceMode; + mXrModeSwitchCallback = completedCallback; - if (fsmModeRequested) { + if (requestFullSpaceMode) { mJxrPlatformAdapter.requestFullSpaceMode(); } else { mJxrPlatformAdapter.requestHomeSpaceMode(); } + return true; } @@ -119,26 +108,20 @@ return mIsFullSpaceModeNowSupplier; } + @Override + public boolean isXrFullSpaceMode() { + return Boolean.TRUE.equals(mIsFullSpaceModeNowSupplier.get()); + } + @MainThread @Override - public void finishSpaceModeChange() { - ThreadUtils.assertOnUiThread(); - if (!ThreadUtils.runningOnUiThread()) return; - - if (mIsFsmRequested != null) { - mJxrPlatformAdapter.getMainPanelEntity().setHidden(false); - mIsFsmRequested = null; - } + public void setMainPanelVisibility(boolean visible) { + mJxrPlatformAdapter.getMainPanelEntity().setHidden(!visible); } @SuppressWarnings("NullAway") @Override public void destroy() { - if (mCallbackController != null) { - mCallbackController.destroy(); - mCallbackController = null; - } - if (mJxrPlatformAdapter != null) { mJxrPlatformAdapter .getActivitySpace() @@ -151,27 +134,14 @@ private void boundsChangeCallback(Dimensions dimensions) { mIsFullSpaceModeNowSupplier.set(dimensions.width == Float.POSITIVE_INFINITY); - if (mIsFsmRequested == null) { - // This is an initial callback on `addOnBoundsChangedListener` or - // callback on `requestSpaceModeChange`. - return; - } - if (!assumeNonNull(mIsFullSpaceModeNowSupplier.get()).equals(mIsFsmRequested)) { - // Leave if this is not XR space mode we expect. - return; + if (mIsFullSpaceModeRequested != null && mIsFullSpaceModeRequested == isXrFullSpaceMode()) { + // Mark the current request as completed. + mIsFullSpaceModeRequested = null; + if (mXrModeSwitchCallback != null) { + mXrModeSwitchCallback.run(); + mXrModeSwitchCallback = null; + } } - - ThreadUtils.postOnUiThreadDelayed( - mCallbackController.makeCancelable( - () -> { - if (mXrModeSwitchCallback != null) { - mXrModeSwitchCallback.run(); - mXrModeSwitchCallback = null; - } - }), - Boolean.TRUE.equals(mIsFullSpaceModeNowSupplier.get()) - ? XR_MODE_UI_UPDATE_DELAY_MS - : 0); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillCardBenefitsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillCardBenefitsFragmentTest.java index de81bfbb..0629c08 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillCardBenefitsFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillCardBenefitsFragmentTest.java
@@ -306,8 +306,8 @@ assertEquals(3, getPreferenceScreen(activity).getPreferenceCount()); } - // Test to verify terms for different card issuers with benefits are listed if the card issuer's - // respective benefit feature flag is enabled. + // Test to verify terms for different card with benefits are listed if the card's respective + // benefit feature flag is enabled. @Test @MediumTest public void testCardBenefitsPreferenceScreen_withBenefitFlagsOn() throws Exception { @@ -319,8 +319,8 @@ assertEquals(2, getPreferenceCountWithKey(activity, PREF_KEY_CARD_BENEFIT_TERM)); } - // Test to verify terms for different card issuers with benefits are listed only if the card - // issuer's respective benefit feature flag is enabled. + // Test to verify terms for different cards with benefits are listed only if the card's + // respective benefit feature flag is enabled. @Test @MediumTest @DisableFeatures({ChromeFeatureList.AUTOFILL_ENABLE_CARD_BENEFITS_FOR_BMO}) @@ -337,8 +337,8 @@ SAMPLE_CARD_AMERICAN_EXPRESS_WITH_BENEFIT.getProductDescription())); } - // Test to verify terms for different card issuers with benefits are not listed if the card - // issuer's respective benefit feature flag is disabled. + // Test to verify terms for different card with benefits are not listed if the card's respective + // benefit feature flag is disabled. @Test @MediumTest @DisableFeatures({ @@ -355,7 +355,7 @@ } // Test to verify terms for card with the same product (same product description and same - // issuer) is only displayed once. + // benefit source) is only displayed once. @Test @MediumTest public void testCardBenefitsPreferenceScreen_withDuplicateCardProduct_termsOnlyDisplayedOnce() @@ -395,10 +395,10 @@ assertEquals(1, getPreferenceCountWithKey(activity, PREF_KEY_CARD_BENEFIT_TERM)); } - // Test to verify terms for different card products from the same issuer are listed. + // Test to verify terms for different card products from the same benefit source are listed. @Test @MediumTest - public void testCardBenefitsPreferenceScreen_FromSameIssuer() throws Exception { + public void testCardBenefitsPreferenceScreen_FromSameBenefitSource() throws Exception { mAutofillTestHelper.addServerCreditCard(SAMPLE_CARD_AMERICAN_EXPRESS_WITH_BENEFIT); mAutofillTestHelper.addServerCreditCard( new CreditCard( @@ -433,8 +433,8 @@ assertEquals(2, getPreferenceCountWithKey(activity, PREF_KEY_CARD_BENEFIT_TERM)); } - // Test to verify terms for cards with the same product description from the different issuers - // are listed. + // Test to verify terms for cards with the same product description from the different benefit + // sources are listed. @Test @MediumTest public void testCardBenefitsPreferenceScreen_withDuplicateCardProductDescription()
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/WebsitePermissionsFetcherTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/WebsitePermissionsFetcherTest.java index b3ea450..413c8a1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/WebsitePermissionsFetcherTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/WebsitePermissionsFetcherTest.java
@@ -722,7 +722,7 @@ // Otherwise, just update count in the assert. // TODO(https://b/332704817): Add test for Tracking Protection content setting after Android // integration. - assertEquals(123, ContentSettingsType.MAX_VALUE); + assertEquals(121, ContentSettingsType.MAX_VALUE); websitePreferenceBridge.addContentSettingException( new ContentSettingException( ContentSettingsType.COOKIES,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabCollectionTabModelImplTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabCollectionTabModelImplTest.java index b1df2c8..5c77d7f9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabCollectionTabModelImplTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabCollectionTabModelImplTest.java
@@ -204,7 +204,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { fail("didSelectTab should not be called. " + tab.getId()); } }; @@ -248,7 +248,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { // Should not be called as the selected tab is not removed. fail("didSelectTab should not be called."); } @@ -293,7 +293,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { assertEquals("Incorrect tab selected.", tab1, tab); assertEquals( "Incorrect selection type.", TabSelectionType.FROM_CLOSE, type); @@ -366,7 +366,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { tabInDidSelect.set(tab); assertEquals(TabSelectionType.FROM_CLOSE, type); assertEquals(tab1.getId(), lastId); @@ -455,7 +455,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { tabInDidSelect.set(tab); assertEquals(TabSelectionType.FROM_CLOSE, type); assertEquals(tab2.getId(), lastId); @@ -547,7 +547,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { fail("didSelectTab should not be called when closing all tabs."); } }; @@ -677,12 +677,6 @@ Tab tab0 = getTabAt(0); Tab tab1 = createTab(); - // TODO(crbug.com/429145597): Remove this once the implementation is further along. - // Create a tab that is not in a group to act as the current tab. This is required to - // prevent TabListMediator from being created and failing a bunch of lookups for - // representative tabs that are not yet implemented. - createTab(); - ThreadUtils.runOnUiThreadBlocking( () -> { assertNotNull(tab0); @@ -934,6 +928,59 @@ } @Test + @SmallTest + public void testMoveRelatedTabs_IndividualTab() throws Exception { + Tab tab0 = getTabAt(0); + Tab tab1 = createTab(); + Tab tab2 = createTab(); + assertTabsInOrderAre(List.of(tab0, tab1, tab2)); + + CallbackHelper didMoveTabGroupHelper = new CallbackHelper(); + CallbackHelper didMoveTabHelper = new CallbackHelper(); + + TabGroupModelFilterObserver groupObserver = + new TabGroupModelFilterObserver() { + @Override + public void willMoveTabGroup(Token tabGroupId, int currentIndex) { + fail("willMoveTabGroup should not be called for individual tab."); + } + + @Override + public void didMoveTabGroup(Tab movedTab, int newIndex, int oldIndex) { + assertEquals(tab1, movedTab); + assertEquals(2, newIndex); + assertEquals(1, oldIndex); + didMoveTabGroupHelper.notifyCalled(); + } + }; + TabModelObserver modelObserver = + new TabModelObserver() { + @Override + public void didMoveTab(Tab tab, int newIndex, int oldIndex) { + assertEquals(tab1, tab); + assertEquals(2, newIndex); + assertEquals(1, oldIndex); + didMoveTabHelper.notifyCalled(); + } + }; + + ThreadUtils.runOnUiThreadBlocking( + () -> { + mCollectionModel.addTabGroupObserver(groupObserver); + mCollectionModel.addObserver(modelObserver); + // Move tab1 to the end. + mCollectionModel.moveRelatedTabs(tab1.getId(), 3); + mCollectionModel.removeTabGroupObserver(groupObserver); + mCollectionModel.removeObserver(modelObserver); + }); + + didMoveTabGroupHelper.waitForOnly(); + didMoveTabHelper.waitForOnly(); + + assertTabsInOrderAre(List.of(tab0, tab2, tab1)); + } + + @Test @MediumTest public void testMoveTab_InGroup() { Tab tab0 = getTabAt(0); @@ -1048,16 +1095,10 @@ Tab tab0 = getTabAt(0); Tab tab1 = createTab(); - // TODO(crbug.com/429145597): Remove this once the implementation is further along. - // Create a tab that is not in a group to act as the current tab. This is required to - // prevent TabListMediator from being created and failing a bunch of lookups for - // representative tabs that are not yet implemented. - Tab tab2 = createTab(); - ThreadUtils.runOnUiThreadBlocking(() -> mCollectionModel.createSingleTabGroup(tab1)); Token groupId = tab1.getTabGroupId(); assertNotNull(groupId); - assertTabsInOrderAre(List.of(tab0, tab1, tab2)); + assertTabsInOrderAre(List.of(tab0, tab1)); CallbackHelper willMoveOutOfGroup = new CallbackHelper(); CallbackHelper didMoveOutOfGroup = new CallbackHelper(); @@ -1100,7 +1141,7 @@ assertTrue(tab1.getIsPinned()); assertNull(tab1.getTabGroupId()); - assertTabsInOrderAre(List.of(tab1, tab0, tab2)); + assertTabsInOrderAre(List.of(tab1, tab0)); } @Test @@ -1342,12 +1383,18 @@ @Test @SmallTest public void testRepresentativeTabLogic() { - // Setup: tab0, tab1 (in group), tab2 + // Setup: tab0, {tab1, tab3} (in group), tab2 Tab tab0 = getTabAt(0); Tab tab1 = createTab(); Tab tab2 = createTab(); - assertTabsInOrderAre(List.of(tab0, tab1, tab2)); - ThreadUtils.runOnUiThreadBlocking(() -> mCollectionModel.createSingleTabGroup(tab1)); + Tab tab3 = createTab(); + assertTabsInOrderAre(List.of(tab0, tab1, tab2, tab3)); + ThreadUtils.runOnUiThreadBlocking( + () -> { + mCollectionModel.mergeListOfTabsToGroup( + List.of(tab1, tab3), tab1, /* notify= */ false); + }); + assertTabsInOrderAre(List.of(tab0, tab1, tab3, tab2)); Token tab1GroupId = tab1.getTabGroupId(); assertNotNull(tab1GroupId); @@ -1358,7 +1405,6 @@ assertEquals(tab0, representativeTabs.get(0)); assertEquals(tab1, representativeTabs.get(1)); assertEquals(tab2, representativeTabs.get(2)); - ThreadUtils.runOnUiThreadBlocking( () -> { assertEquals(3, mCollectionModel.getIndividualTabAndGroupCount()); @@ -1368,23 +1414,25 @@ assertEquals(tab2, mCollectionModel.getRepresentativeTabAt(2)); assertNull(mCollectionModel.getRepresentativeTabAt(3)); assertNull(mCollectionModel.getRepresentativeTabAt(-1)); - assertEquals(0, mCollectionModel.representativeIndexOf(tab0)); assertEquals(1, mCollectionModel.representativeIndexOf(tab1)); + assertEquals(1, mCollectionModel.representativeIndexOf(tab3)); assertEquals(2, mCollectionModel.representativeIndexOf(tab2)); assertEquals( TabList.INVALID_TAB_INDEX, mCollectionModel.representativeIndexOf(null)); - mCollectionModel.setIndex(0, TabSelectionType.FROM_USER); // Select tab0 assertEquals(tab0, mCollectionModel.getCurrentRepresentativeTab()); assertEquals(0, mCollectionModel.getCurrentRepresentativeTabIndex()); - mCollectionModel.setIndex(1, TabSelectionType.FROM_USER); // Select tab1 assertEquals(tab1, mCollectionModel.getCurrentRepresentativeTab()); assertEquals(1, mCollectionModel.getCurrentRepresentativeTabIndex()); - mCollectionModel.setIndex(2, TabSelectionType.FROM_USER); // Select tab2 + mCollectionModel.setIndex(2, TabSelectionType.FROM_USER); // Select tab3 + assertEquals(tab3, mCollectionModel.getCurrentRepresentativeTab()); + assertEquals(1, mCollectionModel.getCurrentRepresentativeTabIndex()); + + mCollectionModel.setIndex(3, TabSelectionType.FROM_USER); // Select tab2 assertEquals(tab2, mCollectionModel.getCurrentRepresentativeTab()); assertEquals(2, mCollectionModel.getCurrentRepresentativeTabIndex()); }); @@ -1526,6 +1574,7 @@ // prevent TabListMediator from being created and failing a bunch of lookups for // representative tabs that are not yet implemented. Tab tab4 = createTab(); + assertTabsInOrderAre(List.of(tab0, tab1, tab2, tab3, tab4)); CallbackHelper didRemoveTabGroupHelper = new CallbackHelper();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ChromeActivityUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ChromeActivityUnitTest.java index f52838f..d89a71f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ChromeActivityUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ChromeActivityUnitTest.java
@@ -7,6 +7,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; @@ -35,15 +36,18 @@ import org.robolectric.Robolectric; import org.robolectric.annotation.Config; +import org.chromium.base.UserDataHost; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.OneshotSupplier; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.Features.DisableFeatures; import org.chromium.base.test.util.Features.EnableFeatures; +import org.chromium.base.test.util.UserActionTester; import org.chromium.chrome.R; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.app.metrics.LaunchCauseMetrics; import org.chromium.chrome.browser.app.tabmodel.TabModelOrchestrator; +import org.chromium.chrome.browser.dom_distiller.ReaderModeManager; import org.chromium.chrome.browser.enterprise.util.EnterpriseInfo; import org.chromium.chrome.browser.flags.ActivityType; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -59,6 +63,7 @@ import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate; import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; +import org.chromium.components.dom_distiller.core.DomDistillerUrlUtilsJni; import org.chromium.components.ukm.UkmRecorder; import org.chromium.components.ukm.UkmRecorderJni; import org.chromium.content_public.browser.RenderFrameHost; @@ -78,10 +83,12 @@ @Mock Tab mActivityTab; @Mock ActivityTabProvider mActivityTabProvider; @Mock ReadAloudController mReadAloudController; + @Mock ReaderModeManager mReaderModeManager; @Mock FullscreenVideoPictureInPictureController mFullscreenVideoPictureInPictureController; @Mock PictureInPictureUiState mPictureInPictureUiState; @Mock EnterpriseInfo mEnterpriseInfo; @Mock UkmRecorder.Natives mUkmRecorderJniMock; + @Mock DomDistillerUrlUtilsJni mDomDistillerUrlUtilsJni; ObservableSupplierImpl<ReadAloudController> mReadAloudControllerSupplier = new ObservableSupplierImpl<>(); @@ -142,6 +149,7 @@ @Before public void setup() { mActivity = Robolectric.buildActivity(TestActivity.class).setup().get(); + DomDistillerUrlUtilsJni.setInstanceForTesting(mDomDistillerUrlUtilsJni); } @Test @@ -235,4 +243,48 @@ assertTrue(isWorkProfile); assertEquals("content", Uri.parse(contentUri).getScheme()); } + + @Test + public void testReaderModeMenuItemClicked_ShowReadingMode() { + TestChromeActivity chromeActivity = Mockito.spy(new TestChromeActivity()); + UserActionTester userActionTester = new UserActionTester(); + + UserDataHost userDataHost = new UserDataHost(); + userDataHost.setUserData(ReaderModeManager.class, mReaderModeManager); + + doReturn(mActivityTab).when(chromeActivity).getActivityTab(); + doReturn(mTabModel).when(chromeActivity).getCurrentTabModel(); + when(mTabModel.getProfile()).thenReturn(mProfile); + when(mActivityTab.getUserDataHost()).thenReturn(userDataHost); + when(mActivityTab.getUrl()).thenReturn(JUnitTestGURLs.EXAMPLE_URL); + when(mDomDistillerUrlUtilsJni.isDistilledPage(any())).thenReturn(false); + + assertTrue( + chromeActivity.onMenuOrKeyboardAction( + R.id.reader_mode_menu_id, /* fromMenu= */ true)); + verify(mReaderModeManager).activateReaderMode(); + assertEquals(1, userActionTester.getActionCount("MobileMenuShowReaderMode")); + } + + @Test + public void testReaderModeMenuItemClicked_HideReadingMode() { + TestChromeActivity chromeActivity = Mockito.spy(new TestChromeActivity()); + UserActionTester userActionTester = new UserActionTester(); + + UserDataHost userDataHost = new UserDataHost(); + userDataHost.setUserData(ReaderModeManager.class, mReaderModeManager); + + doReturn(mActivityTab).when(chromeActivity).getActivityTab(); + doReturn(mTabModel).when(chromeActivity).getCurrentTabModel(); + when(mTabModel.getProfile()).thenReturn(mProfile); + when(mActivityTab.getUserDataHost()).thenReturn(userDataHost); + when(mActivityTab.getUrl()).thenReturn(JUnitTestGURLs.CHROME_DISTILLER_EXAMPLE_URL); + when(mDomDistillerUrlUtilsJni.isDistilledPage(any())).thenReturn(true); + + assertTrue( + chromeActivity.onMenuOrKeyboardAction( + R.id.reader_mode_menu_id, /* fromMenu= */ true)); + verify(mReaderModeManager).hideReaderMode(); + assertEquals(1, userActionTester.getActionCount("MobileMenuHideReaderMode")); + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerTest.java index 89a1c8874..dbdb7d88 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManagerTest.java
@@ -36,6 +36,7 @@ import org.chromium.base.test.util.Features.DisableFeatures; import org.chromium.base.test.util.Features.EnableFeatures; import org.chromium.base.test.util.HistogramWatcher; +import org.chromium.base.test.util.UserActionTester; import org.chromium.chrome.browser.dom_distiller.ReaderModeManager.DistillationResult; import org.chromium.chrome.browser.dom_distiller.ReaderModeManager.DistillationStatus; import org.chromium.chrome.browser.dom_distiller.TabDistillabilityProvider.DistillabilityObserver; @@ -518,6 +519,16 @@ any(), eq(mWebContents), eq(MessageScopeType.NAVIGATION), eq(false)); } + @Test + @Feature("ReaderMode") + public void testHideReadingMode() { + UserActionTester userActionTester = new UserActionTester(); + + mManager.hideReaderMode(); + verify(mTab).goBack(); + assertEquals(1, userActionTester.getActionCount("MobileReaderModeHidden")); + } + /** * @param index The index of the entry. * @param url The URL the entry represents.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonControllerTest.java index ded630da..04eb6567 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonControllerTest.java
@@ -93,7 +93,7 @@ } @Test - public void testButtonClickEnablesReaderMode() { + public void testButtonClickNonDistilledPage_EnablesReaderMode() { ReaderModeToolbarButtonController controller = createController(); ButtonData readerModeButton = controller.get(mMockTab); @@ -104,6 +104,20 @@ @Test @EnableFeatures(DomDistillerFeatures.READER_MODE_DISTILL_IN_APP) + public void testButtonClickDistilledPage_HidesReaderMode() { + ReaderModeToolbarButtonController controller = createController(); + + when(mMockTab.getUrl()).thenReturn(new GURL("chrome-distiller://test")); + when(mDomDistillerUrlUtilsJni.isDistilledPage(any())).thenReturn(true); + + ButtonData readerModeButton = controller.get(mMockTab); + readerModeButton.getButtonSpec().getOnClickListener().onClick(null); + + verify(mMockReaderModeManager).hideReaderMode(); + } + + @Test + @EnableFeatures(DomDistillerFeatures.READER_MODE_DISTILL_IN_APP) public void buttonSpecChangesWhenInReaderMode() { ReaderModeToolbarButtonController controller = createController(); assertEquals(
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java index 1f4327e..4e915c6 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java
@@ -122,6 +122,7 @@ import org.chromium.components.commerce.core.ShoppingService; import org.chromium.components.content_settings.ContentSettingValues; import org.chromium.components.dom_distiller.core.DomDistillerFeatures; +import org.chromium.components.dom_distiller.core.DomDistillerUrlUtilsJni; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.favicon.LargeIconBridge; import org.chromium.components.favicon.LargeIconBridgeJni; @@ -234,6 +235,7 @@ @Mock private TranslateBridge.Natives mTranslateBridgeJniMock; @Mock private UpdateMenuItemHelper mUpdateMenuItemHelper; @Mock private LargeIconBridge.Natives mLargeIconBridgeJni; + @Mock private DomDistillerUrlUtilsJni mDomDistillerUrlUtilsJni; private ShadowPackageManager mShadowPackageManager; @@ -360,6 +362,8 @@ ShoppingServiceFactory.setShoppingServiceForTesting(mShoppingService); LargeIconBridgeJni.setInstanceForTesting(mLargeIconBridgeJni); + + DomDistillerUrlUtilsJni.setInstanceForTesting(mDomDistillerUrlUtilsJni); } @After @@ -1321,14 +1325,38 @@ @Test @EnableFeatures(DomDistillerFeatures.READER_MODE_IMPROVEMENTS + ":always_on_entry_point/true") - public void readerModeEntryPointEnabled() { + public void readerModeEntryPointEnabled_ShowReadingMode() { setUpMocksForPageMenu(); when(mTab.getUrl()).thenReturn(JUnitTestGURLs.EXAMPLE_URL); doReturn(mTabModel).when(mTabModelSelector).getCurrentModel(); + when(mDomDistillerUrlUtilsJni.isDistilledPage(any())).thenReturn(false); MVCListAdapter.ModelList modelList = mTabbedAppMenuPropertiesDelegate.getMenuItems(); - assertTrue(isMenuVisible(modelList, R.id.reader_mode_menu_id)); + Context context = ContextUtils.getApplicationContext(); + assertTrue( + isMenuVisibleWithCorrectTitle( + modelList, + R.id.reader_mode_menu_id, + context.getString(R.string.show_reading_mode_text))); + } + + @Test + @EnableFeatures(DomDistillerFeatures.READER_MODE_IMPROVEMENTS + ":always_on_entry_point/true") + public void readerModeEntryPointEnabled_HideReadingMode() { + setUpMocksForPageMenu(); + when(mTab.getUrl()).thenReturn(JUnitTestGURLs.CHROME_DISTILLER_EXAMPLE_URL); + doReturn(mTabModel).when(mTabModelSelector).getCurrentModel(); + when(mDomDistillerUrlUtilsJni.isDistilledPage(any())).thenReturn(true); + + MVCListAdapter.ModelList modelList = mTabbedAppMenuPropertiesDelegate.getMenuItems(); + + Context context = ContextUtils.getApplicationContext(); + assertTrue( + isMenuVisibleWithCorrectTitle( + modelList, + R.id.reader_mode_menu_id, + context.getString(R.string.hide_reading_mode_text))); } private MVCListAdapter.ModelList setUpMenuWithIncognitoReauthPage(boolean isShowing) { @@ -2153,6 +2181,13 @@ return findItemById(modelList, itemId) != null; } + private boolean isMenuVisibleWithCorrectTitle( + MVCListAdapter.ModelList modelList, int itemId, String expectedTitle) { + MVCListAdapter.ListItem menuItem = findItemById(modelList, itemId); + if (menuItem == null) return false; + return menuItem.model.get(AppMenuItemProperties.TITLE) == expectedTitle; + } + private String getMenuTitles(MVCListAdapter.ModelList modelList) { StringBuilder items = new StringBuilder(); for (MVCListAdapter.ListItem item : modelList) {
diff --git a/chrome/android/webapk/shell_apk/current_version/current_version.gni b/chrome/android/webapk/shell_apk/current_version/current_version.gni index 83b789a..31bb3b4 100644 --- a/chrome/android/webapk/shell_apk/current_version/current_version.gni +++ b/chrome/android/webapk/shell_apk/current_version/current_version.gni
@@ -12,4 +12,4 @@ # //chrome/android/webapk/shell_apk:webapk is changed. This includes # Java files, Android resource files and AndroidManifest.xml. Does not affect # Chrome.apk -current_shell_apk_version = 185 +current_shell_apk_version = 186
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/LaunchHostBrowserSelector.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/LaunchHostBrowserSelector.java index ee02ea9..1e92f842 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/LaunchHostBrowserSelector.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/LaunchHostBrowserSelector.java
@@ -34,7 +34,7 @@ * Called once {@link #selectHostBrowser()} has selected the host browser either via a shared * preferences/<meta-data> lookup or via the user selecting the host browser from a dialog. */ - public static interface Callback { + public interface Callback { void onBrowserSelected( @Nullable PackageNameAndComponentName hostBrowserPackageNameAndComponentName, boolean dialogShown);
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index b914bbc..7c72081 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -8520,6 +8520,12 @@ <message name="IDS_NTP_COMPOSE_DELETE_FILE_A11Y_LABEL" desc="The accessibility label for the delete button shown on hover for uploaded files." translateable="false"> <ph name="FILE_NAME">$1<ex>recipe.pdf</ex></ph> press enter to delete file </message> + <message name="IDS_NTP_COMPOSE_FILE_UPLOAD_STARTED_A11Y_TEXT" desc="Text for a screenreader to read aloud when the user starts uploading a file." translateable="false"> + Uploading file + </message> + <message name="IDS_NTP_COMPOSE_FILE_UPLOAD_COMPLETE_A11Y_TEXT" desc="Text for a screenreader to read aloud when the user's file upload completes successfully." translateable="false">> + File upload complete + </message> <message name="IDS_NTP_COMPOSE_FILE_UPLOAD_INVALID_EMPTY_SIZE" desc="The text to display when a file upload is empty." translateable="false"> Can't upload. File appears to be empty. </message>
diff --git a/chrome/app/profiles_strings.grdp b/chrome/app/profiles_strings.grdp index f316912f..a86ebe0 100644 --- a/chrome/app/profiles_strings.grdp +++ b/chrome/app/profiles_strings.grdp
@@ -703,6 +703,9 @@ <message name="IDS_ENTERPRISE_VALUE_PROPOSITION_CONSUMER_SUBTITLE" desc="Subtitle the value proposition dialog for creating an enterprise profile."> Sign in to get your passwords and more on all your devices </message> + <message name="IDS_ENTERPRISE_VALUE_PROPOSITION_CONSUMER_SUBTITLE_WITH_BOOKMARKS" desc="Subtitle the value proposition dialog for creating an enterprise profile."> + Sign in to get your passwords, bookmarks, and more on all your devices + </message> <message name="IDS_ENTERPRISE_VALUE_PROPOSITION_SCHOOL_SUBTITLE" desc="Subtitle the value proposition dialog for creating an enterprise profile for school."> Set up a school profile to save and use your passwords and more in your account </message>
diff --git a/chrome/app/profiles_strings_grdp/IDS_ENTERPRISE_VALUE_PROPOSITION_CONSUMER_SUBTITLE_WITH_BOOKMARKS.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_ENTERPRISE_VALUE_PROPOSITION_CONSUMER_SUBTITLE_WITH_BOOKMARKS.png.sha1 new file mode 100644 index 0000000..2e5734b --- /dev/null +++ b/chrome/app/profiles_strings_grdp/IDS_ENTERPRISE_VALUE_PROPOSITION_CONSUMER_SUBTITLE_WITH_BOOKMARKS.png.sha1
@@ -0,0 +1 @@ +b7c77c5f37544a8436eee5028524063aafdb182e \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 7806a77..940a05a 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1295,16 +1295,6 @@ "privacy_sandbox/tracking_protection_onboarding_factory.h", "privacy_sandbox/tracking_protection_settings_factory.cc", "privacy_sandbox/tracking_protection_settings_factory.h", - "private_network_access/chrome_private_network_device_chooser.cc", - "private_network_access/chrome_private_network_device_chooser.h", - "private_network_access/chrome_private_network_device_delegate.cc", - "private_network_access/chrome_private_network_device_delegate.h", - "private_network_access/private_network_device_chooser_controller.cc", - "private_network_access/private_network_device_chooser_controller.h", - "private_network_access/private_network_device_permission_context.cc", - "private_network_access/private_network_device_permission_context.h", - "private_network_access/private_network_device_permission_context_factory.cc", - "private_network_access/private_network_device_permission_context_factory.h", "process_resource_usage.cc", "process_resource_usage.h", "process_singleton.h", @@ -1878,6 +1868,10 @@ # - account_password_store_factory.h" # - profile_password_store_factory.h" "//chrome/browser/ui/webauthn:impl", + + # TODO(crbug.com/432421124): Remove this circular dependency when history_service_factory.h, + # task_tab_helper.h and supervised_user_navigation_observer.h get componentized. + "//chrome/browser/ui/sync:impl", ] public_deps = [ @@ -2081,6 +2075,8 @@ "//chrome/browser/ui/safety_hub:impl", "//chrome/browser/ui/search_engines", "//chrome/browser/ui/side_search", + "//chrome/browser/ui/sync", + "//chrome/browser/ui/sync:impl", "//chrome/browser/ui/translate", "//chrome/browser/ui/webid", "//chrome/browser/webauthn", @@ -3821,6 +3817,8 @@ "download/download_open_prompt.h", "download/download_ui_context_menu.cc", "download/download_ui_context_menu.h", + "download/download_ui_enterprise_util.cc", + "download/download_ui_enterprise_util.h", "download/download_warning_desktop_hats_utils.cc", "download/download_warning_desktop_hats_utils.h", "download/offline_item_model.cc", @@ -4143,8 +4141,6 @@ "privacy_sandbox/privacy_sandbox_survey_desktop_controller_factory.h", "privacy_sandbox/privacy_sandbox_tab_observer.cc", "privacy_sandbox/privacy_sandbox_tab_observer.h", - "private_network_access/chrome_private_network_device_chooser_desktop.cc", - "private_network_access/chrome_private_network_device_chooser_desktop.h", "process_singleton_startup_lock.cc", "process_singleton_startup_lock.h", "profile_resetter/brandcode_config_fetcher.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 55a635c..bbabc32f5 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -12950,6 +12950,10 @@ flag_descriptions::kMigrateAccountPrefsOnMobileName, flag_descriptions::kMigrateAccountPrefsOnMobileDescription, kOsAndroid, FEATURE_VALUE_TYPE(syncer::kMigrateAccountPrefs)}, + + {"tab-model-init-fixes", flag_descriptions::kTabModelInitFixesName, + flag_descriptions::kTabModelInitFixesDescription, kOsAndroid, + FEATURE_VALUE_TYPE(chrome::android::kTabModelInitFixes)}, #endif // BUILDFLAG(IS_ANDROID) // Add new entries above this line.
diff --git a/chrome/browser/actor/ui/BUILD.gn b/chrome/browser/actor/ui/BUILD.gn index 02a2419..c8e82be6 100644 --- a/chrome/browser/actor/ui/BUILD.gn +++ b/chrome/browser/actor/ui/BUILD.gn
@@ -38,18 +38,18 @@ deps = [ ":ui_event_types", "//base", - "//chrome/app/vector_icons:vector_icons", - "//chrome/browser/actor:actor", + "//chrome/app/vector_icons", + "//chrome/browser/actor", "//chrome/browser/actor:variant_visitor", "//chrome/browser/profiles:profile", "//chrome/browser/resources/actor_overlay:resources", - "//chrome/browser/ui/browser_window:browser_window", + "//chrome/browser/ui/browser_window", "//chrome/browser/ui/tabs:tabs_public", "//chrome/browser/ui/webui:webui_util", "//chrome/common", "//content/public/browser", - "//ui/views:views", - "//ui/views/controls/webview:webview", + "//ui/views", + "//ui/views/controls/webview", "//ui/webui", ] @@ -85,9 +85,9 @@ ":tool_request_variant", ":ui_event_types", ":ui_event_utils", - "//chrome/browser/actor:actor", + "//chrome/browser/actor", "//chrome/browser/actor:variant_visitor", - "//chrome/browser/actor/ui:ui", + "//chrome/browser/actor/ui", ] } @@ -110,7 +110,7 @@ deps = [ ":event_dispatcher", ":ui", - "//chrome/browser/actor:actor", + "//chrome/browser/actor", ] # TODO(crbug.com/40031409): Fix code that adds exit-time destructors and @@ -125,7 +125,7 @@ ] deps = [ "//base", - "//chrome/browser/actor:actor", + "//chrome/browser/actor", ] } @@ -138,7 +138,7 @@ "//base", # ActorTask::State isn't in actor:types - "//chrome/browser/actor:actor", + "//chrome/browser/actor", "//chrome/browser/actor:types", ] deps = [ "//components/tabs:public" ] @@ -173,7 +173,7 @@ ":ui", ":ui_event_types", ":ui_event_utils", - "//chrome/browser/actor:actor", + "//chrome/browser/actor", "//chrome/browser/actor:impl", "//chrome/browser/actor:test_support", "//chrome/browser/ui/tabs:tabs_public", @@ -200,8 +200,12 @@ deps = [ ":ui", - "//chrome/browser/ui:ui", - "//chrome/browser/ui/browser_window:browser_window", + ":ui_event_types", + "//base/test:test_support", + "//chrome/browser/actor", + "//chrome/browser/profiles:profile", + "//chrome/browser/ui", + "//chrome/browser/ui/browser_window", "//chrome/browser/ui/tabs:tab_strip", "//chrome/common", "//chrome/test:test_support_ui",
diff --git a/chrome/browser/actor/ui/actor_overlay_browsertest.cc b/chrome/browser/actor/ui/actor_overlay_browsertest.cc index 325a6abd..d4cffaa 100644 --- a/chrome/browser/actor/ui/actor_overlay_browsertest.cc +++ b/chrome/browser/actor/ui/actor_overlay_browsertest.cc
@@ -2,15 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/test/run_until.h" +#include "chrome/browser/actor/actor_keyed_service.h" #include "chrome/browser/actor/ui/actor_overlay_window_controller.h" +#include "chrome/browser/actor/ui/actor_ui_state_manager_interface.h" +#include "chrome/browser/actor/ui/ui_event.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window/public/browser_window_features.h" +#include "chrome/browser/ui/tabs/public/tab_features.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/common/chrome_features.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/tabs/public/tab_interface.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" @@ -39,44 +46,65 @@ EXPECT_EQ(web_contents->GetTitle(), u"Actor Overlay"); } -// Verifies that the ActorOverlayWindowController should only exist for normal -// browser windows. +// Verifies that the ActorOverlayWindowController and Actor Ui Tab Controller +// should only exist for normal browser windows. IN_PROC_BROWSER_TEST_F(ActorOverlayTest, ControllerExistsForNormalBrowsers) { Profile* const profile = browser()->profile(); // Normal browser window BrowserWindowFeatures* const normal_window_features = browser()->browser_window_features(); - ASSERT_TRUE(normal_window_features->actor_overlay_window_controller()); + ASSERT_NE(normal_window_features->actor_overlay_window_controller(), nullptr); + ASSERT_NE(normal_window_features->tab_strip_model() + ->GetActiveTab() + ->GetTabFeatures() + ->actor_ui_tab_controller(), + nullptr); // Popup window BrowserWindowFeatures* const popup_window_features = CreateBrowserForPopup(profile)->browser_window_features(); - EXPECT_FALSE(popup_window_features->actor_overlay_window_controller()); + ASSERT_EQ(popup_window_features->actor_overlay_window_controller(), nullptr); + ASSERT_EQ(popup_window_features->tab_strip_model() + ->GetActiveTab() + ->GetTabFeatures() + ->actor_ui_tab_controller(), + nullptr); // App window BrowserWindowFeatures* const app_window_features = CreateBrowserForApp("test_app_name", profile)->browser_window_features(); - EXPECT_FALSE(app_window_features->actor_overlay_window_controller()); + ASSERT_EQ(app_window_features->actor_overlay_window_controller(), nullptr); + ASSERT_EQ(app_window_features->tab_strip_model() + ->GetActiveTab() + ->GetTabFeatures() + ->actor_ui_tab_controller(), + nullptr); // Picture-in-Picture window BrowserWindowFeatures* const pip_window_features = Browser::Create(Browser::CreateParams::CreateForPictureInPicture( "test_app_name", false, profile, false)) ->browser_window_features(); - EXPECT_FALSE(pip_window_features->actor_overlay_window_controller()); + ASSERT_EQ(pip_window_features->actor_overlay_window_controller(), nullptr); + // Tab Interface is null for Picture-in-Picture windows, so we don't test the + // tab controller's existence. // DevTools window BrowserWindowFeatures* const devtools_window_features = Browser::Create(Browser::CreateParams::CreateForDevTools(profile)) ->browser_window_features(); - EXPECT_FALSE(devtools_window_features->actor_overlay_window_controller()); + ASSERT_EQ(devtools_window_features->actor_overlay_window_controller(), + nullptr); + // Tab Interface is null for DevTools windows, so we don't test the tab + // controller's existence. } +// Testing the Actor Overlay Window Controller IN_PROC_BROWSER_TEST_F(ActorOverlayTest, ViewLifecycleAndVisibility) { actor::ui::ActorOverlayWindowController* window_controller = browser()->browser_window_features()->actor_overlay_window_controller(); - ASSERT_TRUE(window_controller); + ASSERT_NE(window_controller, nullptr); // The main actor_overlay_view container should initially be hidden. It should // also have no children. @@ -91,7 +119,7 @@ web_view->SetVisible(false); raw_ptr<views::WebView> overlay_web_view = window_controller->AddChildWebView(std::move(web_view)); - ASSERT_TRUE(overlay_web_view); + ASSERT_NE(overlay_web_view, nullptr); // Verify container size and that it remains hidden because the child is // hidden. @@ -112,12 +140,92 @@ // Confirm managed WebView is not null and the container should become hidden // again - ASSERT_TRUE(managed_overlay_web_view); + ASSERT_NE(managed_overlay_web_view, nullptr); EXPECT_FALSE(browser()->GetBrowserView().GetActorOverlayView()->GetVisible()); EXPECT_EQ( browser()->GetBrowserView().GetActorOverlayView()->children().size(), 0u); } +IN_PROC_BROWSER_TEST_F(ActorOverlayTest, SendStartEventAndStopEvent) { + Profile* const profile = browser()->profile(); + actor::ui::ActorUiStateManagerInterface* state_manager = + actor::ActorKeyedService::Get(profile)->GetActorUiStateManager(); + ASSERT_NE(state_manager, nullptr); + // actor::PageTarget page_target(gfx::Point(100, 200)); + tabs::TabHandle tab_handle = + browser()->tab_strip_model()->GetActiveTab()->GetHandle(); + state_manager->OnUiEvent( + actor::ui::StartingToActOnTab(tab_handle, actor::TaskId(1)), + base::DoNothing()); + ASSERT_TRUE(base::test::RunUntil([&]() { + return browser()->GetBrowserView().GetActorOverlayView()->GetVisible(); + })); + EXPECT_EQ( + browser()->GetBrowserView().GetActorOverlayView()->children().size(), 1u); + EXPECT_TRUE(browser() + ->GetBrowserView() + .GetActorOverlayView() + ->children()[0] + ->GetVisible()); + state_manager->OnUiEvent(actor::ui::StoppedActingOnTab(tab_handle)); + ASSERT_TRUE(base::test::RunUntil([&]() { + return !browser()->GetBrowserView().GetActorOverlayView()->GetVisible(); + })); + EXPECT_EQ( + browser()->GetBrowserView().GetActorOverlayView()->children().size(), 1u); + EXPECT_FALSE(browser() + ->GetBrowserView() + .GetActorOverlayView() + ->children()[0] + ->GetVisible()); +} + +IN_PROC_BROWSER_TEST_F(ActorOverlayTest, OverlayHidesOnTabBackgrounding) { + Profile* const profile = browser()->profile(); + actor::ui::ActorUiStateManagerInterface* state_manager = + actor::ActorKeyedService::Get(profile)->GetActorUiStateManager(); + ASSERT_NE(state_manager, nullptr); + tabs::TabHandle tab_handle = + browser()->tab_strip_model()->GetActiveTab()->GetHandle(); + state_manager->OnUiEvent( + actor::ui::StartingToActOnTab(tab_handle, actor::TaskId(1)), + base::DoNothing()); + ASSERT_TRUE(base::test::RunUntil([&]() { + return browser()->GetBrowserView().GetActorOverlayView()->GetVisible(); + })); + EXPECT_EQ( + browser()->GetBrowserView().GetActorOverlayView()->children().size(), 1u); + EXPECT_TRUE(browser() + ->GetBrowserView() + .GetActorOverlayView() + ->children()[0] + ->GetVisible()); + browser()->tab_strip_model()->AppendWebContents( + content::WebContents::Create(content::WebContents::CreateParams(profile)), + /*foreground=*/true); + ASSERT_TRUE(base::test::RunUntil([&]() { + return !browser()->GetBrowserView().GetActorOverlayView()->GetVisible(); + })); + EXPECT_EQ( + browser()->GetBrowserView().GetActorOverlayView()->children().size(), 1u); + EXPECT_FALSE(browser() + ->GetBrowserView() + .GetActorOverlayView() + ->children()[0] + ->GetVisible()); + browser()->tab_strip_model()->ActivateTabAt(0); + ASSERT_TRUE(base::test::RunUntil([&]() { + return browser()->GetBrowserView().GetActorOverlayView()->GetVisible(); + })); + EXPECT_EQ( + browser()->GetBrowserView().GetActorOverlayView()->children().size(), 1u); + EXPECT_TRUE(browser() + ->GetBrowserView() + .GetActorOverlayView() + ->children()[0] + ->GetVisible()); +} + class ActorOverlayDisabledTest : public InProcessBrowserTest { public: void SetUp() override { @@ -148,33 +256,55 @@ ControllerDoesntExistsForNormalBrowsers) { Profile* const profile = browser()->profile(); - // Normal browser window + // Normal browser window, only the overlay controller's should be null since + // the feature param for the overlay is disabled, but the GlicActorUi feature + // is still enabled. BrowserWindowFeatures* const normal_window_features = browser()->browser_window_features(); - EXPECT_FALSE(normal_window_features->actor_overlay_window_controller()); + ASSERT_EQ(normal_window_features->actor_overlay_window_controller(), nullptr); + ASSERT_NE(normal_window_features->tab_strip_model() + ->GetActiveTab() + ->GetTabFeatures() + ->actor_ui_tab_controller(), + nullptr); // Popup window BrowserWindowFeatures* const popup_window_features = CreateBrowserForPopup(profile)->browser_window_features(); - EXPECT_FALSE(popup_window_features->actor_overlay_window_controller()); + ASSERT_EQ(popup_window_features->actor_overlay_window_controller(), nullptr); + ASSERT_EQ(popup_window_features->tab_strip_model() + ->GetActiveTab() + ->GetTabFeatures() + ->actor_ui_tab_controller(), + nullptr); // App window BrowserWindowFeatures* const app_window_features = CreateBrowserForApp("test_app_name", profile)->browser_window_features(); - EXPECT_FALSE(app_window_features->actor_overlay_window_controller()); + ASSERT_EQ(app_window_features->actor_overlay_window_controller(), nullptr); + ASSERT_EQ(app_window_features->tab_strip_model() + ->GetActiveTab() + ->GetTabFeatures() + ->actor_ui_tab_controller(), + nullptr); // Picture-in-Picture window BrowserWindowFeatures* const pip_window_features = Browser::Create(Browser::CreateParams::CreateForPictureInPicture( "test_app_name", false, profile, false)) ->browser_window_features(); - EXPECT_FALSE(pip_window_features->actor_overlay_window_controller()); + ASSERT_EQ(pip_window_features->actor_overlay_window_controller(), nullptr); + // Tab Interface is null for Picture-in-Picture windows, so we don't test the + // tab controller's existence. // DevTools window BrowserWindowFeatures* const devtools_window_features = Browser::Create(Browser::CreateParams::CreateForDevTools(profile)) ->browser_window_features(); - EXPECT_FALSE(devtools_window_features->actor_overlay_window_controller()); + ASSERT_EQ(devtools_window_features->actor_overlay_window_controller(), + nullptr); + // Tab Interface is null for DevTools windows, so we don't test the tab + // controller's existence. } } // namespace
diff --git a/chrome/browser/actor/ui/actor_overlay_view_controller.cc b/chrome/browser/actor/ui/actor_overlay_view_controller.cc index 7b6a21c..145b817 100644 --- a/chrome/browser/actor/ui/actor_overlay_view_controller.cc +++ b/chrome/browser/actor/ui/actor_overlay_view_controller.cc
@@ -5,13 +5,19 @@ #include "chrome/browser/actor/ui/actor_overlay_view_controller.h" #include "chrome/browser/actor/ui/actor_ui_tab_controller.h" +#include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/tabs/public/tab_features.h" +#include "chrome/browser/ui/webui/webui_embedding_context.h" +#include "chrome/common/webui_url_constants.h" +#include "content/public/browser/browser_context.h" +#include "ui/views/controls/webview/web_contents_set_background_color.h" +#include "ui/views/controls/webview/webview.h" namespace actor::ui { ActorOverlayViewController::ActorOverlayViewController( tabs::TabInterface* tab_interface) - : tab_interface_(tab_interface) {} + : tab_interface_(*tab_interface) {} ActorOverlayViewController::~ActorOverlayViewController() = default; @@ -24,11 +30,111 @@ return tab_interface_->GetTabFeatures()->actor_ui_tab_controller(); } -// TODO(crbug.com/422540636): Not sufficient to determine when the handoff -// button should be visible. Look into ways of tracking mouse movements +// TODO(crbug.com/422540636): Might not be sufficient to determine when the +// handoff button should be visible. Look into ways of tracking mouse movements // directly. void ActorOverlayViewController::OnHoverStatusChanged(bool is_hovering) { GetTabController()->SetHandoffButtonVisibility(is_hovering); } +void ActorOverlayViewController::UpdateState(const ActorOverlayState& state, + bool is_visible) { + if (is_visible) { + // Create the WebView only if it doesn't already exist (either attached or + // managed). + if (!overlay_web_view_ && !managed_overlay_web_view_) { + CreateWebView(); + } + ShowWebView(); + } else { + HideWebView(); + } +} + +void ActorOverlayViewController::AttachManagedWebViewToWindowController() { + if (!managed_overlay_web_view_) { + return; // No WebView to attach. + } + CHECK(actor_overlay_window_controller_); + // Transfer ownership from `managed_overlay_web_view_` to the window + // controller's container. + overlay_web_view_ = actor_overlay_window_controller_->AddChildWebView( + std::move(managed_overlay_web_view_)); + // Ensure the newly attached WebView is initially hidden. + overlay_web_view_->SetVisible(false); + // Clear the unique_ptr as ownership has been transferred. + managed_overlay_web_view_ = nullptr; +} + +void ActorOverlayViewController::SetWindowController( + ActorOverlayWindowController* controller) { + CHECK(controller); + actor_overlay_window_controller_ = controller; + // If a WebView was previously detached, re-attach it to the new window + // controller. + AttachManagedWebViewToWindowController(); +} + +void ActorOverlayViewController::NullifyWebView() { + if (!overlay_web_view_) { + return; + } + // Reclaim ownership of the WebView from the window controller's container. + managed_overlay_web_view_ = + actor_overlay_window_controller_->RemoveChildWebView(overlay_web_view_); + // Clear the raw pointer since the WebView is no longer attached. + overlay_web_view_ = nullptr; +} + +void ActorOverlayViewController::CreateWebView() { + // These CHECKs enforce that this function is only for initial creation, not + // for re-attaching an already existing WebView. + CHECK(!overlay_web_view_); + CHECK(!managed_overlay_web_view_); + + content::BrowserContext* browser_context = + tab_interface_->GetContents()->GetBrowserContext(); + managed_overlay_web_view_ = std::make_unique<views::WebView>(browser_context); + content::WebContents* web_view_contents = + managed_overlay_web_view_->GetWebContents(); + + // Make the WebUI background transparent so it can act as an overlay. + views::WebContentsSetBackgroundColor::CreateForWebContentsWithColor( + web_view_contents, SK_ColorTRANSPARENT); + // Associates the WebView's WebContents with its corresponding TabInterface. + // This allows the WebUI (ActorOverlayUI) to access the correct tab-scoped + // controllers (e.g., ActorUiTabController) for Mojo communication. + webui::SetTabInterface(web_view_contents, &*tab_interface_); + + managed_overlay_web_view_->LoadInitialURL( + GURL(chrome::kChromeUIActorOverlayURL)); + managed_overlay_web_view_->SetVisible(false); + // Attach the newly created WebView to the window controller. + AttachManagedWebViewToWindowController(); +} + +void ActorOverlayViewController::ShowWebView() { + // Disable mouse and keyboard inputs to the underlying contents. + scoped_ignore_input_events_ = + tab_interface_->GetContents()->IgnoreInputEvents(std::nullopt); + // Ensure the overlay WebView exists before showing it. + CHECK(overlay_web_view_); + overlay_web_view_->SetVisible(true); + actor_overlay_window_controller_->MaybeUpdateContainerVisibility(); +} + +// TODO(crbug.com/422540636): Look into if HideWebView is called when the Actor +// Task fails. +void ActorOverlayViewController::HideWebView() { + // Only hide if the WebView is currently attached. + if (!overlay_web_view_) { + return; + } + overlay_web_view_->SetVisible(false); + actor_overlay_window_controller_->MaybeUpdateContainerVisibility(); + // Re-enable mouse and keyboard events to the underlying web contents by + // resetting the ScopedIgnoreInputEvents object. + scoped_ignore_input_events_.reset(); +} + } // namespace actor::ui
diff --git a/chrome/browser/actor/ui/actor_overlay_view_controller.h b/chrome/browser/actor/ui/actor_overlay_view_controller.h index be79b1a..0821ff8 100644 --- a/chrome/browser/actor/ui/actor_overlay_view_controller.h +++ b/chrome/browser/actor/ui/actor_overlay_view_controller.h
@@ -6,17 +6,21 @@ #define CHROME_BROWSER_ACTOR_UI_ACTOR_OVERLAY_VIEW_CONTROLLER_H_ #include "chrome/browser/actor/ui/actor_overlay.mojom.h" +#include "chrome/browser/actor/ui/actor_overlay_window_controller.h" #include "chrome/browser/actor/ui/actor_ui_tab_controller_interface.h" +#include "chrome/browser/actor/ui/states/actor_overlay_state.h" #include "components/tabs/public/tab_interface.h" +#include "content/public/browser/web_contents.h" #include "mojo/public/cpp/bindings/receiver.h" namespace actor::ui { -// Manages the browser-side logic for the chrome://actor-overlay WebUI. This -// controller implements mojom::ActorOverlayPageHandler to receive events from -// the renderer and delegates them to the ActorUiTabController. -// TODO(crbug.com/422540636): Add in view management portion once tab controller -// is ready to send information to the view controller. +// Manages the browser-side UI and lifecycle of the Actor Overlay for a specific +// tab. This controller implements mojom::ActorOverlayPageHandler to receive +// events from the WebUI. It orchestrates the creation, display, and hiding of +// the overlay's views::WebView, managing its attachment to the +// ActorOverlayWindowController (which is window-scoped) and controlling input +// to the underlying web content. class ActorOverlayViewController : public mojom::ActorOverlayPageHandler { public: explicit ActorOverlayViewController(tabs::TabInterface* tab_interface); @@ -27,16 +31,78 @@ ~ActorOverlayViewController() override; + // Binds the Mojo receiver to enable communication from the WebUI. Called by + // ActorUiTabController. void BindOverlay( mojo::PendingReceiver<mojom::ActorOverlayPageHandler> receiver); + + // Returns the tab-specific ActorUiTabController. virtual ActorUiTabControllerInterface* GetTabController(); + // Updates the visibility and state of the Actor Overlay for this tab. Called + // by ActorUiTabController when the tab's active status or foreground status + // changes. It orchestrates the creation, showing, or hiding of the overlay + // WebView. + void UpdateState(const ActorOverlayState& state, bool is_visible); + + // Updates the associated window controller for this tab's overlay. Called by + // ActorUiTabController when the tab is inserted into a window. Re-attaches a + // previously detached WebView if one exists. This is important when tab's + // that are being actuated, move between different windows. + void SetWindowController(ActorOverlayWindowController* controller); + + // Detaches the overlay's WebView from its current window controller and + // reclaims its ownership. Called by ActorUiTabController when the tab is + // about to detach from a window. This is important when tab's that are being + // actuated, move between different windows. + void NullifyWebView(); + // mojom::ActorOverlayPageHandler + // Notifies the ActorUiTabController that the user's hovering status over the + // overlay has changed. Called by the ActorOverlay WebUI (renderer-side). void OnHoverStatusChanged(bool is_hovering) override; private: + // Creates a new WebView instance for the overlay. Called by UpdateState when + // the overlay needs to be shown for the first time for this tab. It also + // attaches the WebView to the window controller. + void CreateWebView(); + + // Attaches a WebView (either newly created or previously detached) to the + // current ActorOverlayWindowController. Called by CreateWebView and + // SetWindowController. + void AttachManagedWebViewToWindowController(); + + // Makes the overlay WebView visible and disables input to the underlying web + // contents. Called by UpdateState. + void ShowWebView(); + + // Hides the overlay WebView and re-enables input to the underlying web + // contents. Called by UpdateState. + void HideWebView(); + + // Manages the lifetime of the WebContents input event ignoring state. + std::optional<content::WebContents::ScopedIgnoreInputEvents> + scoped_ignore_input_events_; + + // A raw pointer to the views::WebView that is currently attached to the + // ActorOverlayWindowController's parent container View. This represents the + // "active" or "displayed" (though possibly hidden) overlay WebView for this + // tab in the current window. + raw_ptr<views::WebView> overlay_web_view_ = nullptr; + + // A unique_ptr that holds ownership of the views::WebView when it is detached + // from the browser's views hierarchy (e.g., when a tab is dragged out of a + // window). This WebView is managed by the view controller and is awaiting + // re-attachment to a new window's hierarchy. This happens when NullifyWebView + // and SetWindowController are called by the Tab Controller after tab detach + // and insert events are received. + std::unique_ptr<views::WebView> managed_overlay_web_view_; + mojo::Receiver<mojom::ActorOverlayPageHandler> receiver_{this}; - const raw_ptr<tabs::TabInterface> tab_interface_; + const raw_ref<tabs::TabInterface> tab_interface_; + raw_ptr<ActorOverlayWindowController> actor_overlay_window_controller_ = + nullptr; }; } // namespace actor::ui
diff --git a/chrome/browser/actor/ui/actor_ui_tab_controller.cc b/chrome/browser/actor/ui/actor_ui_tab_controller.cc index a57f942..adb872f 100644 --- a/chrome/browser/actor/ui/actor_ui_tab_controller.cc +++ b/chrome/browser/actor/ui/actor_ui_tab_controller.cc
@@ -8,6 +8,9 @@ #include "chrome/browser/actor/actor_keyed_service.h" #include "chrome/browser/actor/ui/actor_ui_tab_controller_interface.h" #include "chrome/browser/actor/ui/handoff_button_controller.h" +#include "chrome/browser/ui/browser_window/public/browser_window_features.h" +#include "chrome/browser/ui/browser_window/public/browser_window_interface.h" +#include "chrome/common/chrome_features.h" #include "components/tabs/public/tab_interface.h" namespace actor::ui { @@ -17,18 +20,18 @@ ActorKeyedService* actor_service) : tab_(tab), actor_keyed_service_(actor_service) { CHECK(actor_keyed_service_); - actor_overlay_view_controller_ = - std::make_unique<ActorOverlayViewController>(&*tab_); + if (features::kGlicActorUiOverlay.Get()) { + tab_subscriptions_.push_back(tab_->RegisterWillDetach(base::BindRepeating( + &ActorUiTabController::OnTabWillDetach, weak_factory_.GetWeakPtr()))); + tab_subscriptions_.push_back(tab_->RegisterDidInsert(base::BindRepeating( + &ActorUiTabController::OnTabDidInsert, weak_factory_.GetWeakPtr()))); + } tab_subscriptions_.push_back(tab.RegisterDidActivate( base::BindRepeating(&ActorUiTabController::OnTabActiveStatusChanged, weak_factory_.GetWeakPtr(), /*is_activated=*/true))); tab_subscriptions_.push_back(tab.RegisterWillDeactivate( base::BindRepeating(&ActorUiTabController::OnTabActiveStatusChanged, weak_factory_.GetWeakPtr(), /*is_activated=*/false))); - tab_subscriptions_.push_back(tab_->RegisterWillDetach(base::BindRepeating( - &ActorUiTabController::OnTabWillDetach, weak_factory_.GetWeakPtr()))); - tab_subscriptions_.push_back(tab_->RegisterDidInsert(base::BindRepeating( - &ActorUiTabController::OnTabDidInsert, weak_factory_.GetWeakPtr()))); } ActorUiTabController::~ActorUiTabController() = default; @@ -45,11 +48,18 @@ void ActorUiTabController::OnTabWillDetach(TabInterface* tab, TabInterface::DetachReason reason) { - // TODO(crbug.com/422540636): Implement. + if (features::kGlicActorUiOverlay.Get()) { + GetActorOverlayViewController()->NullifyWebView(); + } } void ActorUiTabController::OnTabDidInsert(TabInterface* tab) { - // TODO(crbug.com/422540636): Implement. + if (features::kGlicActorUiOverlay.Get()) { + GetActorOverlayViewController()->SetWindowController( + tab->GetBrowserWindowInterface() + ->GetFeatures() + .actor_overlay_window_controller()); + } } void ActorUiTabController::UpdateState(const UiTabState& ui_tab_state, @@ -73,10 +83,14 @@ current_tab_active_status_ = tab_active_status; } - // TODO(crbug.com/425952887): Change this once ui components are implemented, - // for now always return true. - base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), true)); + if (features::kGlicActorUiOverlay.Get()) { + // TODO(crbug.com/425952887): Simplify the is_visible logic to a helper + // function that both UI components can use. + GetActorOverlayViewController()->UpdateState( + current_ui_tab_state_.actor_overlay, + current_tab_active_status_ && + current_ui_tab_state_.actor_overlay.is_active); + } // TODO(crbug.com/428216197): Only notify relevant UI components on change. if (GetHandoffButtonController()) { @@ -86,6 +100,11 @@ GetHandoffButtonController()->UpdateState( current_ui_tab_state_.handoff_button, current_tab_active_status_); } + + // TODO(crbug.com/425952887): Change this once ui components are implemented, + // for now always return true. + base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), true)); } void ActorUiTabController::SetActiveTaskId(TaskId task_id) { @@ -98,6 +117,7 @@ void ActorUiTabController::ClearActiveTaskId() { active_task_id_ = TaskId(0); } + void ActorUiTabController::SetActorTaskPaused() { if (auto* task = actor_keyed_service_->GetTask(active_task_id_)) { task->Pause(); @@ -112,7 +132,9 @@ void ActorUiTabController::BindActorOverlay( mojo::PendingReceiver<mojom::ActorOverlayPageHandler> receiver) { - actor_overlay_view_controller_->BindOverlay(std::move(receiver)); + if (features::kGlicActorUiOverlay.Get()) { + GetActorOverlayViewController()->BindOverlay(std::move(receiver)); + } } void ActorUiTabController::SetHandoffButtonVisibility(bool is_visible) { @@ -131,6 +153,15 @@ return handoff_button_controller_.get(); } +ActorOverlayViewController* +ActorUiTabController::GetActorOverlayViewController() { + if (!actor_overlay_view_controller_) { + actor_overlay_view_controller_ = + std::make_unique<ActorOverlayViewController>(&*tab_); + } + return actor_overlay_view_controller_.get(); +} + base::WeakPtr<ActorUiTabControllerInterface> ActorUiTabController::GetWeakPtr() { return weak_factory_.GetWeakPtr();
diff --git a/chrome/browser/actor/ui/actor_ui_tab_controller.h b/chrome/browser/actor/ui/actor_ui_tab_controller.h index 64d8a25..4be8f9ed 100644 --- a/chrome/browser/actor/ui/actor_ui_tab_controller.h +++ b/chrome/browser/actor/ui/actor_ui_tab_controller.h
@@ -38,6 +38,8 @@ void SetActorTaskResume() override; void SetHandoffButtonVisibility(bool is_visible) override; + // Binds the Mojo receiver to the tab's ActorOverlayViewController. + // Called by ActorOverlayUI when the chrome://actor-overlay page loads. void BindActorOverlay( mojo::PendingReceiver<mojom::ActorOverlayPageHandler> receiver) override; @@ -52,6 +54,8 @@ UiResultCallback callback); // Gets a new or existing handoff button controller for this tab. HandoffButtonController* GetHandoffButtonController(); + // Get a new or existing Actor Overlay View Controller for this tab. + ActorOverlayViewController* GetActorOverlayViewController(); // Tab subscriptions: // Called when the tab is detached. void OnTabWillDetach(tabs::TabInterface* tab,
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index 2b08403..0e4184df 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -70,6 +70,7 @@ "//chromeos/components/onc", "//chromeos/dbus/power", "//chromeos/dbus/tpm_manager", + "//components/account_id:test_support", "//components/download/content/public", "//components/download/public/common:test_support", "//components/onc",
diff --git a/chrome/browser/ash/app_restore/full_restore_service.cc b/chrome/browser/ash/app_restore/full_restore_service.cc index 9977c58..435f7243 100644 --- a/chrome/browser/ash/app_restore/full_restore_service.cc +++ b/chrome/browser/ash/app_restore/full_restore_service.cc
@@ -242,6 +242,11 @@ if (is_shut_down_) return; + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + ash::switches::kDisableWelcomeRecapForFactoryTest)) { + return; + } + PrefService* prefs = profile_->GetPrefs(); DCHECK(prefs);
diff --git a/chrome/browser/ash/app_restore/full_restore_service_unittest.cc b/chrome/browser/ash/app_restore/full_restore_service_unittest.cc index e91018d..8868677c 100644 --- a/chrome/browser/ash/app_restore/full_restore_service_unittest.cc +++ b/chrome/browser/ash/app_restore/full_restore_service_unittest.cc
@@ -818,4 +818,17 @@ VerifyRestoreInitSettingHistogram(RestoreOption::kAskEveryTime, 2); } +// If the welcome recap switch is disabled for factory testing, don't show the +// informed restore dialog. +TEST_F(FullRestoreServiceTest, DisableWelcomeRecapForFactoryTest) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kDisableWelcomeRecapForFactoryTest); + + auto mock_delegate = std::make_unique<MockFullRestoreServiceDelegate>(); + EXPECT_CALL(*mock_delegate, + MaybeStartInformedRestoreOverviewSession(testing::_)) + .Times(0); + CreateFullRestoreServiceForTesting(std::move(mock_delegate)); +} + } // namespace ash::full_restore
diff --git a/chrome/browser/ash/bruschetta/bruschetta_network_context.cc b/chrome/browser/ash/bruschetta/bruschetta_network_context.cc index 7114b82..0a7ab01 100644 --- a/chrome/browser/ash/bruschetta/bruschetta_network_context.cc +++ b/chrome/browser/ash/bruschetta/bruschetta_network_context.cc
@@ -232,15 +232,6 @@ auth_challenge_responder_remote->OnAuthCredentials(std::nullopt); } -void BruschettaNetworkContext::OnPrivateNetworkAccessPermissionRequired( - const GURL& url, - const net::IPAddress& ip_address, - const std::optional<std::string>& private_network_device_id, - const std::optional<std::string>& private_network_device_name, - OnPrivateNetworkAccessPermissionRequiredCallback callback) { - std::move(callback).Run(false); -} - void BruschettaNetworkContext::OnLocalNetworkAccessPermissionRequired( OnLocalNetworkAccessPermissionRequiredCallback callback) { std::move(callback).Run(false);
diff --git a/chrome/browser/ash/bruschetta/bruschetta_network_context.h b/chrome/browser/ash/bruschetta/bruschetta_network_context.h index d7cec44..52c78d7 100644 --- a/chrome/browser/ash/bruschetta/bruschetta_network_context.h +++ b/chrome/browser/ash/bruschetta/bruschetta_network_context.h
@@ -69,12 +69,6 @@ const scoped_refptr<net::HttpResponseHeaders>& head_headers, mojo::PendingRemote<network::mojom::AuthChallengeResponder> auth_challenge_responder) override; - void OnPrivateNetworkAccessPermissionRequired( - const GURL& url, - const net::IPAddress& ip_address, - const std::optional<std::string>& private_network_device_id, - const std::optional<std::string>& private_network_device_name, - OnPrivateNetworkAccessPermissionRequiredCallback callback) override; void OnLocalNetworkAccessPermissionRequired( OnLocalNetworkAccessPermissionRequiredCallback callback) override; void OnClearSiteData(
diff --git a/chrome/browser/ash/events/event_rewriter_delegate_impl.cc b/chrome/browser/ash/events/event_rewriter_delegate_impl.cc index 5620082..43e964b 100644 --- a/chrome/browser/ash/events/event_rewriter_delegate_impl.cc +++ b/chrome/browser/ash/events/event_rewriter_delegate_impl.cc
@@ -311,11 +311,14 @@ return std::nullopt; } - CHECK(settings->f11.has_value() && settings->f12.has_value()); - if (key_code == ui::KeyboardCode::VKEY_F11) { + if (settings->f11.has_value() && key_code == ui::KeyboardCode::VKEY_F11) { return settings->f11; + } else if (settings->f12.has_value() && + key_code == ui::KeyboardCode::VKEY_F12) { + return settings->f12; } - return settings->f12; + + return std::nullopt; } void EventRewriterDelegateImpl::NotifySixPackRewriteBlockedByFnKey(
diff --git a/chrome/browser/ash/floating_workspace/floating_workspace_service.cc b/chrome/browser/ash/floating_workspace/floating_workspace_service.cc index 9c8d2943..e884adc 100644 --- a/chrome/browser/ash/floating_workspace/floating_workspace_service.cc +++ b/chrome/browser/ash/floating_workspace/floating_workspace_service.cc
@@ -717,6 +717,17 @@ LOG(WARNING) << "Desk capture failed. Nothing to upload."; return; } + + const app_restore::RestoreData* restore_data = + desk_template->desk_restore_data(); + if (restore_data && restore_data->app_id_to_launch_list().empty() && + ash::Shell::Get()->session_controller()->GetSessionState() != + session_manager::SessionState::ACTIVE) { + // A capture event can be triggered while the device is on the lock screen, + // but then it always captures an empty desk. Don't upload it in such case. + return; + } + // Check if there's an associated floating workspace uuid from the desk // sync bridge. If there is, use that one. The // `floating_workspace_uuid_ is populated once during the first capture
diff --git a/chrome/browser/ash/floating_workspace/floating_workspace_service_unittest.cc b/chrome/browser/ash/floating_workspace/floating_workspace_service_unittest.cc index 51b62502..c750a2f 100644 --- a/chrome/browser/ash/floating_workspace/floating_workspace_service_unittest.cc +++ b/chrome/browser/ash/floating_workspace/floating_workspace_service_unittest.cc
@@ -12,6 +12,7 @@ #include "ash/constants/ash_features.h" #include "ash/public/cpp/desk_template.h" +#include "ash/session/session_controller_impl.h" #include "ash/session/test_session_controller_client.h" #include "ash/shell.h" #include "ash/system/session/logout_confirmation_controller.h" @@ -1459,7 +1460,7 @@ } TEST_F(FloatingWorkspaceServiceV2Test, - CaptureFloatingWorkspaceTemplateOnLockScreen) { + CaptureFloatingWorkspaceTemplateWhenLockingTheScreen) { SessionControllerClientImpl client( CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state())); client.Init(); @@ -1493,6 +1494,53 @@ creation_time); } +TEST_F(FloatingWorkspaceServiceV2Test, DontUploadEmptyDeskFromLockScreen) { + SkipOnFirstSyncCallback(); + PopulateAppsCache(); + CreateFloatingWorkspaceServiceForTesting(profile()); + FloatingWorkspaceService* floating_workspace_service = + InitFloatingWorkspaceServiceAndStartSession(); + + // Create and capture a template + const std::string template_name = "floating_workspace_captured_template"; + const base::Time creation_time = base::Time::Now(); + std::unique_ptr<DeskTemplate> floating_workspace_template = + MakeTestFloatingWorkspaceDeskTemplate(template_name, creation_time); + mock_desks_client()->SetCapturedDeskTemplate( + std::move(floating_workspace_template)); + test_sync_service()->SetDownloadStatusFor( + {syncer::DataType::WORKSPACE_DESK}, + syncer::SyncService::DataTypeDownloadStatus::kUpToDate); + test_sync_service()->FireStateChanged(); + task_environment().FastForwardBy( + ash::features::kFloatingWorkspaceV2PeriodicJobIntervalInSeconds.Get() + + base::Seconds(1)); + user_activity_detector()->set_last_activity_time_for_test( + base::TimeTicks::Now()); + ASSERT_TRUE(floating_workspace_service->GetLatestFloatingWorkspaceTemplate()); + EXPECT_EQ(floating_workspace_service->GetLatestFloatingWorkspaceTemplate() + ->created_time(), + creation_time); + + // Simulate screen lock and verify that the session state is reported as + // locked. + GetSessionControllerClient()->SetSessionState( + session_manager::SessionState::LOCKED); + GetSessionControllerClient()->FlushForTest(); + ASSERT_EQ(session_manager::SessionState::LOCKED, + ash::Shell::Get()->session_controller()->GetSessionState()); + + // Wait for the next capture and verify that we didn't capture an empty desk. + task_environment().FastForwardBy( + ash::features::kFloatingWorkspaceV2PeriodicJobIntervalInSeconds.Get() + + base::Seconds(1)); + const DeskTemplate* current_template = + floating_workspace_service->GetLatestFloatingWorkspaceTemplate(); + const app_restore::RestoreData* restore_data = + current_template->desk_restore_data(); + EXPECT_FALSE(restore_data->app_id_to_launch_list().empty()); +} + TEST_F(FloatingWorkspaceServiceV2Test, RestoreAfterWakingUpFromSleepWithSyncUpdatesAfterUnlock) { PopulateAppsCache();
diff --git a/chrome/browser/ash/scalable_iph/scalable_iph_browser_test_base.cc b/chrome/browser/ash/scalable_iph/scalable_iph_browser_test_base.cc index 81a43a5..6c318b8 100644 --- a/chrome/browser/ash/scalable_iph/scalable_iph_browser_test_base.cc +++ b/chrome/browser/ash/scalable_iph/scalable_iph_browser_test_base.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/constants/ash_features.h" +#include "ash/public/cpp/multi_user_window_manager.h" #include "base/containers/fixed_flat_set.h" #include "base/functional/bind.h" #include "base/memory/raw_ptr.h" @@ -185,8 +186,11 @@ // Re-create for multi profile tests. This has to be done after // `SetUpOnMainThread` of a base class as the original multi-profile-off // `MultiUserWindowManager` is created there. - MultiUserWindowManagerHelper::CreateInstanceForTest( - GetPrimaryUserContext().GetAccountId()); + MultiUserWindowManagerHelper::CreateInstanceForTest(); + auto account_id = GetPrimaryUserContext().GetAccountId(); + MultiUserWindowManagerHelper::GetWindowManager()->SetPrimaryUser( + account_id); + MultiUserWindowManagerHelper::GetInstance()->AddUser(account_id); } // If we don't intend to enforce ScalableIph setup (i.e. the user profile
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/AddressEditorCoordinator.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/AddressEditorCoordinator.java index 4375abb..985ebb6 100644 --- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/AddressEditorCoordinator.java +++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/editors/AddressEditorCoordinator.java
@@ -33,7 +33,7 @@ private @Nullable PropertyModel mEditorModel; /** Delegate used to subscribe to AddressEditor user interactions. */ - public static interface Delegate { + public interface Delegate { /** * The user has tapped "Done" button. *
diff --git a/chrome/browser/bluetooth/web_bluetooth_browsertest.cc b/chrome/browser/bluetooth/web_bluetooth_browsertest.cc index 70a35de9..8641ea5 100644 --- a/chrome/browser/bluetooth/web_bluetooth_browsertest.cc +++ b/chrome/browser/bluetooth/web_bluetooth_browsertest.cc
@@ -1139,7 +1139,8 @@ navigator.bluetooth.requestDevice({ filters: [{name: 'Test Device', services: ['heart_rate']}]}))", content::EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE); - EXPECT_THAT(result.error, ::testing::HasSubstr(kUserGestureError)); + EXPECT_THAT(result, content::EvalJsResult::ErrorIs( + ::testing::HasSubstr(kUserGestureError))); // In the prerendering, the connection of Web Bluetooth is deferred and // `observer` doesn't have any update.
diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/ScopedBookmarkModelObservation.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/ScopedBookmarkModelObservation.java index 4caf206..343a8026 100644 --- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/ScopedBookmarkModelObservation.java +++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/ScopedBookmarkModelObservation.java
@@ -26,7 +26,7 @@ * An observer to which events are propagated if and only if they involve the supplied bookmark * folder's direct descendants. */ - public static interface Observer { + public interface Observer { /** * Invoked when a direct descendant of the supplied bookmark folder is added. *
diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/bar/BookmarkBarItemsProvider.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/bar/BookmarkBarItemsProvider.java index f40512c8..9ab0eb45 100644 --- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/bar/BookmarkBarItemsProvider.java +++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/bar/BookmarkBarItemsProvider.java
@@ -42,7 +42,7 @@ * An observer to which events are propagated if and only if they involve top-level bookmark bar * items from the supplied bookmark model. */ - public static interface Observer extends ScopedBookmarkModelObservation.Observer { + public interface Observer extends ScopedBookmarkModelObservation.Observer { /** * Invoked when top-level bookmark bar items are added to the supplied bookmark model. *
diff --git a/chrome/browser/bookmarks/android/junit/src/org/chromium/chrome/browser/bookmarks/bar/BookmarkBarItemsProviderTest.java b/chrome/browser/bookmarks/android/junit/src/org/chromium/chrome/browser/bookmarks/bar/BookmarkBarItemsProviderTest.java index 0c05f1d..59f6eff 100644 --- a/chrome/browser/bookmarks/android/junit/src/org/chromium/chrome/browser/bookmarks/bar/BookmarkBarItemsProviderTest.java +++ b/chrome/browser/bookmarks/android/junit/src/org/chromium/chrome/browser/bookmarks/bar/BookmarkBarItemsProviderTest.java
@@ -44,7 +44,7 @@ /** A factory for creating {@link ScopedBookmarkModelObservation} instances. */ @FunctionalInterface - private static interface ScopedBookmarkModelObservationFactory { + private interface ScopedBookmarkModelObservationFactory { /** * Invoked to create a scoped bookmark model observation. *
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc index 53c58286..755d657 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -930,13 +930,6 @@ host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( ContentSettingsType::INTENT_PICKER_DISPLAY, delete_begin_, delete_end_, website_settings_filter); - - host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( - ContentSettingsType::PRIVATE_NETWORK_GUARD, delete_begin_, delete_end_, - website_settings_filter); - host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( - ContentSettingsType::PRIVATE_NETWORK_CHOOSER_DATA, delete_begin_, - delete_end_, website_settings_filter); #endif host_content_settings_map_->ClearSettingsForOneTypeWithPredicate(
diff --git a/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc b/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc index 95d6144e..be09c87d 100644 --- a/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc +++ b/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc
@@ -1500,9 +1500,9 @@ content::EvalJsResult result = EvalJs( web_contents()->GetPrimaryMainFrame(), content::JsReplace("fetch($1, {browsingTopics: true})", resource_url)); - EXPECT_THAT(result.error, - testing::HasSubstr("browsingTopics: Topics operations are only " - "available in secure contexts.")); + EXPECT_THAT(result, content::EvalJsResult::ErrorIs(testing::HasSubstr( + "browsingTopics: Topics operations are only " + "available in secure contexts."))); } else { EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); }
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index a4515dc2..6132c95 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -130,7 +130,6 @@ #include "chrome/browser/privacy_budget/identifiability_study_state.h" #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.h" #include "chrome/browser/privacy_sandbox/tracking_protection_settings_factory.h" -#include "chrome/browser/private_network_access/chrome_private_network_device_delegate.h" #include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_io_data.h" @@ -6625,15 +6624,6 @@ return serial_delegate_.get(); } -content::PrivateNetworkDeviceDelegate* -ChromeContentBrowserClient::GetPrivateNetworkDeviceDelegate() { - if (!private_network_device_delegate_) { - private_network_device_delegate_ = - std::make_unique<ChromePrivateNetworkDeviceDelegate>(); - } - return private_network_device_delegate_.get(); -} - bool ChromeContentBrowserClient::IsSecurityLevelAcceptableForWebAuthn( content::RenderFrameHost* rfh, const url::Origin& caller_origin) {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 4e3d896..d7a57c5d 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -126,7 +126,6 @@ class ChromeDirectSocketsDelegate; class ChromeHidDelegate; -class ChromePrivateNetworkDeviceDelegate; class ChromeSerialDelegate; class ChromeBluetoothDelegate; class ChromeUsbDelegate; @@ -762,8 +761,6 @@ content::BluetoothDelegate* GetBluetoothDelegate() override; content::UsbDelegate* GetUsbDelegate() override; content::SerialDelegate* GetSerialDelegate() override; - content::PrivateNetworkDeviceDelegate* GetPrivateNetworkDeviceDelegate() - override; bool IsSecurityLevelAcceptableForWebAuthn( content::RenderFrameHost* rfh, const url::Origin& caller_origin) override; @@ -1358,8 +1355,6 @@ std::unique_ptr<ChromeBluetoothDelegate> bluetooth_delegate_; std::unique_ptr<ChromeUsbDelegate> usb_delegate_; std::unique_ptr<ChromeSerialDelegate> serial_delegate_; - std::unique_ptr<ChromePrivateNetworkDeviceDelegate> - private_network_device_delegate_; #if BUILDFLAG(IS_CHROMEOS) std::unique_ptr<content::SmartCardDelegate> smart_card_delegate_;
diff --git a/chrome/browser/content_settings/content_settings_default_provider_unittest.cc b/chrome/browser/content_settings/content_settings_default_provider_unittest.cc index 18c3dd0..b195210 100644 --- a/chrome/browser/content_settings/content_settings_default_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_default_provider_unittest.cc
@@ -183,6 +183,8 @@ TEST_F(ContentSettingsDefaultProviderTest, DiscardObsoletePreferences) { static const char kNfcPrefPath[] = "profile.default_content_setting_values.nfc"; + static const char kObsoletePrivateNetworkGuardDefaultPref[] = + "profile.default_content_setting_values.private_network_guard"; #if !BUILDFLAG(IS_ANDROID) static const char kMouselockPrefPath[] = "profile.default_content_setting_values.mouselock"; @@ -209,6 +211,8 @@ CONTENT_SETTING_ALLOW); #endif prefs->SetInteger(kGeolocationPrefPath, CONTENT_SETTING_BLOCK); + prefs->SetInteger(kObsoletePrivateNetworkGuardDefaultPref, + CONTENT_SETTING_BLOCK); // Instantiate a new DefaultProvider; can't use |provider_| because we want to // test the constructor's behavior after setting the above. @@ -216,6 +220,7 @@ // Check that obsolete prefs have been deleted. EXPECT_FALSE(prefs->HasPrefPath(kNfcPrefPath)); + EXPECT_FALSE(prefs->HasPrefPath(kObsoletePrivateNetworkGuardDefaultPref)); #if !BUILDFLAG(IS_ANDROID) EXPECT_FALSE(prefs->HasPrefPath(kMouselockPrefPath)); EXPECT_FALSE(prefs->HasPrefPath(kObsoletePluginsDefaultPref));
diff --git a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc index 0c28fe2c..2727d01 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
@@ -154,6 +154,8 @@ const char kObsoleteInstalledWebAppMetadataExceptionsPref[] = "profile.content_settings.exceptions.installed_web_app_metadata"; #endif + static char kObsoletePrivateNetworkChooserDataPref[] = + "profile.content_settings.exceptions.private_network_chooser_data"; static const char kGeolocationPrefPath[] = "profile.content_settings.exceptions.geolocation"; static const char kGetDisplayMediaSetSelectAllScreensAllowedForUrlsPref[] = @@ -179,6 +181,7 @@ prefs->SetDict(kObsoleteInstalledWebAppMetadataExceptionsPref, pref_data.Clone()); #endif + prefs->SetDict(kObsoletePrivateNetworkChooserDataPref, pref_data.Clone()); prefs->SetDict(kGeolocationPrefPath, std::move(pref_data)); prefs->SetList(kGetDisplayMediaSetSelectAllScreensAllowedForUrlsPref, std::move(pref_list)); @@ -194,6 +197,7 @@ EXPECT_FALSE( prefs->HasPrefPath(kObsoleteInstalledWebAppMetadataExceptionsPref)); #endif + EXPECT_FALSE(prefs->HasPrefPath(kObsoletePrivateNetworkChooserDataPref)); EXPECT_FALSE(prefs->HasPrefPath( kGetDisplayMediaSetSelectAllScreensAllowedForUrlsPref)); EXPECT_TRUE(prefs->HasPrefPath(kGeolocationPrefPath));
diff --git a/chrome/browser/contextual_cueing/zero_state_suggestions_request.cc b/chrome/browser/contextual_cueing/zero_state_suggestions_request.cc index 31f12cda..d427896 100644 --- a/chrome/browser/contextual_cueing/zero_state_suggestions_request.cc +++ b/chrome/browser/contextual_cueing/zero_state_suggestions_request.cc
@@ -29,8 +29,10 @@ OPTIMIZATION_GUIDE_LOG( optimization_guide_common::mojom::LogSource::MODEL_EXECUTION, optimization_guide_keyed_service_->GetOptimizationGuideLogger(), - "ZeroStateSuggestionsRequest: Creating new zero state suggestions " - "request"); + base::StringPrintf( + "ZeroStateSuggestionsRequest: Creating new zero state suggestions " + "request for %llu tabs", + requested_tabs.size())); auto barrier_callback = base::BarrierCallback< std::optional<optimization_guide::proto::ZeroStatePageContext>>( requested_tabs.size(), @@ -59,7 +61,13 @@ } } -ZeroStateSuggestionsRequest::~ZeroStateSuggestionsRequest() = default; +ZeroStateSuggestionsRequest::~ZeroStateSuggestionsRequest() { + OPTIMIZATION_GUIDE_LOG( + optimization_guide_common::mojom::LogSource::MODEL_EXECUTION, + optimization_guide_keyed_service_->GetOptimizationGuideLogger(), + "ZeroStateSuggestionsRequest: Destructing zero state suggestions " + "request"); +} void ZeroStateSuggestionsRequest::AddCallback( base::OnceCallback<void(std::vector<std::string>)> callback) { @@ -118,8 +126,10 @@ OPTIMIZATION_GUIDE_LOG( optimization_guide_common::mojom::LogSource::MODEL_EXECUTION, optimization_guide_keyed_service_->GetOptimizationGuideLogger(), - "ZeroStateSuggestionsRequest: Starting fetch for " - "suggestions."); + base::StringPrintf( + "ZeroStateSuggestionsRequest: Starting fetch for " + "suggestions. Is-mulitab request: %s", + pending_base_request_.has_page_context_list() ? "true" : "false")); optimization_guide_keyed_service_->ExecuteModel( optimization_guide::ModelBasedCapabilityKey::kZeroStateSuggestions, pending_base_request_,
diff --git a/chrome/browser/controlled_frame/controlled_frame_permissions_unittest.cc b/chrome/browser/controlled_frame/controlled_frame_permissions_unittest.cc index 691f0f15..7c6d007b 100644 --- a/chrome/browser/controlled_frame/controlled_frame_permissions_unittest.cc +++ b/chrome/browser/controlled_frame/controlled_frame_permissions_unittest.cc
@@ -165,8 +165,6 @@ case ContentSettingsType::NOTIFICATION_INTERACTIONS: case ContentSettingsType::REDUCED_ACCEPT_LANGUAGE: case ContentSettingsType::NOTIFICATION_PERMISSION_REVIEW: - case ContentSettingsType::PRIVATE_NETWORK_GUARD: - case ContentSettingsType::PRIVATE_NETWORK_CHOOSER_DATA: case ContentSettingsType:: FEDERATED_IDENTITY_IDENTITY_PROVIDER_SIGNIN_STATUS: case ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS:
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_browsertest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_browsertest.cc index 72022451..ecbfedf 100644 --- a/chrome/browser/custom_handlers/protocol_handler_registry_browsertest.cc +++ b/chrome/browser/custom_handlers/protocol_handler_registry_browsertest.cc
@@ -387,17 +387,17 @@ navigator.registerProtocolHandler("web+meow", "%s"); )"; ASSERT_THAT(EvalJs(web_contents, base::StringPrintf(kRegisterProtocolScript, - protocol_url.spec())) - .error, - testing::HasSubstr("Isolated Web Apps do not support " - "registering/unregistering protocol")); + protocol_url.spec())), + content::EvalJsResult::ErrorIs( + testing::HasSubstr("Isolated Web Apps do not support " + "registering/unregistering protocol"))); static constexpr std::string_view kUnegisterProtocolScript = R"( navigator.unregisterProtocolHandler("web+meow", "%s"); )"; ASSERT_THAT(EvalJs(web_contents, base::StringPrintf(kUnegisterProtocolScript, - protocol_url.spec())) - .error, - testing::HasSubstr("Isolated Web Apps do not support " - "registering/unregistering protocol")); + protocol_url.spec())), + content::EvalJsResult::ErrorIs( + testing::HasSubstr("Isolated Web Apps do not support " + "registering/unregistering protocol"))); }
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc index 7429ded..13d55fc4 100644 --- a/chrome/browser/devtools/devtools_browsertest.cc +++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -3721,9 +3721,9 @@ OpenDevToolsWindow("about:blank", true); const auto result = FetchFromDevToolsWindow("http://www.google.com"); - EXPECT_THAT(result.error, - ::testing::StartsWith( - "a JavaScript error: \"TypeError: Failed to fetch\n")); + EXPECT_THAT(result, + content::EvalJsResult::ErrorIs(::testing::StartsWith( + "a JavaScript error: \"TypeError: Failed to fetch\n"))); CloseDevToolsWindow(); } @@ -3734,9 +3734,9 @@ const auto result = Fetch(GetInspectedTab(), "devtools://devtools/bundled/devtools_compatibility.js"); - EXPECT_THAT(result.error, - ::testing::StartsWith( - "a JavaScript error: \"TypeError: Failed to fetch\n")); + EXPECT_THAT(result, + content::EvalJsResult::ErrorIs(::testing::StartsWith( + "a JavaScript error: \"TypeError: Failed to fetch\n"))); } IN_PROC_BROWSER_TEST_F(DevToolsTest, HostBindingsSyncIntegration) {
diff --git a/chrome/browser/direct_sockets/direct_sockets_apitest.cc b/chrome/browser/direct_sockets/direct_sockets_apitest.cc index f525c74f..26bf35b 100644 --- a/chrome/browser/direct_sockets/direct_sockets_apitest.cc +++ b/chrome/browser/direct_sockets/direct_sockets_apitest.cc
@@ -270,7 +270,7 @@ } auto ErrorIs(const auto& matcher) { - return testing::Field(&content::EvalJsResult::error, matcher); + return content::EvalJsResult::ErrorIs(matcher); } auto IsOk() {
diff --git a/chrome/browser/download/OWNERS b/chrome/browser/download/OWNERS index 1dd1a9c..9eb3a5e 100644 --- a/chrome/browser/download/OWNERS +++ b/chrome/browser/download/OWNERS
@@ -7,6 +7,7 @@ per-file download_item_model*=file://chrome/browser/download/bubble/OWNERS per-file download_item_warning_data*=file://chrome/browser/download/bubble/OWNERS per-file download_ui_controller*=file://chrome/browser/download/bubble/OWNERS +per-file download_ui_enterprise_util*=file://components/enterprise/connectors/OWNERS per-file download_ui_model*=file://chrome/browser/download/bubble/OWNERS per-file download_ui_safe_browsing_util*=file://chrome/browser/download/bubble/OWNERS per-file download_warning_desktop_hats_utils*=file://chrome/browser/download/bubble/OWNERS
diff --git a/chrome/browser/download/bubble/download_bubble_prefs.cc b/chrome/browser/download/bubble/download_bubble_prefs.cc index 648526b..62e52284 100644 --- a/chrome/browser/download/bubble/download_bubble_prefs.cc +++ b/chrome/browser/download/bubble/download_bubble_prefs.cc
@@ -9,14 +9,9 @@ #include "chrome/browser/download/download_core_service_factory.h" #include "chrome/browser/headless/headless_mode_util.h" #include "chrome/common/pref_names.h" -#include "components/enterprise/buildflags/buildflags.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing/core/common/features.h" -#if BUILDFLAG(ENTERPRISE_CLOUD_CONTENT_ANALYSIS) -#include "chrome/browser/enterprise/connectors/connectors_service.h" -#endif - namespace download { bool IsDownloadBubbleEnabled() { @@ -42,29 +37,6 @@ ->IsDownloadUiEnabled(); } -bool DoesDownloadConnectorBlock(Profile* profile, const GURL& url) { -#if BUILDFLAG(ENTERPRISE_CLOUD_CONTENT_ANALYSIS) - auto* connector_service = - enterprise_connectors::ConnectorsServiceFactory::GetForBrowserContext( - profile); - if (!connector_service) { - return false; - } - - std::optional<enterprise_connectors::AnalysisSettings> settings = - connector_service->GetAnalysisSettings( - url, enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED); - if (!settings) { - return false; - } - - return settings->block_until_verdict == - enterprise_connectors::BlockUntilVerdict::kBlock; -#else - return false; -#endif // BUILDFLAG(ENTERPRISE_CLOUD_CONTENT_ANALYSIS) -} - bool IsDownloadBubblePartialViewControlledByPref() { #if BUILDFLAG(IS_CHROMEOS) return false;
diff --git a/chrome/browser/download/bubble/download_bubble_prefs.h b/chrome/browser/download/bubble/download_bubble_prefs.h index fec6776b..53027ee 100644 --- a/chrome/browser/download/bubble/download_bubble_prefs.h +++ b/chrome/browser/download/bubble/download_bubble_prefs.h
@@ -15,10 +15,6 @@ // Called when deciding whether to show or hide the bubble. bool ShouldShowDownloadBubble(Profile* profile); -// The enterprise download connectors can be enabled in blocking or nonblocking -// mode. This returns false if the connector is disabled. -bool DoesDownloadConnectorBlock(Profile* profile, const GURL& url); - // Whether the partial view is controlled by prefs. If not controlled by prefs, // the partial view defaults to disabled. bool IsDownloadBubblePartialViewControlledByPref();
diff --git a/chrome/browser/download/bubble/download_bubble_prefs_unittest.cc b/chrome/browser/download/bubble/download_bubble_prefs_unittest.cc index 9d3e1325..7ea1951 100644 --- a/chrome/browser/download/bubble/download_bubble_prefs_unittest.cc +++ b/chrome/browser/download/bubble/download_bubble_prefs_unittest.cc
@@ -4,51 +4,23 @@ #include "chrome/browser/download/bubble/download_bubble_prefs.h" -#include "base/json/json_reader.h" #include "base/memory/raw_ptr.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" -#include "chrome/browser/enterprise/connectors/common.h" -#include "chrome/browser/policy/dm_token_utils.h" -#include "chrome/browser/safe_browsing/advanced_protection_status_manager.h" -#include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" -#include "components/enterprise/common/proto/connectors.pb.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" +namespace download { namespace { -constexpr char kDownloadConnectorEnabledNonBlockingPref[] = R"([ - { - "service_provider": "google", - "enable": [ - {"url_list": ["*"], "tags": ["malware"]} - ] - } -])"; - -constexpr char kDownloadConnectorEnabledBlockingPref[] = R"([ - { - "service_provider": "google", - "block_until_verdict":1, - "enable": [ - {"url_list": ["*"], "tags": ["malware"]} - ] - } -])"; - -} // namespace - -namespace download { - -class DownloadBubblePrefsTest : public testing::Test { +class DownloadBubblePrefsTest : public ::testing::Test { public: DownloadBubblePrefsTest() : testing_profile_manager_(TestingBrowserProcess::GetGlobal()) {} @@ -57,14 +29,7 @@ void SetUp() override { ASSERT_TRUE(testing_profile_manager_.SetUp()); - profile_ = testing_profile_manager_.CreateTestingProfile("testing_profile"); - policy::SetDMTokenForTesting( - policy::DMToken::CreateValidToken("fake-token")); - profile_->GetPrefs()->SetInteger( - AnalysisConnectorScopePref( - enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED), - policy::POLICY_SCOPE_MACHINE); } protected: @@ -85,20 +50,6 @@ #endif } -TEST_F(DownloadBubblePrefsTest, DoesDownloadConnectorBlock) { - EXPECT_FALSE(DoesDownloadConnectorBlock(profile_, GURL())); - profile_->GetPrefs()->Set( - enterprise_connectors::AnalysisConnectorPref( - enterprise_connectors::FILE_DOWNLOADED), - *base::JSONReader::Read(kDownloadConnectorEnabledNonBlockingPref)); - EXPECT_FALSE(DoesDownloadConnectorBlock(profile_, GURL())); - profile_->GetPrefs()->Set( - enterprise_connectors::AnalysisConnectorPref( - enterprise_connectors::FILE_DOWNLOADED), - *base::JSONReader::Read(kDownloadConnectorEnabledBlockingPref)); - EXPECT_TRUE(DoesDownloadConnectorBlock(profile_, GURL())); -} - #if !BUILDFLAG(IS_CHROMEOS) TEST_F(DownloadBubblePrefsTest, IsPartialViewEnabled) { // Test default value. @@ -135,4 +86,5 @@ EXPECT_EQ(DownloadBubblePartialViewImpressions(profile_), 1); } +} // namespace } // namespace download
diff --git a/chrome/browser/download/bubble/download_bubble_ui_controller.cc b/chrome/browser/download/bubble/download_bubble_ui_controller.cc index f5343dd4..e4aa494 100644 --- a/chrome/browser/download/bubble/download_bubble_ui_controller.cc +++ b/chrome/browser/download/bubble/download_bubble_ui_controller.cc
@@ -33,10 +33,12 @@ #include "chrome/browser/profiles/profile_key.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/browser_window/public/browser_window_features.h" +#include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h" #include "chrome/browser/ui/hats/trust_safety_sentiment_service.h" #include "chrome/browser/ui/hats/trust_safety_sentiment_service_factory.h" +#include "chrome/browser/ui/views/download/bubble/download_toolbar_ui_controller.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "components/download/public/common/download_danger_type.h" #include "components/download/public/common/download_item.h" @@ -63,23 +65,25 @@ // user clicks on the button to open the main view. constexpr base::TimeDelta kShowPartialViewMinInterval = base::Seconds(15); -bool IsForDownload(Browser* browser, download::DownloadItem* item) { +bool IsForDownload(BrowserWindowInterface* browser, + download::DownloadItem* item) { Profile* profile = Profile::FromBrowserContext( content::DownloadItemUtils::GetBrowserContext(item)); // An off-the-record `profile` should match only the off-the-record browsers, // but a regular `profile` should match both the regular and off-the-record // browsers. - if (browser->profile() != profile && - browser->profile()->GetOriginalProfile() != profile) { + if (browser->GetProfile() != profile && + browser->GetProfile()->GetOriginalProfile() != profile) { return false; } if (DownloadItemWebAppData* web_app_data = DownloadItemWebAppData::Get(item); web_app_data) { - return web_app::AppBrowserController::IsForWebApp(browser, - web_app_data->id()); + return web_app::AppBrowserController::IsForWebApp( + browser->GetBrowserForMigrationOnly(), web_app_data->id()); } else { - return !web_app::AppBrowserController::IsWebApp(browser); + return !web_app::AppBrowserController::IsWebApp( + browser->GetBrowserForMigrationOnly()); } } @@ -88,10 +92,16 @@ // static DownloadBubbleUIController* DownloadBubbleUIController::GetForDownload( download::DownloadItem* item) { - for (Browser* browser : BrowserList::GetInstance()->OrderedByActivation()) { - if (IsForDownload(browser, item) && browser->window() && - browser->window()->GetDownloadBubbleUIController()) { - return browser->window()->GetDownloadBubbleUIController(); + for (BrowserWindowInterface* browser : + GetBrowserWindowInterfacesOrderedByActivation()) { + if (IsForDownload(browser, item) && + browser->GetFeatures().download_toolbar_ui_controller() && + browser->GetFeatures() + .download_toolbar_ui_controller() + ->bubble_controller()) { + return browser->GetFeatures() + .download_toolbar_ui_controller() + ->bubble_controller(); } } return nullptr;
diff --git a/chrome/browser/download/download_ui_enterprise_util.cc b/chrome/browser/download/download_ui_enterprise_util.cc new file mode 100644 index 0000000..deb4fad2 --- /dev/null +++ b/chrome/browser/download/download_ui_enterprise_util.cc
@@ -0,0 +1,39 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/download/download_ui_enterprise_util.h" + +#include "components/enterprise/buildflags/buildflags.h" + +#if BUILDFLAG(ENTERPRISE_CLOUD_CONTENT_ANALYSIS) +#include "chrome/browser/enterprise/connectors/connectors_service.h" +#include "components/enterprise/connectors/core/analysis_settings.h" +#endif + +namespace download { + +bool DoesDownloadConnectorBlock(Profile* profile, const GURL& url) { +#if BUILDFLAG(ENTERPRISE_CLOUD_CONTENT_ANALYSIS) + auto* connector_service = + enterprise_connectors::ConnectorsServiceFactory::GetForBrowserContext( + profile); + if (!connector_service) { + return false; + } + + std::optional<enterprise_connectors::AnalysisSettings> settings = + connector_service->GetAnalysisSettings( + url, enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED); + if (!settings) { + return false; + } + + return settings->block_until_verdict == + enterprise_connectors::BlockUntilVerdict::kBlock; +#else + return false; +#endif // BUILDFLAG(ENTERPRISE_CLOUD_CONTENT_ANALYSIS) +} + +} // namespace download
diff --git a/chrome/browser/download/download_ui_enterprise_util.h b/chrome/browser/download/download_ui_enterprise_util.h new file mode 100644 index 0000000..4f288a4c --- /dev/null +++ b/chrome/browser/download/download_ui_enterprise_util.h
@@ -0,0 +1,19 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_UI_ENTERPRISE_UTIL_H_ +#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_UI_ENTERPRISE_UTIL_H_ + +class GURL; +class Profile; + +namespace download { + +// The enterprise download connectors can be enabled in blocking or nonblocking +// mode. This returns false if the connector is disabled. +bool DoesDownloadConnectorBlock(Profile* profile, const GURL& url); + +} // namespace download + +#endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_UI_ENTERPRISE_UTIL_H_
diff --git a/chrome/browser/download/download_ui_enterprise_util_unittest.cc b/chrome/browser/download/download_ui_enterprise_util_unittest.cc new file mode 100644 index 0000000..dc72b209 --- /dev/null +++ b/chrome/browser/download/download_ui_enterprise_util_unittest.cc
@@ -0,0 +1,92 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/download/download_ui_enterprise_util.h" + +#include "base/json/json_reader.h" +#include "base/memory/raw_ptr.h" +#include "build/build_config.h" +#include "chrome/browser/enterprise/connectors/common.h" +#include "chrome/browser/policy/dm_token_utils.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "components/enterprise/buildflags/buildflags.h" +#include "components/enterprise/common/proto/connectors.pb.h" +#include "components/prefs/pref_service.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace download { +namespace { + +constexpr char kDownloadConnectorEnabledNonBlockingPref[] = R"([ + { + "service_provider": "google", + "enable": [ + {"url_list": ["*"], "tags": ["malware"]} + ] + } +])"; + +constexpr char kDownloadConnectorEnabledBlockingPref[] = R"([ + { + "service_provider": "google", + "block_until_verdict":1, + "enable": [ + {"url_list": ["*"], "tags": ["malware"]} + ] + } +])"; + +class DownloadUiEnterpriseUtilTest : public ::testing::Test { + public: + DownloadUiEnterpriseUtilTest() + : testing_profile_manager_(TestingBrowserProcess::GetGlobal()) {} + DownloadUiEnterpriseUtilTest(const DownloadUiEnterpriseUtilTest&) = delete; + DownloadUiEnterpriseUtilTest& operator=(const DownloadUiEnterpriseUtilTest&) = + delete; + + void SetUp() override { + ASSERT_TRUE(testing_profile_manager_.SetUp()); + + profile_ = testing_profile_manager_.CreateTestingProfile("testing_profile"); + policy::SetDMTokenForTesting( + policy::DMToken::CreateValidToken("fake-token")); + profile_->GetPrefs()->SetInteger( + AnalysisConnectorScopePref( + enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED), + policy::POLICY_SCOPE_MACHINE); + } + + protected: + raw_ptr<TestingProfile, DanglingUntriaged> profile_; + + private: + content::BrowserTaskEnvironment task_environment_; + TestingProfileManager testing_profile_manager_; +}; + +TEST_F(DownloadUiEnterpriseUtilTest, DoesDownloadConnectorBlock) { + EXPECT_FALSE(DoesDownloadConnectorBlock(profile_, GURL())); + profile_->GetPrefs()->Set( + enterprise_connectors::AnalysisConnectorPref( + enterprise_connectors::FILE_DOWNLOADED), + *base::JSONReader::Read(kDownloadConnectorEnabledNonBlockingPref)); + EXPECT_FALSE(DoesDownloadConnectorBlock(profile_, GURL())); + profile_->GetPrefs()->Set( + enterprise_connectors::AnalysisConnectorPref( + enterprise_connectors::FILE_DOWNLOADED), + *base::JSONReader::Read(kDownloadConnectorEnabledBlockingPref)); +#if BUILDFLAG(ENTERPRISE_CLOUD_CONTENT_ANALYSIS) + EXPECT_TRUE(DoesDownloadConnectorBlock(profile_, GURL())); +#else + EXPECT_FALSE(DoesDownloadConnectorBlock(profile_, GURL())); +#endif +} + +} // namespace +} // namespace download
diff --git a/chrome/browser/download/download_ui_model.cc b/chrome/browser/download/download_ui_model.cc index c7655a9..abb452513 100644 --- a/chrome/browser/download/download_ui_model.cc +++ b/chrome/browser/download/download_ui_model.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/download/bubble/download_bubble_prefs.h" #include "chrome/browser/download/download_commands.h" #include "chrome/browser/download/download_item_warning_data.h" +#include "chrome/browser/download/download_ui_enterprise_util.h" #include "chrome/browser/download/download_ui_safe_browsing_util.h" #include "chrome/browser/download/offline_item_utils.h" #include "chrome/browser/enterprise/connectors/common.h"
diff --git a/chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_apitest.cc b/chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_apitest.cc index 8832fd4..0398e78 100644 --- a/chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_apitest.cc +++ b/chrome/browser/extensions/api/web_authentication_proxy/web_authentication_proxy_apitest.cc
@@ -43,13 +43,14 @@ constexpr char kJsErrorPrefix[] = "a JavaScript error: \""; -MATCHER_P(IsJsError, name, "") { - return base::StartsWith(arg.error, base::StrCat({kJsErrorPrefix, name})); +auto IsJsError(std::string_view name) { + return content::EvalJsResult::ErrorIs( + testing::StartsWith(base::StrCat({kJsErrorPrefix, name}))); } -MATCHER_P2(IsJsErrorWithMessage, name, message, "") { - return base::StrCat({kJsErrorPrefix, name, ": ", message, "\"\n"}) == - arg.error; +auto IsJsErrorWithMessage(std::string_view name, std::string_view message) { + return content::EvalJsResult::ErrorIs( + base::StrCat({kJsErrorPrefix, name, ": ", message, "\"\n"})); } class WebAuthenticationProxyApiTest : public ExtensionApiTest {
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc index 81425dc6..6859558 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -6275,11 +6275,8 @@ } }; -#if !BUILDFLAG(IS_ANDROID) // Tests a service worker-based extension intercepting requests with // webRequestBlocking. -// TODO(crbug.com/391921314): Enable on desktop Android when InstallExtension() -// is supported (for LoadPolicyExtension). IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, WebRequestBlocking) { ASSERT_TRUE(StartEmbeddedTestServer()); static constexpr char kManifest[] = @@ -6451,6 +6448,7 @@ << errors[0]->message(); } +#if !BUILDFLAG(IS_ANDROID) // Tests an extension returning a promise that never resolves from a webRequest // blocking handler. The request should hang forever. IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, @@ -6615,11 +6613,8 @@ EXPECT_EQ(1, get_third_count()); } -#if !BUILDFLAG(IS_ANDROID) // Tests that a service worker-based extension with webRequestBlocking can // intercept requests after the service worker stops. -// TODO(crbug.com/391921314): Enable on desktop Android when InstallExtension() -// is supported (for LoadPolicyExtension). IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, WebRequestBlocking_AfterWorkerShutdown) { ASSERT_TRUE(StartEmbeddedTestServer()); @@ -6683,7 +6678,6 @@ EXPECT_EQ(net::ERR_BLOCKED_BY_CLIENT, nav_observer.last_net_error_code()); } } -#endif // !BUILDFLAG(IS_ANDROID) // Tests a service worker-based extension using webRequest for observational // purposes receives events after the worker stops. @@ -7191,6 +7185,7 @@ EXPECT_EQ(auth_url, GetActiveWebContents()->GetLastCommittedURL()); EXPECT_TRUE(navigation_observer.last_navigation_succeeded()); } +#endif // !BUILDFLAG(IS_ANDROID) class ManifestV3WebRequestApiTestWithBypassRedirectChecksPerRequest : public ManifestV3WebRequestApiTest, @@ -7325,6 +7320,7 @@ base::ScopedTempDir service_worker_dir_; }; +#if !BUILDFLAG(IS_ANDROID) // Tests that an MV3 extension can use the `webRequestAuthProvider` permission // to intercept and handle `onAuthRequired` events coming from an extension // service worker. This test does the following: @@ -7333,6 +7329,7 @@ // (3) The extension attempts to fetch a resource that requires http auth. // (4) This triggers the listener in (3), which supplies credentials // (5) Checks that the fetch succeeded. +// Fails on Android crbug.com/371324825 IN_PROC_BROWSER_TEST_F(OnAuthRequiredApiTest, TestOnAuthRequiredExtensionServiceWorker) { // After the extension loads, trigger an async request to fetch an http auth @@ -7361,6 +7358,7 @@ ASSERT_TRUE(result_catcher.GetNextResult()); } +#endif // !BUILDFLAG(IS_ANDROID) // This test is similar to TestOnAuthRequiredExtensionServiceWorker but the // service worker is hosted by a website instead of the extension istelf. @@ -7492,6 +7490,7 @@ will_register_listener.Reply("unused"); } +#if !BUILDFLAG(IS_ANDROID) // Tests behavior when a service worker is stopped while processing an event. IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, ServiceWorkerGoesAwayWhileHandlingRequest) { @@ -7724,7 +7723,7 @@ ExtensionTestMessageListener listener("ready"); ASSERT_TRUE(LoadExtension(test_dir2.UnpackedPath())); EXPECT_TRUE(listener.WaitUntilSatisfied()); -#endif // BUILDFLAG(IS_ANDROID) +#endif // !BUILDFLAG(IS_ANDROID) // We don't support manifest version 2 on android, so only the first extension // will be loaded on android.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index a954321..927d401 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -6705,7 +6705,7 @@ { "name": "mvc-update-view-when-model-changed", "owners": [ "acondor@chromium.org" ], - "expiry_milestone": 139 + "expiry_milestone": 141 }, { "name": "nav-bar-color-animation", @@ -8465,7 +8465,7 @@ { "name": "reload-tab-ui-resources-if-changed", "owners": [ "acondor@chromium.org" ], - "expiry_milestone": 139 + "expiry_milestone": 141 }, { "name": "remote-playback-backend", @@ -9400,6 +9400,11 @@ "expiry_milestone": 130 }, { + "name": "tab-model-init-fixes", + "owners": [ "skym@chromium.org", "clank-tab-dev@google.com" ], + "expiry_milestone": 150 + }, + { "name": "tab-resumption", "owners": [ "olivierrobin@chromium.org", "gambard@chromium.org", "bling-flags@google.com" ], "expiry_milestone": 142
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 179c45b0..3178ea6 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3930,6 +3930,22 @@ "data loss, etc. Don't enable this flag unless you know what you are doing " "and are working on developing this feature."; +const char kTabGroupEntryPointsAndroidName[] = "Tab Group Entry Points"; +const char kTabGroupEntryPointsAndroidDescription[] = + "Enables additional entry points for creating tab groups"; + +const char kTabGroupParityBottomSheetAndroidName[] = + "Tab Group Parity Bottom Sheet"; +const char kTabGroupParityBottomSheetAndroidDescription[] = + "Enables adding Tabs to Tab Groups via the Tab Group Parity Bottom Sheet"; + +const char kTabModelInitFixesName[] = "Tab Model Init Fixes"; +const char kTabModelInitFixesDescription[] = + "A grab bag of simple and miscellaneous improvements for tab model " + "initialization on Android. Should speed up initialization, as well as " + "have better handling for app menu tab model operations during " + "initialization."; + const char kTabSwitcherDragDropName[] = "Tab Drag and Drop via Tab Switcher"; const char kTabSwitcherDragDropDescription[] = "Enables long-pressing on tab switcher tab to start drag-and-drop. Users " @@ -3947,15 +3963,6 @@ "Helper flag for testing that shows group suggestions for the last 3 tabs " "in the tab switcher (if present)."; -const char kTabGroupEntryPointsAndroidName[] = "Tab Group Entry Points"; -const char kTabGroupEntryPointsAndroidDescription[] = - "Enables additional entry points for creating tab groups"; - -const char kTabGroupParityBottomSheetAndroidName[] = - "Tab Group Parity Bottom Sheet"; -const char kTabGroupParityBottomSheetAndroidDescription[] = - "Enables adding Tabs to Tab Groups via the Tab Group Parity Bottom Sheet"; - const char kTabletTabStripAnimationName[] = "Tablet Tab Strip Animation"; const char kTabletTabStripAnimationDescription[] = "Enables new tablet tab strip animations.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 27d29aa3..c362ef9 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2218,6 +2218,15 @@ extern const char kTabCollectionAndroidName[]; extern const char kTabCollectionAndroidDescription[]; +extern const char kTabGroupEntryPointsAndroidName[]; +extern const char kTabGroupEntryPointsAndroidDescription[]; + +extern const char kTabGroupParityBottomSheetAndroidName[]; +extern const char kTabGroupParityBottomSheetAndroidDescription[]; + +extern const char kTabModelInitFixesName[]; +extern const char kTabModelInitFixesDescription[]; + extern const char kTabSwitcherDragDropName[]; extern const char kTabSwitcherDragDropDescription[]; @@ -2227,12 +2236,6 @@ extern const char kTabSwitcherGroupSuggestionsTestModeAndroidName[]; extern const char kTabSwitcherGroupSuggestionsTestModeAndroidDescription[]; -extern const char kTabGroupEntryPointsAndroidName[]; -extern const char kTabGroupEntryPointsAndroidDescription[]; - -extern const char kTabGroupParityBottomSheetAndroidName[]; -extern const char kTabGroupParityBottomSheetAndroidDescription[]; - extern const char kTabletTabStripAnimationName[]; extern const char kTabletTabStripAnimationDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index f6a91720..50a7235b 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -244,7 +244,6 @@ &kBlockIntentsWhileLocked, &kBookmarkPaneAndroid, &kBottomBrowserControlsRefactor, - &kTabClosureMethodRefactor, &kBrowserControlsDebugging, &kBrowserControlsEarlyResize, &kCacheActivityTaskID, @@ -391,10 +390,13 @@ &kSmallerTabStripTitleLimit, &kSuppressToolbarCapturesAtGestureEnd, &kSwapNewTabAndNewTabInGroupAndroid, + &kTabArchivalDragDropAndroid, + &kTabClosureMethodRefactor, + &kTabCollectionAndroid, + &kTabFreezeOnUndoableClosureKillSwitch, &kTabGroupEntryPointsAndroid, &kTabGroupParityBottomSheetAndroid, - &kTabletTabStripAnimation, - &kTabFreezeOnUndoableClosureKillSwitch, + &kTabModelInitFixes, &kTabStateFlatBuffer, &kTabStorageSqlitePrototype, &kTabStripDensityChangeAndroid, @@ -403,13 +405,12 @@ &kTabStripLayoutOptimization, &kTabStripMouseCloseResizeDelay, &kTabStripTransitionInDesktopWindow, - &kTabArchivalDragDropAndroid, - &kTabCollectionAndroid, &kTabSwitcherDragDropAndroid, &kTabSwitcherForeignFaviconSupport, &kTabSwitcherGroupSuggestionsAndroid, &kTabSwitcherGroupSuggestionsTestModeAndroid, &kTabWindowManagerReportIndicesMismatch, + &kTabletTabStripAnimation, &kTestDefaultDisabled, &kTestDefaultEnabled, &kThirdPartyDisableChromeAutofillSettingsScreen, @@ -824,10 +825,6 @@ "CCTPredictiveBackGesture", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kTabClosureMethodRefactor, - "TabClosureMethodRefactor", - base::FEATURE_DISABLED_BY_DEFAULT); - BASE_FEATURE(kGridTabSwitcherUpdate, "GridTabSwitcherUpdate", base::FEATURE_DISABLED_BY_DEFAULT); @@ -1278,6 +1275,22 @@ "SwapNewTabAndNewTabInGroupAndroid", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kTabArchivalDragDropAndroid, + "TabArchivalDragDropAndroid", + base::FEATURE_ENABLED_BY_DEFAULT); + +BASE_FEATURE(kTabClosureMethodRefactor, + "TabClosureMethodRefactor", + base::FEATURE_DISABLED_BY_DEFAULT); + +BASE_FEATURE(kTabCollectionAndroid, + "TabCollectionAndroid", + base::FEATURE_DISABLED_BY_DEFAULT); + +BASE_FEATURE(kTabFreezeOnUndoableClosureKillSwitch, + "TabFreezeOnUndoableClosureKillSwitch", + base::FEATURE_ENABLED_BY_DEFAULT); + BASE_FEATURE(kTabGroupEntryPointsAndroid, "TabGroupEntryPointsAndroid", base::FEATURE_DISABLED_BY_DEFAULT); @@ -1286,14 +1299,10 @@ "TabGroupParityBottomSheetAndroid", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kTabletTabStripAnimation, - "TabletTabStripAnimation", +BASE_FEATURE(kTabModelInitFixes, + "TabModelInitFixes", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kTabFreezeOnUndoableClosureKillSwitch, - "TabFreezeOnUndoableClosureKillSwitch", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kTabStateFlatBuffer, "TabStateFlatBuffer", base::FEATURE_ENABLED_BY_DEFAULT); @@ -1310,6 +1319,10 @@ "TabStripGroupDragDropAndroid", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kTabStripIncognitoMigration, + "TabStripIncognitoMigration", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kTabStripLayoutOptimization, "TabStripLayoutOptimization", base::FEATURE_ENABLED_BY_DEFAULT); @@ -1322,18 +1335,6 @@ "TabStripTransitionInDesktopWindow", base::FEATURE_ENABLED_BY_DEFAULT); -BASE_FEATURE(kTabStripIncognitoMigration, - "TabStripIncognitoMigration", - base::FEATURE_DISABLED_BY_DEFAULT); - -BASE_FEATURE(kTabArchivalDragDropAndroid, - "TabArchivalDragDropAndroid", - base::FEATURE_ENABLED_BY_DEFAULT); - -BASE_FEATURE(kTabCollectionAndroid, - "TabCollectionAndroid", - base::FEATURE_DISABLED_BY_DEFAULT); - BASE_FEATURE(kTabSwitcherDragDropAndroid, "TabSwitcherDragDropAndroid", base::FEATURE_DISABLED_BY_DEFAULT); @@ -1354,6 +1355,10 @@ "TabWindowManagerReportIndicesMismatch", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kTabletTabStripAnimation, + "TabletTabStripAnimation", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kTestDefaultDisabled, "TestDefaultDisabled", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 6b287c3..404faa6 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -227,10 +227,13 @@ BASE_DECLARE_FEATURE(kScrollToTLDOptimization); BASE_DECLARE_FEATURE(kSuppressToolbarCapturesAtGestureEnd); BASE_DECLARE_FEATURE(kSwapNewTabAndNewTabInGroupAndroid); +BASE_DECLARE_FEATURE(kTabArchivalDragDropAndroid); +BASE_DECLARE_FEATURE(kTabClosureMethodRefactor); +BASE_DECLARE_FEATURE(kTabCollectionAndroid); +BASE_DECLARE_FEATURE(kTabFreezeOnUndoableClosureKillSwitch); BASE_DECLARE_FEATURE(kTabGroupEntryPointsAndroid); BASE_DECLARE_FEATURE(kTabGroupParityBottomSheetAndroid); -BASE_DECLARE_FEATURE(kTabletTabStripAnimation); -BASE_DECLARE_FEATURE(kTabFreezeOnUndoableClosureKillSwitch); +BASE_DECLARE_FEATURE(kTabModelInitFixes); BASE_DECLARE_FEATURE(kTabStateFlatBuffer); BASE_DECLARE_FEATURE(kTabStorageSqlitePrototype); BASE_DECLARE_FEATURE(kTabStripDensityChangeAndroid); @@ -238,15 +241,13 @@ BASE_DECLARE_FEATURE(kTabStripIncognitoMigration); BASE_DECLARE_FEATURE(kTabStripLayoutOptimization); BASE_DECLARE_FEATURE(kTabStripMouseCloseResizeDelay); -BASE_DECLARE_FEATURE(kTabClosureMethodRefactor); BASE_DECLARE_FEATURE(kTabStripTransitionInDesktopWindow); -BASE_DECLARE_FEATURE(kTabArchivalDragDropAndroid); -BASE_DECLARE_FEATURE(kTabCollectionAndroid); BASE_DECLARE_FEATURE(kTabSwitcherDragDropAndroid); BASE_DECLARE_FEATURE(kTabSwitcherForeignFaviconSupport); BASE_DECLARE_FEATURE(kTabSwitcherGroupSuggestionsAndroid); BASE_DECLARE_FEATURE(kTabSwitcherGroupSuggestionsTestModeAndroid); BASE_DECLARE_FEATURE(kTabWindowManagerReportIndicesMismatch); +BASE_DECLARE_FEATURE(kTabletTabStripAnimation); BASE_DECLARE_FEATURE(kThirdPartyDisableChromeAutofillSettingsScreen); BASE_DECLARE_FEATURE(kTestDefaultDisabled); BASE_DECLARE_FEATURE(kTestDefaultEnabled);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 67b98722..eeccbf2 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -618,7 +618,9 @@ public static final String TAB_GROUP_ENTRY_POINTS_ANDROID = "TabGroupEntryPointsAndroid"; public static final String TAB_GROUP_PARITY_BOTTOM_SHEET_ANDROID = "TabGroupParityBottomSheetAndroid"; + public static final String TAB_MODEL_INIT_FIXES = "TabModelInitFixes"; public static final String TAB_STATE_FLAT_BUFFER = "TabStateFlatBuffer"; + public static final String TAB_STORAGE_SQLITE_PROTOTYPE = "TabStorageSqlitePrototype"; public static final String TAB_STRIP_DENSITY_CHANGE_ANDROID = "TabStripDensityChangeAndroid"; public static final String TAB_STRIP_GROUP_DRAG_DROP_ANDROID = "TabStripGroupDragDropAndroid"; public static final String TAB_STRIP_INCOGNITO_MIGRATION = "TabStripIncognitoMigration"; @@ -626,14 +628,13 @@ public static final String TAB_STRIP_MOUSE_CLOSE_RESIZE_DELAY = "TabStripMouseCloseResizeDelay"; public static final String TAB_STRIP_TRANSITION_IN_DESKTOP_WINDOW = "TabStripTransitionInDesktopWindow"; - public static final String TAB_STORAGE_SQLITE_PROTOTYPE = "TabStorageSqlitePrototype"; public static final String TAB_SWITCHER_DRAG_DROP_ANDROID = "TabSwitcherDragDropAndroid"; + public static final String TAB_SWITCHER_FOREIGN_FAVICON_SUPPORT = + "TabSwitcherForeignFaviconSupport"; public static final String TAB_SWITCHER_GROUP_SUGGESTIONS_ANDROID = "TabSwitcherGroupSuggestionsAndroid"; public static final String TAB_SWITCHER_GROUP_SUGGESTIONS_TEST_MODE_ANDROID = "TabSwitcherGroupSuggestionsTestModeAndroid"; - public static final String TAB_SWITCHER_FOREIGN_FAVICON_SUPPORT = - "TabSwitcherForeignFaviconSupport"; public static final String TAB_WINDOW_MANAGER_REPORT_INDICES_MISMATCH = "TabWindowManagerReportIndicesMismatch"; public static final String TASK_MANAGER_CLANK = "TaskManagerClank"; @@ -985,6 +986,8 @@ newCachedFlag(START_SURFACE_RETURN_TIME, true); public static final CachedFlag sTabClosureMethodRefactor = newCachedFlag(TAB_CLOSURE_METHOD_REFACTOR, false); + public static final CachedFlag sTabModelInitFixes = + newCachedFlag(TAB_MODEL_INIT_FIXES, /* defaultValue= */ false); public static final CachedFlag sTabStateFlatBuffer = newCachedFlag( TAB_STATE_FLAT_BUFFER, @@ -1161,6 +1164,7 @@ sSmallerTabStripTitleLimit, sStartSurfaceReturnTime, sTabClosureMethodRefactor, + sTabModelInitFixes, sTabStateFlatBuffer, sTabStripDensityChangeAndroid, sTabStripIncognitoMigration,
diff --git a/chrome/browser/glic/glic_metrics.cc b/chrome/browser/glic/glic_metrics.cc index 1d9b25fa..5da9cb0f 100644 --- a/chrome/browser/glic/glic_metrics.cc +++ b/chrome/browser/glic/glic_metrics.cc
@@ -364,6 +364,14 @@ base::UmaHistogramBoolean("Glic.Response.Rated", positive); } +void GlicMetrics::OnTurnCompleted(mojom::WebClientModel model, + base::TimeDelta duration) { + base::UmaHistogramMediumTimes(model == mojom::WebClientModel::kActor + ? "Glic.Response.TurnDuration.Actor" + : "Glic.Response.TurnDuration.Default", + duration); +} + void GlicMetrics::OnGlicWindowOpen(bool attached, mojom::InvocationSource source) { base::UmaHistogramEnumeration(
diff --git a/chrome/browser/glic/glic_metrics.h b/chrome/browser/glic/glic_metrics.h index cfa30a7..fea9cbf 100644 --- a/chrome/browser/glic/glic_metrics.h +++ b/chrome/browser/glic/glic_metrics.h
@@ -219,6 +219,8 @@ void OnResponseStopped(); void OnSessionTerminated(); void OnResponseRated(bool positive); + void OnTurnCompleted(mojom::WebClientModel model, base::TimeDelta duration); + void OnAttachedToBrowser(AttachChangeReason reason); void OnDetachedFromBrowser(AttachChangeReason reason);
diff --git a/chrome/browser/glic/host/glic.mojom b/chrome/browser/glic/host/glic.mojom index b79a97b..e94083a 100644 --- a/chrome/browser/glic/host/glic.mojom +++ b/chrome/browser/glic/host/glic.mojom
@@ -710,6 +710,9 @@ // Called when the session is terminated. OnSessionTerminated(); + // Called when the web client completes a turn. + OnTurnCompleted(WebClientModel mode, mojo_base.mojom.TimeDelta duration); + // Called when the user rates a response. OnResponseRated(bool positive); @@ -839,6 +842,16 @@ // LINT.ThenChange(//tools/metrics/histograms/metadata/glic/enums.xml:WebClientMode) +// Web client's operation model. +// WARNING: These enum values should match WebClientModel in +// chrome/browser/resources/glic/glic_api/glic_api.ts +[Stable, Extensible] +enum WebClientModel { + [Default] kDefault = 0, + // Actor operation mode. + kActor = 1, +}; + // Carries back to the browser information on how to configure the panel being // opened. struct OpenPanelInfo {
diff --git a/chrome/browser/glic/host/glic_api_browsertest.cc b/chrome/browser/glic/host/glic_api_browsertest.cc index 33cc075..13be9f2 100644 --- a/chrome/browser/glic/host/glic_api_browsertest.cc +++ b/chrome/browser/glic/host/glic_api_browsertest.cc
@@ -304,7 +304,8 @@ void ProcessTestResult(const ExecuteTestOptions& options, const content::EvalJsResult& result) { if (options.expect_guest_frame_destroyed) { - ASSERT_THAT(result.error, testing::HasSubstr("RenderFrame deleted.")); + ASSERT_THAT(result, content::EvalJsResult::ErrorIs( + testing::HasSubstr("RenderFrame deleted."))); return; }
diff --git a/chrome/browser/glic/host/glic_page_handler.cc b/chrome/browser/glic/host/glic_page_handler.cc index 99cf82b..ae6e52b38 100644 --- a/chrome/browser/glic/host/glic_page_handler.cc +++ b/chrome/browser/glic/host/glic_page_handler.cc
@@ -1061,6 +1061,11 @@ glic_service_->metrics()->OnSessionTerminated(); } + void OnTurnCompleted(glic::mojom::WebClientModel model, + base::TimeDelta duration) override { + glic_service_->metrics()->OnTurnCompleted(model, duration); + } + void OnResponseRated(bool positive) override { glic_service_->metrics()->OnResponseRated(positive); }
diff --git a/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubAnimationConstants.java b/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubAnimationConstants.java index b72e808..4be93239 100644 --- a/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubAnimationConstants.java +++ b/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubAnimationConstants.java
@@ -22,6 +22,12 @@ /** Duration in milliseconds of fade animations for the Hub Layout. */ public static final long HUB_LAYOUT_FADE_DURATION_MS = 325L; + /** Duration in milliseconds before the fade in animation for the Hub Layout on XR. */ + public static final long HUB_LAYOUT_XR_FADE_IN_DELAY_MS = 250L; + + /** Duration in milliseconds before the fade out animation for the Hub Layout on XR. */ + public static final long HUB_LAYOUT_XR_FADE_OUT_DELAY_MS = 250L; + /** Duration in milliseconds before a fallback animation will occur for the Hub Layout. */ public static final long HUB_LAYOUT_TIMEOUT_MS = 300L;
diff --git a/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubLayoutDependencyHolder.java b/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubLayoutDependencyHolder.java index 7c076f1..8603527 100644 --- a/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubLayoutDependencyHolder.java +++ b/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubLayoutDependencyHolder.java
@@ -18,7 +18,6 @@ import org.chromium.build.annotations.Nullable; import org.chromium.chrome.browser.hub.HubColorMixer.OverviewModeAlphaObserver; import org.chromium.components.browser_ui.widget.scrim.ScrimManager; -import org.chromium.ui.xr.scenecore.XrSceneCoreSessionManager; /** * Holds dependencies for initialization of {@link HubLayout}. These dependencies come from the @@ -32,7 +31,7 @@ private final LazyOneshotSupplier<ViewGroup> mHubRootViewGroupSupplier; private final HubLayoutScrimController mScrimController; private final OverviewModeAlphaObserver mOnOverviewAlphaChange; - private final @Nullable XrSceneCoreSessionManager mXrSceneCoreSessionManager; + private final @Nullable Supplier<Boolean> mXrFullSpaceModeSupplier; /** * @param hubManagerSupplier The supplier of {@link HubManager}. @@ -45,8 +44,8 @@ * {@link HubLayout} scrims. * @param onOverviewAlphaChange Observer to notify when overview color alpha changes during * animations. - * @param xrSceneCoreSessionManager The {@link XrSceneCoreSessionManager} to manage XR space - * modes. + * @param xrFullSpaceModeSupplier Supplies current XR space mode status. True for XR full space + * mode, false otherwise. */ public HubLayoutDependencyHolder( LazyOneshotSupplier<HubManager> hubManagerSupplier, @@ -55,14 +54,14 @@ Supplier<View> scrimAnchorViewSupplier, ObservableSupplier<Boolean> isIncognitoSupplier, OverviewModeAlphaObserver onOverviewAlphaChange, - @Nullable XrSceneCoreSessionManager xrSceneCoreSessionManager) { + @Nullable Supplier<Boolean> xrFullSpaceModeSupplier) { this( hubManagerSupplier, hubRootViewGroupSupplier, new HubLayoutScrimController( scrimManager, scrimAnchorViewSupplier, isIncognitoSupplier), onOverviewAlphaChange, - xrSceneCoreSessionManager); + xrFullSpaceModeSupplier); } /** @@ -70,8 +69,8 @@ * @param hubRootViewGroupSupplier Supplier for the root view to attach the hub to. * @param scrimController The {@link HubLayoutScrimController} for managing scrims. * @param onOverviewAlphaChange Observer to notify when alpha changes during animations. - * @param xrSceneCoreSessionManager The {@link XrSceneCoreSessionManager} to manage XR space - * modes. + * @param xrFullSpaceModeSupplier Supplies current XR space mode status. True for XR full space + * mode, false otherwise. */ @VisibleForTesting HubLayoutDependencyHolder( @@ -79,12 +78,12 @@ LazyOneshotSupplier<ViewGroup> hubRootViewGroupSupplier, HubLayoutScrimController scrimController, OverviewModeAlphaObserver onOverviewAlphaChange, - @Nullable XrSceneCoreSessionManager xrSceneCoreSessionManager) { + @Nullable Supplier<Boolean> xrFullSpaceModeSupplier) { mHubManagerSupplier = hubManagerSupplier; mHubRootViewGroupSupplier = hubRootViewGroupSupplier; mScrimController = scrimController; mOnOverviewAlphaChange = onOverviewAlphaChange; - mXrSceneCoreSessionManager = xrSceneCoreSessionManager; + mXrFullSpaceModeSupplier = xrFullSpaceModeSupplier; } /** Returns the {@link HubManager} creating it if necessary. */ @@ -107,9 +106,11 @@ return mOnOverviewAlphaChange; } - /** Returns {@link XrSceneCoreSessionManager} managing XR space modes. */ - @Nullable - public XrSceneCoreSessionManager getXrSceneCoreSessionManager() { - return mXrSceneCoreSessionManager; + /** Returns the supplier of the current status of the Full Space mode on XR. */ + public Supplier<Boolean> getXrFullSpaceModeSupplier() { + if (mXrFullSpaceModeSupplier != null) { + return mXrFullSpaceModeSupplier; + } + return () -> false; } }
diff --git a/chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker.cc b/chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker.cc index 45946ae..b8b4d58 100644 --- a/chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker.cc +++ b/chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker.cc
@@ -25,11 +25,16 @@ : touch_ui_controller_(touch_ui_controller) { session_duration_tracker->AddObserver(this); - // If this instance is destroyed, |mode_change_subscription_|'s destructor - // will unregister the callback. Hence Unretained is safe. - mode_change_subscription_ = + // If this instance is destroyed, |touch_mode_change_subscription_|'s + // destructor will unregister the callback. Hence Unretained is safe. + touch_mode_change_subscription_ = touch_ui_controller->RegisterCallback(base::BindRepeating( &TouchModeStatsTracker::TouchModeChanged, base::Unretained(this))); +#if BUILDFLAG(IS_WIN) + tablet_mode_change_subscription_ = + touch_ui_controller->RegisterTabletModeCallback(base::BindRepeating( + &TouchModeStatsTracker::TabletModeChanged, base::Unretained(this))); +#endif // BUILDFLAG(IS_WIN) } TouchModeStatsTracker::~TouchModeStatsTracker() = default; @@ -37,6 +42,10 @@ // static const char TouchModeStatsTracker::kSessionTouchDurationHistogramName[] = "Session.TotalDuration.TouchMode"; +#if BUILDFLAG(IS_WIN) +const char TouchModeStatsTracker::kSessionTabletDurationHistogramName[] = + "Session.TotalDuration.TabletMode"; +#endif // BUILDFLAG(IS_WIN) void TouchModeStatsTracker::TouchModeChanged() { if (session_start_time_.is_null()) @@ -55,10 +64,34 @@ last_touch_mode_switch_in_session_ = switch_time; } +#if BUILDFLAG(IS_WIN) +void TouchModeStatsTracker::TabletModeChanged() { + if (session_start_time_.is_null()) { + return; + } + + auto switch_time = base::TimeTicks::Now(); + DCHECK_GE(switch_time, last_tablet_mode_switch_in_session_); + + // If we changed to desktop mode, we were in tablet mode in the span + // of time from last_tablet_mode_switch_in_session_ to switch_time. + if (!touch_ui_controller_->tablet_mode()) { + tablet_mode_duration_in_session_ += + switch_time - last_tablet_mode_switch_in_session_; + } + + last_tablet_mode_switch_in_session_ = switch_time; +} +#endif // BUILDFLAG(IS_WIN) + void TouchModeStatsTracker::OnSessionStarted(base::TimeTicks session_start) { session_start_time_ = session_start; last_touch_mode_switch_in_session_ = session_start_time_; touch_mode_duration_in_session_ = base::TimeDelta(); +#if BUILDFLAG(IS_WIN) + last_tablet_mode_switch_in_session_ = session_start_time_; + tablet_mode_duration_in_session_ = base::TimeDelta(); +#endif // BUILDFLAG(IS_WIN) } void TouchModeStatsTracker::OnSessionEnded(base::TimeDelta session_length, @@ -76,7 +109,13 @@ touch_mode_duration_in_session_ += session_end - last_touch_mode_switch_in_session_; } - +#if BUILDFLAG(IS_WIN) + if (touch_ui_controller_->tablet_mode() && + session_end >= last_tablet_mode_switch_in_session_) { + tablet_mode_duration_in_session_ += + session_end - last_tablet_mode_switch_in_session_; + } +#endif // BUILDFLAG(IS_WIN) // The samples here correspond 1:1 with Session.TotalDuration, so the // bucketing matches too. base::UmaHistogramLongTimes(kSessionTouchDurationHistogramName, @@ -85,4 +124,10 @@ session_start_time_ = base::TimeTicks(); last_touch_mode_switch_in_session_ = base::TimeTicks(); touch_mode_duration_in_session_ = base::TimeDelta(); +#if BUILDFLAG(IS_WIN) + base::UmaHistogramLongTimes(kSessionTabletDurationHistogramName, + tablet_mode_duration_in_session_); + last_tablet_mode_switch_in_session_ = base::TimeTicks(); + tablet_mode_duration_in_session_ = base::TimeDelta(); +#endif // BUILDFLAG(IS_WIN) }
diff --git a/chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker.h b/chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker.h index a4f0534..abbed4ef 100644 --- a/chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker.h +++ b/chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker.h
@@ -30,9 +30,15 @@ ui::TouchUiController* touch_ui_controller); static const char kSessionTouchDurationHistogramName[]; +#if BUILDFLAG(IS_WIN) + static const char kSessionTabletDurationHistogramName[]; +#endif // BUILDFLAG(IS_WIN) private: void TouchModeChanged(); +#if BUILDFLAG(IS_WIN) + void TabletModeChanged(); +#endif // BUILDFLAG(IS_WIN) // metrics::DesktopSessionDurationTracker::Observer: void OnSessionStarted(base::TimeTicks session_start) override; @@ -41,7 +47,10 @@ const raw_ptr<ui::TouchUiController> touch_ui_controller_; - base::CallbackListSubscription mode_change_subscription_; + base::CallbackListSubscription touch_mode_change_subscription_; +#if BUILDFLAG(IS_WIN) + base::CallbackListSubscription tablet_mode_change_subscription_; +#endif // BUILDFLAG(IS_WIN) // The time passed by OnSessionStarted() if there is an ongoing // session, or 0 otherwise. @@ -55,6 +64,17 @@ // and before the corresponding OnSessionEnded() call. This value is logged // and discarded upon OnSessionEnded(). base::TimeDelta touch_mode_duration_in_session_; + +#if BUILDFLAG(IS_WIN) + // The time when the last posture mode change was detected. + // This is used to calculate the time spent in tablet mode. + base::TimeTicks last_tablet_mode_switch_in_session_; + + // The total time spent in tablet mode since the last OnSessionStarted() call, + // and before the corresponding OnSessionEnded() call. This value is logged + // and discarded upon OnSessionEnded(). + base::TimeDelta tablet_mode_duration_in_session_; +#endif // BUILDFLAG(IS_WIN) }; #endif // CHROME_BROWSER_METRICS_DESKTOP_SESSION_DURATION_TOUCH_MODE_STATS_TRACKER_H_
diff --git a/chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker_unittest.cc b/chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker_unittest.cc index 21f14557..98b37c0 100644 --- a/chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker_unittest.cc +++ b/chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker_unittest.cc
@@ -115,6 +115,9 @@ std::unique_ptr<Browser> browser_; }; +#if BUILDFLAG(IS_WIN) +class DevicePostureModeStatsTrackerTest : public TouchModeStatsTrackerTest {}; +#endif // BUILDFLAG(IS_WIN) // An entire session spent in touch mode should be logged accordingly. TEST_F(TouchModeStatsTrackerTest, TouchSession) { ui::TouchUiController::TouchUiScoperForTesting enable_touch_mode(true); @@ -190,3 +193,103 @@ base::Seconds(30), 1); } } + +#if BUILDFLAG(IS_WIN) +// An entire session spent in tablet mode should be logged accordingly. +TEST_F(DevicePostureModeStatsTrackerTest, TabletSession) { + ui::TouchUiController::TouchUiScoperForTesting enable_tablet_mode( + true, /*tablet_mode_enabled*/ true); + base::HistogramTester histograms; + + StartSession(); + task_environment_.RunUntilIdle(); + // Have to reset the tablet mode again since + // IsDeviceInTabletMode() is called again in StartSession() + // and might override the previous value. + enable_tablet_mode.UpdateTabletMode(true); + task_environment_.FastForwardBy(base::Minutes(1)); + EndSession(); + + histograms.ExpectUniqueTimeSample( + TouchModeStatsTracker::kSessionTabletDurationHistogramName, + base::Minutes(1), 1); +} + +// The tablet duration logged should be 0 for a non-tablet session. +TEST_F(DevicePostureModeStatsTrackerTest, NonTabletSession) { + ui::TouchUiController::TouchUiScoperForTesting disable_tablet_mode( + true, /*tablet_mode_enabled*/ false); + base::HistogramTester histograms; + + StartSession(); + task_environment_.RunUntilIdle(); + // Have to reset the tablet mode again since + // IsDeviceInTabletMode() is called again in StartSession() + // and might override the previous value. + disable_tablet_mode.UpdateTabletMode(false); + task_environment_.FastForwardBy(base::Minutes(1)); + EndSession(); + + histograms.ExpectUniqueTimeSample( + TouchModeStatsTracker::kSessionTabletDurationHistogramName, + base::TimeDelta(), 1); +} + +// If the tablet mode changes during a session, the logged duration +// should comprise the session time spent in tablet mode. +TEST_F(DevicePostureModeStatsTrackerTest, TabletModeChangesDuringSession) { + ui::TouchUiController::TouchUiScoperForTesting posture_mode_override( + true, /*tablet_mode_enabled*/ false); + + // Check starting in tablet mode. + { + base::HistogramTester histograms; + StartSession(); + task_environment_.RunUntilIdle(); + // Have to reset the tablet mode again since + // IsDeviceInTabletMode() is called again in StartSession() + // and might override the previous value. + posture_mode_override.UpdateTabletMode(false); + + task_environment_.FastForwardBy(base::Seconds(15)); + posture_mode_override.UpdateTabletMode(true); // Enter tablet mode + task_environment_.FastForwardBy(base::Seconds(15)); + posture_mode_override.UpdateTabletMode(false); // Exit tablet mode + task_environment_.FastForwardBy(base::Seconds(15)); + posture_mode_override.UpdateTabletMode(true); // Enter tablet mode again + task_environment_.FastForwardBy(base::Seconds(15)); + posture_mode_override.UpdateTabletMode(false); // Exit tablet mode + task_environment_.FastForwardBy(base::Seconds(15)); + + EndSession(); + histograms.ExpectUniqueTimeSample( + TouchModeStatsTracker::kSessionTabletDurationHistogramName, + base::Seconds(30), 1); + } + + posture_mode_override.UpdateTabletMode(true); + task_environment_.FastForwardBy(base::Seconds(15)); + + // Check starting in non-tablet mode. + { + base::HistogramTester histograms; + StartSession(); + task_environment_.RunUntilIdle(); + // Have to reset the tablet mode again since + // IsDeviceInTabletMode() is called again in StartSession() + // and might override the previous value. + posture_mode_override.UpdateTabletMode(true); + + task_environment_.FastForwardBy(base::Seconds(15)); + posture_mode_override.UpdateTabletMode(true); // Enter tablet mode + task_environment_.FastForwardBy(base::Seconds(15)); + posture_mode_override.UpdateTabletMode(false); // Exit tablet mode + task_environment_.FastForwardBy(base::Seconds(15)); + + EndSession(); + histograms.ExpectUniqueTimeSample( + TouchModeStatsTracker::kSessionTabletDurationHistogramName, + base::Seconds(30), 1); + } +} +#endif // BUILDFLAG(IS_WIN)
diff --git a/chrome/browser/payments/payment_request_can_make_payment_browsertest.cc b/chrome/browser/payments/payment_request_can_make_payment_browsertest.cc index 0c5a76d..214148a 100644 --- a/chrome/browser/payments/payment_request_can_make_payment_browsertest.cc +++ b/chrome/browser/payments/payment_request_can_make_payment_browsertest.cc
@@ -159,27 +159,27 @@ NavigateTo("b.com", "/payment_request_can_make_payment_query_test.html"); test_controller()->SetValidSsl(false); - content::EvalJsResult can_make_payment_result = - content::EvalJs(GetActiveWebContents(), - content::JsReplace("checkCanMakePayment($1)", method)); // canMakePayment() will either reject or resolve with "false", depending on // timing of when the browser completes the SSL check and when the website // calls canMakePayment(). // TODO(crbug.com/40858197): More consistent canMakePayment() behavior. - EXPECT_TRUE("a JavaScript error: \"false\"\n" == - can_make_payment_result.error || - false == can_make_payment_result.ExtractBool()); + EXPECT_THAT( + content::EvalJs(GetActiveWebContents(), + content::JsReplace("checkCanMakePayment($1)", method)), + testing::AnyOf( + content::EvalJsResult::ErrorIs("a JavaScript error: \"false\"\n"), + content::EvalJsResult::IsOkAndHolds(false))); - content::EvalJsResult has_enrolled_instrument_result = content::EvalJs( - GetActiveWebContents(), - content::JsReplace("checkHasEnrolledInstrument($1)", method)); // hasEnrolledInstrument() will either reject or resolve with "false", // depending on timing of when the browser completes the SSL check and when // the website calls hasEnrolledInstrument(). // TODO(crbug.com/40858197): More consistent hasEnrolledInstrument() behavior. - EXPECT_TRUE("a JavaScript error: \"false\"\n" == - has_enrolled_instrument_result.error || - false == has_enrolled_instrument_result.ExtractBool()); + EXPECT_THAT(content::EvalJs( + GetActiveWebContents(), + content::JsReplace("checkHasEnrolledInstrument($1)", method)), + testing::AnyOf(content::EvalJsResult::ErrorIs( + "a JavaScript error: \"false\"\n"), + content::EvalJsResult::IsOkAndHolds(false))); EXPECT_EQ("NotSupportedError: Invalid SSL certificate", content::EvalJs(GetActiveWebContents(),
diff --git a/chrome/browser/pdf/pdf_searchify_browsertest.cc b/chrome/browser/pdf/pdf_searchify_browsertest.cc index ca0c939..34bac43d 100644 --- a/chrome/browser/pdf/pdf_searchify_browsertest.cc +++ b/chrome/browser/pdf/pdf_searchify_browsertest.cc
@@ -66,11 +66,11 @@ // As nested feature lists are expected to be reset in the reverse order of // their initialization, the feature list of `PDFExtensionTestBase` is reset // here. - PDFExtensionTestBase::ResetFeatureList(); + ResetFeatureList(); InteractiveFeaturePromoTestT::TearDown(); } - // PDFExtensionTestBase: + // InteractiveFeaturePromoTestT: void TearDownOnMainThread() override { component_download_observer_.Reset(); InteractiveFeaturePromoTestT::TearDownOnMainThread();
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.cc b/chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.cc index dab07d6..1276886b 100644 --- a/chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.cc +++ b/chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.cc
@@ -214,6 +214,11 @@ UpdateObserverStateForWidget(observed_widget, /*force_update=*/true); } +void PictureInPictureOcclusionTracker:: + FireBoundsChangedThrottleTimerForTesting() { + bounds_changed_throttle_timer_.FireNow(); +} + void PictureInPictureOcclusionTracker::ObserveWidgetAndParents( views::Widget* widget, bool directly_observe_this_widget) {
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.h b/chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.h index 25a30df..11220d8 100644 --- a/chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.h +++ b/chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.h
@@ -115,6 +115,8 @@ void SetWidgetOcclusionStateForTesting(views::Widget* observed_widget, bool occluded); + void FireBoundsChangedThrottleTimerForTesting(); + private: struct ObservedWidgetData { // True if the widget associated with this observation is a
diff --git a/chrome/browser/predictors/loading_predictor_browsertest.cc b/chrome/browser/predictors/loading_predictor_browsertest.cc index a58508e8..93a7f8c4 100644 --- a/chrome/browser/predictors/loading_predictor_browsertest.cc +++ b/chrome/browser/predictors/loading_predictor_browsertest.cc
@@ -61,6 +61,7 @@ #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/common/content_features.h" #include "content/public/common/referrer.h" #include "content/public/test/back_forward_cache_util.h" #include "content/public/test/browser_test.h"
diff --git a/chrome/browser/predictors/preconnect_manager_impl.cc b/chrome/browser/predictors/preconnect_manager_impl.cc index 2dd50c6..1b606c60 100644 --- a/chrome/browser/predictors/preconnect_manager_impl.cc +++ b/chrome/browser/predictors/preconnect_manager_impl.cc
@@ -12,12 +12,12 @@ #include "base/metrics/histogram_macros.h" #include "base/trace_event/trace_event.h" #include "base/types/optional_util.h" -#include "chrome/browser/predictors/predictors_features.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/preconnect_request.h" #include "content/public/browser/storage_partition.h" +#include "content/public/common/content_features.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "services/network/public/mojom/connection_change_observer_client.mojom.h" #include "services/network/public/mojom/network_context.mojom.h"
diff --git a/chrome/browser/predictors/preconnect_manager_impl_unittest.cc b/chrome/browser/predictors/preconnect_manager_impl_unittest.cc index 48918e9d0..50cfd10 100644 --- a/chrome/browser/predictors/preconnect_manager_impl_unittest.cc +++ b/chrome/browser/predictors/preconnect_manager_impl_unittest.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/preloading/preloading_prefs.h" #include "chrome/test/base/testing_profile.h" #include "content/public/browser/preconnect_request.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_task_environment.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h"
diff --git a/chrome/browser/predictors/predictors_features.cc b/chrome/browser/predictors/predictors_features.cc index 914abba..9336a531 100644 --- a/chrome/browser/predictors/predictors_features.cc +++ b/chrome/browser/predictors/predictors_features.cc
@@ -95,12 +95,6 @@ false); } -// If this is enabled, LoadingPredictor restricts the number of preconnects for -// the same destination to one. -BASE_FEATURE(kLoadingPredictorLimitPreconnectSocketCount, - "LoadingPredictorLimitPreconnectSocketCount", - base::FEATURE_DISABLED_BY_DEFAULT); - BASE_FEATURE(kPrefetchManagerUseNetworkContextPrefetch, "PrefetchManagerUseNetworkContextPrefetch", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/chrome/browser/predictors/predictors_features.h b/chrome/browser/predictors/predictors_features.h index 922b1159..dd0f2f1 100644 --- a/chrome/browser/predictors/predictors_features.h +++ b/chrome/browser/predictors/predictors_features.h
@@ -50,8 +50,6 @@ // even if local predictions are available for preconnect predictions. bool ShouldAlwaysRetrieveOptimizationGuidePredictions(); -BASE_DECLARE_FEATURE(kLoadingPredictorLimitPreconnectSocketCount); - BASE_DECLARE_FEATURE(kPrefetchManagerUseNetworkContextPrefetch); } // namespace features
diff --git a/chrome/browser/private_network_access/COMMON_METADATA b/chrome/browser/private_network_access/COMMON_METADATA index c54b42b..88bb7de 100644 --- a/chrome/browser/private_network_access/COMMON_METADATA +++ b/chrome/browser/private_network_access/COMMON_METADATA
@@ -1,7 +1,7 @@ monorail: { component: "Blink>SecurityFeature>CORS>PrivateNetworkAccess" } -team_email: "chrome-security-owp@chromium.org" +team_email: "chrome-secure-web-and-net@chromium.org" buganizer_public: { component_id: 1456363 }
diff --git a/chrome/browser/private_network_access/chrome_private_network_device_chooser.cc b/chrome/browser/private_network_access/chrome_private_network_device_chooser.cc deleted file mode 100644 index 9be3d19..0000000 --- a/chrome/browser/private_network_access/chrome_private_network_device_chooser.cc +++ /dev/null
@@ -1,10 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/private_network_access/chrome_private_network_device_chooser.h" - -ChromePrivateNetworkDeviceChooser::ChromePrivateNetworkDeviceChooser() = - default; -ChromePrivateNetworkDeviceChooser::~ChromePrivateNetworkDeviceChooser() = - default;
diff --git a/chrome/browser/private_network_access/chrome_private_network_device_chooser.h b/chrome/browser/private_network_access/chrome_private_network_device_chooser.h deleted file mode 100644 index 96992fab..0000000 --- a/chrome/browser/private_network_access/chrome_private_network_device_chooser.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_CHROME_PRIVATE_NETWORK_DEVICE_CHOOSER_H_ -#define CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_CHROME_PRIVATE_NETWORK_DEVICE_CHOOSER_H_ - -#include <memory> - -namespace content { -class RenderFrameHost; -} // namespace content - -class PrivateNetworkDeviceChooserController; - -// Token representing a private network device chooser prompt. Destroying this -// object should cancel the prompt. -class ChromePrivateNetworkDeviceChooser { - public: - ChromePrivateNetworkDeviceChooser(const ChromePrivateNetworkDeviceChooser&) = - delete; - ChromePrivateNetworkDeviceChooser& operator=( - const ChromePrivateNetworkDeviceChooser&) = delete; - virtual ~ChromePrivateNetworkDeviceChooser(); - - protected: - ChromePrivateNetworkDeviceChooser(); - - virtual void ShowChooser( - content::RenderFrameHost* render_frame_host, - std::unique_ptr<PrivateNetworkDeviceChooserController> controller) = 0; -}; - -#endif // CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_CHROME_PRIVATE_NETWORK_DEVICE_CHOOSER_H_
diff --git a/chrome/browser/private_network_access/chrome_private_network_device_chooser_desktop.cc b/chrome/browser/private_network_access/chrome_private_network_device_chooser_desktop.cc deleted file mode 100644 index 2c7fe4ac..0000000 --- a/chrome/browser/private_network_access/chrome_private_network_device_chooser_desktop.cc +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/private_network_access/chrome_private_network_device_chooser_desktop.h" - -#include <utility> - -#include "build/build_config.h" -#include "chrome/browser/private_network_access/private_network_device_chooser_controller.h" -#include "chrome/browser/ui/browser_dialogs.h" -#include "content/public/browser/render_frame_host.h" - -ChromePrivateNetworkDeviceChooserDesktop:: - ChromePrivateNetworkDeviceChooserDesktop() = default; - -ChromePrivateNetworkDeviceChooserDesktop:: - ~ChromePrivateNetworkDeviceChooserDesktop() = default; - -std::unique_ptr<ChromePrivateNetworkDeviceChooserDesktop> -ChromePrivateNetworkDeviceChooserDesktop::Create( - content::RenderFrameHost* render_frame_host, - std::unique_ptr<PrivateNetworkDeviceChooserController> controller) { - std::unique_ptr<ChromePrivateNetworkDeviceChooserDesktop> chooser; - chooser = std::make_unique<ChromePrivateNetworkDeviceChooserDesktop>(); - chooser->ShowChooser(render_frame_host, std::move(controller)); - return chooser; -} - -void ChromePrivateNetworkDeviceChooserDesktop::ShowChooser( - content::RenderFrameHost* render_frame_host, - std::unique_ptr<PrivateNetworkDeviceChooserController> controller) { - DCHECK(render_frame_host); - closure_runner_.ReplaceClosure(chrome::ShowDeviceChooserDialog( - render_frame_host, std::move(controller))); -}
diff --git a/chrome/browser/private_network_access/chrome_private_network_device_chooser_desktop.h b/chrome/browser/private_network_access/chrome_private_network_device_chooser_desktop.h deleted file mode 100644 index 2fea0d8..0000000 --- a/chrome/browser/private_network_access/chrome_private_network_device_chooser_desktop.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_CHROME_PRIVATE_NETWORK_DEVICE_CHOOSER_DESKTOP_H_ -#define CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_CHROME_PRIVATE_NETWORK_DEVICE_CHOOSER_DESKTOP_H_ - -#include <memory> -#include <string> - -#include "base/functional/callback.h" -#include "base/functional/callback_helpers.h" -#include "chrome/browser/private_network_access/chrome_private_network_device_chooser.h" - -namespace content { -class RenderFrameHost; -} - -class PrivateNetworkDeviceChooserController; - -// ChromePrivateNetworkDeviceChooserDesktop is a permission chooser prompt for -// desktop devices. Permission chooser prompt for private network access only -// shows up after pricate network access preflight response and have one device -// to show at a time. -class ChromePrivateNetworkDeviceChooserDesktop - : public ChromePrivateNetworkDeviceChooser { - public: - ChromePrivateNetworkDeviceChooserDesktop(); - ~ChromePrivateNetworkDeviceChooserDesktop() override; - - static std::unique_ptr<ChromePrivateNetworkDeviceChooserDesktop> Create( - content::RenderFrameHost* render_frame_host, - std::unique_ptr<PrivateNetworkDeviceChooserController> controller); - - void ShowChooser(content::RenderFrameHost* render_frame_host, - std::unique_ptr<PrivateNetworkDeviceChooserController> - controller) override; - - private: - base::ScopedClosureRunner closure_runner_; -}; - -#endif // CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_CHROME_PRIVATE_NETWORK_DEVICE_CHOOSER_DESKTOP_H_
diff --git a/chrome/browser/private_network_access/chrome_private_network_device_delegate.cc b/chrome/browser/private_network_access/chrome_private_network_device_delegate.cc deleted file mode 100644 index ce50a19..0000000 --- a/chrome/browser/private_network_access/chrome_private_network_device_delegate.cc +++ /dev/null
@@ -1,133 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/private_network_access/chrome_private_network_device_delegate.h" - -#include "base/metrics/histogram_functions.h" -#include "base/observer_list.h" -#include "base/observer_list_types.h" -#include "base/scoped_observation.h" -#include "chrome/browser/private_network_access/chrome_private_network_device_chooser_desktop.h" -#include "chrome/browser/private_network_access/private_network_device_chooser_controller.h" -#include "chrome/browser/private_network_access/private_network_device_permission_context.h" -#include "chrome/browser/private_network_access/private_network_device_permission_context_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/console_message.h" -#include "content/public/browser/render_frame_host.h" -#include "services/network/public/mojom/url_loader_network_service_observer.mojom.h" -#include "third_party/re2/src/re2/re2.h" - -ChromePrivateNetworkDeviceDelegate::ChromePrivateNetworkDeviceDelegate() = - default; -ChromePrivateNetworkDeviceDelegate::~ChromePrivateNetworkDeviceDelegate() = - default; - -void ChromePrivateNetworkDeviceDelegate::RequestPermission( - content::RenderFrameHost& frame, - blink::mojom::PrivateNetworkDevicePtr device, - network::mojom::URLLoaderNetworkServiceObserver:: - OnPrivateNetworkAccessPermissionRequiredCallback callback) { - bool is_device_valid = CheckDevice(*device, frame); - if (HasDevicePermission(frame, *device, is_device_valid)) { - std::move(callback).Run(true); - return; - } - chooser_ = RunChooser(frame, std::move(device), std::move(callback), - is_device_valid); -} - -bool ChromePrivateNetworkDeviceDelegate::CheckDevice( - const blink::mojom::PrivateNetworkDevice& device, - content::RenderFrameHost& frame) { - // Check if `Private-Network-Access-ID` is missing. - if (!device.id.has_value()) { - base::UmaHistogramEnumeration( - kPrivateNetworkDeviceValidityHistogramName, - PrivateNetworkDeviceValidity::kDeviceIDMissing); - frame.AddMessageToConsole(blink::mojom::ConsoleMessageLevel::kWarning, - "`Private-Network-Access-ID` is missing."); - return false; - } - - // Check if `Private-Network-Access-Name` is valid. - const re2::RE2 pattern("^[a-zA-Z0-9_\\-.]+$"); - if (!device.name.has_value() || device.name.value().length() > 248 || - !re2::RE2::FullMatch(device.name.value(), pattern)) { - base::UmaHistogramEnumeration( - kPrivateNetworkDeviceValidityHistogramName, - device.name.has_value() - ? PrivateNetworkDeviceValidity::kDeviceNameInvalid - : PrivateNetworkDeviceValidity::kDeviceNameMissing); - frame.AddMessageToConsole(blink::mojom::ConsoleMessageLevel::kWarning, - "`Private-Network-Access-Name` is invalid. " - "A valid name is a string that matches the " - "[ECMAScript] regexp /^[a-z0-9_-.]+$/. " - "The maximum number of UTF-8 code units in a " - "Private Network Device name is 248."); - return false; - } - - return true; -} - -bool ChromePrivateNetworkDeviceDelegate::HasDevicePermission( - content::RenderFrameHost& frame, - const blink::mojom::PrivateNetworkDevice& device, - bool is_device_valid) { - PrivateNetworkDevicePermissionContext* context = - GetPermissionContext(frame.GetBrowserContext()); - return context && context->HasDevicePermission(frame.GetLastCommittedOrigin(), - device, is_device_valid); -} - -std::unique_ptr<ChromePrivateNetworkDeviceChooser> -ChromePrivateNetworkDeviceDelegate::RunChooser( - content::RenderFrameHost& frame, - blink::mojom::PrivateNetworkDevicePtr device, - network::mojom::URLLoaderNetworkServiceObserver:: - OnPrivateNetworkAccessPermissionRequiredCallback callback, - bool is_device_valid) { -#if BUILDFLAG(IS_ANDROID) - std::move(callback).Run(false); - return nullptr; -#else - auto controller = std::make_unique<PrivateNetworkDeviceChooserController>( - &frame, std::move(device), - base::BindOnce(&ChromePrivateNetworkDeviceDelegate:: - HandlePrivateNetworkDeviceChooserResult, - base::Unretained(this), is_device_valid, - std::move(callback))); - return ChromePrivateNetworkDeviceChooserDesktop::Create( - &frame, std::move(controller)); -#endif // BUILDFLAG(IS_ANDROID) -} - -PrivateNetworkDevicePermissionContext* -ChromePrivateNetworkDeviceDelegate::GetPermissionContext( - content::BrowserContext* browser_context) { - if (!browser_context) { - return nullptr; - } - auto* profile = Profile::FromBrowserContext(browser_context); - return profile ? PrivateNetworkDevicePermissionContextFactory::GetForProfile( - profile) - : nullptr; -} - -void ChromePrivateNetworkDeviceDelegate:: - HandlePrivateNetworkDeviceChooserResult( - bool is_device_valid, - network::mojom::URLLoaderNetworkServiceObserver:: - OnPrivateNetworkAccessPermissionRequiredCallback callback, - PrivateNetworkDevicePermissionContext* permission_context, - const url::Origin& origin, - const blink::mojom::PrivateNetworkDevice& device, - bool permission_granted) { - chooser_ = nullptr; - if (permission_granted && permission_context) { - permission_context->GrantDevicePermission(origin, device, is_device_valid); - } - std::move(callback).Run(permission_granted); -}
diff --git a/chrome/browser/private_network_access/chrome_private_network_device_delegate.h b/chrome/browser/private_network_access/chrome_private_network_device_delegate.h deleted file mode 100644 index ac06166c..0000000 --- a/chrome/browser/private_network_access/chrome_private_network_device_delegate.h +++ /dev/null
@@ -1,85 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_CHROME_PRIVATE_NETWORK_DEVICE_DELEGATE_H_ -#define CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_CHROME_PRIVATE_NETWORK_DEVICE_DELEGATE_H_ - -#include "base/containers/contains.h" -#include "base/observer_list.h" -#include "base/observer_list_types.h" -#include "base/scoped_observation.h" -#include "chrome/browser/private_network_access/chrome_private_network_device_chooser.h" -#include "content/public/browser/private_network_device_delegate.h" -#include "mojo/public/cpp/bindings/pending_receiver.h" -#include "mojo/public/cpp/bindings/pending_remote.h" -#include "services/network/public/mojom/url_loader_network_service_observer.mojom.h" -#include "third_party/blink/public/mojom/private_network_device/private_network_device.mojom.h" - -namespace content { -class BrowserContext; -class RenderFrameHost; -} // namespace content - -class PrivateNetworkDevicePermissionContext; - -// Interface to support Private Network permission APIs. -class ChromePrivateNetworkDeviceDelegate - : public content::PrivateNetworkDeviceDelegate { - public: - ChromePrivateNetworkDeviceDelegate(); - ChromePrivateNetworkDeviceDelegate(ChromePrivateNetworkDeviceDelegate&) = - delete; - ChromePrivateNetworkDeviceDelegate(ChromePrivateNetworkDeviceDelegate&&) = - delete; - ChromePrivateNetworkDeviceDelegate& operator=( - ChromePrivateNetworkDeviceDelegate&) = delete; - ChromePrivateNetworkDeviceDelegate& operator=( - ChromePrivateNetworkDeviceDelegate&&) = delete; - ~ChromePrivateNetworkDeviceDelegate() override; - - // Request permission for Private Network Device. - // |callback| will be run when the prompt is closed. - void RequestPermission( - content::RenderFrameHost& frame, - blink::mojom::PrivateNetworkDevicePtr device, - network::mojom::URLLoaderNetworkServiceObserver:: - OnPrivateNetworkAccessPermissionRequiredCallback callback) override; - - bool HasDevicePermission(content::RenderFrameHost& frame, - const blink::mojom::PrivateNetworkDevice& device, - bool is_device_valid); - - std::unique_ptr<ChromePrivateNetworkDeviceChooser> RunChooser( - content::RenderFrameHost& frame, - blink::mojom::PrivateNetworkDevicePtr device, - network::mojom::URLLoaderNetworkServiceObserver:: - OnPrivateNetworkAccessPermissionRequiredCallback callback, - bool is_device_valid); - - void HandlePrivateNetworkDeviceChooserResult( - bool is_device_valid, - network::mojom::URLLoaderNetworkServiceObserver:: - OnPrivateNetworkAccessPermissionRequiredCallback callback, - PrivateNetworkDevicePermissionContext* permission_context, - const url::Origin& origin, - const blink::mojom::PrivateNetworkDevice& device, - bool permission_granted); - - static bool CheckDevice(const blink::mojom::PrivateNetworkDevice& device, - content::RenderFrameHost& frame); - - private: - PrivateNetworkDevicePermissionContext* GetPermissionContext( - content::BrowserContext* browser_context); - - // The currently-displayed private network device chooser prompt, if any. - // - // If a new permission request comes while a chooser was already being - // displayed, the old one is canceled when we reassign this field. - // TODO(crbug.com/40272624): Handle multiple permission checks - // better, perhaps by serializing them. - std::unique_ptr<ChromePrivateNetworkDeviceChooser> chooser_; -}; - -#endif // CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_CHROME_PRIVATE_NETWORK_DEVICE_DELEGATE_H_
diff --git a/chrome/browser/private_network_access/private_network_device_browser_test_utils.cc b/chrome/browser/private_network_access/private_network_device_browser_test_utils.cc deleted file mode 100644 index fda954a..0000000 --- a/chrome/browser/private_network_access/private_network_device_browser_test_utils.cc +++ /dev/null
@@ -1,115 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/private_network_access/private_network_device_browser_test_utils.h" - -#include "chrome/browser/private_network_access/chrome_private_network_device_chooser.h" -#include "chrome/browser/private_network_access/private_network_device_chooser_controller.h" -#include "components/permissions/chooser_controller.h" -#include "content/public/common/content_client.h" - -class FakeChooserView : public permissions::ChooserController::View { - public: - explicit FakeChooserView( - std::unique_ptr<permissions::ChooserController> controller) - : controller_(std::move(controller)) { - controller_->set_view(this); - } - - FakeChooserView(const FakeChooserView&) = delete; - FakeChooserView& operator=(const FakeChooserView&) = delete; - - ~FakeChooserView() override { controller_->set_view(nullptr); } - - void OnOptionsInitialized() override { - if (controller_->NumOptions()) { - controller_->Select({0}); - } else { - controller_->Cancel(); - } - delete this; - } - - void OnOptionAdded(size_t index) override { NOTREACHED(); } - void OnOptionRemoved(size_t index) override { NOTREACHED(); } - void OnOptionUpdated(size_t index) override { NOTREACHED(); } - void OnAdapterEnabledChanged(bool enabled) override { NOTREACHED(); } - void OnRefreshStateChanged(bool refreshing) override { NOTREACHED(); } - - private: - std::unique_ptr<permissions::ChooserController> controller_; -}; - -class FakePNAChooser : public ChromePrivateNetworkDeviceChooser { - public: - FakePNAChooser() = default; - FakePNAChooser(const FakePNAChooser&) = delete; - FakePNAChooser& operator=(const FakePNAChooser&) = delete; - ~FakePNAChooser() override = default; - - void ShowChooser(content::RenderFrameHost* frame, - std::unique_ptr<PrivateNetworkDeviceChooserController> - controller) override { - // Device list initialization in PrivateNetworkDeviceChooserController may - // complete before having a valid view in which case OnOptionsInitialized() - // has no chance to be triggered, so select the first option directly if - // options are ready. - if (controller->NumOptions()) { - controller->Select({0}); - } else { - new FakeChooserView(std::move(controller)); - } - } -}; - -TestPNADelegate::TestPNADelegate() = default; -TestPNADelegate::~TestPNADelegate() = default; - -void TestPNADelegate::RequestPermission( - content::RenderFrameHost& frame, - blink::mojom::PrivateNetworkDevicePtr device, - network::mojom::URLLoaderNetworkServiceObserver:: - OnPrivateNetworkAccessPermissionRequiredCallback callback) { - bool is_device_valid = CheckDevice(*device, frame); - if (HasDevicePermission(frame, *device, is_device_valid)) { - std::move(callback).Run(true); - return; - } - RunChooser(frame, std::move(device), std::move(callback), is_device_valid); -} - -std::unique_ptr<ChromePrivateNetworkDeviceChooser> TestPNADelegate::RunChooser( - content::RenderFrameHost& frame, - blink::mojom::PrivateNetworkDevicePtr device, - network::mojom::URLLoaderNetworkServiceObserver:: - OnPrivateNetworkAccessPermissionRequiredCallback callback, - bool is_device_valid) { - auto chooser = std::make_unique<FakePNAChooser>(); - chooser->ShowChooser( - &frame, std::make_unique<PrivateNetworkDeviceChooserController>( - &frame, std::move(device), - base::BindOnce(&ChromePrivateNetworkDeviceDelegate:: - HandlePrivateNetworkDeviceChooserResult, - base::Unretained(this), is_device_valid, - std::move(callback)))); - return chooser; -} - -TestPNAContentBrowserClient::TestPNAContentBrowserClient() - : pna_delegate_(std::make_unique<TestPNADelegate>()) {} -TestPNAContentBrowserClient::~TestPNAContentBrowserClient() = default; - -ChromePrivateNetworkDeviceDelegate* -TestPNAContentBrowserClient::GetPrivateNetworkDeviceDelegate() { - return pna_delegate_.get(); -} - -void TestPNAContentBrowserClient::SetAsBrowserClient() { - original_content_browser_client_ = content::SetBrowserClientForTesting(this); -} - -void TestPNAContentBrowserClient::UnsetAsBrowserClient() { - content::SetBrowserClientForTesting(original_content_browser_client_); - pna_delegate_.reset(); -}
diff --git a/chrome/browser/private_network_access/private_network_device_browser_test_utils.h b/chrome/browser/private_network_access/private_network_device_browser_test_utils.h deleted file mode 100644 index edcdcd0..0000000 --- a/chrome/browser/private_network_access/private_network_device_browser_test_utils.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_PRIVATE_NETWORK_DEVICE_BROWSER_TEST_UTILS_H_ -#define CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_PRIVATE_NETWORK_DEVICE_BROWSER_TEST_UTILS_H_ - -#include <memory> - -#include "base/memory/raw_ptr.h" -#include "chrome/browser/chrome_content_browser_client.h" -#include "chrome/browser/private_network_access/chrome_private_network_device_delegate.h" - -class TestPNADelegate : public ChromePrivateNetworkDeviceDelegate { - public: - TestPNADelegate(); - TestPNADelegate(const TestPNADelegate&) = delete; - TestPNADelegate& operator=(const TestPNADelegate&) = delete; - ~TestPNADelegate() override; - - void RequestPermission( - content::RenderFrameHost& frame, - blink::mojom::PrivateNetworkDevicePtr device, - network::mojom::URLLoaderNetworkServiceObserver:: - OnPrivateNetworkAccessPermissionRequiredCallback callback) override; - - std::unique_ptr<ChromePrivateNetworkDeviceChooser> RunChooser( - content::RenderFrameHost& frame, - blink::mojom::PrivateNetworkDevicePtr device, - network::mojom::URLLoaderNetworkServiceObserver:: - OnPrivateNetworkAccessPermissionRequiredCallback callback, - bool is_device_valid); -}; - -class TestPNAContentBrowserClient : public ChromeContentBrowserClient { - public: - TestPNAContentBrowserClient(); - TestPNAContentBrowserClient(const TestPNAContentBrowserClient&) = delete; - TestPNAContentBrowserClient& operator=(const TestPNAContentBrowserClient&) = - delete; - ~TestPNAContentBrowserClient() override; - - // ChromeContentBrowserClient: - ChromePrivateNetworkDeviceDelegate* GetPrivateNetworkDeviceDelegate() - override; - - TestPNADelegate& delegate() { return *pna_delegate_; } - - void SetAsBrowserClient(); - void UnsetAsBrowserClient(); - - private: - std::unique_ptr<TestPNADelegate> pna_delegate_; - raw_ptr<content::ContentBrowserClient> original_content_browser_client_; -}; - -#endif // CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_PRIVATE_NETWORK_DEVICE_BROWSER_TEST_UTILS_H_
diff --git a/chrome/browser/private_network_access/private_network_device_chooser_controller.cc b/chrome/browser/private_network_access/private_network_device_chooser_controller.cc deleted file mode 100644 index 1375e32..0000000 --- a/chrome/browser/private_network_access/private_network_device_chooser_controller.cc +++ /dev/null
@@ -1,129 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/private_network_access/private_network_device_chooser_controller.h" - -#include <stddef.h> -#include <utility> - -#include "base/functional/bind.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "chrome/browser/chooser_controller/title_util.h" -#include "chrome/browser/net/referrer.h" -#include "chrome/browser/private_network_access/private_network_device_permission_context.h" -#include "chrome/browser/private_network_access/private_network_device_permission_context_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/global_routing_id.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/web_contents.h" -#include "services/network/public/mojom/url_loader_network_service_observer.mojom.h" -#include "ui/base/l10n/l10n_util.h" -#include "url/gurl.h" - -using content::RenderFrameHost; -using content::WebContents; - -PrivateNetworkDeviceChooserController::PrivateNetworkDeviceChooserController( - content::RenderFrameHost* render_frame_host, - blink::mojom::PrivateNetworkDevicePtr device, - DoneCallback callback) - : ChooserController( - CreateChooserTitle(render_frame_host, - IDS_PRIVATE_NETWORK_DEVICE_CHOOSER_PROMPT_ORIGIN)), - device_(std::move(device)), - callback_(std::move(callback)) { - RenderFrameHost* main_frame = render_frame_host->GetMainFrame(); - origin_ = main_frame->GetLastCommittedOrigin(); - Profile* profile = - Profile::FromBrowserContext(main_frame->GetBrowserContext()); - permission_context_ = - PrivateNetworkDevicePermissionContextFactory::GetForProfile(profile) - ->AsWeakPtr(); - DCHECK(permission_context_); -} - -PrivateNetworkDeviceChooserController:: - ~PrivateNetworkDeviceChooserController() { - if (callback_.is_null()) { - return; - } - RunCallback(false); -} - -std::u16string PrivateNetworkDeviceChooserController::GetOkButtonLabel() const { - return l10n_util::GetStringUTF16( - IDS_PRIVATE_NETWORK_DEVICE_CHOOSER_CONNECT_BUTTON_TEXT); -} - -std::u16string PrivateNetworkDeviceChooserController::GetNoOptionsText() const { - return l10n_util::GetStringUTF16(IDS_DEVICE_CHOOSER_NO_DEVICES_FOUND_PROMPT); -} - -std::pair<std::u16string, std::u16string> -PrivateNetworkDeviceChooserController::GetThrobberLabelAndTooltip() const { - return { - l10n_util::GetStringUTF16(IDS_DEVICE_PERMISSIONS_DIALOG_LOADING_LABEL), - l10n_util::GetStringUTF16( - IDS_DEVICE_PERMISSIONS_DIALOG_LOADING_LABEL_TOOLTIP)}; -} -size_t PrivateNetworkDeviceChooserController::NumOptions() const { - return device_ ? 1 : 0; -} - -std::u16string PrivateNetworkDeviceChooserController::GetOption( - size_t index) const { - // PNA permission prompt only allows one device at once. - DCHECK(index == 0); - if (device_->name.has_value() && device_->id.has_value()) { - return l10n_util::GetStringFUTF16(IDS_DEVICE_CHOOSER_DEVICE_NAME_WITH_ID, - base::UTF8ToUTF16(device_->name.value()), - base::UTF8ToUTF16(device_->id.value())); - } else if (device_->name.has_value()) { - return l10n_util::GetStringFUTF16( - IDS_DEVICE_CHOOSER_DEVICE_NAME_WITH_ID, - base::UTF8ToUTF16(device_->name.value()), - base::UTF8ToUTF16(net::IPAddress(device_->ip_address).ToString())); - } else if (device_->id.has_value()) { - return l10n_util::GetStringFUTF16( - IDS_DEVICE_CHOOSER_DEVICE_NAME_WITH_ID, - base::UTF8ToUTF16(device_->id.value()), - base::UTF8ToUTF16(net::IPAddress(device_->ip_address).ToString())); - } else { - return base::UTF8ToUTF16(net::IPAddress(device_->ip_address).ToString()); - } -} - -void PrivateNetworkDeviceChooserController::Select( - const std::vector<size_t>& indices) { - RunCallback(true); -} - -void PrivateNetworkDeviceChooserController::ReplaceDeviceForTesting( - blink::mojom::PrivateNetworkDevicePtr device) { - device_ = std::move(device); - if (view()) { - view()->OnOptionAdded(0); - } -} - -void PrivateNetworkDeviceChooserController::OpenHelpCenterUrl() const {} - -void PrivateNetworkDeviceChooserController::Cancel() { - RunCallback(false); -} - -void PrivateNetworkDeviceChooserController::Close() { - RunCallback(false); -} - -void PrivateNetworkDeviceChooserController::RunCallback( - bool permission_granted) { - std::move(callback_).Run(permission_context_.get(), origin_, *device_, - permission_granted); -}
diff --git a/chrome/browser/private_network_access/private_network_device_chooser_controller.h b/chrome/browser/private_network_access/private_network_device_chooser_controller.h deleted file mode 100644 index 348c216..0000000 --- a/chrome/browser/private_network_access/private_network_device_chooser_controller.h +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_PRIVATE_NETWORK_DEVICE_CHOOSER_CONTROLLER_H_ -#define CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_PRIVATE_NETWORK_DEVICE_CHOOSER_CONTROLLER_H_ - -#include <string> -#include <unordered_map> -#include <utility> -#include <vector> - -#include "base/memory/raw_ptr.h" -#include "base/memory/raw_ref.h" -#include "base/memory/weak_ptr.h" -#include "base/scoped_observation.h" -#include "components/permissions/chooser_controller.h" -#include "services/network/public/mojom/url_loader_network_service_observer.mojom.h" -#include "third_party/blink/public/mojom/private_network_device/private_network_device.mojom.h" -#include "url/origin.h" - -namespace content { -class RenderFrameHost; -} - -class PrivateNetworkDevicePermissionContext; - -// PrivateNetworkDeviceChooserController creates a chooser for Private Network -// Device. -class PrivateNetworkDeviceChooserController - : public permissions::ChooserController { - public: - using DoneCallback = base::OnceCallback<void( - PrivateNetworkDevicePermissionContext* permission_context, - const url::Origin&, - const blink::mojom::PrivateNetworkDevice&, - bool)>; - PrivateNetworkDeviceChooserController( - content::RenderFrameHost* render_frame_host, - blink::mojom::PrivateNetworkDevicePtr device, - DoneCallback callback); - - PrivateNetworkDeviceChooserController( - const PrivateNetworkDeviceChooserController&) = delete; - PrivateNetworkDeviceChooserController& operator=( - const PrivateNetworkDeviceChooserController&) = delete; - - ~PrivateNetworkDeviceChooserController() override; - - // Permission::ChooserController: - std::u16string GetOkButtonLabel() const override; - std::u16string GetNoOptionsText() const override; - std::pair<std::u16string, std::u16string> GetThrobberLabelAndTooltip() - const override; - size_t NumOptions() const override; - std::u16string GetOption(size_t index) const override; - void Select(const std::vector<size_t>& indices) override; - void OpenHelpCenterUrl() const override; - void Cancel() override; - void Close() override; - - void ReplaceDeviceForTesting(blink::mojom::PrivateNetworkDevicePtr device); - void RunCallback(bool permission_granted); - - private: - bool DisplayDevice(const blink::mojom::PrivateNetworkDevice& device) const; - - url::Origin origin_; - - base::WeakPtr<PrivateNetworkDevicePermissionContext> permission_context_; - blink::mojom::PrivateNetworkDevicePtr device_; - DoneCallback callback_; - - base::WeakPtrFactory<PrivateNetworkDeviceChooserController> weak_factory_{ - this}; -}; - -#endif // CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_PRIVATE_NETWORK_DEVICE_CHOOSER_CONTROLLER_H_
diff --git a/chrome/browser/private_network_access/private_network_device_chooser_controller_unittest.cc b/chrome/browser/private_network_access/private_network_device_chooser_controller_unittest.cc deleted file mode 100644 index b9632f9..0000000 --- a/chrome/browser/private_network_access/private_network_device_chooser_controller_unittest.cc +++ /dev/null
@@ -1,97 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <memory> -#include <string> -#include <utility> - -#include "base/memory/ref_counted.h" -#include "base/run_loop.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/private_network_access/private_network_device_chooser_controller.h" -#include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "chrome/test/base/testing_profile.h" -#include "components/permissions/mock_chooser_controller_view.h" -#include "content/public/test/web_contents_tester.h" -#include "net/base/ip_address.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/mojom/private_network_device/private_network_device.mojom.h" -#include "url/gurl.h" - -using testing::NiceMock; - -namespace { -const char kDefaultTestUrl[] = "https://www.google.com/"; -} // namespace - -class PrivateNetworkDeviceChooserControllerTest - : public ChromeRenderViewHostTestHarness { - public: - PrivateNetworkDeviceChooserControllerTest() = default; - PrivateNetworkDeviceChooserControllerTest( - const PrivateNetworkDeviceChooserControllerTest&) = delete; - PrivateNetworkDeviceChooserControllerTest& operator=( - const PrivateNetworkDeviceChooserControllerTest&) = delete; - - void SetUp() override { - ChromeRenderViewHostTestHarness::SetUp(); - - content::WebContentsTester* web_contents_tester = - content::WebContentsTester::For(web_contents()); - web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); - - private_network_device_chooser_controller_ = - std::make_unique<PrivateNetworkDeviceChooserController>( - main_rfh(), blink::mojom::PrivateNetworkDevice::New(), - PrivateNetworkDeviceChooserController::DoneCallback()); - mock_chooser_view_ = - std::make_unique<NiceMock<permissions::MockChooserControllerView>>(); - private_network_device_chooser_controller_->set_view( - mock_chooser_view_.get()); - base::RunLoop().RunUntilIdle(); - } - - protected: - void CreateAndAddFakePrivateNetworkDevice(const std::string& id, - const std::string& name, - const net::IPAddress& ip_address) { - private_network_device_chooser_controller_->ReplaceDeviceForTesting( - blink::mojom::PrivateNetworkDevice::New(id, name, ip_address)); - } - - std::unique_ptr<PrivateNetworkDeviceChooserController> - private_network_device_chooser_controller_; - std::unique_ptr<permissions::MockChooserControllerView> mock_chooser_view_; -}; - -// The new added device will overwrite the device list because PNA chooser only -// have one device at a time. -TEST_F(PrivateNetworkDeviceChooserControllerTest, AddDevice) { - EXPECT_CALL(*mock_chooser_view_, OnOptionAdded(0)).Times(1); - CreateAndAddFakePrivateNetworkDevice("a", "001", - net::IPAddress(192, 168, 1, 1)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1u, private_network_device_chooser_controller_->NumOptions()); - EXPECT_EQ(u"001 (a)", - private_network_device_chooser_controller_->GetOption(0)); - - EXPECT_CALL(*mock_chooser_view_, OnOptionAdded(0)).Times(1); - CreateAndAddFakePrivateNetworkDevice("b", "002", - net::IPAddress(192, 168, 0, 1)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1u, private_network_device_chooser_controller_->NumOptions()); - EXPECT_EQ(u"002 (b)", - private_network_device_chooser_controller_->GetOption(0)); - - EXPECT_CALL(*mock_chooser_view_, OnOptionAdded(0)).Times(1); - CreateAndAddFakePrivateNetworkDevice("c", "003", - net::IPAddress(127, 0, 0, 1)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1u, private_network_device_chooser_controller_->NumOptions()); - EXPECT_EQ(u"003 (c)", - private_network_device_chooser_controller_->GetOption(0)); -} - -// TODO(crbug.com/40272624): add test for Select(), Close() and Cancel().
diff --git a/chrome/browser/private_network_access/private_network_device_permission_context.cc b/chrome/browser/private_network_access/private_network_device_permission_context.cc deleted file mode 100644 index e6e287b..0000000 --- a/chrome/browser/private_network_access/private_network_device_permission_context.cc +++ /dev/null
@@ -1,131 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/private_network_access/private_network_device_permission_context.h" - -#include "base/metrics/histogram_functions.h" -#include "base/strings/strcat.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/profiles/profile.h" - -namespace { - -constexpr char kDeviceNameKey[] = "device-name"; -constexpr char kDeviceIdKey[] = "device-id"; -constexpr char kIPAddressKey[] = "ip-address"; - -} // namespace - -PrivateNetworkDevicePermissionContext::PrivateNetworkDevicePermissionContext( - Profile* profile) - : ObjectPermissionContextBase( - ContentSettingsType::PRIVATE_NETWORK_GUARD, - ContentSettingsType::PRIVATE_NETWORK_CHOOSER_DATA, - HostContentSettingsMapFactory::GetForProfile(profile)) {} - -PrivateNetworkDevicePermissionContext:: - ~PrivateNetworkDevicePermissionContext() = default; - -std::string PrivateNetworkDevicePermissionContext::GetKeyForObject( - const base::Value::Dict& object) { - if (!IsValidObject(object)) { - return std::string(); - } - if (const std::string* device_id = object.FindString(kDeviceIdKey)) { - return base::StrCat({"id:", *device_id}); - } - return base::StrCat({"ip:", *(object.FindString(kIPAddressKey))}); -} - -std::u16string PrivateNetworkDevicePermissionContext::GetObjectDisplayName( - const base::Value::Dict& object) { - const std::string* name = object.FindString(kDeviceNameKey); - DCHECK(name); - if (!name->empty()) { - return base::UTF8ToUTF16(*name); - } - - const std::string* ip_address = object.FindString(kIPAddressKey); - DCHECK(ip_address); - return base::UTF8ToUTF16(*ip_address); -} - -bool PrivateNetworkDevicePermissionContext::IsValidObject( - const base::Value::Dict& object) { - return object.size() == 3 && object.FindString(kDeviceNameKey) && - object.FindString(kDeviceIdKey) && object.FindString(kIPAddressKey); -} - -void PrivateNetworkDevicePermissionContext::GrantDevicePermission( - const url::Origin& origin, - const blink::mojom::PrivateNetworkDevice& device, - bool is_device_valid) { - // Store ephemeral permission with IP address. - if (!is_device_valid) { - ephemeral_devices_[origin].insert(device.ip_address); - base::UmaHistogramEnumeration( - kUserAcceptedPrivateNetworkDeviceHistogramName, - NewAcceptedDeviceType::kEphemeralDevice); - return; - } - base::UmaHistogramEnumeration(kUserAcceptedPrivateNetworkDeviceHistogramName, - NewAcceptedDeviceType::kValidDevice); - GrantObjectPermission(origin, DeviceInfoToValue(device)); -} - -bool PrivateNetworkDevicePermissionContext::HasDevicePermission( - const url::Origin& origin, - const blink::mojom::PrivateNetworkDevice& device, - bool is_device_valid) { - if (is_device_valid) { - std::vector<std::unique_ptr<Object>> object_list = - GetGrantedObjects(origin); - for (const auto& object : object_list) { - const base::Value::Dict& value = object->value; - DCHECK(IsValidObject(value)); - DCHECK(device.id.has_value()); - if (*value.FindString(kDeviceIdKey) == device.id.value()) { - base::UmaHistogramEnumeration( - kPrivateNetworkDeviceValidityHistogramName, - PrivateNetworkDeviceValidity::kExistingDevice); - return true; - } - } - } else { - // If there's no valid id and name, then look up for ephemeral permission - // based on IP address. - auto it = ephemeral_devices_.find(origin); - if (it != ephemeral_devices_.end()) { - std::set<net::IPAddress> device_set = it->second; - auto ip_address = device_set.find(device.ip_address); - if (ip_address != device_set.end()) { - return true; - } - } - } - - return false; -} - -void PrivateNetworkDevicePermissionContext::Shutdown() { - FlushScheduledSaveSettingsCalls(); - permissions::ObjectPermissionContextBase::Shutdown(); -} - -base::WeakPtr<PrivateNetworkDevicePermissionContext> -PrivateNetworkDevicePermissionContext::AsWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - -// static -base::Value::Dict PrivateNetworkDevicePermissionContext::DeviceInfoToValue( - const blink::mojom::PrivateNetworkDevice& device) { - base::Value::Dict device_value; - device_value.Set(kDeviceNameKey, device.name.value()); - device_value.Set(kDeviceIdKey, device.id.value()); - device_value.Set(kIPAddressKey, device.ip_address.ToString()); - return device_value; -}
diff --git a/chrome/browser/private_network_access/private_network_device_permission_context.h b/chrome/browser/private_network_access/private_network_device_permission_context.h deleted file mode 100644 index da144a2..0000000 --- a/chrome/browser/private_network_access/private_network_device_permission_context.h +++ /dev/null
@@ -1,95 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_PRIVATE_NETWORK_DEVICE_PERMISSION_CONTEXT_H_ -#define CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_PRIVATE_NETWORK_DEVICE_PERMISSION_CONTEXT_H_ - -#include "base/containers/queue.h" -#include "base/observer_list.h" -#include "base/values.h" -#include "build/build_config.h" -#include "components/permissions/object_permission_context_base.h" -#include "content/public/browser/browser_context.h" -#include "third_party/blink/public/mojom/private_network_device/private_network_device.mojom.h" -#include "url/origin.h" - -class Profile; - -inline constexpr char kPrivateNetworkDeviceValidityHistogramName[] = - "Security.PrivateNetworkAccess.PermissionDeviceValidity"; -inline constexpr char kUserAcceptedPrivateNetworkDeviceHistogramName[] = - "Security.PrivateNetworkAccess.PermissionNewAcceptedDeviceType"; - -// These values are logged to UMA. Entries should not be renumbered and numeric -// values should never be reused. Please keep in sync with -// "PrivateNetworkDeviceValidity" in -// src/tools/metrics/histograms/metadata/security/enums.xml. -enum class PrivateNetworkDeviceValidity { - kExistingDevice = 0, - kNewValidDevice = 1, - kDeviceIDMissing = 2, - kDeviceIDInvalid = 3, // kDeviceIDInvalid is deprecated. - kDeviceNameMissing = 4, - kDeviceNameInvalid = 5, - kMaxValue = kDeviceNameInvalid, -}; - -// These values are logged to UMA. Entries should not be renumbered and numeric -// values should never be reused. Please keep in sync with -// "NewAcceptedDeviceType" in -// src/tools/metrics/histograms/metadata/security/enums.xml. -enum class NewAcceptedDeviceType { - kValidDevice = 0, - kEphemeralDevice = 1, - kMaxValue = kEphemeralDevice, -}; - -// Manages the permissions for Private Network device objects. A Private Network -// device permission object consists of its id, name and IP address. -// The id is provided by the device in `Private-Network-Access-ID` preflight -// header. The name is provided by the device in `Private-Network-Access-Name` -// preflight header. -class PrivateNetworkDevicePermissionContext - : public permissions::ObjectPermissionContextBase { - public: - explicit PrivateNetworkDevicePermissionContext(Profile* profile); - - PrivateNetworkDevicePermissionContext( - const PrivateNetworkDevicePermissionContext&) = delete; - PrivateNetworkDevicePermissionContext& operator=( - const PrivateNetworkDevicePermissionContext&) = delete; - - ~PrivateNetworkDevicePermissionContext() override; - - std::string GetKeyForObject(const base::Value::Dict& object) override; - std::u16string GetObjectDisplayName(const base::Value::Dict& object) override; - - bool IsValidObject(const base::Value::Dict& object) override; - - // Grants `origin` access to the device. - void GrantDevicePermission(const url::Origin& origin, - const blink::mojom::PrivateNetworkDevice& device, - bool is_device_valid); - - // Checks if `origin` has access to `device`. - bool HasDevicePermission(const url::Origin& origin, - const blink::mojom::PrivateNetworkDevice& device, - bool is_device_valid); - - // KeyedService: - void Shutdown() override; - - // Tracks the set of devices to which an origin has temporary access to. - std::map<url::Origin, std::set<net::IPAddress>> ephemeral_devices_; - - base::WeakPtr<PrivateNetworkDevicePermissionContext> AsWeakPtr(); - - static base::Value::Dict DeviceInfoToValue( - const blink::mojom::PrivateNetworkDevice& device); - - base::WeakPtrFactory<PrivateNetworkDevicePermissionContext> weak_factory_{ - this}; -}; - -#endif // CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_PRIVATE_NETWORK_DEVICE_PERMISSION_CONTEXT_H_
diff --git a/chrome/browser/private_network_access/private_network_device_permission_context_factory.cc b/chrome/browser/private_network_access/private_network_device_permission_context_factory.cc deleted file mode 100644 index 08aa6f43..0000000 --- a/chrome/browser/private_network_access/private_network_device_permission_context_factory.cc +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/private_network_access/private_network_device_permission_context_factory.h" - -#include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/private_network_access/private_network_device_permission_context.h" -#include "chrome/browser/profiles/profile.h" - -PrivateNetworkDevicePermissionContextFactory:: - PrivateNetworkDevicePermissionContextFactory() - : ProfileKeyedServiceFactory( - "PrivateNetworkDevicePermissionContext", - ProfileSelections::Builder() - .WithRegular(ProfileSelection::kOwnInstance) - .WithGuest(ProfileSelection::kOwnInstance) - // TODO(crbug.com/41488885): Check if this service is needed for - // Ash Internals. - .WithAshInternals(ProfileSelection::kOwnInstance) - .Build()) { - DependsOn(HostContentSettingsMapFactory::GetInstance()); -} - -PrivateNetworkDevicePermissionContextFactory:: - ~PrivateNetworkDevicePermissionContextFactory() = default; - -std::unique_ptr<KeyedService> PrivateNetworkDevicePermissionContextFactory:: - BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { - return std::make_unique<PrivateNetworkDevicePermissionContext>( - Profile::FromBrowserContext(context)); -} - -// static -PrivateNetworkDevicePermissionContextFactory* -PrivateNetworkDevicePermissionContextFactory::GetInstance() { - static base::NoDestructor<PrivateNetworkDevicePermissionContextFactory> - instance; - return instance.get(); -} - -// static -PrivateNetworkDevicePermissionContext* -PrivateNetworkDevicePermissionContextFactory::GetForProfile(Profile* profile) { - return static_cast<PrivateNetworkDevicePermissionContext*>( - GetInstance()->GetServiceForBrowserContext(profile, /*create=*/true)); -} - -PrivateNetworkDevicePermissionContext* -PrivateNetworkDevicePermissionContextFactory::GetForProfileIfExists( - Profile* profile) { - return static_cast<PrivateNetworkDevicePermissionContext*>( - GetInstance()->GetServiceForBrowserContext(profile, /*create=*/false)); -}
diff --git a/chrome/browser/private_network_access/private_network_device_permission_context_factory.h b/chrome/browser/private_network_access/private_network_device_permission_context_factory.h deleted file mode 100644 index a43cd6b..0000000 --- a/chrome/browser/private_network_access/private_network_device_permission_context_factory.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_PRIVATE_NETWORK_DEVICE_PERMISSION_CONTEXT_FACTORY_H_ -#define CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_PRIVATE_NETWORK_DEVICE_PERMISSION_CONTEXT_FACTORY_H_ - -#include "base/no_destructor.h" -#include "chrome/browser/profiles/profile_keyed_service_factory.h" - -class PrivateNetworkDevicePermissionContext; -class Profile; - -// This class gets the correct `PrivateNetworkDevicePermissionContext` for the -// current profile. -class PrivateNetworkDevicePermissionContextFactory - : public ProfileKeyedServiceFactory { - public: - // Gets the private network device permission context for the current - // user profile. - // Returns nullptr if the `profile` is null or invalid. - // Otherwise, if no context exists for the profile, creates one and returns - // it. - static PrivateNetworkDevicePermissionContext* GetForProfile(Profile* profile); - - // Returns nullptr if the `profile` is null, invalid or no context exists for - // the profile. Otherwise, returns the existing profile. - static PrivateNetworkDevicePermissionContext* GetForProfileIfExists( - Profile* profile); - - // Gets the `PrivateNetworkDevicePermissionContextFactory` singleton. - static PrivateNetworkDevicePermissionContextFactory* GetInstance(); - - PrivateNetworkDevicePermissionContextFactory( - const PrivateNetworkDevicePermissionContextFactory&) = delete; - PrivateNetworkDevicePermissionContextFactory& operator=( - const PrivateNetworkDevicePermissionContextFactory&) = delete; - - private: - friend base::NoDestructor<PrivateNetworkDevicePermissionContextFactory>; - - PrivateNetworkDevicePermissionContextFactory(); - ~PrivateNetworkDevicePermissionContextFactory() override; - - // BrowserContextKeyedServiceFactory methods: - std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( - content::BrowserContext* profile) const override; -}; - -#endif // CHROME_BROWSER_PRIVATE_NETWORK_ACCESS_PRIVATE_NETWORK_DEVICE_PERMISSION_CONTEXT_FACTORY_H_
diff --git a/chrome/browser/private_network_access/private_network_device_permission_context_unittest.cc b/chrome/browser/private_network_access/private_network_device_permission_context_unittest.cc deleted file mode 100644 index bd6867b..0000000 --- a/chrome/browser/private_network_access/private_network_device_permission_context_unittest.cc +++ /dev/null
@@ -1,117 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/private_network_access/private_network_device_permission_context.h" - -#include <string_view> - -#include "base/test/metrics/histogram_tester.h" -#include "chrome/browser/private_network_access/private_network_device_permission_context_factory.h" -#include "chrome/test/base/testing_profile.h" -#include "content/public/test/browser_task_environment.h" -#include "net/base/ip_address.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -using ::testing::Optional; - -namespace network { -namespace { - -using Validity = PrivateNetworkDeviceValidity; -using Type = NewAcceptedDeviceType; - -constexpr std::string_view kPrivateNetworkDeviceValidityHistogramName = - "Security.PrivateNetworkAccess.PermissionDeviceValidity"; -constexpr std::string_view kUserAcceptedPrivateNetworkDeviceHistogramName = - "Security.PrivateNetworkAccess.PermissionNewAcceptedDeviceType"; - -class PrivateNetworkDevicePermissionContextTest : public testing::Test { - public: - PrivateNetworkDevicePermissionContextTest() - : foo_url_("https://foo.com"), - bar_url_("https://bar.com"), - foo_origin_(url::Origin::Create(foo_url_)), - bar_origin_(url::Origin::Create(bar_url_)), - fake_device1_(blink::mojom::PrivateNetworkDevice::New( - "test_id1", - "test_name1", - net::IPAddress(10, 0, 0, 1))), - fake_device2_(blink::mojom::PrivateNetworkDevice::New( - "test_id2", - "test_name2", - net::IPAddress(1, 2, 3, 4))) {} - - ~PrivateNetworkDevicePermissionContextTest() override = default; - - // Move-only class. - PrivateNetworkDevicePermissionContextTest( - const PrivateNetworkDevicePermissionContextTest&) = delete; - PrivateNetworkDevicePermissionContextTest& operator=( - const PrivateNetworkDevicePermissionContextTest&) = delete; - - protected: - Profile* profile() { return &profile_; } - - PrivateNetworkDevicePermissionContext* GetChooserContext(Profile* profile) { - auto* chooser_context = - PrivateNetworkDevicePermissionContextFactory::GetForProfile(profile); - return chooser_context; - } - - const GURL foo_url_; - const GURL bar_url_; - const url::Origin foo_origin_; - const url::Origin bar_origin_; - blink::mojom::PrivateNetworkDevicePtr fake_device1_; - blink::mojom::PrivateNetworkDevicePtr fake_device2_; - - private: - content::BrowserTaskEnvironment task_environment_; - TestingProfile profile_; -}; - -TEST_F(PrivateNetworkDevicePermissionContextTest, CheckGrantDevicePermission) { - base::HistogramTester histogram_tester; - PrivateNetworkDevicePermissionContext* context = GetChooserContext(profile()); - - context->GrantDevicePermission(foo_origin_, *fake_device1_, - /*is_device_valid=*/true); - histogram_tester.ExpectUniqueSample( - kUserAcceptedPrivateNetworkDeviceHistogramName, Type::kValidDevice, 1); - - context->GrantDevicePermission(foo_origin_, *fake_device2_, - /*is_device_valid=*/false); - histogram_tester.ExpectBucketCount( - kUserAcceptedPrivateNetworkDeviceHistogramName, Type::kEphemeralDevice, - 1); -} - -TEST_F(PrivateNetworkDevicePermissionContextTest, CheckHasDevicePermission) { - base::HistogramTester histogram_tester; - PrivateNetworkDevicePermissionContext* context = GetChooserContext(profile()); - - context->HasDevicePermission(foo_origin_, *fake_device1_, - /*is_device_valid=*/true); - histogram_tester.ExpectUniqueSample( - kPrivateNetworkDeviceValidityHistogramName, Validity::kExistingDevice, 0); - - context->HasDevicePermission(foo_origin_, *fake_device2_, - /*is_device_valid=*/false); - histogram_tester.ExpectUniqueSample( - kPrivateNetworkDeviceValidityHistogramName, Validity::kExistingDevice, 0); - - context->GrantDevicePermission(foo_origin_, *fake_device1_, - /*is_device_valid=*/true); - context->HasDevicePermission(foo_origin_, *fake_device1_, - /*is_device_valid=*/true); - context->HasDevicePermission(foo_origin_, *fake_device2_, - /*is_device_valid=*/true); - histogram_tester.ExpectUniqueSample( - kPrivateNetworkDeviceValidityHistogramName, Validity::kExistingDevice, 1); -} - -} // namespace -} // namespace network
diff --git a/chrome/browser/profiles/android/java/src/org/chromium/chrome/browser/profiles/ProfileManager.java b/chrome/browser/profiles/android/java/src/org/chromium/chrome/browser/profiles/ProfileManager.java index 9ac1c49..f66dd32 100644 --- a/chrome/browser/profiles/android/java/src/org/chromium/chrome/browser/profiles/ProfileManager.java +++ b/chrome/browser/profiles/android/java/src/org/chromium/chrome/browser/profiles/ProfileManager.java
@@ -27,9 +27,10 @@ private static boolean sInitialized; /** Observer for Profile creation. */ - public static interface Observer { + public interface Observer { /** * Called whenever a profile is created. + * * @param profile The profile that has just been created. */ public void onProfileAdded(Profile profile);
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 23ebee9..1c1893e 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -167,7 +167,6 @@ #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.h" #include "chrome/browser/privacy_sandbox/tracking_protection_onboarding_factory.h" #include "chrome/browser/privacy_sandbox/tracking_protection_settings_factory.h" -#include "chrome/browser/private_network_access/private_network_device_permission_context_factory.h" #include "chrome/browser/profile_resetter/triggered_profile_resetter_factory.h" #include "chrome/browser/profiles/batch_upload/batch_upload_service_factory.h" #include "chrome/browser/profiles/renderer_updater_factory.h" @@ -1197,9 +1196,6 @@ PrefsTabHelper::GetServiceInstance(); prerender::NoStatePrefetchLinkManagerFactory::GetInstance(); prerender::NoStatePrefetchManagerFactory::GetInstance(); -#if !BUILDFLAG(IS_ANDROID) - PrivateNetworkDevicePermissionContextFactory::GetInstance(); -#endif PrivacyMetricsServiceFactory::GetInstance(); PrivacySandboxIncognitoSurveyServiceFactory::GetInstance(); PrivacySandboxNoticeServiceFactory::GetInstance();
diff --git a/chrome/browser/resources/actor_internals/actor_internals.ts b/chrome/browser/resources/actor_internals/actor_internals.ts index 6047ba1e..477de8d 100644 --- a/chrome/browser/resources/actor_internals/actor_internals.ts +++ b/chrome/browser/resources/actor_internals/actor_internals.ts
@@ -42,7 +42,11 @@ td[1]!.textContent = entry.event; td[2]!.textContent = entry.type; td[3]!.textContent = entry.details; - td[4]!.textContent = new Date(entry.timestamp).toUTCString(); + td[4]!.textContent = + new Date(entry.timestamp).toLocaleTimeString(undefined, { + hour12: false, + timeZoneName: 'short', + }); const rows = table.rows; for (let i = rows.length - 1; i > 0; i--) {
diff --git a/chrome/browser/resources/glic/glic_api/glic_api.ts b/chrome/browser/resources/glic/glic_api/glic_api.ts index 7caa897..9458de1e 100644 --- a/chrome/browser/resources/glic/glic_api/glic_api.ts +++ b/chrome/browser/resources/glic/glic_api/glic_api.ts
@@ -716,6 +716,11 @@ * This can get fired multiple times in a single session. */ onClosedCaptionsShown?(): void; + + /** + * Called when a turn has been completed. + */ + onTurnCompleted?(model: WebClientModel, duration: number): void; } /** Web client's operation modes */ @@ -726,6 +731,14 @@ AUDIO = 1, } +export enum WebClientModel { + /** Default model. */ + DEFAULT = 0, + + /** Actor model. */ + ACTOR = 1, +} + /** An encoded journal. */ export declare interface Journal { /**
diff --git a/chrome/browser/resources/glic/glic_api_impl/glic_api_client.ts b/chrome/browser/resources/glic/glic_api_impl/glic_api_client.ts index 6d8ec76..22fb6135 100644 --- a/chrome/browser/resources/glic/glic_api_impl/glic_api_client.ts +++ b/chrome/browser/resources/glic/glic_api_impl/glic_api_client.ts
@@ -823,6 +823,11 @@ this.sender.requestNoResponse( 'glicBrowserOnClosedCaptionsShown', undefined); } + + onTurnCompleted?(model: number, duration: number): void { + this.sender.requestNoResponse( + 'glicBrowserOnTurnCompleted', {model, duration}); + } } // Converts an RgbaImage into a Blob through the canvas API. Output is a PNG.
diff --git a/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts b/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts index ab8d447..536c91a4 100644 --- a/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts +++ b/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts
@@ -642,6 +642,11 @@ this.handler.onSessionTerminated(); } + glicBrowserOnTurnCompleted(request: {model: number, duration: number}): void { + this.handler.onTurnCompleted( + request.model, timeDeltaFromClient(request.duration)); + } + glicBrowserLogBeginAsyncEvent(request: { asyncEventId: number, taskId: number,
diff --git a/chrome/browser/resources/glic/glic_api_impl/request_types.ts b/chrome/browser/resources/glic/glic_api_impl/request_types.ts index 449a977c..d6a9a98 100644 --- a/chrome/browser/resources/glic/glic_api_impl/request_types.ts +++ b/chrome/browser/resources/glic/glic_api_impl/request_types.ts
@@ -270,6 +270,12 @@ glicBrowserOnResponseStarted: {}; glicBrowserOnResponseStopped: {}; glicBrowserOnSessionTerminated: {}; + glicBrowserOnTurnCompleted: { + request: { + model: number, + duration: number, + }, + }; glicBrowserOnResponseRated: { request: { positive: boolean, @@ -489,11 +495,12 @@ JournalStop: 0, JournalRecordFeedback: 0, OnUserInputSubmitted: 0, + OnResponseRated: 0, OnRequestStarted: 0, OnResponseStarted: 0, OnResponseStopped: 0, OnSessionTerminated: 0, - OnResponseRated: 0, + OnTurnCompleted: 0, ScrollTo: 0, SetSyntheticExperimentState: 0, OpenOsPermissionSettingsMenu: 0,
diff --git a/chrome/browser/resources/new_tab_page/composebox/composebox.ts b/chrome/browser/resources/new_tab_page/composebox/composebox.ts index fcb4c625..2c84685 100644 --- a/chrome/browser/resources/new_tab_page/composebox/composebox.ts +++ b/chrome/browser/resources/new_tab_page/composebox/composebox.ts
@@ -11,6 +11,7 @@ import {CrLitElement} from '//resources/lit/v3_0/lit.rollup.js'; import type {BigBuffer} from '//resources/mojo/mojo/public/mojom/base/big_buffer.mojom-webui.js'; import type {UnguessableToken} from '//resources/mojo/mojo/public/mojom/base/unguessable_token.mojom-webui.js'; +import {getInstance as getAnnouncerInstance} from 'chrome://resources/cr_elements/cr_a11y_announcer/cr_a11y_announcer.js'; import {I18nMixinLit} from 'chrome://resources/cr_elements/i18n_mixin_lit.js'; import {EventTracker} from 'chrome://resources/js/event_tracker.js'; @@ -160,6 +161,12 @@ } else { file = {...file, status: status}; this.files_.set(token, file); + + if (status === FileUploadStatus.kUploadSuccessful) { + const announcer = getAnnouncerInstance(); + announcer.announce( + this.i18n('composeboxFileUploadCompleteText')); + } } this.files_ = new Map([...this.files_]); } @@ -272,6 +279,9 @@ status: FileUploadStatus.kNotUploaded, }; this.files_ = new Map([...this.files_.entries(), [token, attachment]]); + + const announcer = getAnnouncerInstance(); + announcer.announce(this.i18n('composeboxFileUploadStartedText')); } } // Clear the file input.
diff --git a/chrome/browser/resources/privacy_sandbox/internals/content_settings_groups.ts b/chrome/browser/resources/privacy_sandbox/internals/content_settings_groups.ts index 512ebba..33a158ae 100644 --- a/chrome/browser/resources/privacy_sandbox/internals/content_settings_groups.ts +++ b/chrome/browser/resources/privacy_sandbox/internals/content_settings_groups.ts
@@ -109,8 +109,6 @@ ContentSettingsType.DIRECT_SOCKETS, ContentSettingsType.DIRECT_SOCKETS_PRIVATE_NETWORK_ACCESS, ContentSettingsType.LOCAL_NETWORK_ACCESS, - ContentSettingsType.PRIVATE_NETWORK_CHOOSER_DATA, - ContentSettingsType.PRIVATE_NETWORK_GUARD, ContentSettingsType.PROTOCOL_HANDLERS, ], },
diff --git a/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubNotificationsPreference.java b/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubNotificationsPreference.java index 73e1419f..96c8d3c1 100644 --- a/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubNotificationsPreference.java +++ b/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubNotificationsPreference.java
@@ -28,7 +28,7 @@ @NullMarked public class SafetyHubNotificationsPreference extends ChromeBasePreference implements ListMenu.Delegate { - static interface MenuClickListener { + interface MenuClickListener { void onAllowClicked(SafetyHubNotificationsPreference preference); void onResetClicked(SafetyHubNotificationsPreference preference);
diff --git a/chrome/browser/selection/android/java/src/org/chromium/chrome/browser/selection/SelectionPopupBackPressHandler.java b/chrome/browser/selection/android/java/src/org/chromium/chrome/browser/selection/SelectionPopupBackPressHandler.java index a0cc0868..f681104 100644 --- a/chrome/browser/selection/android/java/src/org/chromium/chrome/browser/selection/SelectionPopupBackPressHandler.java +++ b/chrome/browser/selection/android/java/src/org/chromium/chrome/browser/selection/SelectionPopupBackPressHandler.java
@@ -12,6 +12,7 @@ import org.chromium.build.annotations.Nullable; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.components.browser_ui.widget.gesture.BackPressHandler; @@ -65,7 +66,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { mBackPressChangedSupplier.set(false); updatePopupControllerObserving(tab); }
diff --git a/chrome/browser/sharing/sharing_device_registration_impl.cc b/chrome/browser/sharing/sharing_device_registration_impl.cc index 17a5abd7..0935173 100644 --- a/chrome/browser/sharing/sharing_device_registration_impl.cc +++ b/chrome/browser/sharing/sharing_device_registration_impl.cc
@@ -27,7 +27,6 @@ #include "components/sharing_message/sharing_utils.h" #include "components/sync/service/sync_service.h" #include "components/sync_device_info/device_info.h" -#include "crypto/ec_private_key.h" #if BUILDFLAG(IS_ANDROID) #include "chrome/android/chrome_jni_headers/SharingJNIBridge_jni.h"
diff --git a/chrome/browser/sharing/sharing_device_registration_impl_unittest.cc b/chrome/browser/sharing/sharing_device_registration_impl_unittest.cc index ccb1c21..bbc8d8ac 100644 --- a/chrome/browser/sharing/sharing_device_registration_impl_unittest.cc +++ b/chrome/browser/sharing/sharing_device_registration_impl_unittest.cc
@@ -30,7 +30,6 @@ #include "components/sync_device_info/fake_device_info_sync_service.h" #include "components/sync_preferences/pref_service_mock_factory.h" #include "components/sync_preferences/testing_pref_service_syncable.h" -#include "crypto/ec_private_key.h" #include "google_apis/gcm/engine/account_mapping.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/storage/shared_storage_browsertest.cc b/chrome/browser/storage/shared_storage_browsertest.cc index 51ce5de..15d81988 100644 --- a/chrome/browser/storage/shared_storage_browsertest.cc +++ b/chrome/browser/storage/shared_storage_browsertest.cc
@@ -2310,13 +2310,12 @@ GURL script_url = https_server()->GetURL(kMainHost, "/shared_storage/erroneous_module.js"); - content::EvalJsResult result = content::EvalJs( - GetActiveWebContents(), - content::JsReplace("sharedStorage.worklet.addModule($1)", script_url)); - EXPECT_THAT( - result.error, - testing::HasSubstr("ReferenceError: undefinedVariable is not defined")); + content::EvalJs(GetActiveWebContents(), + content::JsReplace("sharedStorage.worklet.addModule($1)", + script_url)), + content::EvalJsResult::ErrorIs(testing::HasSubstr( + "ReferenceError: undefinedVariable is not defined"))); WaitForHistograms({kErrorTypeHistogram}); histogram_tester_.ExpectUniqueSample( @@ -2340,13 +2339,12 @@ EXPECT_TRUE(content::ExecJs( GetActiveWebContents(), content::JsReplace("sharedStorage.worklet.addModule($1)", script_url))); - content::EvalJsResult result = content::EvalJs( - GetActiveWebContents(), - content::JsReplace("sharedStorage.worklet.addModule($1)", script_url)); - EXPECT_THAT( - result.error, - testing::HasSubstr("addModule() can only be invoked once per worklet")); + content::EvalJs(GetActiveWebContents(), + content::JsReplace("sharedStorage.worklet.addModule($1)", + script_url)), + content::EvalJsResult::ErrorIs(testing::HasSubstr( + "addModule() can only be invoked once per worklet"))); WaitForHistogramsWithSampleCounts( {std::make_tuple(kTimingDocumentAddModuleHistogram, 1), @@ -2367,15 +2365,13 @@ IN_PROC_BROWSER_TEST_P(SharedStorageChromeBrowserTest, Run_NotLoadedError) { Set3rdPartyCookieAndMainHostAttestationSettingsThenNavigateToMainHostPage(); - content::EvalJsResult result = content::EvalJs(GetActiveWebContents(), R"( + EXPECT_THAT( + content::EvalJs(GetActiveWebContents(), R"( sharedStorage.run( 'test-operation', {data: {}}); - )"); - - EXPECT_THAT( - result.error, - testing::HasSubstr( - "sharedStorage.worklet.addModule() has to be called before run()")); + )"), + content::EvalJsResult::ErrorIs(testing::HasSubstr( + "sharedStorage.worklet.addModule() has to be called before run()"))); WaitForHistograms({kErrorTypeHistogram}); histogram_tester_.ExpectUniqueSample( @@ -2540,7 +2536,7 @@ EXPECT_TRUE(ExecJs(GetActiveWebContents(), content::JsReplace("window.resolveSelectURLToConfig = $1;", ResolveSelectURLToConfig()))); - content::EvalJsResult result = EvalJs(GetActiveWebContents(), R"( + EXPECT_THAT(EvalJs(GetActiveWebContents(), R"( (async function() { window.select_url_result = await sharedStorage.selectURL( 'test-url-selection-operation-1', @@ -2560,11 +2556,10 @@ } return window.select_url_result; })() - )"); - - EXPECT_THAT(result.error, - testing::HasSubstr("sharedStorage.worklet.addModule() has to be " - "called before selectURL()")); + )"), + content::EvalJsResult::ErrorIs(testing::HasSubstr( + "sharedStorage.worklet.addModule() has to be " + "called before selectURL()"))); WaitForHistograms({kErrorTypeHistogram}); @@ -3264,16 +3259,16 @@ content::SharedStorageCrossOriginWorkletResponseHeaderReplacement( "", "Shared-Storage-Cross-Origin-Worklet-Allowed: ?1"))); - content::EvalJsResult result = + EXPECT_THAT( content::EvalJs(GetActiveWebContents(), content::JsReplace(R"( (async function() { window.testWorklet = await sharedStorage.createWorklet($1, {dataOrigin: 'script-origin'}); })() )", - script_url)); - - EXPECT_THAT(result.error, testing::HasSubstr("Error: Failed to load")); + script_url)), + content::EvalJsResult::ErrorIs( + testing::HasSubstr("Error: Failed to load"))); WaitForHistograms({kErrorTypeHistogram}); histogram_tester_.ExpectUniqueSample( @@ -3296,16 +3291,16 @@ content::SharedStorageCrossOriginWorkletResponseHeaderReplacement( "Access-Control-Allow-Origin: *", ""))); - content::EvalJsResult result = + EXPECT_THAT( content::EvalJs(GetActiveWebContents(), content::JsReplace(R"( (async function() { window.testWorklet = await sharedStorage.createWorklet($1, {dataOrigin: 'script-origin'}); })() )", - script_url)); - - EXPECT_THAT(result.error, testing::HasSubstr("Error: Failed to load")); + script_url)), + content::EvalJsResult::ErrorIs( + testing::HasSubstr("Error: Failed to load"))); WaitForHistograms({kErrorTypeHistogram}); histogram_tester_.ExpectUniqueSample( @@ -3324,16 +3319,16 @@ GURL script_url = https_server()->GetURL( kCrossOriginHost, "/shared_storage/nonexistent_module.js"); - content::EvalJsResult result = + EXPECT_THAT( content::EvalJs(GetActiveWebContents(), content::JsReplace(R"( (async function() { window.testWorklet = await sharedStorage.createWorklet($1, {dataOrigin: 'script-origin'}); })() )", - script_url)); - - EXPECT_THAT(result.error, testing::HasSubstr("Error: Failed to load")); + script_url)), + content::EvalJsResult::ErrorIs( + testing::HasSubstr("Error: Failed to load"))); WaitForHistograms({kErrorTypeHistogram}); histogram_tester_.ExpectUniqueSample( @@ -3472,15 +3467,15 @@ content::SharedStorageCrossOriginWorkletResponseHeaderReplacement( "", ""))); - content::EvalJsResult result = + EXPECT_THAT( content::EvalJs(GetActiveWebContents(), content::JsReplace(R"( (async function() { await sharedStorage.createWorklet($1); })() )", - script_url)); - - EXPECT_THAT(result.error, testing::HasSubstr("Error: Failed to load")); + script_url)), + content::EvalJsResult::ErrorIs( + testing::HasSubstr("Error: Failed to load"))); WaitForHistograms({kErrorTypeHistogram}); histogram_tester_.ExpectUniqueSample( @@ -3618,15 +3613,15 @@ content::SharedStorageCrossOriginWorkletResponseHeaderReplacement( "", ""))); - content::EvalJsResult result = + EXPECT_THAT( content::EvalJs(GetActiveWebContents(), content::JsReplace(R"( (async function() { await sharedStorage.createWorklet($1, {dataOrigin: 'context-origin'}); })() )", - script_url)); - - EXPECT_THAT(result.error, testing::HasSubstr("Error: Failed to load")); + script_url)), + content::EvalJsResult::ErrorIs( + testing::HasSubstr("Error: Failed to load"))); WaitForHistograms({kErrorTypeHistogram}); histogram_tester_.ExpectUniqueSample( @@ -3799,11 +3794,12 @@ content::SharedStorageCrossOriginWorkletResponseHeaderReplacement( "", ""))); - content::EvalJsResult result = content::EvalJs( - GetActiveWebContents(), - content::JsReplace("sharedStorage.worklet.addModule($1)", script_url)); - - EXPECT_THAT(result.error, testing::HasSubstr("Error: Failed to load")); + EXPECT_THAT( + content::EvalJs(GetActiveWebContents(), + content::JsReplace("sharedStorage.worklet.addModule($1)", + script_url)), + content::EvalJsResult::ErrorIs( + testing::HasSubstr("Error: Failed to load"))); WaitForHistograms({kErrorTypeHistogram}); histogram_tester_.ExpectUniqueSample( @@ -3821,11 +3817,12 @@ GURL script_url = https_server()->GetURL( kCrossOriginHost, "/shared_storage/nonexistent_module.js"); - content::EvalJsResult result = content::EvalJs( - GetActiveWebContents(), - content::JsReplace("sharedStorage.worklet.addModule($1)", script_url)); - - EXPECT_THAT(result.error, testing::HasSubstr("Error: Failed to load")); + EXPECT_THAT( + content::EvalJs(GetActiveWebContents(), + content::JsReplace("sharedStorage.worklet.addModule($1)", + script_url)), + content::EvalJsResult::ErrorIs( + testing::HasSubstr("Error: Failed to load"))); WaitForHistograms({kErrorTypeHistogram}); histogram_tester_.ExpectUniqueSample(
diff --git a/chrome/browser/sync/BUILD.gn b/chrome/browser/sync/BUILD.gn index 835f9fe..7fef238 100644 --- a/chrome/browser/sync/BUILD.gn +++ b/chrome/browser/sync/BUILD.gn
@@ -85,6 +85,7 @@ "//chrome/browser/password_manager/factories", "//chrome/browser/plus_addresses", "//chrome/browser/signin", + "//chrome/browser/ui/sync", "//chrome/browser/ui/toolbar", "//chrome/browser/webauthn",
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TrustedCdn.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TrustedCdn.java index 2c0a8cb..ccd5e4b 100644 --- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TrustedCdn.java +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TrustedCdn.java
@@ -28,10 +28,10 @@ private final long mNativeTrustedCdn; /** - * UnownedUserData shared across all tabs to get the publisher url visibility. - * This hangs off of an activity via WindowAndroid. + * UnownedUserData shared across all tabs to get the publisher url visibility. This hangs off of + * an activity via WindowAndroid. */ - public static interface PublisherUrlVisibility extends UnownedUserData { + public interface PublisherUrlVisibility extends UnownedUserData { /** The key for accessing this object on an {@link UnownedUserDataHost}. */ public static final UnownedUserDataKey<PublisherUrlVisibility> KEY = new UnownedUserDataKey<>(PublisherUrlVisibility.class);
diff --git a/chrome/browser/tab_group_suggestion/android/java/src/org/chromium/chrome/browser/tab_group_suggestion/SuggestionEventObserver.java b/chrome/browser/tab_group_suggestion/android/java/src/org/chromium/chrome/browser/tab_group_suggestion/SuggestionEventObserver.java index e3831b2..7a8e1dc9 100644 --- a/chrome/browser/tab_group_suggestion/android/java/src/org/chromium/chrome/browser/tab_group_suggestion/SuggestionEventObserver.java +++ b/chrome/browser/tab_group_suggestion/android/java/src/org/chromium/chrome/browser/tab_group_suggestion/SuggestionEventObserver.java
@@ -38,7 +38,10 @@ private final TabModelObserver mTabModelObserver = new TabModelObserver() { @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab( + Tab tab, + @org.chromium.chrome.browser.tab.TabSelectionType int type, + int lastId) { @TabSelectionType int selectionType = switch (type) {
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabGroupModelFilterImpl.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabGroupModelFilterImpl.java index 01dbd05..fca988e 100644 --- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabGroupModelFilterImpl.java +++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabGroupModelFilterImpl.java
@@ -29,6 +29,7 @@ import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabId; import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tab.TabStateAttributes; import org.chromium.chrome.browser.tab_group_sync.TabGroupSyncFeatures; import org.chromium.chrome.browser.tabmodel.TabGroupModelFilterObserver.DidRemoveTabGroupReason; @@ -1767,7 +1768,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { RecordHistogram.recordBooleanHistogram( "TabGroups.SelectedTabInTabGroup", isTabInTabGroup(tab)); selectTab(tab);
diff --git a/chrome/browser/thumbnail/generator/android/java/src/org/chromium/chrome/browser/thumbnail/generator/ThumbnailProvider.java b/chrome/browser/thumbnail/generator/android/java/src/org/chromium/chrome/browser/thumbnail/generator/ThumbnailProvider.java index 5fde7c7..a095a31 100644 --- a/chrome/browser/thumbnail/generator/android/java/src/org/chromium/chrome/browser/thumbnail/generator/ThumbnailProvider.java +++ b/chrome/browser/thumbnail/generator/android/java/src/org/chromium/chrome/browser/thumbnail/generator/ThumbnailProvider.java
@@ -14,7 +14,7 @@ @NullMarked public interface ThumbnailProvider { /** Used to request the retrieval of a thumbnail. */ - public static interface ThumbnailRequest { + public interface ThumbnailRequest { /** Local storage path to the file. */ @Nullable String getFilePath();
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 0d635e59..7e25bf0 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -92,8 +92,6 @@ "startup/test_third_party_cookie_phaseout_infobar_delegate.h", "status_bubble.h", "storage_pressure_bubble.h", - "sync/tab_contents_synced_tab_delegate.cc", - "sync/tab_contents_synced_tab_delegate.h", "tab_dialogs.cc", "tab_dialogs.h", "tab_helpers.cc", @@ -382,6 +380,8 @@ "//chrome/browser/ui/search_engines", "//chrome/browser/ui/serial", "//chrome/browser/ui/serial:impl", + "//chrome/browser/ui/sync", + "//chrome/browser/ui/sync:impl", "//chrome/browser/ui/tab_contents", "//chrome/browser/ui/tab_contents:impl", "//chrome/browser/ui/toolbar", @@ -1107,14 +1107,6 @@ "startup/startup_tab_provider.cc", "startup/startup_tab_provider.h", "startup/startup_types.h", - "sync/browser_synced_tab_delegate.cc", - "sync/browser_synced_tab_delegate.h", - "sync/browser_synced_window_delegate.cc", - "sync/browser_synced_window_delegate.h", - "sync/browser_synced_window_delegates_getter.cc", - "sync/browser_synced_window_delegates_getter.h", - "sync/profile_signin_confirmation_helper.cc", - "sync/profile_signin_confirmation_helper.h", "tab_modal_confirm_dialog_delegate.cc", "tab_modal_confirm_dialog_delegate.h", "tabs/glic_actor_task_icon_controller.cc", @@ -1851,6 +1843,10 @@ # TODO(crbug.com/430078439): Remove this circular dependency when # .cc files stop including browser.h, browser_window.h and browser_navigator.h. "//chrome/browser/ui/user_education:impl", + + # TODO(crbug.com/432421124): Remove when the following headers aren't included + # or get componentized: c/b/ui/browser_dialogs.h, browser_navigation.h, browser.h. + "//chrome/browser/ui/sync:impl", ] if (is_mac) { @@ -3502,9 +3498,6 @@ if (toolkit_views) { sources += [ "bubble_anchor_util.h", - "sync/one_click_signin_links_delegate.h", - "sync/one_click_signin_links_delegate_impl.cc", - "sync/one_click_signin_links_delegate_impl.h", "toolbar_controller_util.cc", "toolbar_controller_util.h", "views/accelerator_table.cc", @@ -5027,8 +5020,6 @@ if (!is_chromeos) { sources += [ "idle_dialog.h", - "sync/sync_passphrase_dialog.cc", - "sync/sync_passphrase_dialog.h", "views/accessibility/accessibility_focus_highlight.cc", "views/accessibility/accessibility_focus_highlight.h", "views/frame/opaque_browser_frame_view.cc",
diff --git a/chrome/browser/ui/android/multiwindow/BUILD.gn b/chrome/browser/ui/android/multiwindow/BUILD.gn index 4a9ff834..b1cbb00 100644 --- a/chrome/browser/ui/android/multiwindow/BUILD.gn +++ b/chrome/browser/ui/android/multiwindow/BUILD.gn
@@ -43,6 +43,7 @@ "//third_party/android_deps:material_design_java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", + "//third_party/androidx:androidx_constraintlayout_constraintlayout_java", "//third_party/androidx:androidx_core_core_java", "//third_party/androidx:androidx_recyclerview_recyclerview_java__classes", "//ui/android:ui_no_recycler_view_java",
diff --git a/chrome/browser/ui/android/multiwindow/java/res/layout/instance_switcher_cmd_item_v2.xml b/chrome/browser/ui/android/multiwindow/java/res/layout/instance_switcher_cmd_item_v2.xml index 3c6c523..791736e 100644 --- a/chrome/browser/ui/android/multiwindow/java/res/layout/instance_switcher_cmd_item_v2.xml +++ b/chrome/browser/ui/android/multiwindow/java/res/layout/instance_switcher_cmd_item_v2.xml
@@ -16,10 +16,9 @@ <LinearLayout android:id="@+id/new_window" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="@dimen/instance_switcher_dialog_list_item_height" android:orientation="horizontal" android:visibility="gone" - android:paddingVertical="5dp" android:background="@drawable/list_item_background_bottom"> <ImageView android:id="@+id/favicon"
diff --git a/chrome/browser/ui/android/multiwindow/java/res/layout/instance_switcher_item_v2.xml b/chrome/browser/ui/android/multiwindow/java/res/layout/instance_switcher_item_v2.xml index b6e8ab6..ae9bbd9 100644 --- a/chrome/browser/ui/android/multiwindow/java/res/layout/instance_switcher_item_v2.xml +++ b/chrome/browser/ui/android/multiwindow/java/res/layout/instance_switcher_item_v2.xml
@@ -25,48 +25,57 @@ android:importantForAccessibility="no" /> <LinearLayout - android:id="@+id/text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="match_parent" + android:layout_height="@dimen/instance_switcher_dialog_list_item_height" + android:orientation="horizontal" + android:weightSum="8" android:layout_toEndOf="@id/favicon" - android:layout_toStartOf="@id/last_accessed" - android:layout_centerVertical="true" - android:orientation="vertical" - android:layout_marginEnd="8dp" > + android:layout_toStartOf="@id/close_button" + android:layout_centerVertical="true"> - <org.chromium.ui.widget.TextViewWithLeading - android:id="@+id/title" - android:layout_width="wrap_content" + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/text" + android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginTop="10dp" - android:maxLines="1" - android:ellipsize="end" - android:textAppearance="@style/TextAppearance.TextLarge.Primary.InstanceSwitcherItem" - android:layout_gravity="center_vertical" - app:leading="@dimen/text_size_large_leading" /> + android:layout_weight="5" + android:layout_gravity="center_vertical"> + <org.chromium.ui.widget.TextViewWithLeading + android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:maxLines="1" + android:ellipsize="end" + android:textAppearance="@style/TextAppearance.TextLarge.Primary.InstanceSwitcherItem" + app:leading="@dimen/text_size_large_leading" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintBottom_toTopOf="@+id/desc" + app:layout_constraintVertical_chainStyle="packed" /> + <TextView + android:id="@+id/desc" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:maxLines="1" + android:textAppearance="@style/TextAppearance.TextLarge.Secondary.InstanceSwitcherItem" + app:leading="@dimen/text_size_medium_leading" + app:layout_constraintTop_toBottomOf="@+id/title" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintBottom_toBottomOf="parent" /> + </androidx.constraintlayout.widget.ConstraintLayout> <TextView - android:id="@+id/desc" - android:layout_width="wrap_content" + android:id="@+id/last_accessed" + android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginBottom="10dp" + android:layout_weight="3" + android:ellipsize="end" + android:layout_marginEnd="16dp" android:maxLines="1" android:textAppearance="@style/TextAppearance.TextLarge.Secondary.InstanceSwitcherItem" android:layout_gravity="center_vertical" + android:gravity="end" app:leading="@dimen/text_size_medium_leading" /> </LinearLayout> - <TextView - android:id="@+id/last_accessed" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:maxLines="1" - android:textAppearance="@style/TextAppearance.TextLarge.Secondary.InstanceSwitcherItem" - android:layout_centerVertical="true" - android:layout_toStartOf="@id/close_button" - android:layout_marginEnd="16dp" - android:gravity="end" - app:leading="@dimen/text_size_medium_leading" /> - <ImageView android:id="@+id/close_button" android:src="@drawable/material_ic_close_24dp" @@ -75,7 +84,7 @@ android:layout_height="24dp" android:layout_alignParentEnd="true" android:layout_centerVertical="true" - android:layout_marginHorizontal="16dp" + android:layout_marginEnd="16dp" android:scaleType="fitCenter" app:tint="@color/instance_switcher_item_foreground_color_list"/> </RelativeLayout>
diff --git a/chrome/browser/ui/android/multiwindow/java/res/values/dimens.xml b/chrome/browser/ui/android/multiwindow/java/res/values/dimens.xml index 80bdc274..f8b28e3 100644 --- a/chrome/browser/ui/android/multiwindow/java/res/values/dimens.xml +++ b/chrome/browser/ui/android/multiwindow/java/res/values/dimens.xml
@@ -9,6 +9,7 @@ <dimen name="confirmation_dialog_width">328dp</dimen> <dimen name="confirmation_dialog_side_margin">16dp</dimen> <dimen name="instance_switcher_dialog_content_padding">16dp</dimen> + <dimen name="instance_switcher_dialog_list_item_height">64dp</dimen> <dimen name="instance_switcher_dialog_list_item_padding">2dp</dimen> <dimen name="instance_switcher_dialog_max_info_top_padding">16dp</dimen> <dimen name="instance_switcher_dialog_favicon_start_margin">16dp</dimen>
diff --git a/chrome/browser/ui/android/multiwindow/java/src/org/chromium/chrome/browser/multiwindow/TargetSelectorItemViewBinder.java b/chrome/browser/ui/android/multiwindow/java/src/org/chromium/chrome/browser/multiwindow/TargetSelectorItemViewBinder.java index 24de07c..6fa5b95c 100644 --- a/chrome/browser/ui/android/multiwindow/java/src/org/chromium/chrome/browser/multiwindow/TargetSelectorItemViewBinder.java +++ b/chrome/browser/ui/android/multiwindow/java/src/org/chromium/chrome/browser/multiwindow/TargetSelectorItemViewBinder.java
@@ -6,7 +6,6 @@ import android.view.View; import android.widget.ImageView; -import android.widget.RelativeLayout; import android.widget.TextView; import androidx.core.content.ContextCompat; @@ -58,9 +57,6 @@ TextView lastAccessedView = view.findViewById(R.id.last_accessed); String text = model.get(TargetSelectorItemProperties.LAST_ACCESSED); lastAccessedView.setText(text); - RelativeLayout.LayoutParams params = - (RelativeLayout.LayoutParams) lastAccessedView.getLayoutParams(); - params.addRule(RelativeLayout.ALIGN_PARENT_END); ImageView closeButton = view.findViewById(R.id.close_button); closeButton.setVisibility(View.GONE); }
diff --git a/chrome/browser/ui/ash/multi_user/BUILD.gn b/chrome/browser/ui/ash/multi_user/BUILD.gn index a62a4a9..fa3ee99 100644 --- a/chrome/browser/ui/ash/multi_user/BUILD.gn +++ b/chrome/browser/ui/ash/multi_user/BUILD.gn
@@ -58,23 +58,6 @@ ] } -static_library("test_support") { - testonly = true - - sources = [ - "test_multi_user_window_manager.cc", - "test_multi_user_window_manager.h", - ] - - deps = [ - ":multi_user", - "//ash/public/cpp", - "//base", - "//chrome/browser/ui", - "//components/account_id", - ] -} - source_set("unit_tests") { testonly = true
diff --git a/chrome/browser/ui/ash/multi_user/multi_profile_support.cc b/chrome/browser/ui/ash/multi_user/multi_profile_support.cc index d3a5daf..9e4e5faa 100644 --- a/chrome/browser/ui/ash/multi_user/multi_profile_support.cc +++ b/chrome/browser/ui/ash/multi_user/multi_profile_support.cc
@@ -70,6 +70,8 @@ : multi_user_window_manager_(multi_user_window_manager) { CHECK(multi_user_window_manager); multi_user_window_manager_observation_.Observe(multi_user_window_manager); + + BrowserList::AddObserver(this); } MultiProfileSupport::~MultiProfileSupport() { @@ -79,19 +81,6 @@ account_id_to_app_observer_.clear(); } -void MultiProfileSupport::Init() { - // Since we are setting the SessionStateObserver and adding the user, this - // function should get called only once. - auto current_account_id = multi_user_window_manager_->CurrentAccountId(); - DCHECK(account_id_to_app_observer_.find(current_account_id) == - account_id_to_app_observer_.end()); - - BrowserList::AddObserver(this); - - // Add an app window observer & all already running apps. - AddUser(current_account_id); -} - void MultiProfileSupport::AddUser(const AccountId& account_id) { // AddUser must not be called twice for the same account_id. CHECK(account_id_to_app_observer_.find(account_id) ==
diff --git a/chrome/browser/ui/ash/multi_user/multi_profile_support.h b/chrome/browser/ui/ash/multi_user/multi_profile_support.h index c6597eaa..3b4cf18 100644 --- a/chrome/browser/ui/ash/multi_user/multi_profile_support.h +++ b/chrome/browser/ui/ash/multi_user/multi_profile_support.h
@@ -42,9 +42,6 @@ ~MultiProfileSupport() override; - // Initializes the manager after its creation. Should only be called once. - void Init(); - void AddUser(const AccountId& account_id); // BrowserListObserver:
diff --git a/chrome/browser/ui/ash/multi_user/multi_profile_support_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_profile_support_unittest.cc index 01e67db..96df2f23 100644 --- a/chrome/browser/ui/ash/multi_user/multi_profile_support_unittest.cc +++ b/chrome/browser/ui/ash/multi_user/multi_profile_support_unittest.cc
@@ -204,7 +204,7 @@ .AddRegularUser(account_id)); } - void LoginUser(const AccountId& account_id) { + void LogInUser(const AccountId& account_id) { const auto* user = user_manager_->FindUser(account_id); CHECK(user); user_manager_->UserLoggedIn( @@ -231,15 +231,36 @@ if (user_manager_->GetActiveUser() != user) { user_manager_->SwitchActiveUser(user->GetAccountId()); + GetSessionControllerClient()->SwitchActiveUser(user->GetAccountId()); } } void AddLoggedInUsers(base::span<const AccountId> ids) { + // This must run only once, and when this is called, + // there should be no logged in users yet. + CHECK(user_manager::UserManager::Get()->GetLoggedInUsers().empty()); + CHECK(!ids.empty()); + for (const AccountId& account_id : ids) { AddUser(account_id); } - for (const AccountId& account_id : ids) { - LoginUser(account_id); + + // Primary user log-in. + LogInUser(ids[0]); + + // After the primary user log-in, (and before any more user log-ins), + // create MultiProfileSupport instance held by MultiUserWindowManagerHelper + // and initializes for the primary user, mirroring the timing of the + // initialization in the production. + // TODO(crbug.com/425160398): This should be simplified for the bug fix. + ::MultiUserWindowManagerHelper::CreateInstanceForTest(); + ash::MultiUserWindowManagerImpl::Get()->SetAnimationSpeedForTest( + ash::MultiUserWindowManagerImpl::ANIMATION_SPEED_DISABLED); + ::MultiUserWindowManagerHelper::GetWindowManager()->SetPrimaryUser(ids[0]); + + for (const AccountId& account_id : ids.subspan(1u)) { + LogInUser(account_id); + ::MultiUserWindowManagerHelper::GetInstance()->AddUser(account_id); } } @@ -364,10 +385,6 @@ windows_.push_back(CreateTestWindowInShellWithId(i)); windows_[i]->Show(); } - ::MultiUserWindowManagerHelper::CreateInstanceForTest( - user_manager_->GetActiveUser()->GetAccountId()); - ash::MultiUserWindowManagerImpl::Get()->SetAnimationSpeedForTest( - ash::MultiUserWindowManagerImpl::ANIMATION_SPEED_DISABLED); } std::vector<std::unique_ptr<views::Widget>> @@ -746,10 +763,6 @@ TEST_F(MultiProfileSupportTest, WindowVisibilityInMultipleDesksTests) { AddLoggedInUsers({kAccountIdA, kAccountIdB}); - ::MultiUserWindowManagerHelper::CreateInstanceForTest(kAccountIdA); - ash::MultiUserWindowManagerImpl::Get()->SetAnimationSpeedForTest( - ash::MultiUserWindowManagerImpl::ANIMATION_SPEED_DISABLED); - // In the user A, setup two desks with one window each. SwitchActiveUser(kAccountIdA); ash::AutotestDesksApi().CreateNewDesk();
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_context_menu_chromeos_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_user_context_menu_chromeos_unittest.cc index 7e7e32f..f9bcc68b2 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_context_menu_chromeos_unittest.cc +++ b/chrome/browser/ui/ash/multi_user/multi_user_context_menu_chromeos_unittest.cc
@@ -73,7 +73,10 @@ window_.reset(CreateTestWindowInShellWithId(0)); window_->Show(); - MultiUserWindowManagerHelper::CreateInstanceForTest(kAccountId1); + MultiUserWindowManagerHelper::CreateInstanceForTest(); + MultiUserWindowManagerHelper::GetWindowManager()->SetPrimaryUser( + kAccountId1); + MultiUserWindowManagerHelper::GetInstance()->AddUser(kAccountId1); } void TearDown() override {
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.cc index b00d8be4..a5d9706 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.cc +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.cc
@@ -8,8 +8,8 @@ #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.h" #include "chrome/browser/ui/ash/session/session_controller_client_impl.h" #include "components/account_id/account_id.h" -#include "components/user_manager/user.h" -#include "components/user_manager/user_manager.h" +#include "components/session_manager/core/session.h" +#include "components/session_manager/core/session_manager.h" namespace { MultiUserWindowManagerHelper* g_multi_user_window_manager_instance = nullptr; @@ -32,13 +32,12 @@ MultiUserWindowManagerHelper* MultiUserWindowManagerHelper::CreateInstance() { DCHECK(!g_multi_user_window_manager_instance); if (SessionControllerClientImpl::IsMultiProfileAvailable()) { - g_multi_user_window_manager_instance = new MultiUserWindowManagerHelper( - user_manager::UserManager::Get()->GetActiveUser()->GetAccountId()); + g_multi_user_window_manager_instance = + new MultiUserWindowManagerHelper(ash::MultiUserWindowManager::Create()); } else { g_multi_user_window_manager_instance = new MultiUserWindowManagerHelper( std::make_unique<MultiUserWindowManagerStub>()); } - g_multi_user_window_manager_instance->Init(); return g_multi_user_window_manager_instance; } @@ -65,14 +64,12 @@ } // static -void MultiUserWindowManagerHelper::CreateInstanceForTest( - const AccountId& account_id) { +void MultiUserWindowManagerHelper::CreateInstanceForTest() { if (g_multi_user_window_manager_instance) { DeleteInstance(); } g_multi_user_window_manager_instance = - new MultiUserWindowManagerHelper(account_id); - g_multi_user_window_manager_instance->Init(); + new MultiUserWindowManagerHelper(ash::MultiUserWindowManager::Create()); } // static @@ -83,19 +80,10 @@ } g_multi_user_window_manager_instance = new MultiUserWindowManagerHelper(std::move(window_manager)); - g_multi_user_window_manager_instance->Init(); -} - -void MultiUserWindowManagerHelper::Init() { - if (multi_profile_support_) { - multi_profile_support_->Init(); - } } void MultiUserWindowManagerHelper::AddUser(const AccountId& account_id) { - if (multi_profile_support_) { - multi_profile_support_->AddUser(account_id); - } + multi_profile_support_->AddUser(account_id); } bool MultiUserWindowManagerHelper::IsWindowOnDesktopOfUser( @@ -107,16 +95,11 @@ } MultiUserWindowManagerHelper::MultiUserWindowManagerHelper( - const AccountId& account_id) - : multi_user_window_manager_( - ash::MultiUserWindowManager::Create(account_id)), + std::unique_ptr<ash::MultiUserWindowManager> window_manager) + : multi_user_window_manager_(std::move(window_manager)), multi_profile_support_(std::make_unique<MultiProfileSupport>( multi_user_window_manager_.get())) {} -MultiUserWindowManagerHelper::MultiUserWindowManagerHelper( - std::unique_ptr<ash::MultiUserWindowManager> window_manager) - : multi_user_window_manager_(std::move(window_manager)) {} - MultiUserWindowManagerHelper::~MultiUserWindowManagerHelper() = default; const ash::MultiUserWindowManager*
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h index f462df2..4247703 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h
@@ -48,19 +48,13 @@ // Used in tests to create an instance with MultiProfileSupport configured for // |account_id|. - static void CreateInstanceForTest(const AccountId& account_id); + static void CreateInstanceForTest(); // Used in tests that want to supply a specific ash::MultiUserWindowManager // implementation. static void CreateInstanceForTest( std::unique_ptr<ash::MultiUserWindowManager> window_manager); - // Initializes |multi_profile_support_| if there is one. Separated from - // constructor because |multi_profile_support_| initialization code path - // accesses the helper instance via GetInstance(), which return nullptr - // before the constructor finishes. See https://crbug.com/1038300 - void Init(); - // Adds user to monitor starting and running V1/V2 application windows. // Returns immediately if the user (identified by a |profile|) is already // known to the manager. Note: This function is not implemented as a @@ -75,7 +69,6 @@ const AccountId& account_id) const; private: - explicit MultiUserWindowManagerHelper(const AccountId& account_id); explicit MultiUserWindowManagerHelper( std::unique_ptr<ash::MultiUserWindowManager> window_manager); ~MultiUserWindowManagerHelper();
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.cc index 7b8b5ae3..99a3f0b 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.cc +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.cc
@@ -54,3 +54,7 @@ ash::MultiUserWindowManagerObserver* observer) { NOTIMPLEMENTED_LOG_ONCE(); } + +void MultiUserWindowManagerStub::SetPrimaryUser(const AccountId& account_id) { + // Do nothing. +}
diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.h b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.h index 236bb566..2af9299 100644 --- a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.h +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_stub.h
@@ -32,6 +32,7 @@ const AccountId& CurrentAccountId() const override; void AddObserver(ash::MultiUserWindowManagerObserver* observer) override; void RemoveObserver(ash::MultiUserWindowManagerObserver* observer) override; + void SetPrimaryUser(const AccountId& account_id) override; }; #endif // CHROME_BROWSER_UI_ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_STUB_H_
diff --git a/chrome/browser/ui/ash/multi_user/test_multi_user_window_manager.cc b/chrome/browser/ui/ash/multi_user/test_multi_user_window_manager.cc deleted file mode 100644 index 0fae93f..0000000 --- a/chrome/browser/ui/ash/multi_user/test_multi_user_window_manager.cc +++ /dev/null
@@ -1,116 +0,0 @@ -// Copyright 2015 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/ash/multi_user/test_multi_user_window_manager.h" - -#include "base/memory/ptr_util.h" -#include "base/notimplemented.h" -#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" -#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h" -#include "chrome/browser/ui/browser_window.h" -#include "components/account_id/account_id.h" -#include "ui/aura/window.h" -#include "ui/views/widget/widget.h" - -TestMultiUserWindowManager::~TestMultiUserWindowManager() { - // This object is owned by the MultiUserWindowManager since the - // SetInstanceForTest call. As such no uninstall is required. -} - -// static -TestMultiUserWindowManager* TestMultiUserWindowManager::Create( - Browser* visiting_browser, - const AccountId& desktop_owner) { - // Must use WrapUnique() as constructor is private. - std::unique_ptr<TestMultiUserWindowManager> window_manager = base::WrapUnique( - new TestMultiUserWindowManager(visiting_browser, desktop_owner)); - TestMultiUserWindowManager* raw_window_manager = window_manager.get(); - MultiUserWindowManagerHelper::CreateInstanceForTest( - std::move(window_manager)); - return raw_window_manager; -} - -void TestMultiUserWindowManager::SetWindowOwner(aura::Window* window, - const AccountId& account_id) { - NOTREACHED(); -} - -const AccountId& TestMultiUserWindowManager::GetWindowOwner( - const aura::Window* window) const { - // No matter which window will get queried - all browsers belong to the - // original browser's user. - return browser_owner_; -} - -void TestMultiUserWindowManager::ShowWindowForUser( - aura::Window* window, - const AccountId& account_id) { - // This class is only able to handle one additional window <-> user - // association beside the creation parameters. - // If no association has yet been requested remember it now. - if (browser_owner_ != account_id) { - DCHECK(!created_window_); - } - created_window_ = window; - created_window_shown_for_ = account_id; - - if (browser_window_ == window) { - desktop_owner_ = account_id; - } - - if (account_id == current_account_id_) { - return; - } - - // Change the visibility of the window to update the view recursively. - views::Widget* widget = views::Widget::GetWidgetForNativeView(window); - widget->Hide(); - widget->Show(); - current_account_id_ = account_id; -} - -bool TestMultiUserWindowManager::AreWindowsSharedAmongUsers() const { - return browser_owner_ != desktop_owner_; -} - -std::set<AccountId> TestMultiUserWindowManager::GetOwnersOfVisibleWindows() - const { - return {}; -} - -const AccountId& TestMultiUserWindowManager::GetUserPresentingWindow( - const aura::Window* window) const { - if (window == browser_window_) { - return desktop_owner_; - } - if (created_window_ && window == created_window_) { - return created_window_shown_for_; - } - // We can come here before the window gets registered. - return browser_owner_; -} - -const AccountId& TestMultiUserWindowManager::CurrentAccountId() const { - return current_account_id_; -} - -void TestMultiUserWindowManager::AddObserver( - ash::MultiUserWindowManagerObserver* observer) { - NOTIMPLEMENTED_LOG_ONCE(); -} - -void TestMultiUserWindowManager::RemoveObserver( - ash::MultiUserWindowManagerObserver* observer) { - NOTIMPLEMENTED_LOG_ONCE(); -} - -TestMultiUserWindowManager::TestMultiUserWindowManager( - Browser* visiting_browser, - const AccountId& desktop_owner) - : browser_window_(visiting_browser->window()->GetNativeWindow()), - browser_owner_(multi_user_util::GetAccountIdFromProfile( - visiting_browser->profile())), - desktop_owner_(desktop_owner), - created_window_shown_for_(browser_owner_), - current_account_id_(desktop_owner) {}
diff --git a/chrome/browser/ui/ash/multi_user/test_multi_user_window_manager.h b/chrome/browser/ui/ash/multi_user/test_multi_user_window_manager.h deleted file mode 100644 index 1740715..0000000 --- a/chrome/browser/ui/ash/multi_user/test_multi_user_window_manager.h +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2015 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_ASH_MULTI_USER_TEST_MULTI_USER_WINDOW_MANAGER_H_ -#define CHROME_BROWSER_UI_ASH_MULTI_USER_TEST_MULTI_USER_WINDOW_MANAGER_H_ - -#include "ash/public/cpp/multi_user_window_manager.h" -#include "base/memory/raw_ptr.h" -#include "components/account_id/account_id.h" - -class Browser; - -// This is a test implementation of a MultiUserWindowManager which allows to -// test a visiting window on another desktop. It will install and remove itself -// from the system upon creation / destruction. The creation function gets a -// |browser| which is shown on |desktop_owner|'s desktop. -class TestMultiUserWindowManager : public ash::MultiUserWindowManager { - public: - TestMultiUserWindowManager(const TestMultiUserWindowManager&) = delete; - TestMultiUserWindowManager& operator=(const TestMultiUserWindowManager&) = - delete; - - ~TestMultiUserWindowManager() override; - - // Creates an installs TestMultiUserWindowManager as the - // MultiUserWindowManager used by MultiUserWindowManagerHelper. The returned - // value is owned by MultiUserWindowManagerHelper. - static TestMultiUserWindowManager* Create(Browser* visiting_browser, - const AccountId& desktop_owner); - - aura::Window* created_window() { return created_window_; } - - // ash::MultiUserWindowManager overrides: - void SetWindowOwner(aura::Window* window, - const AccountId& account_id) override; - const AccountId& GetWindowOwner(const aura::Window* window) const override; - void ShowWindowForUser(aura::Window* window, - const AccountId& account_id) override; - bool AreWindowsSharedAmongUsers() const override; - std::set<AccountId> GetOwnersOfVisibleWindows() const override; - const AccountId& GetUserPresentingWindow( - const aura::Window* window) const override; - const AccountId& CurrentAccountId() const override; - void AddObserver(ash::MultiUserWindowManagerObserver* observer) override; - void RemoveObserver(ash::MultiUserWindowManagerObserver* observer) override; - - private: - TestMultiUserWindowManager(Browser* visiting_browser, - const AccountId& desktop_owner); - - // The window of the visiting browser. - raw_ptr<aura::Window, AcrossTasksDanglingUntriaged> browser_window_; - // The owner of the visiting browser. - AccountId browser_owner_; - // The owner of the currently shown desktop. - AccountId desktop_owner_; - // The created window. - raw_ptr<aura::Window, AcrossTasksDanglingUntriaged> created_window_ = nullptr; - // The location of the window. - AccountId created_window_shown_for_; - // The current selected active user. - AccountId current_account_id_; -}; - -#endif // CHROME_BROWSER_UI_ASH_MULTI_USER_TEST_MULTI_USER_WINDOW_MANAGER_H_
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc index 562af092..5e283ff 100644 --- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc +++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
@@ -102,6 +102,8 @@ #include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/cpp/package_id.h" #include "components/services/app_service/public/cpp/types_util.h" +#include "components/session_manager/core/session.h" +#include "components/session_manager/core/session_manager.h" #include "components/strings/grit/components_strings.h" #include "components/sync_preferences/pref_service_syncable.h" #include "components/user_manager/user_manager.h" @@ -317,6 +319,11 @@ // On Chrome OS using multi profile we want to switch the content of the shelf // with a user change. Note that for unit tests the instance can be nullptr. if (SessionControllerClientImpl::IsMultiProfileAvailable()) { + auto active_account_id = + user_manager::UserManager::Get()->GetActiveUser()->GetAccountId(); + MultiUserWindowManagerHelper::GetWindowManager()->SetPrimaryUser( + active_account_id); + MultiUserWindowManagerHelper::GetInstance()->AddUser(active_account_id); user_switch_observer_ = std::make_unique<ChromeShelfControllerUserSwitchObserver>(this); }
diff --git a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client_unittest.cc b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client_unittest.cc index 14fa3aa..3ce0b4f 100644 --- a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client_unittest.cc +++ b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client_unittest.cc
@@ -375,8 +375,8 @@ std::u16string expected_description; #if BUILDFLAG(GOOGLE_CHROME_BRANDING) expected_description = - u"To pay faster next time, save your card, encrypted security code, and " - u"billing address in your Google Account"; + u"Pay faster when your card is saved. Card details are encrypted in " + u"your Google Account."; #endif // Verify that `AutofillSaveCardUiInfo` has the correct attributes that
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 0f0f52e..e0410ab 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1852,6 +1852,10 @@ window()->PreHandleDragExit(); } +void Browser::HandleDragEnded() { + window()->HandleDragEnded(); +} + content::KeyboardEventProcessingResult Browser::PreHandleKeyboardEvent( content::WebContents* source, const NativeWebKeyboardEvent& event) {
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index faef0cb..c5665ec2 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -709,6 +709,7 @@ void PreHandleDragUpdate(const content::DropData& drop_data, const gfx::PointF& client_pt) override; void PreHandleDragExit() override; + void HandleDragEnded() override; content::KeyboardEventProcessingResult PreHandleKeyboardEvent( content::WebContents* source, const input::NativeWebKeyboardEvent& event) override;
diff --git a/chrome/browser/ui/browser_finder_chromeos_unittest.cc b/chrome/browser/ui/browser_finder_chromeos_unittest.cc index 5988a0de..b8e4c02 100644 --- a/chrome/browser/ui/browser_finder_chromeos_unittest.cc +++ b/chrome/browser/ui/browser_finder_chromeos_unittest.cc
@@ -14,6 +14,7 @@ #include "chrome/test/base/test_browser_window_aura.h" #include "chrome/test/base/testing_profile_manager.h" #include "components/account_id/account_id.h" +#include "components/account_id/account_id_literal.h" #include "components/user_manager/user.h" #include "google_apis/gaia/gaia_id.h" #include "ui/base/ui_base_features.h" @@ -22,9 +23,12 @@ namespace { -constexpr char kTestAccount1[] = "user1@test.com"; -constexpr char kTestAccount2[] = "user2@test.com"; -constexpr GaiaId::Literal kFakeGaia2("fakegaia2"); +constexpr auto kTestAccountId1 = + AccountId::Literal::FromUserEmailGaiaId("user1@test.com", + GaiaId::Literal("fakegaia")); +constexpr auto kTestAccountId2 = + AccountId::Literal::FromUserEmailGaiaId("user2@test.com", + GaiaId::Literal("fakegaia2")); } // namespace @@ -35,23 +39,26 @@ BrowserFinderChromeOSTest& operator=(const BrowserFinderChromeOSTest&) = delete; - ash::MultiUserWindowManager* GetMultiUserWindowManager() { - if (!MultiUserWindowManagerHelper::GetInstance()) { - MultiUserWindowManagerHelper::CreateInstanceForTest(test_account_id1_); - } - return MultiUserWindowManagerHelper::GetWindowManager(); - } - - const AccountId test_account_id1_ = AccountId::FromUserEmail(kTestAccount1); - const AccountId test_account_id2_ = AccountId::FromUserEmail(kTestAccount2); - private: void SetUp() override { BrowserWithTestWindowTest::SetUp(); ash::ProfileHelper::Get(); // Instantiate. + + // Here the primary user/profile is created. + // *Then*, set up MultiUserWindowManagerHelper. This is to mirror the + // current implementation of the helper, which is done as a part of the + // shelf creation. The structure is going to be changed soon, though + // (crbug.com/4251603989). + ASSERT_FALSE(MultiUserWindowManagerHelper::GetInstance()); + MultiUserWindowManagerHelper::CreateInstanceForTest(); + MultiUserWindowManagerHelper::GetWindowManager()->SetPrimaryUser( + kTestAccountId1); + MultiUserWindowManagerHelper::GetInstance()->AddUser(kTestAccountId1); + // Create secondary user/profile. - LogIn(kTestAccount2, kFakeGaia2); - second_profile_ = CreateProfile(kTestAccount2); + LogIn(kTestAccountId2.GetUserEmail(), kTestAccountId2.GetGaiaId()); + second_profile_ = + CreateProfile(std::string(kTestAccountId2.GetUserEmail())); } void TearDown() override { @@ -62,7 +69,7 @@ // BrowserWithTestWindow: std::optional<std::string> GetDefaultProfileName() override { - return kTestAccount1; + return std::string(kTestAccountId1.GetUserEmail()); } TestingProfile* CreateProfile(const std::string& profile_name) override { @@ -70,12 +77,8 @@ auto* user = user_manager()->FindUserAndModify( AccountId::FromUserEmail(profile_name)); ash::ProfileHelper::Get()->SetUserToProfileMappingForTesting(user, profile); - // Force creation of MultiProfileSupport. - if (auto* helper = MultiUserWindowManagerHelper::GetInstance(); !helper) { - // First time. Create MultiUserWindowManagerHelper, which also registers - // the current user. - GetMultiUserWindowManager(); - } else { + + if (auto* helper = MultiUserWindowManagerHelper::GetInstance()) { // Second time or later. Explicitly call AddUser is needed to register // the user. helper->AddUser(user->GetAccountId()); @@ -111,16 +114,16 @@ Browser::CreateParams params(profile()->GetOriginalProfile(), true); std::unique_ptr<Browser> browser( chrome::CreateBrowserWithViewsTestWindowForParams(params)); - GetMultiUserWindowManager()->SetWindowOwner( - browser->window()->GetNativeWindow(), test_account_id1_); + MultiUserWindowManagerHelper::GetWindowManager()->SetWindowOwner( + browser->window()->GetNativeWindow(), kTestAccountId1); EXPECT_EQ(1u, chrome::GetBrowserCount(profile())); EXPECT_TRUE(chrome::FindAnyBrowser(profile(), true)); EXPECT_TRUE(chrome::FindAnyBrowser(profile(), false)); // Move the browser window to another user's desktop. Then no window should // be available for the current profile. - GetMultiUserWindowManager()->ShowWindowForUser( - browser->window()->GetNativeWindow(), test_account_id2_); + MultiUserWindowManagerHelper::GetWindowManager()->ShowWindowForUser( + browser->window()->GetNativeWindow(), kTestAccountId2); // ShowWindowForUser() notifies chrome async. FlushBindings() to ensure all // the changes happen. EXPECT_EQ(0u, chrome::GetBrowserCount(profile()));
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index cd517c1..0569b65 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h
@@ -528,6 +528,7 @@ virtual void PreHandleDragUpdate(const content::DropData& drop_data, const gfx::PointF& point) = 0; virtual void PreHandleDragExit() = 0; + virtual void HandleDragEnded() = 0; // Allows the BrowserWindow object to handle the specified keyboard event // before sending it to the renderer. virtual content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
diff --git a/chrome/browser/ui/browser_window/internal/BUILD.gn b/chrome/browser/ui/browser_window/internal/BUILD.gn index f42c699..d763b69 100644 --- a/chrome/browser/ui/browser_window/internal/BUILD.gn +++ b/chrome/browser/ui/browser_window/internal/BUILD.gn
@@ -44,6 +44,7 @@ "//chrome/browser/ui/lens", "//chrome/browser/ui/performance_controls", "//chrome/browser/ui/signin", + "//chrome/browser/ui/sync", "//chrome/browser/ui/tabs:tab_list_bridge", "//chrome/browser/ui/tabs/tab_strip_api", "//chrome/browser/ui/toasts",
diff --git a/chrome/browser/ui/cocoa/main_menu_builder.h b/chrome/browser/ui/cocoa/main_menu_builder.h index a9d8d87c..3bfa6f1 100644 --- a/chrome/browser/ui/cocoa/main_menu_builder.h +++ b/chrome/browser/ui/cocoa/main_menu_builder.h
@@ -131,6 +131,12 @@ return *this; } + // Gives the item a symbol from SF Symbols on macOS 26. + MenuItemBuilder& sf_symbol(NSString* symbol_name) { + sf_symbol_name_ = symbol_name; + return *this; + } + // Builds a NSMenuItem instance from the properties set on the Builder. NSMenuItem* Build() const; @@ -142,7 +148,7 @@ int tag_ = 0; - id __strong target_ = nil; + id __strong target_; SEL action_ = nil; NSString* __strong key_equivalent_ = @""; @@ -157,6 +163,9 @@ bool is_hidden_ = false; bool is_section_header_ = false; + + // The action image to use on macOS 26+. + NSString* __strong sf_symbol_name_; }; } // namespace internal
diff --git a/chrome/browser/ui/cocoa/main_menu_builder.mm b/chrome/browser/ui/cocoa/main_menu_builder.mm index 701f94a..3c66b05 100644 --- a/chrome/browser/ui/cocoa/main_menu_builder.mm +++ b/chrome/browser/ui/cocoa/main_menu_builder.mm
@@ -21,6 +21,18 @@ #import "ui/base/l10n/l10n_util_mac.h" #include "ui/strings/grit/ui_strings.h" +@interface NSImage (SPI) + +// Creates a system symbol image from SF Symbols with the specified name and +// value. Differs from +imageWithSystemSymbolName:accessibilityDescription: in +// that it allows instantiation of private symbols, those intended for +// Apple-only usage (see the SFSymbols.framework's bundles CoreGlyphs vs +// CoreGlyphsPrivate). ++ (instancetype)imageWithPrivateSystemSymbolName:(NSString*)name + accessibilityDescription:(NSString*)description; + +@end + namespace chrome { namespace { @@ -182,9 +194,11 @@ .action(@selector(paste:)), Item(IDS_PASTE_MATCH_STYLE_MAC) .tag(IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE) - .action(@selector(pasteAndMatchStyle:)), + .action(@selector(pasteAndMatchStyle:)) + .sf_symbol(@"paintbrush.page.on.clipboard"), Item(IDS_PASTE_MATCH_STYLE_MAC) .action(@selector(pasteAndMatchStyle:)) + .sf_symbol(@"paintbrush.page.on.clipboard") .is_alternate() .key_equivalent(@"V", NSEventModifierFlagCommand | NSEventModifierFlagOption), @@ -666,6 +680,14 @@ item.keyEquivalentModifierMask = key_equivalent_flags; item.alternate = is_alternate_; item.hidden = is_hidden_; + if (@available(macOS 26, *)) { + if (sf_symbol_name_) { + // Some action images that macOS uses by default are private and aren't + // accessible via normal lookup, so use SPI. + item.image = [NSImage imageWithPrivateSystemSymbolName:sf_symbol_name_ + accessibilityDescription:nil]; + } + } if (submenu_.has_value()) { NSMenu* menu = [[NSMenu alloc] initWithTitle:title];
diff --git a/chrome/browser/ui/download/download_bubble_security_view_info.cc b/chrome/browser/ui/download/download_bubble_security_view_info.cc index 73289562..a0b73954 100644 --- a/chrome/browser/ui/download/download_bubble_security_view_info.cc +++ b/chrome/browser/ui/download/download_bubble_security_view_info.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/download/bubble/download_bubble_prefs.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_item_warning_data.h" +#include "chrome/browser/download/download_ui_enterprise_util.h" #include "chrome/browser/download/download_ui_safe_browsing_util.h" #include "chrome/browser/download/offline_item_utils.h" #include "chrome/browser/safe_browsing/advanced_protection_status_manager.h"
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc index 091ecc6..50a6424 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -1176,6 +1176,12 @@ } IN_PROC_BROWSER_TEST_P(AutomaticFullscreenTest, CrossOriginIFrameDenied) { +#if BUILDFLAG(IS_MAC) + if (GetParam()) { + GTEST_SKIP() << "Flaky. See https://crbug.com/404887514"; + } +#endif + // Append a cross-origin iframe without the permission policy. const GURL src = embedded_https_test_server().GetURL("b.com", "/simple.html"); content::RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
diff --git a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/infobar/SimpleConfirmInfoBarBuilder.java b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/infobar/SimpleConfirmInfoBarBuilder.java index 998573c..f8e8107d 100644 --- a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/infobar/SimpleConfirmInfoBarBuilder.java +++ b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/infobar/SimpleConfirmInfoBarBuilder.java
@@ -24,7 +24,7 @@ @NullMarked public class SimpleConfirmInfoBarBuilder { /** Listens for when users interact with an infobar. */ - public static interface Listener { + public interface Listener { /** Called when the infobar was dismissed. */ void onInfoBarDismissed();
diff --git a/chrome/browser/ui/plus_addresses/android/java/src/org/chromium/chrome/browser/ui/plus_addresses/AllPlusAddressesBottomSheetCoordinator.java b/chrome/browser/ui/plus_addresses/android/java/src/org/chromium/chrome/browser/ui/plus_addresses/AllPlusAddressesBottomSheetCoordinator.java index 4b12cf65..9d7a03d 100644 --- a/chrome/browser/ui/plus_addresses/android/java/src/org/chromium/chrome/browser/ui/plus_addresses/AllPlusAddressesBottomSheetCoordinator.java +++ b/chrome/browser/ui/plus_addresses/android/java/src/org/chromium/chrome/browser/ui/plus_addresses/AllPlusAddressesBottomSheetCoordinator.java
@@ -38,7 +38,7 @@ * This delegate is called when the AllPlusAddressesBottomSheet is interacted with (e.g. * dismissed or a suggestion was selected). */ - static interface Delegate { + interface Delegate { /** * Called when the user taps on one of the plus addresses chips. *
diff --git a/chrome/browser/ui/plus_addresses/android/java/src/org/chromium/chrome/browser/ui/plus_addresses/PlusAddressCreationMediator.java b/chrome/browser/ui/plus_addresses/android/java/src/org/chromium/chrome/browser/ui/plus_addresses/PlusAddressCreationMediator.java index 271bc91..d921c39 100644 --- a/chrome/browser/ui/plus_addresses/android/java/src/org/chromium/chrome/browser/ui/plus_addresses/PlusAddressCreationMediator.java +++ b/chrome/browser/ui/plus_addresses/android/java/src/org/chromium/chrome/browser/ui/plus_addresses/PlusAddressCreationMediator.java
@@ -27,6 +27,7 @@ import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -220,7 +221,7 @@ // TabModelObserver @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { // While the bottom sheet scrim covers the omnibox UI, a new tab can be created in other // ways such as by opening a link from another app. In this case we want to hide the bottom // sheet rather than keeping the bottom sheet open while this tab loads behind the scrim.
diff --git a/chrome/browser/ui/plus_addresses/android/java/src/org/chromium/chrome/browser/ui/plus_addresses/PlusAddressCreationViewBridge.java b/chrome/browser/ui/plus_addresses/android/java/src/org/chromium/chrome/browser/ui/plus_addresses/PlusAddressCreationViewBridge.java index 329c836..fe555a0 100644 --- a/chrome/browser/ui/plus_addresses/android/java/src/org/chromium/chrome/browser/ui/plus_addresses/PlusAddressCreationViewBridge.java +++ b/chrome/browser/ui/plus_addresses/android/java/src/org/chromium/chrome/browser/ui/plus_addresses/PlusAddressCreationViewBridge.java
@@ -58,7 +58,7 @@ } @VisibleForTesting - /*package*/ static interface CoordinatorFactory { + /*package*/ interface CoordinatorFactory { PlusAddressCreationCoordinator create( Context context, BottomSheetController bottomSheetController,
diff --git a/chrome/browser/ui/sync/BUILD.gn b/chrome/browser/ui/sync/BUILD.gn new file mode 100644 index 0000000..96ef0b6 --- /dev/null +++ b/chrome/browser/ui/sync/BUILD.gn
@@ -0,0 +1,169 @@ +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/ui.gni") +import("//extensions/buildflags/buildflags.gni") + +source_set("sync") { + sources = [ "tab_contents_synced_tab_delegate.h" ] + public_deps = [ + "//base", + "//components/sessions:session_id", + "//components/sync_sessions", + ] + + if (!is_android) { + sources += [ + "browser_synced_tab_delegate.h", + "browser_synced_window_delegate.h", + "browser_synced_window_delegates_getter.h", + "profile_signin_confirmation_helper.h", + ] + public_deps += [ + "//chrome/browser/ui/browser_window", + "//chrome/browser/ui/tabs:tab_strip_model_observer", + "//content/public/browser", + ] + } + + if (toolkit_views) { + sources += [ + "one_click_signin_links_delegate.h", + "one_click_signin_links_delegate_impl.h", + ] + if (!is_chromeos) { + sources += [ "sync_passphrase_dialog.h" ] + public_deps += [ "//ui/base" ] + } + } +} + +source_set("impl") { + sources = [ "tab_contents_synced_tab_delegate.cc" ] + deps = [ + ":sync", + "//base", + "//chrome/browser/profiles:profile", + "//components/sessions", + "//components/sync/base:features", + "//components/sync_sessions", + "//content/public/browser", + "//extensions/buildflags", + ] + + if (enable_extensions) { + deps += [ "//chrome/browser/apps/app_service" ] + } + + if (!is_android) { + sources += [ + "browser_synced_tab_delegate.cc", + "browser_synced_window_delegate.cc", + "browser_synced_window_delegates_getter.cc", + "profile_signin_confirmation_helper.cc", + ] + deps += [ + "//chrome/browser/sync", + "//chrome/browser/ui/tabs:tab_strip", + "//components/bookmarks/browser", + "//components/browser_sync", + "//components/history/core/browser", + ] + } + + if (toolkit_views) { + sources += [ "one_click_signin_links_delegate_impl.cc" ] + deps += [ "//chrome/common" ] + + if (!is_chromeos) { + sources += [ "sync_passphrase_dialog.cc" ] + deps += [ + "//chrome/browser:browser_process", + "//components/strings", + "//ui/base", + "//url", + ] + } + } +} + +source_set("unit_tests") { + testonly = true + sources = [ "tab_contents_synced_tab_delegate_unittest.cc" ] + deps = [ + ":sync", + "//base/test:test_support", + "//chrome/test:test_support", + "//components/sync/base:features", + "//components/sync/protocol", + "//components/sync_sessions:test_support", + "//content/public/browser", + "//content/test:test_support", + "//testing/gtest", + "//third_party/blink/public/common:headers", + ] + + if (!is_android) { + sources += [ "profile_signin_confirmation_helper_unittest.cc" ] + deps += [ + "//chrome/browser:browser_process", + "//chrome/browser/extensions:test_support", + "//chrome/browser/prefs", + "//components/bookmarks/test", + "//components/pref_registry:pref_registry", + "//components/prefs:test_support", + "//components/sync_preferences:test_support", + ] + if (is_chromeos) { + deps += [ + "//chrome/browser/ash/login/users", + "//chrome/browser/ash/settings:test_support", + ] + } + + if (is_linux || is_mac || is_win) { + sources += [ "sync_passphrase_dialog_unittest.cc" ] + deps += [ "//components/sync:test_support" ] + } + } +} + +if (!is_android) { + source_set("browser_tests") { + testonly = true + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] + sources = [ "one_click_signin_links_delegate_impl_browsertest.cc" ] + deps = [ + ":sync", + "//chrome/browser/ui/tabs:tab_strip", + "//chrome/test:test_support", + "//chrome/test:test_support_ui", + "//content/test:test_support", + ] + } + + if (!is_chromeos_device) { + source_set("interactive_ui_tests") { + testonly = true + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] + + if (is_mac || is_linux || is_win) { + sources = [ "sync_passphrase_dialog_browsertest.cc" ] + deps = [ + ":sync", + "//base", + "//base/test:test_support", + "//chrome/common", + "//chrome/test:test_support_ui", + "//content/test:test_support", + "//testing/gtest", + "//ui/base", + "//ui/base:test_support", + "//ui/views", + "//url", + ] + } + } + } +}
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 6351999..9b81e66 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
@@ -16,6 +16,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/extension_install_prompt_show_params.h" +#include "chrome/browser/picture_in_picture/picture_in_picture_input_protector.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" @@ -58,6 +59,8 @@ #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/table_layout.h" #include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_delegate.h" +#include "ui/views/window/dialog_delegate.h" using content::OpenURLParams; using content::Referrer; @@ -465,6 +468,18 @@ justification_view_->SetJustificationTextForTesting(new_text); // IN-TEST } +bool ExtensionInstallDialogView:: + ShouldIgnoreButtonPressedEventHandlingForTesting( + View* button, + const ui::Event& event) const { + return ShouldIgnoreButtonPressedEventHandling(button, event); +} + +bool ExtensionInstallDialogView:: + ShouldAllowKeyEventsDuringInputProtectionForTesting() const { + return ShouldAllowKeyEventsDuringInputProtection(); +} + void ExtensionInstallDialogView::ResizeWidget() { GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); } @@ -561,6 +576,10 @@ } GetBubbleFrameView()->SetTitleView(std::move(title_container)); + + picture_in_picture_input_protector_ = + std::make_unique<PictureInPictureInputProtector>( + GetWidget()->widget_delegate()->AsDialogDelegate()); } void ExtensionInstallDialogView::OnDialogCanceled() { @@ -621,6 +640,20 @@ return title_; } +bool ExtensionInstallDialogView::ShouldIgnoreButtonPressedEventHandling( + View* button, + const ui::Event& event) const { + // Ignore button pressed events whenever we are occluded by a + // Picture-in-Picture window. + return picture_in_picture_input_protector_ && + picture_in_picture_input_protector_->OccludedByPictureInPicture(); +} + +bool ExtensionInstallDialogView::ShouldAllowKeyEventsDuringInputProtection() + const { + return false; +} + void ExtensionInstallDialogView::CloseDialog() { GetWidget()->Close(); }
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view.h b/chrome/browser/ui/views/extensions/extension_install_dialog_view.h index 6451801..370eeb20 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.h +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.h
@@ -23,6 +23,7 @@ #include "ui/views/controls/textfield/textfield_controller.h" #include "ui/views/view.h" +class PictureInPictureInputProtector; class Profile; // Modal dialog that shows when the user attempts to install an extension. Also @@ -60,11 +61,19 @@ void AddedToWidget() override; bool IsDialogButtonEnabled(ui::mojom::DialogButton button) const override; std::u16string GetAccessibleWindowTitle() const override; + bool ShouldIgnoreButtonPressedEventHandling( + View* button, + const ui::Event& event) const override; + bool ShouldAllowKeyEventsDuringInputProtection() const override; ExtensionInstallPromptShowParams* GetShowParamsForTesting(); void ClickLinkForTesting(); bool IsJustificationFieldVisibleForTesting(); void SetJustificationTextForTesting(const std::u16string& new_text); + bool ShouldIgnoreButtonPressedEventHandlingForTesting( + View* button, + const ui::Event& event) const; + bool ShouldAllowKeyEventsDuringInputProtectionForTesting() const; private: // Forward-declaration. @@ -130,6 +139,12 @@ // The justification text field view where users enter their justification for // requesting an extension. raw_ptr<ExtensionJustificationView> justification_view_ = nullptr; + + // The PictureInPictureInputProtector tracks dialog occlusions by + // Picture-in-Picture windows, to ensure input protection and ignore spurious + // interactions. + std::unique_ptr<PictureInPictureInputProtector> + picture_in_picture_input_protector_; }; #endif // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_INSTALL_DIALOG_VIEW_H_
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc index 247f315..15e65eff 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view_browsertest.cc
@@ -14,6 +14,7 @@ #include "base/memory/raw_ptr.h" #include "base/path_service.h" #include "base/run_loop.h" +#include "base/scoped_observation.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -25,6 +26,9 @@ #include "chrome/browser/extensions/extension_install_prompt_show_params.h" #include "chrome/browser/extensions/extension_install_prompt_test_helper.h" #include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/picture_in_picture/document_picture_in_picture_mixin_test_base.h" +#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.h" +#include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -33,11 +37,14 @@ #include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/test/test_browser_dialog.h" +#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension_test_util.h" #include "chrome/grit/generated_resources.h" +#include "chrome/test/base/mixin_based_in_process_browser_test.h" #include "components/constrained_window/constrained_window_views.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/document_picture_in_picture_window_controller.h" #include "content/public/test/browser_test.h" #include "content/public/test/test_utils.h" #include "extensions/browser/extension_icon_manager.h" @@ -54,13 +61,18 @@ #include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/mojom/dialog_button.mojom.h" +#include "ui/events/event.h" +#include "ui/events/event_utils.h" #include "ui/gfx/native_widget_types.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/bubble/bubble_frame_view.h" #include "ui/views/controls/scroll_view.h" +#include "ui/views/metrics.h" +#include "ui/views/test/button_test_api.h" #include "ui/views/test/widget_test.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_observer.h" using extensions::PermissionIDSet; using extensions::PermissionMessage; @@ -75,6 +87,29 @@ waiter.Wait(); } +class WidgetBoundsChangedWaiter : public views::WidgetObserver { + public: + explicit WidgetBoundsChangedWaiter(views::Widget* widget) { + old_bounds_ = widget->GetWindowBoundsInScreen(); + observation_.Observe(widget); + } + + void Wait() { run_loop_.Run(); } + + void OnWidgetBoundsChanged(views::Widget* widget, + const gfx::Rect& bounds) override { + if (bounds != old_bounds_) { + run_loop_.Quit(); + } + } + + private: + base::ScopedObservation<views::Widget, views::WidgetObserver> observation_{ + this}; + gfx::Rect old_bounds_; + base::RunLoop run_loop_; +}; + } // namespace class ExtensionInstallDialogViewTestBase @@ -907,3 +942,173 @@ CloseAndWait(delegate_view->GetWidget()); } + +using ExtensionInstallDialogPictureInPictureInputProtectorTestBase = + InProcessBrowserTestMixinHostSupport<ExtensionInstallDialogViewTest>; + +class ExtensionInstallDialogPictureInPictureInputProtectorTest + : public ExtensionInstallDialogPictureInPictureInputProtectorTestBase { + protected: + bool WidgetsOverlap(views::Widget* first_widget, + views::Widget* second_widget) { + return first_widget->GetWindowBoundsInScreen().Intersects( + second_widget->GetWindowBoundsInScreen()); + } + + void ResizeWidgetAndWaitIfNeeded( + views::Widget* widget, + const gfx::Rect& target_bounds, + PictureInPictureWindowManager* pip_window_manager) { + const gfx::Rect current_bounds = widget->GetWindowBoundsInScreen(); + if (current_bounds == target_bounds) { + return; + } + + { + WidgetBoundsChangedWaiter waiter(widget); + widget->SetBounds(target_bounds); + waiter.Wait(); + } + + pip_window_manager->GetOcclusionTracker() + ->FireBoundsChangedThrottleTimerForTesting(); + } + + DocumentPictureInPictureMixinTestBase picture_in_picture_test_base_{ + &mixin_host_}; +}; + +IN_PROC_BROWSER_TEST_F(ExtensionInstallDialogPictureInPictureInputProtectorTest, + ShouldIgnoreButtonEventsWhenOccluded) { + ExtensionInstallDialogView::SetInstallButtonDelayForTesting(0); + ExtensionInstallPromptTestHelper helper; + ExtensionInstallDialogView* delegate_view = CreateAndShowPrompt(&helper); + base::RunLoop().RunUntilIdle(); + + // Check that dialog is visible. + EXPECT_TRUE(delegate_view->GetVisible()); + + // Check buttons state after timeout. + EXPECT_TRUE( + delegate_view->IsDialogButtonEnabled(ui::mojom::DialogButton::kOk)); + EXPECT_TRUE( + delegate_view->IsDialogButtonEnabled(ui::mojom::DialogButton::kCancel)); + EXPECT_TRUE(delegate_view->GetInitiallyFocusedView()->HasFocus()); + + // Open picture-in-picture window + picture_in_picture_test_base_.NavigateToURLAndEnterPictureInPicture( + browser()); + auto* pip_web_contents = + picture_in_picture_test_base_.window_controller()->GetChildWebContents(); + ASSERT_NE(nullptr, pip_web_contents); + picture_in_picture_test_base_.WaitForPageLoad(pip_web_contents); + + auto* browser_view = + BrowserWindow::FindBrowserWindowWithWebContents(pip_web_contents) + ->AsBrowserView(); + auto* pip_window_manager = PictureInPictureWindowManager::GetInstance(); + ASSERT_NE(nullptr, pip_window_manager); + + // Ensure that the extension install dialog and picture-in-picture widgets do + // not overlap. + ResizeWidgetAndWaitIfNeeded(delegate_view->GetWidget(), + gfx::Rect(0, 0, 256, 256), pip_window_manager); + + ResizeWidgetAndWaitIfNeeded(browser_view->GetWidget(), + gfx::Rect(300, 0, 256, 256), pip_window_manager); + ASSERT_FALSE( + WidgetsOverlap(delegate_view->GetWidget(), browser_view->GetWidget())); + + // Verify that button pressed events are not ignored, since the extension + // install dialog is not occluded. + ui::MouseEvent mouse_event(ui::EventType::kMousePressed, gfx::Point(), + gfx::Point(), ui::EventTimeForNow(), 0, 0); + EXPECT_FALSE(delegate_view->ShouldIgnoreButtonPressedEventHandlingForTesting( + nullptr, mouse_event)); + + // Ensure that the extension install dialog and picture-in-picture widgets + // overlap. + ResizeWidgetAndWaitIfNeeded( + browser_view->GetWidget(), + delegate_view->GetWidget()->GetWindowBoundsInScreen(), + pip_window_manager); + ASSERT_TRUE( + WidgetsOverlap(delegate_view->GetWidget(), browser_view->GetWidget())); + + // Verify that button pressed events are ignored, since the extension install + // dialog is occluded. + EXPECT_TRUE(delegate_view->ShouldIgnoreButtonPressedEventHandlingForTesting( + nullptr, mouse_event)); + CloseAndWait(delegate_view->GetWidget()); +} + +IN_PROC_BROWSER_TEST_F(ExtensionInstallDialogPictureInPictureInputProtectorTest, + KeyEventsAreProtected) { + ExtensionInstallDialogView::SetInstallButtonDelayForTesting(0); + ExtensionInstallPromptTestHelper helper; + ExtensionInstallDialogView* delegate_view = CreateAndShowPrompt(&helper); + base::RunLoop().RunUntilIdle(); + + // Check that dialog is visible. + EXPECT_TRUE(delegate_view->GetVisible()); + + // Check buttons state after timeout. + EXPECT_TRUE( + delegate_view->IsDialogButtonEnabled(ui::mojom::DialogButton::kOk)); + EXPECT_TRUE( + delegate_view->IsDialogButtonEnabled(ui::mojom::DialogButton::kCancel)); + EXPECT_TRUE(delegate_view->GetInitiallyFocusedView()->HasFocus()); + + // Verify that key events are not allowed during input protection. + EXPECT_FALSE( + delegate_view->ShouldAllowKeyEventsDuringInputProtectionForTesting()); + + // Open picture-in-picture window + picture_in_picture_test_base_.NavigateToURLAndEnterPictureInPicture( + browser()); + auto* pip_web_contents = + picture_in_picture_test_base_.window_controller()->GetChildWebContents(); + ASSERT_NE(nullptr, pip_web_contents); + picture_in_picture_test_base_.WaitForPageLoad(pip_web_contents); + + auto* browser_view = + BrowserWindow::FindBrowserWindowWithWebContents(pip_web_contents) + ->AsBrowserView(); + auto* pip_window_manager = PictureInPictureWindowManager::GetInstance(); + ASSERT_NE(nullptr, pip_window_manager); + + // Occlude, and immediately un-occlude, the extension install dialog with a + // picture-in-picture window. + ResizeWidgetAndWaitIfNeeded( + browser_view->GetWidget(), + delegate_view->GetWidget()->GetWindowBoundsInScreen(), + pip_window_manager); + ASSERT_TRUE( + WidgetsOverlap(delegate_view->GetWidget(), browser_view->GetWidget())); + + ResizeWidgetAndWaitIfNeeded(delegate_view->GetWidget(), + gfx::Rect(0, 0, 256, 256), pip_window_manager); + + ResizeWidgetAndWaitIfNeeded(browser_view->GetWidget(), + gfx::Rect(300, 0, 256, 256), pip_window_manager); + ASSERT_FALSE( + WidgetsOverlap(delegate_view->GetWidget(), browser_view->GetWidget())); + + // Verify that the Ok button can not be interacted with during input + // protection. + ui::KeyEvent press_enter(ui::EventType::kKeyPressed, ui::VKEY_RETURN, + ui::EF_NONE, ui::EventTimeForNow()); + views::test::ButtonTestApi(delegate_view->GetOkButton()) + .NotifyClick(press_enter); + EXPECT_FALSE(delegate_view->GetWidget()->IsClosed()); + + // Verify that the Ok button can be interacted with after input protection. + ui::KeyEvent press_enter_delayed( + ui::EventType::kKeyPressed, ui::VKEY_RETURN, ui::EF_NONE, + ui::EventTimeForNow() + + base::Milliseconds(views::GetDoubleClickInterval())); + views::test::ButtonTestApi(delegate_view->GetOkButton()) + .NotifyClick(press_enter_delayed); + EXPECT_TRUE(delegate_view->GetWidget()->IsClosed()); + CloseAndWait(delegate_view->GetWidget()); +}
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc index c0ea3be2..5d7a78af 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
@@ -7,6 +7,8 @@ #include <string> #include "ash/constants/web_app_id_constants.h" +#include "ash/public/cpp/multi_user_window_manager.h" +#include "ash/public/cpp/new_window_delegate.h" #include "ash/public/cpp/test/shell_test_api.h" #include "ash/root_window_controller.h" #include "ash/shelf/shelf.h" @@ -28,6 +30,8 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/browser_app_launcher.h" +#include "chrome/browser/ash/login/test/device_state_mixin.h" +#include "chrome/browser/ash/login/test/login_manager_mixin.h" #include "chrome/browser/ash/system_web_apps/system_web_app_manager.h" #include "chrome/browser/ash/system_web_apps/test_support/test_system_web_app_installation.h" #include "chrome/browser/prefs/session_startup_pref.h" @@ -37,7 +41,7 @@ #include "chrome/browser/ui/actions/chrome_action_id.h" #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h" -#include "chrome/browser/ui/ash/multi_user/test_multi_user_window_manager.h" +#include "chrome/browser/ui/ash/session/session_controller_client_impl.h" #include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h" #include "chrome/browser/ui/ash/test_util.h" #include "chrome/browser/ui/browser.h" @@ -83,6 +87,7 @@ #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "chromeos/ash/components/browser_context_helper/browser_context_helper.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/ui/base/chromeos_ui_constants.h" #include "chromeos/ui/base/window_properties.h" @@ -93,10 +98,15 @@ #include "chromeos/ui/frame/frame_header.h" #include "chromeos/ui/frame/multitask_menu/float_controller_base.h" #include "components/account_id/account_id.h" +#include "components/account_id/account_id_literal.h" #include "components/keep_alive_registry/keep_alive_types.h" #include "components/keep_alive_registry/scoped_keep_alive.h" #include "components/password_manager/core/browser/password_form.h" #include "components/services/app_service/public/cpp/app_update.h" +#include "components/session_manager/core/session.h" +#include "components/session_manager/core/session_manager.h" +#include "components/signin/public/identity_manager/account_managed_status_finder.h" +#include "components/user_manager/user_manager_pref_names.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" @@ -1634,8 +1644,57 @@ EXPECT_TRUE(frame_view->caption_button_container()->GetVisible()); } -using BrowserNonClientFrameViewAshTestNoWebUiTabStrip = - BrowserNonClientFrameViewChromeOSTestNoWebUiTabStrip; +class BrowserNonClientFrameViewAshTestNoWebUiTabStrip + : public BrowserNonClientFrameViewChromeOSTestNoWebUiTabStrip { + public: + static constexpr inline auto kPrimaryAccountId = + AccountId::Literal::FromUserEmailGaiaId("primary@test", + GaiaId::Literal("12345")); + + static constexpr inline auto kSecondaryAccountId = + AccountId::Literal::FromUserEmailGaiaId("secondary@test", + GaiaId::Literal("67890")); + + void SetUp() override { + set_exit_when_last_browser_closes(false); + signin::AccountManagedStatusFinder::SetNonEnterpriseDomainForTesting( + "test"); + BrowserNonClientFrameViewChromeOSTestNoWebUiTabStrip::SetUp(); + } + + void TearDown() override { + BrowserNonClientFrameViewChromeOSTestNoWebUiTabStrip::TearDown(); + signin::AccountManagedStatusFinder::SetNonEnterpriseDomainForTesting( + nullptr); + } + + void LogIn(const AccountId& account_id) { + // If there's already a session, i.e. if this is multi user sign in, + // first, launch user selection flow. + if (auto* primary_session = + session_manager::SessionManager::Get()->GetPrimarySession()) { + // Mark the acknowledge for the multi-user sign-in. + user_manager::User* primary_user = + user_manager::UserManager::Get()->FindUserAndModify( + primary_session->account_id()); + primary_user->GetProfilePrefs()->SetBoolean( + user_manager::prefs::kMultiProfileNeverShowIntro, true); + SessionControllerClientImpl::Get()->ShowMultiProfileLogin(); + } + login_manager_mixin_.LoginWithDefaultContext( + ash::LoginManagerMixin::TestUserInfo(account_id)); + } + + private: + ash::DeviceStateMixin device_state_{ + &mixin_host_, + ash::DeviceStateMixin::State::OOBE_COMPLETED_PERMANENTLY_UNOWNED}; + + ash::LoginManagerMixin login_manager_mixin_{ + &mixin_host_, + {ash::LoginManagerMixin::TestUserInfo(kPrimaryAccountId), + ash::LoginManagerMixin::TestUserInfo(kSecondaryAccountId)}}; +}; // Tests that Avatar icon should show on the top left corner of the teleported // browser window on ChromeOS. @@ -1643,28 +1702,47 @@ // webUI tabstrip. IN_PROC_BROWSER_TEST_P(BrowserNonClientFrameViewAshTestNoWebUiTabStrip, AvatarDisplayOnTeleportedWindow) { - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + LogIn(kPrimaryAccountId); + Profile* primary_user_profile = Profile::FromBrowserContext( + ash::BrowserContextHelper::Get()->GetBrowserContextByAccountId( + kPrimaryAccountId)); + + ash::NewWindowDelegate::GetInstance()->NewWindow( + /*incognito=*/false, /*should_trigger_session_restore=*/false); + Browser* browser = chrome::FindBrowserWithProfile(primary_user_profile); + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); BrowserNonClientFrameViewChromeOS* frame_view = GetFrameViewChromeOS(browser_view); BrowserNonClientFrameViewChromeOSTestApi test_api(frame_view); - aura::Window* window = browser()->window()->GetNativeWindow(); + aura::Window* window = browser->window()->GetNativeWindow(); EXPECT_FALSE(MultiUserWindowManagerHelper::ShouldShowAvatar(window)); EXPECT_FALSE(test_api.GetProfileIndicatorIcon()); - const AccountId account_id1 = - multi_user_util::GetAccountIdFromProfile(browser()->profile()); - TestMultiUserWindowManager* window_manager = - TestMultiUserWindowManager::Create(browser(), account_id1); + // Log in with the secondary user. + LogIn(kSecondaryAccountId); - // Teleport the window to another desktop. - const AccountId account_id2(AccountId::FromUserEmail("user2")); - window_manager->ShowWindowForUser(window, account_id2); + // Move back to the primary user's desktop. + SessionControllerClientImpl::Get()->SwitchActiveUser(kPrimaryAccountId); + ASSERT_EQ( + session_manager::SessionManager::Get()->GetActiveSession()->account_id(), + kPrimaryAccountId); + + auto* window_manager = MultiUserWindowManagerHelper::GetWindowManager(); + + // Teleport the window to secondary user's desktop. + browser_view->Activate(); + window_manager->ShowWindowForUser(window, kSecondaryAccountId); + ASSERT_EQ( + session_manager::SessionManager::Get()->GetActiveSession()->account_id(), + kSecondaryAccountId); + EXPECT_TRUE(MultiUserWindowManagerHelper::ShouldShowAvatar(window)); EXPECT_TRUE(test_api.GetProfileIndicatorIcon()); // Teleport the window back to owner desktop. - window_manager->ShowWindowForUser(window, account_id1); + browser_view->Activate(); + window_manager->ShowWindowForUser(window, kPrimaryAccountId); EXPECT_FALSE(MultiUserWindowManagerHelper::ShouldShowAvatar(window)); EXPECT_FALSE(test_api.GetProfileIndicatorIcon()); }
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 955f23a..2aa2c9d 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -3544,6 +3544,12 @@ } } +void BrowserView::HandleDragEnded() { + if (multi_contents_view_) { + multi_contents_view_->drop_target_controller().OnWebContentsDragEnded(); + } +} + bool BrowserView::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { if (frame_->HandleKeyboardEvent(event)) { return true;
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 2e56834..538d631 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -631,6 +631,7 @@ void PreHandleDragUpdate(const content::DropData& drop_data, const gfx::PointF& point) override; void PreHandleDragExit() override; + void HandleDragEnded() override; bool HandleKeyboardEvent(const input::NativeWebKeyboardEvent& event) override; std::unique_ptr<FindBar> CreateFindBar() override; web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost()
diff --git a/chrome/browser/ui/views/frame/contents_container_view.cc b/chrome/browser/ui/views/frame/contents_container_view.cc index ea9ba0a5..51e8703 100644 --- a/chrome/browser/ui/views/frame/contents_container_view.cc +++ b/chrome/browser/ui/views/frame/contents_container_view.cc
@@ -36,10 +36,7 @@ namespace { constexpr float kContentCornerRadius = 6; constexpr gfx::RoundedCornersF kContentRoundedCorners{kContentCornerRadius}; -constexpr gfx::RoundedCornersF kContentUpperRoundedCorners = - gfx::RoundedCornersF{kContentCornerRadius, kContentCornerRadius, 0, 0}; -constexpr gfx::RoundedCornersF kContentLowerRoundedCorners = - gfx::RoundedCornersF{0, 0, kContentCornerRadius, kContentCornerRadius}; + constexpr int kContentOutlineCornerRadius = 8; constexpr int kContentOutlineThickness = 1; constexpr int kSplitViewContentPadding = 4; @@ -51,25 +48,14 @@ ContentsContainerView::ContentsContainerView(BrowserView* browser_view) { SetLayoutManager(std::make_unique<views::DelegatingLayoutManager>(this)); + // The default z-order is the order in which children were added to the + // parent view. So first added the content view and new tab page footer. + // This should be followed by scrims, borders and lastly mini-toolbar. + contents_view_ = AddChildView( std::make_unique<ContentsWebView>(browser_view->GetProfile())); contents_view_->SetID(VIEW_ID_TAB_CONTAINER); - contents_scrim_view_ = AddChildView(std::make_unique<ScrimView>()); - contents_scrim_view_->layer()->SetName("ContentsScrimView"); - -#if BUILDFLAG(ENABLE_GLIC) - if (glic::GlicEnabling::IsProfileEligible(browser_view->GetProfile())) { - glic_border_ = - AddChildView(views::Builder<glic::GlicBorderView>( - glic::GlicBorderView::Factory::Create( - browser_view->browser(), contents_view_)) - .SetVisible(false) - .SetCanProcessEventsWithinSubtree(false) - .Build()); - } -#endif - if (base::FeatureList::IsEnabled(ntp_features::kNtpFooter)) { new_tab_footer_view_separator_ = AddChildView(std::make_unique<ContentsSeparator>()); @@ -82,10 +68,28 @@ new_tab_footer_view_->SetVisible(false); } + contents_scrim_view_ = AddChildView(std::make_unique<ScrimView>()); + contents_scrim_view_->layer()->SetName("ContentsScrimView"); + if (base::FeatureList::IsEnabled(features::kSideBySide)) { inactive_split_scrim_view_ = AddChildView(std::make_unique<ScrimView>(kColorSplitViewScrim)); inactive_split_scrim_view_->SetRoundedCorners(kContentRoundedCorners); + } + +#if BUILDFLAG(ENABLE_GLIC) + if (glic::GlicEnabling::IsProfileEligible(browser_view->GetProfile())) { + glic_border_ = + AddChildView(views::Builder<glic::GlicBorderView>( + glic::GlicBorderView::Factory::Create( + browser_view->browser(), contents_view_)) + .SetVisible(false) + .SetCanProcessEventsWithinSubtree(false) + .Build()); + } +#endif + + if (base::FeatureList::IsEnabled(features::kSideBySide)) { mini_toolbar_ = AddChildView(std::make_unique<MultiContentsViewMiniToolbar>( browser_view, contents_view_)); } @@ -99,12 +103,7 @@ // split. if (!is_in_split) { SetBorder(nullptr); - contents_view_->holder()->SetCornerRadii(gfx::RoundedCornersF{0}); - contents_view_->SetBackgroundRadii(gfx::RoundedCornersF{0}); - contents_scrim_view_->SetRoundedCorners(gfx::RoundedCornersF{0}); - if (new_tab_footer_view_) { - new_tab_footer_view_->holder()->SetCornerRadii(gfx::RoundedCornersF{0}); - } + ClearBorderRoundedCorners(); mini_toolbar_->SetVisible(false); inactive_split_scrim_view_->SetVisible(false); return; @@ -122,14 +121,8 @@ kContentOutlineCornerRadius, color), gfx::Insets(kSplitViewContentPadding))); - UpdateContentsViewRoundedCorners(); - if (contents_scrim_view_->layer()->rounded_corner_radii() != - kContentRoundedCorners) { - contents_scrim_view_->SetRoundedCorners(kContentRoundedCorners); - } - if (new_tab_footer_view_) { - new_tab_footer_view_->holder()->SetCornerRadii(kContentLowerRoundedCorners); - } + UpdateBorderRoundedCorners(); + // Mini toolbar should only be visible for the inactive contents // container view or both depending on configuration. mini_toolbar_->UpdateState(is_active); @@ -138,19 +131,43 @@ inactive_split_scrim_view_->SetVisible(!is_active && show_scrim); } -void ContentsContainerView::UpdateContentsViewRoundedCorners() { +void ContentsContainerView::UpdateBorderRoundedCorners() { + constexpr gfx::RoundedCornersF kContentUpperRoundedCorners = + gfx::RoundedCornersF{kContentCornerRadius, kContentCornerRadius, 0, 0}; + constexpr gfx::RoundedCornersF kContentLowerRoundedCorners = + gfx::RoundedCornersF{0, 0, kContentCornerRadius, kContentCornerRadius}; + auto radii = new_tab_footer_view_ && new_tab_footer_view_->GetVisible() ? kContentUpperRoundedCorners : kContentRoundedCorners; - if (contents_view_->GetBackgroundRadii() != radii) { - contents_view_->holder()->SetCornerRadii(radii); - contents_view_->SetBackgroundRadii(radii); + + contents_view_->holder()->SetCornerRadii(radii); + + if (new_tab_footer_view_) { + new_tab_footer_view_->holder()->SetCornerRadii(kContentLowerRoundedCorners); } + + if (contents_scrim_view_->layer()->rounded_corner_radii() != + kContentRoundedCorners) { + contents_scrim_view_->SetRoundedCorners(kContentRoundedCorners); + } +} + +void ContentsContainerView::ClearBorderRoundedCorners() { + constexpr gfx::RoundedCornersF kNoRoundedCorners = gfx::RoundedCornersF{0}; + + contents_view_->holder()->SetCornerRadii(kNoRoundedCorners); + + if (new_tab_footer_view_) { + new_tab_footer_view_->holder()->SetCornerRadii(kNoRoundedCorners); + } + + contents_scrim_view_->SetRoundedCorners(kNoRoundedCorners); } void ContentsContainerView::ChildVisibilityChanged(View* child) { if (child == new_tab_footer_view_ && is_in_split_) { - UpdateContentsViewRoundedCorners(); + UpdateBorderRoundedCorners(); } } @@ -194,7 +211,7 @@ contents_view_.get(), contents_view_->GetVisible(), contents_rect); #if BUILDFLAG(ENABLE_GLIC) - if (glic_border_ && glic_border_->GetVisible()) { + if (glic_border_) { layouts.child_layouts.emplace_back( glic_border_.get(), glic_border_->GetVisible(), contents_bounds); }
diff --git a/chrome/browser/ui/views/frame/contents_container_view.h b/chrome/browser/ui/views/frame/contents_container_view.h index 8d4677eb..bc5aeac 100644 --- a/chrome/browser/ui/views/frame/contents_container_view.h +++ b/chrome/browser/ui/views/frame/contents_container_view.h
@@ -46,7 +46,8 @@ bool show_scrim); private: - void UpdateContentsViewRoundedCorners(); + void UpdateBorderRoundedCorners(); + void ClearBorderRoundedCorners(); // View: void ChildVisibilityChanged(View* child) override; @@ -58,12 +59,6 @@ bool is_in_split_ = false; raw_ptr<ContentsWebView> contents_view_; - // The scrim view that covers the content area when a tab-modal dialog is - // open. - raw_ptr<ScrimView> contents_scrim_view_; - - // The glic browser view that renders around the web contents area. - raw_ptr<glic::GlicBorderView> glic_border_ = nullptr; // The view that shows a footer at the bottom of the contents // container on new tab pages. @@ -71,10 +66,17 @@ // Separator between the web contents and the Footer. raw_ptr<views::View> new_tab_footer_view_separator_ = nullptr; + // The scrim view that covers the content area when a tab-modal dialog is + // open. + raw_ptr<ScrimView> contents_scrim_view_; + // Scrim view shown on the inactive side of a split view when the omnibox is // focused or site permissions dialogs are showing. raw_ptr<ScrimView> inactive_split_scrim_view_ = nullptr; + // The glic browser view that renders around the web contents area. + raw_ptr<glic::GlicBorderView> glic_border_ = nullptr; + raw_ptr<MultiContentsViewMiniToolbar> mini_toolbar_ = nullptr; };
diff --git a/chrome/browser/ui/views/frame/multi_contents_view.cc b/chrome/browser/ui/views/frame/multi_contents_view.cc index 8490634..552508f 100644 --- a/chrome/browser/ui/views/frame/multi_contents_view.cc +++ b/chrome/browser/ui/views/frame/multi_contents_view.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/ui/views/frame/multi_contents_view_mini_toolbar.h" #include "chrome/browser/ui/views/frame/scrim_view.h" #include "chrome/browser/ui/views/frame/top_container_background.h" +#include "chrome/browser/ui/views/new_tab_footer/footer_web_view.h" #include "content/public/browser/web_contents.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/ozone_buildflags.h" @@ -77,6 +78,14 @@ ->AddWebContentsFocusedCallback( base::BindRepeating(&MultiContentsView::OnWebContentsFocused, base::Unretained(this)))); + + if (contents_container_view->GetNewTabFooterView()) { + ntp_footer_focused_subscriptions_.push_back( + contents_container_view->GetNewTabFooterView() + ->AddWebContentsFocusedCallback( + base::BindRepeating(&MultiContentsView::OnNtpFooterFocused, + base::Unretained(this)))); + } } SetProperty(views::kElementIdentifierKey, kMultiContentsViewElementId); @@ -250,6 +259,19 @@ } } +void MultiContentsView::OnNtpFooterFocused(views::WebView* web_view) { + if (IsInSplitView() && GetWidget()->IsVisible()) { + for (auto* contents_container_view : contents_container_views_) { + if (contents_container_view->GetNewTabFooterView() == web_view && + GetInactiveContentsView() == + contents_container_view->GetContentsView()) { + return delegate_->WebContentsFocused( + GetInactiveContentsView()->web_contents()); + } + } + } +} + // TODO(crbug.com/397777917): Consider using FlexSpecification weights and // interior margins instead of a custom layout once this bug is resolved. views::ProposedLayout MultiContentsView::CalculateProposedLayout(
diff --git a/chrome/browser/ui/views/frame/multi_contents_view.h b/chrome/browser/ui/views/frame/multi_contents_view.h index 4ead815..dec885a 100644 --- a/chrome/browser/ui/views/frame/multi_contents_view.h +++ b/chrome/browser/ui/views/frame/multi_contents_view.h
@@ -167,6 +167,7 @@ int GetInactiveIndex(); void OnWebContentsFocused(views::WebView*); + void OnNtpFooterFocused(views::WebView*); ViewWidths GetViewWidths(gfx::Rect available_space) const; @@ -189,6 +190,10 @@ std::vector<base::CallbackListSubscription> web_contents_focused_subscriptions_; + // Holds subscriptions for when the attached web contents to NtpFooterView + // is focused. + std::vector<base::CallbackListSubscription> ntp_footer_focused_subscriptions_; + // The handle responsible for resizing the two contents views as relative to // each other. raw_ptr<MultiContentsResizeArea> resize_area_ = nullptr;
diff --git a/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.cc b/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.cc index 107fe94..4843254 100644 --- a/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.cc +++ b/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.cc
@@ -99,6 +99,11 @@ ResetDropTargetTimer(); } +void MultiContentsViewDropTargetController::OnWebContentsDragEnded() { + ResetDropTargetTimer(); + drop_target_view_->Hide(); +} + bool MultiContentsViewDropTargetController::HandleDragUpdate( const gfx::PointF& point_in_view) { CHECK_LE(0, point_in_view.x());
diff --git a/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h b/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h index e4ba4a25..85d12b4c 100644 --- a/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h +++ b/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h
@@ -49,6 +49,7 @@ const gfx::PointF& point, bool is_in_split_view); void OnWebContentsDragExit(); + void OnWebContentsDragEnded(); private: // Represents a timer for delaying when a specific drop target view is shown.
diff --git a/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller_unittest.cc b/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller_unittest.cc index a6a0edcc..1091bd0 100644 --- a/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller_unittest.cc +++ b/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller_unittest.cc
@@ -272,6 +272,19 @@ EXPECT_FALSE(drop_target_view().GetVisible()); } +// Tests that the drop target is hidden when the drag ends. +TEST_F(MultiContentsViewDropTargetControllerTest, OnWebContentsDragEnded) { + // First, show the drop target. + DragURLTo(kDragPointForStartDropTargetShow); + FastForward(); + EXPECT_TRUE(drop_target_view().GetVisible()); + + // Ending the drag should hide it. + controller().OnWebContentsDragEnded(); + FastForward(); + EXPECT_FALSE(drop_target_view().GetVisible()); +} + // Tests that the drop target is hidden when dragging more than one tab. TEST_F(MultiContentsViewDropTargetControllerTest, OnTabDragUpdated_HidesTargetWhenDraggingMultipleTabs) {
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.cc index 2943e9f..8f7dd23 100644 --- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.cc +++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.cc
@@ -238,7 +238,8 @@ // If the controls state has changed in some way, update the icon. if (controls_state != controls_state_ || - blocking_status != blocking_status_ || should_highlight_) { + blocking_status != blocking_status_ || + should_highlight != should_highlight_) { state_changed_ = controls_state != controls_state_; controls_state_ = controls_state; blocking_status_ = blocking_status;
diff --git a/chrome/browser/ui/webui/new_tab_page/composebox/composebox_handler_unittest.cc b/chrome/browser/ui/webui/new_tab_page/composebox/composebox_handler_unittest.cc index 4f1e667..ba4f8f87 100644 --- a/chrome/browser/ui/webui/new_tab_page/composebox/composebox_handler_unittest.cc +++ b/chrome/browser/ui/webui/new_tab_page/composebox/composebox_handler_unittest.cc
@@ -45,8 +45,8 @@ constexpr int kImageMaxArea = 1000000; constexpr int kImageMaxHeight = 1000; constexpr int kImageMaxWidth = 1000; +constexpr char kClientUploadDurationQueryParameter[] = "cud"; constexpr char kQuerySubmissionTimeQueryParameter[] = "qsubts"; -constexpr char kUserPerceivedQuerySubmissionTimeQueryParameter[] = "pqsubts"; constexpr char kQueryText[] = "query"; class MockPage : public composebox::mojom::Page { @@ -218,15 +218,15 @@ EXPECT_TRUE(net::GetValueForKeyInQuery( url, kQuerySubmissionTimeQueryParameter, &qsubts_param)); - std::string pqsubts_param; + std::string cud_param; EXPECT_TRUE(net::GetValueForKeyInQuery( - url, kUserPerceivedQuerySubmissionTimeQueryParameter, &pqsubts_param)); + url, kClientUploadDurationQueryParameter, &cud_param)); GURL result_url = url; result_url = net::AppendOrReplaceQueryParameter( result_url, kQuerySubmissionTimeQueryParameter, std::nullopt); result_url = net::AppendOrReplaceQueryParameter( - result_url, kUserPerceivedQuerySubmissionTimeQueryParameter, + result_url, kClientUploadDurationQueryParameter, std::nullopt); return result_url; }
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc index f9e7c5b..af30be4 100644 --- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc +++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -486,6 +486,10 @@ {"composeboxPlaceholderText", IDS_NTP_COMPOSE_PLACEHOLDER_TEXT}, {"composeboxSubmitButtonTitle", IDS_NTP_COMPOSE_SUBMIT_BUTTON_A11Y_LABEL}, {"composeboxDeleteFileTitle", IDS_NTP_COMPOSE_DELETE_FILE_A11Y_LABEL}, + {"composeboxFileUploadStartedText", + IDS_NTP_COMPOSE_FILE_UPLOAD_STARTED_A11Y_TEXT}, + {"composeboxFileUploadCompleteText", + IDS_NTP_COMPOSE_FILE_UPLOAD_COMPLETE_A11Y_TEXT}, {"composeboxFileUploadInvalidEmptySize", IDS_NTP_COMPOSE_FILE_UPLOAD_INVALID_EMPTY_SIZE}, {"composeboxFileUploadInvalidTooLarge",
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 8aa94e2..7c87f97 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -1438,7 +1438,8 @@ IDS_SETTINGS_AUTOFILL_AI_ADD_OR_EDIT_DIALOG_VALIDATION_ERROR}, {"autofillAiSubpageSublabelLoggingManagedDisabled", IDS_SETTINGS_AUTOFILL_AI_ENTERPRISE_LOGGING_MANAGED_DISABLED}, - {"autofillPayOverTimeSettingsLabel", IDS_AUTOFILL_BNPL_SETTINGS_LABEL}, + {"autofillPayOverTimeSettingsLabel", + IDS_AUTOFILL_BNPL_PAY_LATER_OPTIONS_TEXT}, {"editAddressInAccount", IDS_SETTINGS_HOME_AND_WORK_ADDRESS_EDIT}, {"removeFromChrome", IDS_SETTINGS_HOME_AND_WORK_ADDRESS_REMOVE}, {"removeHomeAddressConfirmationTitle",
diff --git a/chrome/browser/ui/webui/settings/site_settings_helper.cc b/chrome/browser/ui/webui/settings/site_settings_helper.cc index bc848c39..fb3e52b 100644 --- a/chrome/browser/ui/webui/settings/site_settings_helper.cc +++ b/chrome/browser/ui/webui/settings/site_settings_helper.cc
@@ -156,9 +156,6 @@ {ContentSettingsType::FILE_SYSTEM_ACCESS_CHOOSER_DATA, "file-system-access-handles-data"}, {ContentSettingsType::FEDERATED_IDENTITY_API, "federated-identity-api"}, - {ContentSettingsType::PRIVATE_NETWORK_GUARD, "private-network-devices"}, - {ContentSettingsType::PRIVATE_NETWORK_CHOOSER_DATA, - "private-network-devices-data"}, {ContentSettingsType::ANTI_ABUSE, "anti-abuse"}, {ContentSettingsType::STORAGE_ACCESS, "storage-access"}, {ContentSettingsType::AUTO_PICTURE_IN_PICTURE, "auto-picture-in-picture"}, @@ -638,11 +635,6 @@ } if (base::FeatureList::IsEnabled( - network::features::kPrivateNetworkAccessPermissionPrompt)) { - base_types->push_back(ContentSettingsType::PRIVATE_NETWORK_GUARD); - } - - if (base::FeatureList::IsEnabled( blink::features::kMediaSessionEnterPictureInPicture)) { base_types->push_back(ContentSettingsType::AUTO_PICTURE_IN_PICTURE); }
diff --git a/chrome/browser/ui/webui/signin/BUILD.gn b/chrome/browser/ui/webui/signin/BUILD.gn index cbb351e..d7c6d1a 100644 --- a/chrome/browser/ui/webui/signin/BUILD.gn +++ b/chrome/browser/ui/webui/signin/BUILD.gn
@@ -192,6 +192,7 @@ deps += [ ":login", "//chrome/browser/ui/browser_window", + "//chrome/browser/ui/sync", "//chrome/browser/ui/tabs:tab_strip", "//components/keyed_service/content", "//components/policy/core/browser",
diff --git a/chrome/browser/ui/webui/signin/managed_user_profile_notice_ui.cc b/chrome/browser/ui/webui/signin/managed_user_profile_notice_ui.cc index 8bc99d9f..1c39b719 100644 --- a/chrome/browser/ui/webui/signin/managed_user_profile_notice_ui.cc +++ b/chrome/browser/ui/webui/signin/managed_user_profile_notice_ui.cc
@@ -37,6 +37,7 @@ #include "components/signin/public/identity_manager/identity_manager.h" #include "components/signin/public/identity_manager/tribool.h" #include "components/strings/grit/components_strings.h" +#include "components/sync/base/features.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" #include "extensions/browser/extension_registry.h" @@ -277,9 +278,13 @@ } if (create_param->account_info.IsManaged() != signin::Tribool::kTrue) { - update_data.Set("valuePropSubtitle", - l10n_util::GetStringUTF16( - IDS_ENTERPRISE_VALUE_PROPOSITION_CONSUMER_SUBTITLE)); + update_data.Set( + "valuePropSubtitle", + l10n_util::GetStringUTF16( + base::FeatureList::IsEnabled( + syncer::kReplaceSyncPromosWithSignInPromos) + ? IDS_ENTERPRISE_VALUE_PROPOSITION_CONSUMER_SUBTITLE_WITH_BOOKMARKS + : IDS_ENTERPRISE_VALUE_PROPOSITION_CONSUMER_SUBTITLE)); update_data.Set( "separateBrowsingDataTitle", l10n_util::GetStringUTF16(
diff --git a/chrome/browser/usb/chrome_usb_browsertest.cc b/chrome/browser/usb/chrome_usb_browsertest.cc index e224638..9d6f2d93a 100644 --- a/chrome/browser/usb/chrome_usb_browsertest.cc +++ b/chrome/browser/usb/chrome_usb_browsertest.cc
@@ -116,9 +116,8 @@ } })();)"; -// Matches an EvalJs error message. -MATCHER_P(FailedWithSubstr, substr, "") { - return arg.error.find(substr) != std::string::npos; +auto FailedWithSubstr(std::string_view substr) { + return content::EvalJsResult::ErrorIs(testing::HasSubstr(substr)); } #if BUILDFLAG(ENABLE_EXTENSIONS) && BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsertest.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsertest.cc index f2e4c74..94637482 100644 --- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsertest.cc +++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsertest.cc
@@ -561,9 +561,8 @@ return response.ok; })(); )", - url_info.origin().Serialize())) - .error, - HasSubstr("Failed to fetch")); + url_info.origin().Serialize())), + content::EvalJsResult::ErrorIs(HasSubstr("Failed to fetch"))); } IN_PROC_BROWSER_TEST_F(IsolatedWebAppBrowserTest, @@ -600,9 +599,8 @@ return response.ok; })(); )", - url_info2.origin().Serialize())) - .error, - HasSubstr("Failed to fetch")); + url_info2.origin().Serialize())), + content::EvalJsResult::ErrorIs(HasSubstr("Failed to fetch"))); } IN_PROC_BROWSER_TEST_F(IsolatedWebAppBrowserTest, @@ -679,8 +677,9 @@ await socket.opened; })(); )"; - EXPECT_THAT(EvalJs(app_frame, openSocketJs).error, - HasSubstr("Permissions-Policy: direct-sockets are disabled.")); + EXPECT_THAT(EvalJs(app_frame, openSocketJs), + content::EvalJsResult::ErrorIs(HasSubstr( + "Permissions-Policy: direct-sockets are disabled."))); } class IsolatedWebAppApiAccessBrowserTest : public IsolatedWebAppBrowserTest {
diff --git a/chrome/browser/web_applications/web_app_link_capturing_parameterized_browsertest.cc b/chrome/browser/web_applications/web_app_link_capturing_parameterized_browsertest.cc index 50e6e50..4a363883 100644 --- a/chrome/browser/web_applications/web_app_link_capturing_parameterized_browsertest.cc +++ b/chrome/browser/web_applications/web_app_link_capturing_parameterized_browsertest.cc
@@ -16,6 +16,11 @@ #include "base/files/file_util.h" #include "base/json/json_file_value_serializer.h" #include "base/json/json_reader.h" + +#if BUILDFLAG(IS_MAC) +#include "base/mac/mac_util.h" +#endif + #include "base/memory/weak_ptr.h" #include "base/notreached.h" #include "base/path_service.h" @@ -1767,6 +1772,14 @@ return false; } +#if BUILDFLAG(IS_MAC) + // TODO(crbug.com/432178469): Remove this and associated import after Mac13 + // flakiness is fixed. + if (base::mac::MacOSMajorVersion() == 13) { + return true; + } +#endif + testing::TestParamInfo<LinkCaptureTestParam> param(GetParam(), 0); const base::Value::Dict& test_case = GetTestCaseDataFromParam();
diff --git a/chrome/browser_exposed_mojom_targets.gni b/chrome/browser_exposed_mojom_targets.gni index 2cba37c..81413e7 100644 --- a/chrome/browser_exposed_mojom_targets.gni +++ b/chrome/browser_exposed_mojom_targets.gni
@@ -296,7 +296,6 @@ "//third_party/blink/public/mojom/gpu:gpu", "//third_party/blink/public/mojom/origin_trials:origin_trial_feature", "//third_party/blink/public/mojom/origin_trials:origin_trial_state", - "//third_party/blink/public/mojom/private_network_device:private_network_device", "//third_party/blink/public/mojom/quota:quota", "//third_party/blink/public/mojom/runtime_feature_state:runtime_feature_state", "//third_party/blink/public/mojom/service_worker:storage",
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 154d0ec..2bba9f05 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1753361333-aeb1dc6eba39e2e2415218749c392c3c69513e16-004413dd99b40f591bae42a2c4a239bdf662bdff.profdata +chrome-android64-main-1753369550-2fe8750f3887b42bb0f94d731de2195c1e16d3cd-28d491c4c65d9e951ae116a5d674f2be7fe89bf5.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 1e9d880..7ca85b2 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1753365557-2337493bf18eb0b39cfa9bbab9ef3e342038f2dd-d406f669272b9c39bf1be2f49c5d4c1594106d53.profdata +chrome-mac-arm-main-1753372783-406a810f21dfbac64e88d23dc60c75f1df0ad2ad-3dd3d966d1f9c76a296c1db7f903cc8257787be4.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index 6ba9f1ab..a7d17b4 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1753336777-2f851cc41613bdcc6fa4f44e6af3c5b06814570b-4ae823526fdcef53011f16f07e9ace9c6e70593a.profdata +chrome-win-arm64-main-1753358362-96ac979d13f633d2bce87451cdca0c530cfb2e47-bf36215bbda209fbccaf4bc00fea27fde178a71e.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 8925602..d97e5cff 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1753336777-1c46bac92a39bfca94ba22aa6340fb119cf06194-4ae823526fdcef53011f16f07e9ace9c6e70593a.profdata +chrome-win32-main-1753358362-da8ccb29bd9fe5f390dca5625dffea9d4ef7b306-bf36215bbda209fbccaf4bc00fea27fde178a71e.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 264e726f..c36d683 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1753347584-f5a31cb77ba5e07bb1b11c90ed5bc07a6bda9805-72f53768900a5181cee448e69ca332d8687f1170.profdata +chrome-win64-main-1753358362-c2abfde29eff3b9f5bfb7148aea46448f0545355-bf36215bbda209fbccaf4bc00fea27fde178a71e.profdata
diff --git a/chrome/renderer/resources/controlled_frame/controlled_frame.js b/chrome/renderer/resources/controlled_frame/controlled_frame.js index aa5a4b71..375bcea 100644 --- a/chrome/renderer/resources/controlled_frame/controlled_frame.js +++ b/chrome/renderer/resources/controlled_frame/controlled_frame.js
@@ -24,18 +24,17 @@ // conventions which are snake case. Convert from the kebab case convention to // the snake case convention. function convertRunAt(webRunAt) { - if (["document_start", "document_end", "document_idle"] - .includes(webRunAt)) { - throw "ERROR: Encountered incorrect naming, please see specification " + - "text for correct naming."; + if (['document_start', 'document_end', 'document_idle'].includes(webRunAt)) { + throw 'ERROR: Encountered incorrect naming, please see specification ' + + 'text for correct naming.'; } - if (webRunAt === "document-start") { - return "document_start"; - } else if (webRunAt === "document-end") { - return "document_end"; - } else if (webRunAt === "document-idle") { - return "document_idle"; + if (webRunAt === 'document-start') { + return 'document_start'; + } else if (webRunAt === 'document-end') { + return 'document_end'; + } else if (webRunAt === 'document-idle') { + return 'document_idle'; } return webRunAt; @@ -48,16 +47,16 @@ function convertContentScriptDetailsKeys(webViewRule, keyMappings) { for (const mapping of keyMappings) { if (!('from' in mapping)) { - throw "ERROR: 'from' is required"; + throw 'ERROR: \'from\' is required'; } if (!('to' in mapping)) { - throw "ERROR: 'to' is required"; + throw 'ERROR: \'to\' is required'; } if (mapping.to in webViewRule) { - throw "ERROR: Encountered incorrect naming, please see specification " + - "text for correct naming."; + throw 'ERROR: Encountered incorrect naming, please see specification ' + + 'text for correct naming.'; } if (mapping.from in webViewRule) { @@ -88,13 +87,13 @@ // Convert the keys in |webViewRule|. webViewRule = convertContentScriptDetailsKeys(webViewRule, [ - { from: "allFrames", to: "all_frames" }, - { from: "excludeGlobs", to: "exclude_globs" }, - { from: "excludeURLPatterns", to: "exclude_matches" }, - { from: "includeGlobs", to: "include_globs" }, - { from: "matchAboutBlank", to: "match_about_blank" }, - { from: "runAt", to: "run_at" }, - { from: "urlPatterns", to: "matches" }, + {from: 'allFrames', to: 'all_frames'}, + {from: 'excludeGlobs', to: 'exclude_globs'}, + {from: 'excludeURLPatterns', to: 'exclude_matches'}, + {from: 'includeGlobs', to: 'include_globs'}, + {from: 'matchAboutBlank', to: 'match_about_blank'}, + {from: 'runAt', to: 'run_at'}, + {from: 'urlPatterns', to: 'matches'}, ]); webViewRules.push(webViewRule); @@ -164,13 +163,13 @@ // Delete GuestView methods that should not be part of the Controlled Frame API. (function() { - for (const methodName of CONTROLLED_FRAME_DELETED_API_METHODS) { - let clazz = ControlledFrameElement.prototype; - while ((methodName in clazz) && clazz.constructor.name !== 'HTMLElement') { - delete clazz[methodName]; - clazz = $Object.getPrototypeOf(clazz); - } +for (const methodName of CONTROLLED_FRAME_DELETED_API_METHODS) { + let clazz = ControlledFrameElement.prototype; + while ((methodName in clazz) && clazz.constructor.name !== 'HTMLElement') { + delete clazz[methodName]; + clazz = $Object.getPrototypeOf(clazz); } +} })(); registerElement('ControlledFrame', ControlledFrameElement);
diff --git a/chrome/renderer/resources/controlled_frame/controlled_frame_context_menus.js b/chrome/renderer/resources/controlled_frame/controlled_frame_context_menus.js index 2a305df..ad4d971 100644 --- a/chrome/renderer/resources/controlled_frame/controlled_frame_context_menus.js +++ b/chrome/renderer/resources/controlled_frame/controlled_frame_context_menus.js
@@ -27,10 +27,9 @@ let matchPatterns = []; for (const urlPatternStr of urlPatternsStrs) { matchPatterns = $Array.concat( - matchPatterns, - WebUrlPatternNatives.URLPatternToMatchPatterns( - new URLPattern(urlPatternStr)) - ); + matchPatterns, + WebUrlPatternNatives.URLPatternToMatchPatterns( + new URLPattern(urlPatternStr))); }; return matchPatterns; } @@ -334,8 +333,7 @@ class ContextMenusShowEvent extends Event { constructor(details) { super('show'); - this['preventDefault'] = - $Function.bind(details.preventDefault, this); + this['preventDefault'] = $Function.bind(details.preventDefault, this); $Object.freeze(this); } }
diff --git a/chrome/renderer/resources/controlled_frame/controlled_frame_events.js b/chrome/renderer/resources/controlled_frame/controlled_frame_events.js index 0baf294..27a14da 100644 --- a/chrome/renderer/resources/controlled_frame/controlled_frame_events.js +++ b/chrome/renderer/resources/controlled_frame/controlled_frame_events.js
@@ -3,7 +3,8 @@ // found in the LICENSE file. const WebViewEvents = require('webViewEvents').WebViewEvents; -const ControlledFrameWebRequest = require('controlledFrameWebRequest').ControlledFrameWebRequest; +const ControlledFrameWebRequest = + require('controlledFrameWebRequest').ControlledFrameWebRequest; class ControlledFrameEvents extends WebViewEvents { getEvents() {
diff --git a/chrome/renderer/resources/controlled_frame/controlled_frame_impl.js b/chrome/renderer/resources/controlled_frame/controlled_frame_impl.js index b47b34fd..0e0f6fd 100644 --- a/chrome/renderer/resources/controlled_frame/controlled_frame_impl.js +++ b/chrome/renderer/resources/controlled_frame/controlled_frame_impl.js
@@ -7,7 +7,7 @@ var ControlledFrameEvents = require('controlledFrameEvents').ControlledFrameEvents; var ControlledFrameContextMenus = - require('controlledFrameContextMenus').ControlledFrameContextMenus; + require('controlledFrameContextMenus').ControlledFrameContextMenus; class ControlledFrameImpl extends ChromeWebViewImpl { constructor(webviewElement) {
diff --git a/chrome/renderer/resources/controlled_frame/controlled_frame_internal_custom_bindings.js b/chrome/renderer/resources/controlled_frame/controlled_frame_internal_custom_bindings.js index 9c2e003e..edcebae 100644 --- a/chrome/renderer/resources/controlled_frame/controlled_frame_internal_custom_bindings.js +++ b/chrome/renderer/resources/controlled_frame/controlled_frame_internal_custom_bindings.js
@@ -8,7 +8,7 @@ var apiFunctions = bindingsAPI.apiFunctions; var handlers = contextMenusHandlers.create( - /*webViewNamespace=*/'controlledFrameInternal'); + /*webViewNamespace=*/ 'controlledFrameInternal'); apiFunctions.setHandleRequest( 'contextMenusCreate', handlers.requestHandlers.create);
diff --git a/chrome/renderer/resources/controlled_frame/controlled_frame_web_request.js b/chrome/renderer/resources/controlled_frame/controlled_frame_web_request.js index 5fc7a622..a2c821e 100644 --- a/chrome/renderer/resources/controlled_frame/controlled_frame_web_request.js +++ b/chrome/renderer/resources/controlled_frame/controlled_frame_web_request.js
@@ -16,9 +16,9 @@ let matchPatterns = []; for (const urlPatternStrOrObj of urlPatternsStrsOrObjs) { matchPatterns = $Array.concat( - matchPatterns, - WebUrlPatternNatives.URLPatternToMatchPatterns( - new URLPattern(urlPatternStrOrObj)) + matchPatterns, + WebUrlPatternNatives.URLPatternToMatchPatterns( + new URLPattern(urlPatternStrOrObj)) ); }; return matchPatterns; @@ -27,9 +27,9 @@ function convertExtensionHeadersToWeb(httpHeaders) { const headers = new $Headers.self(); for (const header of httpHeaders) { - const value = (header.value !== undefined) - ? header.value - : $String.fromCharCode(...header.binaryValue); + const value = (header.value !== undefined) ? + header.value : + $String.fromCharCode(...header.binaryValue); $Headers.append(headers, header.name, value); } return headers; @@ -60,7 +60,7 @@ } function extractAndMapValues(obj, mapping) { - const mapped = { __proto__: null }; + const mapped = {__proto__: null}; for (const [key, value] of $Object.entries(obj)) { if (key in mapping) { $Object.defineProperty(mapped, key, { @@ -368,8 +368,8 @@ return; } - const resultPromises = $Array.self( - $Promise.resolve(result.authCredentials)); + const resultPromises = + $Array.self($Promise.resolve(result.authCredentials)); if (options.signal) { $Array.push(resultPromises, new $Promise.self((resolve) => { options.signal.addEventListener('abort', resolve);
diff --git a/chrome/renderer/resources/extensions/browser_action_custom_bindings.js b/chrome/renderer/resources/extensions/browser_action_custom_bindings.js index 537f28f0..02eb764 100644 --- a/chrome/renderer/resources/extensions/browser_action_custom_bindings.js +++ b/chrome/renderer/resources/extensions/browser_action_custom_bindings.js
@@ -13,8 +13,7 @@ apiFunctions.setHandleRequest( 'setIcon', getSetIconHandler('browserAction.setIcon')); - apiFunctions.setCustomCallback('openPopup', - function(callback, response) { + apiFunctions.setCustomCallback('openPopup', function(callback, response) { if (!callback) return;
diff --git a/chrome/renderer/resources/extensions/certificate_provider_custom_bindings.js b/chrome/renderer/resources/extensions/certificate_provider_custom_bindings.js index 1959b789..f3f392c 100644 --- a/chrome/renderer/resources/extensions/certificate_provider_custom_bindings.js +++ b/chrome/renderer/resources/extensions/certificate_provider_custom_bindings.js
@@ -37,40 +37,41 @@ bindingUtil.addCustomSignature(fullEventName, callbackSchema); - bindingUtil.registerEventArgumentMassager(fullEventName, - function(args, dispatch) { - var responded = false; + bindingUtil.registerEventArgumentMassager( + fullEventName, function(args, dispatch) { + var responded = false; - // Function provided to the extension as the event callback argument. - // The extension calls this to report results in reply to the event. - // It throws an exception if called more than once and if the provided - // results don't match the callback schema. - var reportFunc = function(reportArg1, reportArg2) { - if (responded) - throw new Error('Event callback must not be called more than once.'); + // Function provided to the extension as the event callback argument. + // The extension calls this to report results in reply to the event. + // It throws an exception if called more than once and if the provided + // results don't match the callback schema. + var reportFunc = function(reportArg1, reportArg2) { + if (responded) + throw new Error( + 'Event callback must not be called more than once.'); - var reportArgs = [reportArg1]; - if (reportArg2 !== undefined) - reportArgs.push(reportArg2); - var finalArgs = []; - try { - // Validates that the results reported by the extension matche the - // callback schema of the event. Throws an exception in case of an - // error. - bindingUtil.validateCustomSignature(fullEventName, reportArgs); - finalArgs = reportArgs; - } finally { - responded = true; - internalReportFunc.apply( - null, [args[0] /* requestId */].concat(finalArgs)); - } - }; - dispatch(args.slice(1).concat(reportFunc)); - }); + var reportArgs = [reportArg1]; + if (reportArg2 !== undefined) + reportArgs.push(reportArg2); + var finalArgs = []; + try { + // Validates that the results reported by the extension matche the + // callback schema of the event. Throws an exception in case of an + // error. + bindingUtil.validateCustomSignature(fullEventName, reportArgs); + finalArgs = reportArgs; + } finally { + responded = true; + internalReportFunc.apply( + null, [args[0] /* requestId */].concat(finalArgs)); + } + }; + dispatch(args.slice(1).concat(reportFunc)); + }); } -handleEvent('onCertificatesRequested', - certificateProviderInternal.reportCertificates); +handleEvent( + 'onCertificatesRequested', certificateProviderInternal.reportCertificates); -handleEvent('onSignDigestRequested', - certificateProviderInternal.reportSignature); +handleEvent( + 'onSignDigestRequested', certificateProviderInternal.reportSignature);
diff --git a/chrome/renderer/resources/extensions/chromeos_google_tts_stream_bindings.js b/chrome/renderer/resources/extensions/chromeos_google_tts_stream_bindings.js index 15b9173..4db8957 100644 --- a/chrome/renderer/resources/extensions/chromeos_google_tts_stream_bindings.js +++ b/chrome/renderer/resources/extensions/chromeos_google_tts_stream_bindings.js
@@ -12,8 +12,8 @@ loadScript('chromeos.tts.mojom.google_tts_stream.mojom'); (function() { - let ptr = new chromeos.tts.mojom.GoogleTtsStreamPtr; - Mojo.bindInterface( - chromeos.tts.mojom.GoogleTtsStream.name, mojo.makeRequest(ptr).handle); - exports.$set('returnValue', ptr); +let ptr = new chromeos.tts.mojom.GoogleTtsStreamPtr; +Mojo.bindInterface( + chromeos.tts.mojom.GoogleTtsStream.name, mojo.makeRequest(ptr).handle); +exports.$set('returnValue', ptr); })();
diff --git a/chrome/renderer/resources/extensions/chromeos_ime_service_bindings.js b/chrome/renderer/resources/extensions/chromeos_ime_service_bindings.js index ec42217..ebd7a57 100644 --- a/chrome/renderer/resources/extensions/chromeos_ime_service_bindings.js +++ b/chrome/renderer/resources/extensions/chromeos_ime_service_bindings.js
@@ -19,7 +19,7 @@ * @type {Promise} * @const */ -var IME_CHANNEL_EMPTY_RESULT = Promise.resolve({result: ""}); +var IME_CHANNEL_EMPTY_RESULT = Promise.resolve({result: ''}); /** * Empty message to keep Mojo pipe from disconnection. @@ -240,7 +240,6 @@ */ activateIME(imeSpec, extra, onConnection, onConnectionError) { if (this.isConnected()) { - // TODO(crbug.com/837156): Try to reuse the current engine if possible. // Disconnect the current active engine and make a new one. this.deactivateIME(); @@ -282,8 +281,8 @@ } (function() { - let ptr = new ash.ime.mojom.InputEngineManagerPtr; - Mojo.bindInterface( - ash.ime.mojom.InputEngineManager.name, mojo.makeRequest(ptr).handle); - exports.$set('returnValue', new ImeService(ptr)); +let ptr = new ash.ime.mojom.InputEngineManagerPtr; +Mojo.bindInterface( + ash.ime.mojom.InputEngineManager.name, mojo.makeRequest(ptr).handle); +exports.$set('returnValue', new ImeService(ptr)); })();
diff --git a/chrome/renderer/resources/extensions/desktop_capture_custom_bindings.js b/chrome/renderer/resources/extensions/desktop_capture_custom_bindings.js index 2f4e8a8..9dcecff7 100644 --- a/chrome/renderer/resources/extensions/desktop_capture_custom_bindings.js +++ b/chrome/renderer/resources/extensions/desktop_capture_custom_bindings.js
@@ -19,30 +19,31 @@ } } - apiFunctions.setHandleRequest('chooseDesktopMedia', - function(sources, target_tab, options, - callback) { - // |target_tab| is an optional parameter. - if (callback === undefined) { - callback = target_tab; - target_tab = undefined; - } - var id = idGenerator.GetNextId(); - pendingRequests[id] = callback; - bindingUtil.sendRequest('desktopCapture.chooseDesktopMedia', - [id, sources, target_tab, options, - $Function.bind(onRequestResult, null, id)], - undefined); - return id; - }); + apiFunctions.setHandleRequest( + 'chooseDesktopMedia', function(sources, target_tab, options, callback) { + // |target_tab| is an optional parameter. + if (callback === undefined) { + callback = target_tab; + target_tab = undefined; + } + var id = idGenerator.GetNextId(); + pendingRequests[id] = callback; + bindingUtil.sendRequest( + 'desktopCapture.chooseDesktopMedia', + [ + id, sources, target_tab, options, + $Function.bind(onRequestResult, null, id) + ], + undefined); + return id; + }); apiFunctions.setHandleRequest('cancelChooseDesktopMedia', function(id) { if (id in pendingRequests) { delete pendingRequests[id]; bindingUtil.sendRequest( - 'desktopCapture.cancelChooseDesktopMedia', - [id], undefined, undefined); + 'desktopCapture.cancelChooseDesktopMedia', [id], undefined, + undefined); } }); }); -
diff --git a/chrome/renderer/resources/extensions/developer_private_custom_bindings.js b/chrome/renderer/resources/extensions/developer_private_custom_bindings.js index 50233f31..1d67f4c 100644 --- a/chrome/renderer/resources/extensions/developer_private_custom_bindings.js +++ b/chrome/renderer/resources/extensions/developer_private_custom_bindings.js
@@ -15,7 +15,7 @@ var relativePath = $String.slice(directoryEntry.fullPath, 1); var url = directoryEntry.toURL(); return [fileSystemName, relativePath, url, callback]; - }); + }); } bindFileSystemFunction('loadDirectory'); @@ -33,11 +33,13 @@ if (isNaN(renderProcessId)) throw new Error('Invalid value for render_process_id'); } - chrome.developerPrivate.openDevTools({ - extensionId: options.extension_id, - renderProcessId: renderProcessId, - renderViewId: renderViewId, - incognito: options.incognito - }, callback); + chrome.developerPrivate.openDevTools( + { + extensionId: options.extension_id, + renderProcessId: renderProcessId, + renderViewId: renderViewId, + incognito: options.incognito + }, + callback); }); });
diff --git a/chrome/renderer/resources/extensions/downloads_custom_bindings.js b/chrome/renderer/resources/extensions/downloads_custom_bindings.js index 2842c5e4..d6db85a 100644 --- a/chrome/renderer/resources/extensions/downloads_custom_bindings.js +++ b/chrome/renderer/resources/extensions/downloads_custom_bindings.js
@@ -6,57 +6,60 @@ var downloadsInternal = getInternalApi('downloadsInternal'); -bindingUtil.registerEventArgumentMassager('downloads.onDeterminingFilename', - function(args, dispatch) { - var downloadItem = args[0]; - // Copy the id so that extensions can't change it. - var downloadId = downloadItem.id; - var suggestable = true; - function isValidResult(result) { - if (result === undefined) - return false; - if (typeof result !== 'object') { - console.error( - 'Error: Invocation of form suggest(' + typeof result + - ') doesn\'t match definition suggest({filename: string, ' + - 'conflictAction: string})'); - return false; - } else if ( - typeof result.filename !== 'string' || result.filename.length === 0) { - console.error('Error: "filename" parameter to suggest() must be a ' + - 'non-empty string'); - return false; - } else if ([ - undefined, 'uniquify', 'overwrite', 'prompt' - ].indexOf(result.conflictAction) < 0) { - console.error('Error: "conflictAction" parameter to suggest() must be ' + - 'one of undefined, "uniquify", "overwrite", "prompt"'); - return false; - } - return true; - } - function suggestCallback(result) { - if (!suggestable) { - console.error('suggestCallback may not be called more than once.'); - return; - } - suggestable = false; - if (isValidResult(result)) { - downloadsInternal.determineFilename( - downloadId, result.filename, result.conflictAction || ""); - } else { - downloadsInternal.determineFilename(downloadId, "", ""); - } - } - try { - var results = dispatch([downloadItem, suggestCallback]); - var async = - (results && results.results && (results.results.length !== 0) && - (results.results[0] === true)); - if (suggestable && !async) - suggestCallback(); - } catch (e) { - suggestCallback(); - throw e; - } -}); +bindingUtil.registerEventArgumentMassager( + 'downloads.onDeterminingFilename', function(args, dispatch) { + var downloadItem = args[0]; + // Copy the id so that extensions can't change it. + var downloadId = downloadItem.id; + var suggestable = true; + function isValidResult(result) { + if (result === undefined) + return false; + if (typeof result !== 'object') { + console.error( + 'Error: Invocation of form suggest(' + typeof result + + ') doesn\'t match definition suggest({filename: string, ' + + 'conflictAction: string})'); + return false; + } else if ( + typeof result.filename !== 'string' || + result.filename.length === 0) { + console.error( + 'Error: "filename" parameter to suggest() must be a ' + + 'non-empty string'); + return false; + } else if ([ + undefined, 'uniquify', 'overwrite', 'prompt' + ].indexOf(result.conflictAction) < 0) { + console.error( + 'Error: "conflictAction" parameter to suggest() must be ' + + 'one of undefined, "uniquify", "overwrite", "prompt"'); + return false; + } + return true; + } + function suggestCallback(result) { + if (!suggestable) { + console.error('suggestCallback may not be called more than once.'); + return; + } + suggestable = false; + if (isValidResult(result)) { + downloadsInternal.determineFilename( + downloadId, result.filename, result.conflictAction || ''); + } else { + downloadsInternal.determineFilename(downloadId, '', ''); + } + } + try { + var results = dispatch([downloadItem, suggestCallback]); + var async = + (results && results.results && (results.results.length !== 0) && + (results.results[0] === true)); + if (suggestable && !async) + suggestCallback(); + } catch (e) { + suggestCallback(); + throw e; + } + });
diff --git a/chrome/renderer/resources/extensions/enterprise_platform_keys/subtle_crypto.js b/chrome/renderer/resources/extensions/enterprise_platform_keys/subtle_crypto.js index 3efb550..41cf875 100644 --- a/chrome/renderer/resources/extensions/enterprise_platform_keys/subtle_crypto.js +++ b/chrome/renderer/resources/extensions/enterprise_platform_keys/subtle_crypto.js
@@ -133,8 +133,8 @@ EnterpriseSubtleCryptoImpl.prototype = $Object.create(SubtleCryptoImpl.prototype); -EnterpriseSubtleCryptoImpl.prototype.generateKey = - function(algorithm, extractable, keyUsages) { +EnterpriseSubtleCryptoImpl.prototype.generateKey = function( + algorithm, extractable, keyUsages) { var subtleCrypto = this; return new Promise(function(resolve, reject) { // TODO(pneubeck): Apply the algorithm normalization of the WebCrypto
diff --git a/chrome/renderer/resources/extensions/file_browser_handler_custom_bindings.js b/chrome/renderer/resources/extensions/file_browser_handler_custom_bindings.js index 3e58a77..9982987 100644 --- a/chrome/renderer/resources/extensions/file_browser_handler_custom_bindings.js +++ b/chrome/renderer/resources/extensions/file_browser_handler_custom_bindings.js
@@ -34,12 +34,15 @@ // here, and require handling. const fs = GetIsolatedFileSystem(item.fileSystemId); if (item.isDirectory) { - fs.root.getDirectory(item.baseName, {}, (dirEntry) => { - entryIdManager.registerEntry(item.entryId, dirEntry); - resolve(dirEntry); - }, (err) => { - reject(err.message); - }); + fs.root.getDirectory( + item.baseName, {}, + (dirEntry) => { + entryIdManager.registerEntry(item.entryId, dirEntry); + resolve(dirEntry); + }, + (err) => { + reject(err.message); + }); } else { fs.root.getFile( item.baseName, canCreate ? {create: true} : {}, @@ -56,39 +59,42 @@ } } -bindingUtil.registerEventArgumentMassager('fileBrowserHandler.onExecute', - function(args, dispatch) { - if (args.length < 2) { - dispatch(args); - return; - } - // The second param for this event's payload is file definition dictionary. - const fileList = args[1].entries; - if (!fileList) { - dispatch(args); - return; - } +bindingUtil.registerEventArgumentMassager( + 'fileBrowserHandler.onExecute', function(args, dispatch) { + if (args.length < 2) { + dispatch(args); + return; + } + // The second param for this event's payload is file definition + // dictionary. + const fileList = args[1].entries; + if (!fileList) { + dispatch(args); + return; + } - // Construct File API's Entry instances. $Promise.allSettled() is unavailable, - // so use a |barrier| counter and explicitly sort results. - const results = []; - let barrier = fileList.length; - const onFinish = () => { - results.sort((a, b) => a.key - b.key); - args[1].entries = $Array.map(results, item => item.entry); - dispatch(args); - }; - const onResolve = (index, entry) => { - results.push({key: index, entry}); - if (--barrier === 0) onFinish(); - }; - const onReject = (message) => { - console.error(message); - if (--barrier === 0) onFinish(); - }; - for (let i = 0; i < fileList.length; ++i) { - GetFileEntry( - onResolve.bind(null, i), onReject, - /*canCreate*/ false, /*item*/ fileList[i]); - } -}); + // Construct File API's Entry instances. $Promise.allSettled() is + // unavailable, so use a |barrier| counter and explicitly sort results. + const results = []; + let barrier = fileList.length; + const onFinish = () => { + results.sort((a, b) => a.key - b.key); + args[1].entries = $Array.map(results, item => item.entry); + dispatch(args); + }; + const onResolve = (index, entry) => { + results.push({key: index, entry}); + if (--barrier === 0) + onFinish(); + }; + const onReject = (message) => { + console.error(message); + if (--barrier === 0) + onFinish(); + }; + for (let i = 0; i < fileList.length; ++i) { + GetFileEntry( + onResolve.bind(null, i), onReject, + /*canCreate*/ false, /*item*/ fileList[i]); + } + });
diff --git a/chrome/renderer/resources/extensions/file_manager_private_custom_bindings.js b/chrome/renderer/resources/extensions/file_manager_private_custom_bindings.js index a0b67577..284a460 100644 --- a/chrome/renderer/resources/extensions/file_manager_private_custom_bindings.js +++ b/chrome/renderer/resources/extensions/file_manager_private_custom_bindings.js
@@ -79,24 +79,23 @@ } }); - apiFunctions.setCustomCallback('searchDriveMetadata', - function(callback, response) { - if (response && !response.error) { - for (var i = 0; i < response.length; i++) { - response[i].entry = - getExternalFileEntry(response[i].entry); - } - } + apiFunctions.setCustomCallback( + 'searchDriveMetadata', function(callback, response) { + if (response && !response.error) { + for (var i = 0; i < response.length; i++) { + response[i].entry = getExternalFileEntry(response[i].entry); + } + } - // So |callback| doesn't break if response is not defined. - if (!response) { - response = []; - } + // So |callback| doesn't break if response is not defined. + if (!response) { + response = []; + } - if (callback) { - callback(response); - } - }); + if (callback) { + callback(response); + } + }); apiFunctions.setHandleRequest( 'resolveIsolatedEntries', @@ -178,49 +177,63 @@ callbackAdaptor(successCallback, failureCallback, resultHandler)); }); - apiFunctions.setHandleRequest('getContentMimeType', + apiFunctions.setHandleRequest( + 'getContentMimeType', function(fileEntry, successCallback, failureCallback) { - fileEntry.file(blob => { - var blobUUID = blobNatives.GetBlobUuid(blob); + fileEntry.file( + blob => { + var blobUUID = blobNatives.GetBlobUuid(blob); - if (!blob || !blob.size) { - successCallback(undefined); - return; - } + if (!blob || !blob.size) { + successCallback(undefined); + return; + } - var resultHandler = function(blob, mimeType) { - return mimeType; - }.bind(this, blob); // Bind a blob reference: crbug.com/415792#c12 + var resultHandler = + function(blob, mimeType) { + return mimeType; + }.bind(this, + blob); // Bind a blob reference: crbug.com/415792#c12 - fileManagerPrivateInternal.getContentMimeType( - blobUUID, - callbackAdaptor(successCallback, failureCallback, resultHandler)); - }, (error) => { - failureCallback(`fileEntry.file() blob error: ${error.message}`); - }); - }); + fileManagerPrivateInternal.getContentMimeType( + blobUUID, + callbackAdaptor( + successCallback, failureCallback, resultHandler)); + }, + (error) => { + failureCallback(`fileEntry.file() blob error: ${error.message}`); + }); + }); - apiFunctions.setHandleRequest('getContentMetadata', function( - fileEntry, mimeType, includeImages, successCallback, failureCallback) { - fileEntry.file(blob => { - var blobUUID = blobNatives.GetBlobUuid(blob); + apiFunctions.setHandleRequest( + 'getContentMetadata', + function( + fileEntry, mimeType, includeImages, successCallback, + failureCallback) { + fileEntry.file( + blob => { + var blobUUID = blobNatives.GetBlobUuid(blob); - if (!blob || !blob.size) { - successCallback(undefined); - return; - } + if (!blob || !blob.size) { + successCallback(undefined); + return; + } - var resultHandler = function(blob, metadata) { - return metadata; - }.bind(this, blob); // Bind a blob reference: crbug.com/415792#c12 + var resultHandler = + function(blob, metadata) { + return metadata; + }.bind(this, + blob); // Bind a blob reference: crbug.com/415792#c12 - fileManagerPrivateInternal.getContentMetadata( - blobUUID, mimeType, !!includeImages, - callbackAdaptor(successCallback, failureCallback, resultHandler)); - }, (error) => { - failureCallback(`fileEntry.file() blob error: ${error.message}`); - }); - }); + fileManagerPrivateInternal.getContentMetadata( + blobUUID, mimeType, !!includeImages, + callbackAdaptor( + successCallback, failureCallback, resultHandler)); + }, + (error) => { + failureCallback(`fileEntry.file() blob error: ${error.message}`); + }); + }); apiFunctions.setHandleRequest( 'pinDriveFile', function(entry, pin, successCallback, failureCallback) { @@ -377,8 +390,7 @@ url, callbackAdaptor(successCallback, failureCallback)); }); - apiFunctions.setCustomCallback('searchFiles', - function(callback, response) { + apiFunctions.setCustomCallback('searchFiles', function(callback, response) { if (response && !response.error && response.entries) { response.entries = response.entries.map(getExternalFileEntry); } @@ -445,20 +457,20 @@ bindingUtil.registerEventArgumentMassager( 'fileManagerPrivate.onDirectoryChanged', function(args, dispatch) { - // Convert the entry arguments into a real Entry object. - args[0].entry = getExternalFileEntry(args[0].entry); - dispatch(args); -}); + // Convert the entry arguments into a real Entry object. + args[0].entry = getExternalFileEntry(args[0].entry); + dispatch(args); + }); bindingUtil.registerEventArgumentMassager( 'fileManagerPrivate.onCrostiniChanged', function(args, dispatch) { - // Convert entries arguments into real Entry objects. - const entries = args[0].entries; - for (let i = 0; i < entries.length; i++) { - entries[i] = getExternalFileEntry(entries[i]); - } - dispatch(args); -}); + // Convert entries arguments into real Entry objects. + const entries = args[0].entries; + for (let i = 0; i < entries.length; i++) { + entries[i] = getExternalFileEntry(entries[i]); + } + dispatch(args); + }); bindingUtil.registerEventArgumentMassager( 'fileManagerPrivate.onIOTaskProgressStatus', function(args, dispatch) {
diff --git a/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js b/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js index 11524ca..1f08009 100644 --- a/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js +++ b/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js
@@ -19,8 +19,7 @@ * @type {RegExp} * @const */ -var METADATA_THUMBNAIL_FORMAT = new RegExp( - '^data:image/(png|jpeg|webp);', 'i'); +var METADATA_THUMBNAIL_FORMAT = new RegExp('^data:image/(png|jpeg|webp);', 'i'); /** * Annotates a date with its serialized value. @@ -150,7 +149,7 @@ result.mimeType = metadata.mimeType; if (metadata.thumbnail !== undefined) result.thumbnail = metadata.thumbnail; - if(metadata.cloudIdentifier !== undefined) + if (metadata.cloudIdentifier !== undefined) result.cloudIdentifier = metadata.cloudIdentifier; if (metadata.cloudFileInfo !== undefined) result.cloudFileInfo = metadata.cloudFileInfo; @@ -176,17 +175,15 @@ fileSystemProviderInternal.operationRequestedError( options.fileSystemId, options.requestId, error, Date.now() - executionStart); - } + }; dispatch([options, onSuccessCallback, onErrorCallback]); } bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onUnmountRequested', - massageArgumentsDefault); + 'fileSystemProvider.onUnmountRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onGetMetadataRequested', - function(args, dispatch) { + 'fileSystemProvider.onGetMetadataRequested', function(args, dispatch) { var executionStart = Date.now(); var options = args[0]; var onSuccessCallback = function(metadata) { @@ -198,9 +195,7 @@ } fileSystemProviderInternal.getMetadataRequestedSuccess( - options.fileSystemId, - options.requestId, - annotateMetadata(metadata), + options.fileSystemId, options.requestId, annotateMetadata(metadata), Date.now() - executionStart); }; @@ -210,38 +205,33 @@ fileSystemProviderInternal.operationRequestedError( options.fileSystemId, options.requestId, error, Date.now() - executionStart); - } - + }; dispatch([options, onSuccessCallback, onErrorCallback]); }); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onGetActionsRequested', - function(args, dispatch) { + 'fileSystemProvider.onGetActionsRequested', function(args, dispatch) { var executionStart = Date.now(); var options = args[0]; var onSuccessCallback = function(actions) { fileSystemProviderInternal.getActionsRequestedSuccess( - options.fileSystemId, - options.requestId, - actions, + options.fileSystemId, options.requestId, actions, Date.now() - executionStart); }; - var onErrorCallback = function(error) { + var onErrorCallback = + function(error) { if (!verifyErrorForFailure(error)) return; fileSystemProviderInternal.operationRequestedError( options.fileSystemId, options.requestId, error, Date.now() - executionStart); - } - + }; dispatch([options, onSuccessCallback, onErrorCallback]); }); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onReadDirectoryRequested', - function(args, dispatch) { + 'fileSystemProvider.onReadDirectoryRequested', function(args, dispatch) { var executionStart = Date.now(); var options = args[0]; var onSuccessCallback = function(entries, hasNext) { @@ -272,7 +262,7 @@ fileSystemProviderInternal.operationRequestedError( options.fileSystemId, options.requestId, error, Date.now() - executionStart); - } + }; dispatch([options, onSuccessCallback, onErrorCallback]); }); @@ -296,12 +286,10 @@ }); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onCloseFileRequested', - massageArgumentsDefault); + 'fileSystemProvider.onCloseFileRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onReadFileRequested', - function(args, dispatch) { + 'fileSystemProvider.onReadFileRequested', function(args, dispatch) { var executionStart = Date.now(); var options = args[0]; var onSuccessCallback = function(data, hasNext) { @@ -315,65 +303,51 @@ fileSystemProviderInternal.operationRequestedError( options.fileSystemId, options.requestId, error, Date.now() - executionStart); - } + }; dispatch([options, onSuccessCallback, onErrorCallback]); }); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onCreateDirectoryRequested', - massageArgumentsDefault); + 'fileSystemProvider.onCreateDirectoryRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onDeleteEntryRequested', - massageArgumentsDefault); + 'fileSystemProvider.onDeleteEntryRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onCreateFileRequested', - massageArgumentsDefault); + 'fileSystemProvider.onCreateFileRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onCopyEntryRequested', - massageArgumentsDefault); + 'fileSystemProvider.onCopyEntryRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onMoveEntryRequested', - massageArgumentsDefault); + 'fileSystemProvider.onMoveEntryRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onTruncateRequested', - massageArgumentsDefault); + 'fileSystemProvider.onTruncateRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onWriteFileRequested', - massageArgumentsDefault); + 'fileSystemProvider.onWriteFileRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onAbortRequested', - massageArgumentsDefault); + 'fileSystemProvider.onAbortRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onObserveDirectoryRequested', - massageArgumentsDefault); + 'fileSystemProvider.onObserveDirectoryRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onUnobserveEntryRequested', - massageArgumentsDefault); + 'fileSystemProvider.onUnobserveEntryRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onAddWatcherRequested', - massageArgumentsDefault); + 'fileSystemProvider.onAddWatcherRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onRemoveWatcherRequested', - massageArgumentsDefault); + 'fileSystemProvider.onRemoveWatcherRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onConfigureRequested', - massageArgumentsDefault); + 'fileSystemProvider.onConfigureRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( - 'fileSystemProvider.onExecuteActionRequested', - massageArgumentsDefault); + 'fileSystemProvider.onExecuteActionRequested', massageArgumentsDefault); bindingUtil.registerEventArgumentMassager( 'fileSystemProvider.onMountRequested', function(args, dispatch) { @@ -388,6 +362,6 @@ return; fileSystemProviderInternal.respondToMountRequest( requestId, error, Date.now() - executionStart); - } + }; dispatch([onSuccessCallback, onErrorCallback]); });
diff --git a/chrome/renderer/resources/extensions/gcm_custom_bindings.js b/chrome/renderer/resources/extensions/gcm_custom_bindings.js index 745c06c..d2270be 100644 --- a/chrome/renderer/resources/extensions/gcm_custom_bindings.js +++ b/chrome/renderer/resources/extensions/gcm_custom_bindings.js
@@ -11,31 +11,32 @@ var gcm = bindingsAPI.compiledApi; apiFunctions.setUpdateArgumentsPostValidate( - 'send', function(message, callback) { - // Validate message.data. - var payloadSize = 0; - forEach(message.data, function(property, value) { - if (property.length === 0) - throw new Error("One of data keys is empty."); + 'send', function(message, callback) { + // Validate message.data. + var payloadSize = 0; + forEach(message.data, function(property, value) { + if (property.length === 0) + throw new Error('One of data keys is empty.'); - var lowerCasedProperty = property.toLowerCase(); - // Issue an error for forbidden prefixes of property names. - if (lowerCasedProperty.startsWith("goog.") || - lowerCasedProperty.startsWith("google") || - property.startsWith("collapse_key")) { - throw new Error("Invalid data key: " + property); - } + var lowerCasedProperty = property.toLowerCase(); + // Issue an error for forbidden prefixes of property names. + if (lowerCasedProperty.startsWith('goog.') || + lowerCasedProperty.startsWith('google') || + property.startsWith('collapse_key')) { + throw new Error('Invalid data key: ' + property); + } - payloadSize += property.length + value.length; + payloadSize += property.length + value.length; + }); + + if (payloadSize > gcm.MAX_MESSAGE_SIZE) + throw new Error( + 'Payload exceeded allowed size limit. Payload size is: ' + + payloadSize); + + if (payloadSize === 0) + throw new Error('No data to send.'); + + return arguments; }); - - if (payloadSize > gcm.MAX_MESSAGE_SIZE) - throw new Error("Payload exceeded allowed size limit. Payload size is: " - + payloadSize); - - if (payloadSize === 0) - throw new Error("No data to send."); - - return arguments; - }); });
diff --git a/chrome/renderer/resources/extensions/image_writer_private_custom_bindings.js b/chrome/renderer/resources/extensions/image_writer_private_custom_bindings.js index 3aceaf7..33f33ab 100644 --- a/chrome/renderer/resources/extensions/image_writer_private_custom_bindings.js +++ b/chrome/renderer/resources/extensions/image_writer_private_custom_bindings.js
@@ -9,8 +9,8 @@ apiFunctions.setUpdateArgumentsPostValidate( 'writeFromFile', function(device, fileEntry, callback) { - var fileSystemName = fileEntry.filesystem.name; - var relativePath = $String.slice(fileEntry.fullPath, 1); - return [device, fileSystemName, relativePath, callback]; - }); + var fileSystemName = fileEntry.filesystem.name; + var relativePath = $String.slice(fileEntry.fullPath, 1); + return [device, fileSystemName, relativePath, callback]; + }); });
diff --git a/chrome/renderer/resources/extensions/input.ime_custom_bindings.js b/chrome/renderer/resources/extensions/input.ime_custom_bindings.js index 8d4299ef..8f6a668 100644 --- a/chrome/renderer/resources/extensions/input.ime_custom_bindings.js +++ b/chrome/renderer/resources/extensions/input.ime_custom_bindings.js
@@ -8,26 +8,26 @@ var appWindowNatives = requireNative('app_window_natives'); var keyEventHandled; -bindingUtil.registerEventArgumentMassager('input.ime.onKeyEvent', - function(args, dispatch) { - var keyData = args[1]; - var result = undefined; - try { - // dispatch() is weird - it returns an object {results: array<results>} iff - // there is at least one result value that !== undefined. Since onKeyEvent - // has a maximum of one listener, we know that any result we find is the one - // we're interested in. - var dispatchResult = dispatch(args); - if (dispatchResult && dispatchResult.results) - result = dispatchResult.results[0]; - } catch (e) { - result = false; - console.error('Error in event handler for onKeyEvent: ' + e.stack); - } - if (result !== undefined) { - keyEventHandled(keyData.requestId, !!result); - } -}); +bindingUtil.registerEventArgumentMassager( + 'input.ime.onKeyEvent', function(args, dispatch) { + var keyData = args[1]; + var result = undefined; + try { + // dispatch() is weird - it returns an object {results: array<results>} + // iff there is at least one result value that !== undefined. Since + // onKeyEvent has a maximum of one listener, we know that any result we + // find is the one we're interested in. + var dispatchResult = dispatch(args); + if (dispatchResult && dispatchResult.results) + result = dispatchResult.results[0]; + } catch (e) { + result = false; + console.error('Error in event handler for onKeyEvent: ' + e.stack); + } + if (result !== undefined) { + keyEventHandled(keyData.requestId, !!result); + } + }); apiBridge.registerCustomHook(function(api) { keyEventHandled = api.compiledApi.keyEventHandled; @@ -40,17 +40,17 @@ $Function.call(originalAddListener, this, cb); }; - api.apiFunctions.setCustomCallback('createWindow', - function(callback, windowParams) { - if (!callback) { - return; - } - var view; - if (windowParams && windowParams.frameToken) { - view = appWindowNatives.GetFrame( - windowParams.frameToken, false /* notifyBrowser */); - view.id = windowParams.frameToken; - } - callback(view); - }); + api.apiFunctions.setCustomCallback( + 'createWindow', function(callback, windowParams) { + if (!callback) { + return; + } + var view; + if (windowParams && windowParams.frameToken) { + view = appWindowNatives.GetFrame( + windowParams.frameToken, false /* notifyBrowser */); + view.id = windowParams.frameToken; + } + callback(view); + }); });
diff --git a/chrome/renderer/resources/extensions/media_galleries_custom_bindings.js b/chrome/renderer/resources/extensions/media_galleries_custom_bindings.js index dc53e2f..78cfe15 100644 --- a/chrome/renderer/resources/extensions/media_galleries_custom_bindings.js +++ b/chrome/renderer/resources/extensions/media_galleries_custom_bindings.js
@@ -15,8 +15,8 @@ mediaGalleriesMetadata = {}; // Clear any previous metadata. if (response) { for (var i = 0; i < response.length; i++) { - var filesystem = mediaGalleriesNatives.GetMediaFileSystemObject( - response[i].fsid); + var filesystem = + mediaGalleriesNatives.GetMediaFileSystemObject(response[i].fsid); $Array.push(result, filesystem); var metadata = response[i]; delete metadata.fsid; @@ -31,44 +31,44 @@ // getMediaFileSystems and addUserSelectedFolder use a custom callback so that // they can instantiate and return an array of file system objects. - apiFunctions.setCustomCallback('getMediaFileSystems', - function(callback, response) { - var result = createFileSystemObjectsAndUpdateMetadata(response); - if (callback) - callback(result); - }); + apiFunctions.setCustomCallback( + 'getMediaFileSystems', function(callback, response) { + var result = createFileSystemObjectsAndUpdateMetadata(response); + if (callback) + callback(result); + }); - apiFunctions.setCustomCallback('addUserSelectedFolder', - function(callback, response) { - var fileSystems = []; - var selectedFileSystemName = ""; - if (response && 'mediaFileSystems' in response && - 'selectedFileSystemIndex' in response) { - fileSystems = createFileSystemObjectsAndUpdateMetadata( - response['mediaFileSystems']); - var selectedFileSystemIndex = response['selectedFileSystemIndex']; - if (selectedFileSystemIndex >= 0) { - selectedFileSystemName = fileSystems[selectedFileSystemIndex].name; - } - } - if (callback) - callback(fileSystems, selectedFileSystemName); - }); + apiFunctions.setCustomCallback( + 'addUserSelectedFolder', function(callback, response) { + var fileSystems = []; + var selectedFileSystemName = ''; + if (response && 'mediaFileSystems' in response && + 'selectedFileSystemIndex' in response) { + fileSystems = createFileSystemObjectsAndUpdateMetadata( + response['mediaFileSystems']); + var selectedFileSystemIndex = response['selectedFileSystemIndex']; + if (selectedFileSystemIndex >= 0) { + selectedFileSystemName = fileSystems[selectedFileSystemIndex].name; + } + } + if (callback) + callback(fileSystems, selectedFileSystemName); + }); - apiFunctions.setHandleRequest('getMediaFileSystemMetadata', - function(filesystem) { - if (filesystem && filesystem.name && - filesystem.name in mediaGalleriesMetadata) { - return mediaGalleriesMetadata[filesystem.name]; - } - return { - 'name': '', - 'galleryId': '', - 'isRemovable': false, - 'isMediaDevice': false, - 'isAvailable': false, - }; - }); + apiFunctions.setHandleRequest( + 'getMediaFileSystemMetadata', function(filesystem) { + if (filesystem && filesystem.name && + filesystem.name in mediaGalleriesMetadata) { + return mediaGalleriesMetadata[filesystem.name]; + } + return { + 'name': '', + 'galleryId': '', + 'isRemovable': false, + 'isMediaDevice': false, + 'isAvailable': false, + }; + }); function getMetadataCallback(uuid, callback, response, blobs) { if (response && blobs) @@ -80,21 +80,21 @@ delete blobsAwaitingMetadata[uuid]; } - apiFunctions.setHandleRequest('getMetadata', - function(mediaFile, options, callback) { - var blobUuid = blobNatives.GetBlobUuid(mediaFile) - // Store the blob in a global object to keep its refcount nonzero -- this - // prevents the object from being garbage collected before any metadata - // parsing gets to occur (see crbug.com/415792). - blobsAwaitingMetadata[blobUuid] = mediaFile; + apiFunctions.setHandleRequest( + 'getMetadata', function(mediaFile, options, callback) { + var blobUuid = blobNatives.GetBlobUuid(mediaFile) + // Store the blob in a global object to keep its refcount nonzero -- + // this prevents the object from being garbage collected before any + // metadata parsing gets to occur (see crbug.com/415792). + blobsAwaitingMetadata[blobUuid] = mediaFile; - var optArgs = { - __proto__: null, - customCallback: $Function.bind(getMetadataCallback, null, blobUuid), - }; + var optArgs = { + __proto__: null, + customCallback: $Function.bind(getMetadataCallback, null, blobUuid), + }; - bindingUtil.sendRequest( - 'mediaGalleries.getMetadata', [blobUuid, options, callback], - optArgs); - }); + bindingUtil.sendRequest( + 'mediaGalleries.getMetadata', [blobUuid, options, callback], + optArgs); + }); });
diff --git a/chrome/renderer/resources/extensions/notifications_custom_bindings.js b/chrome/renderer/resources/extensions/notifications_custom_bindings.js index 0864623..7848cdc 100644 --- a/chrome/renderer/resources/extensions/notifications_custom_bindings.js +++ b/chrome/renderer/resources/extensions/notifications_custom_bindings.js
@@ -111,8 +111,8 @@ // changes also being made to the object on the caller's side. // TODO(dewittj): Remove this hack. This is used as a way to deep // copy a complex JSON object. - var notification_details_copy = $JSON.parse( - $JSON.stringify(notification_details)); + var notification_details_copy = + $JSON.parse($JSON.stringify(notification_details)); replaceNotificationOptionURLs(notification_details_copy, function(success) { if (success) { bindingUtil.sendRequest( @@ -124,7 +124,7 @@ }; } -apiBridge.registerCustomHook( function(bindingsAPI) { +apiBridge.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest(
diff --git a/chrome/renderer/resources/extensions/notifications_custom_bindings_test.js b/chrome/renderer/resources/extensions/notifications_custom_bindings_test.js index 829609f..b628593 100644 --- a/chrome/renderer/resources/extensions/notifications_custom_bindings_test.js +++ b/chrome/renderer/resources/extensions/notifications_custom_bindings_test.js
@@ -22,7 +22,7 @@ function testImageDataSetter() { var c = {}; - var k = "key"; + var k = 'key'; var callback = imageDataSetter(c, k); callback('val'); assertTrue(c[k] === 'val'); @@ -31,9 +31,9 @@ function testGetUrlSpecs() { var imageSizes = { scaleFactor: 1.0, - icon: { width: 10, height: 10 }, - image: { width: 24, height: 32 }, - buttonIcon: { width: 2, height: 2} + icon: {width: 10, height: 10}, + image: {width: 24, height: 32}, + buttonIcon: {width: 2, height: 2} }; var notificationDetails = {}; @@ -41,19 +41,18 @@ var emptySpecs = getUrlSpecs(imageSizes, notificationDetails); assertTrue(emptySpecs.length === 0); - notificationDetails.iconUrl = "iconUrl"; - notificationDetails.imageUrl = "imageUrl"; - notificationDetails.buttons = [ - {iconUrl: "buttonOneIconUrl"}, - {iconUrl: "buttonTwoIconUrl"}]; + notificationDetails.iconUrl = 'iconUrl'; + notificationDetails.imageUrl = 'imageUrl'; + notificationDetails.buttons = + [{iconUrl: 'buttonOneIconUrl'}, {iconUrl: 'buttonTwoIconUrl'}]; var allSpecs = getUrlSpecs(imageSizes, notificationDetails); assertTrue(allSpecs.length === 4); - assertFalse(notificationDetails.iconBitmap === "test"); - assertFalse(notificationDetails.imageBitmap === "test"); - assertFalse(notificationDetails.buttons[0].iconBitmap === "test"); - assertFalse(notificationDetails.buttons[1].iconBitmap === "test"); + assertFalse(notificationDetails.iconBitmap === 'test'); + assertFalse(notificationDetails.imageBitmap === 'test'); + assertFalse(notificationDetails.buttons[0].iconBitmap === 'test'); + assertFalse(notificationDetails.buttons[1].iconBitmap === 'test'); for (var i = 0; i < allSpecs.length; i++) { var expectedKeys = ['path', 'width', 'height', 'callback']; @@ -61,43 +60,40 @@ for (var j in expectedKeys) { assertTrue(spec.hasOwnProperty(expectedKeys[j])); } - spec.callback(spec.path + "|" + spec.width + "|" + spec.height); + spec.callback(spec.path + '|' + spec.width + '|' + spec.height); } - assertTrue(notificationDetails.iconBitmap === "iconUrl|10|10"); - assertTrue(notificationDetails.imageBitmap === "imageUrl|24|32"); + assertTrue(notificationDetails.iconBitmap === 'iconUrl|10|10'); + assertTrue(notificationDetails.imageBitmap === 'imageUrl|24|32'); assertTrue( - notificationDetails.buttons[0].iconBitmap === "buttonOneIconUrl|2|2"); + notificationDetails.buttons[0].iconBitmap === 'buttonOneIconUrl|2|2'); assertTrue( - notificationDetails.buttons[1].iconBitmap === "buttonTwoIconUrl|2|2"); + notificationDetails.buttons[1].iconBitmap === 'buttonTwoIconUrl|2|2'); } function testGetUrlSpecsScaled() { var imageSizes = { scaleFactor: 2.0, - icon: { width: 10, height: 10 }, - image: { width: 24, height: 32 }, - buttonIcon: { width: 2, height: 2} + icon: {width: 10, height: 10}, + image: {width: 24, height: 32}, + buttonIcon: {width: 2, height: 2} }; var notificationDetails = { - iconUrl: "iconUrl", - imageUrl: "imageUrl", - buttons: [ - {iconUrl: "buttonOneIconUrl"}, - {iconUrl: "buttonTwoIconUrl"} - ] + iconUrl: 'iconUrl', + imageUrl: 'imageUrl', + buttons: [{iconUrl: 'buttonOneIconUrl'}, {iconUrl: 'buttonTwoIconUrl'}] }; var allSpecs = getUrlSpecs(imageSizes, notificationDetails); for (var i = 0; i < allSpecs.length; i++) { var spec = allSpecs[i]; - spec.callback(spec.path + "|" + spec.width + "|" + spec.height); + spec.callback(spec.path + '|' + spec.width + '|' + spec.height); } - assertEquals(notificationDetails.iconBitmap, "iconUrl|20|20"); - assertEquals(notificationDetails.imageBitmap, "imageUrl|48|64"); - assertEquals(notificationDetails.buttons[0].iconBitmap, - "buttonOneIconUrl|4|4"); - assertEquals(notificationDetails.buttons[1].iconBitmap, - "buttonTwoIconUrl|4|4"); + assertEquals(notificationDetails.iconBitmap, 'iconUrl|20|20'); + assertEquals(notificationDetails.imageBitmap, 'imageUrl|48|64'); + assertEquals( + notificationDetails.buttons[0].iconBitmap, 'buttonOneIconUrl|4|4'); + assertEquals( + notificationDetails.buttons[1].iconBitmap, 'buttonTwoIconUrl|4|4'); }
diff --git a/chrome/renderer/resources/extensions/notifications_test_util.js b/chrome/renderer/resources/extensions/notifications_test_util.js index 50a71e8b..382471cf 100644 --- a/chrome/renderer/resources/extensions/notifications_test_util.js +++ b/chrome/renderer/resources/extensions/notifications_test_util.js
@@ -12,24 +12,21 @@ var require = function(library) { return { - lastError: { - run: function() {} - }, - sendRequest: { - sendRequest: function () {} - }, + lastError: {run: function() {}}, + sendRequest: {sendRequest: function() {}}, }[library]; }; -var requireNative = function(library) { +var requireNative = + function(library) { return { notifications_private: { - GetNotificationImageSizes: function () { + GetNotificationImageSizes: function() { return { scaleFactor: 0, - icon: { width: 0, height: 0 }, - image: { width: 0, height: 0 }, - buttonIcon: { width: 0, height: 0} + icon: {width: 0, height: 0}, + image: {width: 0, height: 0}, + buttonIcon: {width: 0, height: 0} }; } } @@ -37,17 +34,19 @@ } var exports = { - $set: function(k, v) { this.k = v; } + $set: function(k, v) { + this.k = v; + } }; var $Array = { - push: function (ary, val) { + push: function(ary, val) { ary.push(val); } }; var $Function = { - bind: function (fn, context) { + bind: function(fn, context) { return fn.bind(context); } };
diff --git a/chrome/renderer/resources/extensions/omnibox_custom_bindings.js b/chrome/renderer/resources/extensions/omnibox_custom_bindings.js index 7a18b54..6ca99ad 100644 --- a/chrome/renderer/resources/extensions/omnibox_custom_bindings.js +++ b/chrome/renderer/resources/extensions/omnibox_custom_bindings.js
@@ -43,10 +43,7 @@ } // Otherwise, it's valid, so build up the result. - var result = { - description: '', - descriptionStyles: [] - }; + var result = {description: '', descriptionStyles: []}; // Recursively walk the tree. function walk(node) { @@ -143,35 +140,35 @@ apiBridge.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; - apiFunctions.setHandleRequest('setDefaultSuggestion', - function(details, callback) { - var parseResult = parseOmniboxDescription(details.description); - bindingUtil.sendRequest('omnibox.setDefaultSuggestion', - [parseResult, callback], - undefined); - }); + apiFunctions.setHandleRequest( + 'setDefaultSuggestion', function(details, callback) { + var parseResult = parseOmniboxDescription(details.description); + bindingUtil.sendRequest( + 'omnibox.setDefaultSuggestion', [parseResult, callback], + undefined); + }); apiFunctions.setUpdateArgumentsPostValidate( 'sendSuggestions', function(requestId, userSuggestions) { - var suggestions = []; - for (var i = 0; i < userSuggestions.length; i++) { - var parseResult = parseOmniboxDescription( - userSuggestions[i].description); - parseResult.content = userSuggestions[i].content; - parseResult.deletable = userSuggestions[i].deletable; - $Array.push(suggestions, parseResult); - } - return [requestId, suggestions]; - }); + var suggestions = []; + for (var i = 0; i < userSuggestions.length; i++) { + var parseResult = + parseOmniboxDescription(userSuggestions[i].description); + parseResult.content = userSuggestions[i].content; + parseResult.deletable = userSuggestions[i].deletable; + $Array.push(suggestions, parseResult); + } + return [requestId, suggestions]; + }); }); } -bindingUtil.registerEventArgumentMassager('omnibox.onInputChanged', - function(args, dispatch) { - var text = args[0]; - var requestId = args[1]; - var suggestCallback = function(suggestions) { - chrome.omnibox.sendSuggestions(requestId, suggestions); - }; - dispatch([text, suggestCallback]); -}); +bindingUtil.registerEventArgumentMassager( + 'omnibox.onInputChanged', function(args, dispatch) { + var text = args[0]; + var requestId = args[1]; + var suggestCallback = function(suggestions) { + chrome.omnibox.sendSuggestions(requestId, suggestions); + }; + dispatch([text, suggestCallback]); + });
diff --git a/chrome/renderer/resources/extensions/page_capture_custom_bindings.js b/chrome/renderer/resources/extensions/page_capture_custom_bindings.js index c4caf1c1..cba202f 100644 --- a/chrome/renderer/resources/extensions/page_capture_custom_bindings.js +++ b/chrome/renderer/resources/extensions/page_capture_custom_bindings.js
@@ -12,8 +12,7 @@ apiBridge.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; - apiFunctions.setCustomCallback('saveAsMHTML', - function(callback, response) { + apiFunctions.setCustomCallback('saveAsMHTML', function(callback, response) { var requestId; if (response) { requestId = response.requestId;
diff --git a/chrome/renderer/resources/extensions/platform_keys/get_crypto_key_util.js b/chrome/renderer/resources/extensions/platform_keys/get_crypto_key_util.js index 38232fae..63fde90f 100644 --- a/chrome/renderer/resources/extensions/platform_keys/get_crypto_key_util.js +++ b/chrome/renderer/resources/extensions/platform_keys/get_crypto_key_util.js
@@ -5,7 +5,7 @@ var internalAPI = getInternalApi('platformKeysInternal'); var normalizeAlgorithm = - requireNative('platform_keys_natives').NormalizeAlgorithm; + requireNative('platform_keys_natives').NormalizeAlgorithm; // Returns the normalized parameters of |importParams|, which can be used to // import asymmetric keys. Unknown parameters will be ignored. @@ -29,7 +29,7 @@ hashIsNone = true; // Temporarily replace |hash| by a valid WebCrypto Hash for normalization. // This will be reverted to 'none' after normalization. - filteredParams.hash = { name: 'SHA-1' }; + filteredParams.hash = {name: 'SHA-1'}; } else { filteredParams.hash = { name: importParams.hash.name } } @@ -41,7 +41,7 @@ throw $Error.self('A required parameter was missing or out-of-range'); } if (hashIsNone) { - resultParams.hash = { name: 'none' }; + resultParams.hash = {name: 'none'}; } return resultParams; } @@ -64,14 +64,14 @@ // TODO(crbug.com/40136219): Check cert type is ArrayBuffer. importParams = normalizeImportParams(importParams); internalAPI.getPublicKey( - cert, importParams.name, function (publicKey, algorithm) { - if (chrome.runtime.lastError) { - callback(); - return; - } - var combinedAlgorithm = combineAlgorithms(algorithm, importParams); - callback(publicKey, combinedAlgorithm); - }); + cert, importParams.name, function(publicKey, algorithm) { + if (chrome.runtime.lastError) { + callback(); + return; + } + var combinedAlgorithm = combineAlgorithms(algorithm, importParams); + callback(publicKey, combinedAlgorithm); + }); } function getPublicKeyBySpki(publicKeySpkiDer, importParams, callback) { @@ -80,17 +80,16 @@ } importParams = normalizeImportParams(importParams); internalAPI.getPublicKeyBySpki( - publicKeySpkiDer, - importParams.name, - function (foundKeySpki, foundKeyAlgorithm) { - if (bindingUtil.hasLastError()) { - callback(); - return; - } - var combinedAlgorithm = - combineAlgorithms(foundKeyAlgorithm, importParams); - callback(foundKeySpki, combinedAlgorithm); - }); + publicKeySpkiDer, importParams.name, + function(foundKeySpki, foundKeyAlgorithm) { + if (bindingUtil.hasLastError()) { + callback(); + return; + } + var combinedAlgorithm = + combineAlgorithms(foundKeyAlgorithm, importParams); + callback(foundKeySpki, combinedAlgorithm); + }); } function getSymKeyById(symKeyId, callback) { @@ -101,7 +100,7 @@ // TODO(b/288880151): Call |internalAPI.getSymKeyById()|, when the new method // is added there. throw $Error.self( - 'getSymKeyById: method still not implemented by the internal API.'); + 'getSymKeyById: method still not implemented by the internal API.'); } exports.$set('getPublicKey', getPublicKey);
diff --git a/chrome/renderer/resources/extensions/platform_keys/subtle_crypto.js b/chrome/renderer/resources/extensions/platform_keys/subtle_crypto.js index 948444e..3be2b6c 100644 --- a/chrome/renderer/resources/extensions/platform_keys/subtle_crypto.js +++ b/chrome/renderer/resources/extensions/platform_keys/subtle_crypto.js
@@ -115,8 +115,8 @@ } // Create an ArrayBuffer that equals the dataView. Note that dataView.buffer // might contain more data than dataView. - var data = dataView.buffer.slice(dataView.byteOffset, - dataView.byteOffset + dataView.byteLength); + var data = dataView.buffer.slice( + dataView.byteOffset, dataView.byteOffset + dataView.byteLength); internalAPI.sign( subtleCrypto.tokenId, getKeyIdentifier(key), normalizedAlgorithmParameters.name, hashAlgorithmName, data,
diff --git a/chrome/renderer/resources/extensions/platform_keys_custom_bindings.js b/chrome/renderer/resources/extensions/platform_keys_custom_bindings.js index df64847..1446148 100644 --- a/chrome/renderer/resources/extensions/platform_keys_custom_bindings.js +++ b/chrome/renderer/resources/extensions/platform_keys_custom_bindings.js
@@ -63,8 +63,9 @@ }); }); - apiFunctions.setHandleRequest( - 'subtleCrypto', function() { return subtleCrypto }); + apiFunctions.setHandleRequest('subtleCrypto', function() { + return subtleCrypto + }); apiFunctions.setHandleRequest('getKeyPair', function(cert, params, callback) { getPublicKey(cert, params, function(foundKeySpki, foundKeyAlgorithm) {
diff --git a/chrome/renderer/resources/extensions/sync_file_system_custom_bindings.js b/chrome/renderer/resources/extensions/sync_file_system_custom_bindings.js index 0c2f9ba2..ffbed04 100644 --- a/chrome/renderer/resources/extensions/sync_file_system_custom_bindings.js +++ b/chrome/renderer/resources/extensions/sync_file_system_custom_bindings.js
@@ -14,9 +14,9 @@ function bindFileEntryFunction(functionName) { apiFunctions.setUpdateArgumentsPostValidate( functionName, function(entry, callback) { - var fileSystemUrl = entry.toURL(); - return [fileSystemUrl, callback]; - }); + var fileSystemUrl = entry.toURL(); + return [fileSystemUrl, callback]; + }); } $Array.forEach(['getFileStatus'], bindFileEntryFunction); @@ -24,12 +24,12 @@ function bindFileEntryArrayFunction(functionName) { apiFunctions.setUpdateArgumentsPostValidate( functionName, function(entries, callback) { - var fileSystemUrlArray = []; - for (var i=0; i < entries.length; i++) { - $Array.push(fileSystemUrlArray, entries[i].toURL()); - } - return [fileSystemUrlArray, callback]; - }); + var fileSystemUrlArray = []; + for (var i = 0; i < entries.length; i++) { + $Array.push(fileSystemUrlArray, entries[i].toURL()); + } + return [fileSystemUrlArray, callback]; + }); } $Array.forEach(['getFileStatuses'], bindFileEntryArrayFunction); @@ -37,66 +37,60 @@ function bindFileSystemFunction(functionName) { apiFunctions.setUpdateArgumentsPostValidate( functionName, function(filesystem, callback) { - var fileSystemUrl = filesystem.root.toURL(); - return [fileSystemUrl, callback]; - }); + var fileSystemUrl = filesystem.root.toURL(); + return [fileSystemUrl, callback]; + }); } $Array.forEach(['getUsageAndQuota'], bindFileSystemFunction); // Functions which return an [instanceOf=DOMFileSystem]. - apiFunctions.setCustomCallback('requestFileSystem', - function(callback, response) { - var result = null; - if (response) { - result = syncFileSystemNatives.GetSyncFileSystemObject( - response.name, response.root); - } - if (callback) - callback(result); - }); + apiFunctions.setCustomCallback( + 'requestFileSystem', function(callback, response) { + var result = null; + if (response) { + result = syncFileSystemNatives.GetSyncFileSystemObject( + response.name, response.root); + } + if (callback) + callback(result); + }); // Functions which return an array of FileStatusInfo object // which has [instanceOf=FileEntry]. - apiFunctions.setCustomCallback('getFileStatuses', - function(callback, response) { - var results = []; - if (response) { - for (var i = 0; i < response.length; i++) { - var result = {}; - var entry = response[i].entry; - result.fileEntry = fileSystemNatives.GetFileEntry( - entry.fileSystemType, - entry.fileSystemName, - entry.rootUrl, - entry.filePath, - entry.isDirectory); - result.status = response[i].status; - result.error = response[i].error; - $Array.push(results, result); + apiFunctions.setCustomCallback( + 'getFileStatuses', function(callback, response) { + var results = []; + if (response) { + for (var i = 0; i < response.length; i++) { + var result = {}; + var entry = response[i].entry; + result.fileEntry = fileSystemNatives.GetFileEntry( + entry.fileSystemType, entry.fileSystemName, entry.rootUrl, + entry.filePath, entry.isDirectory); + result.status = response[i].status; + result.error = response[i].error; + $Array.push(results, result); + } + } + if (callback) + callback(results); + }); +}); + +bindingUtil.registerEventArgumentMassager( + 'syncFileSystem.onFileStatusChanged', function(args, dispatch) { + // Make FileEntry object using all the base string fields. + var fileEntry = fileSystemNatives.GetFileEntry( + args[0].fileSystemType, args[0].fileSystemName, args[0].rootUrl, + args[0].filePath, args[0].isDirectory); + + // Combine into a single dictionary. + var fileInfo = new Object(); + fileInfo.fileEntry = fileEntry; + fileInfo.status = args[1]; + if (fileInfo.status === 'synced') { + fileInfo.action = args[2]; + fileInfo.direction = args[3]; } - } - if (callback) - callback(results); - }); -}); - -bindingUtil.registerEventArgumentMassager('syncFileSystem.onFileStatusChanged', - function(args, dispatch) { - // Make FileEntry object using all the base string fields. - var fileEntry = fileSystemNatives.GetFileEntry( - args[0].fileSystemType, - args[0].fileSystemName, - args[0].rootUrl, - args[0].filePath, - args[0].isDirectory); - - // Combine into a single dictionary. - var fileInfo = new Object(); - fileInfo.fileEntry = fileEntry; - fileInfo.status = args[1]; - if (fileInfo.status === 'synced') { - fileInfo.action = args[2]; - fileInfo.direction = args[3]; - } - dispatch([fileInfo]); -}); + dispatch([fileInfo]); + });
diff --git a/chrome/renderer/resources/extensions/tab_capture_custom_bindings.js b/chrome/renderer/resources/extensions/tab_capture_custom_bindings.js index 4d5d4326..434fd2e 100644 --- a/chrome/renderer/resources/extensions/tab_capture_custom_bindings.js +++ b/chrome/renderer/resources/extensions/tab_capture_custom_bindings.js
@@ -21,8 +21,8 @@ const getErrorMessage = (error, fallbackMessage) => { if (!error || (typeof error.message !== 'string')) return fallbackMessage; - return error.message.replace('navigator.mediaDevices.getUserMedia', - 'tabCapture.capture'); + return error.message.replace( + 'navigator.mediaDevices.getUserMedia', 'tabCapture.capture'); }; let constraints = {}; @@ -34,13 +34,13 @@ navigator.mediaDevices.getUserMedia(constraints) .then(callback) .catch(error => { - bindingUtil.runCallbackWithLastError( - getErrorMessage(error, "Failed to start MediaStream."), + bindingUtil.runCallbackWithLastError( + getErrorMessage(error, 'Failed to start MediaStream.'), $Function.bind(callback, null, null)); }); } catch (error) { bindingUtil.runCallbackWithLastError( - getErrorMessage(error, "Invalid argument(s)."), + getErrorMessage(error, 'Invalid argument(s).'), $Function.bind(callback, null, null)); } }
diff --git a/chrome/renderer/resources/extensions/tts_custom_bindings.js b/chrome/renderer/resources/extensions/tts_custom_bindings.js index 3f667b2..7371b96d 100644 --- a/chrome/renderer/resources/extensions/tts_custom_bindings.js +++ b/chrome/renderer/resources/extensions/tts_custom_bindings.js
@@ -16,11 +16,11 @@ var eventHandler = handlers[event.srcId]; if (eventHandler) { eventHandler({ - type: event.type, - charIndex: event.charIndex, - length: event.length, - errorMessage: event.errorMessage - }); + type: event.type, + charIndex: event.charIndex, + length: event.length, + errorMessage: event.errorMessage + }); if (event.isFinalEvent) { delete handlers[event.srcId]; // Balanced in 'speak' handler. @@ -35,7 +35,8 @@ // See http://crbug.com/122474. try { tts.onEvent.addListener(ttsEventListener); - } catch (e) {} + } catch (e) { + } apiFunctions.setHandleRequest( 'speak', function(utterance, options, callback) {
diff --git a/chrome/renderer/resources/extensions/tts_engine_custom_bindings.js b/chrome/renderer/resources/extensions/tts_engine_custom_bindings.js index ea6f51065..79484d0 100644 --- a/chrome/renderer/resources/extensions/tts_engine_custom_bindings.js +++ b/chrome/renderer/resources/extensions/tts_engine_custom_bindings.js
@@ -4,59 +4,59 @@ // Custom binding for the ttsEngine API. -bindingUtil.registerEventArgumentMassager('ttsEngine.onSpeak', - function(args, dispatch) { - var text = args[0]; - var options = args[1]; - var requestId = args[2]; - if (args.length !== 3) { - throw new Error('Unexpected number of args: ' + args.length); - } +bindingUtil.registerEventArgumentMassager( + 'ttsEngine.onSpeak', function(args, dispatch) { + var text = args[0]; + var options = args[1]; + var requestId = args[2]; + if (args.length !== 3) { + throw new Error('Unexpected number of args: ' + args.length); + } - var sendTtsEvent = function(event) { - chrome.ttsEngine.sendTtsEvent(requestId, event); - }; - dispatch([text, options, sendTtsEvent]); -}); + var sendTtsEvent = function(event) { + chrome.ttsEngine.sendTtsEvent(requestId, event); + }; + dispatch([text, options, sendTtsEvent]); + }); let currentRequestId; -bindingUtil.registerEventArgumentMassager('ttsEngine.onSpeakWithAudioStream', - function(args, dispatch) { - let text = args[0]; - let options = args[1]; - let requestId = args[2]; - let audioStreamOptions = args[3]; - if (args.length !== 4) { - throw new Error('Unexpected number of args: ' + args.length); - } - - currentRequestId = requestId; - - const sendTtsAudio = function(audioBufferParams) { - const {audioBuffer, charIndex, isLastBuffer} = audioBufferParams; - if (currentRequestId == requestId) { - if (!audioBuffer) { - throw new Error('Invalid audio buffer: ' + audioBuffer); +bindingUtil.registerEventArgumentMassager( + 'ttsEngine.onSpeakWithAudioStream', function(args, dispatch) { + let text = args[0]; + let options = args[1]; + let requestId = args[2]; + let audioStreamOptions = args[3]; + if (args.length !== 4) { + throw new Error('Unexpected number of args: ' + args.length); } - if (audioBuffer.length !== audioStreamOptions.bufferSize) { - throw new Error( - `Invalid audio buffer size ` + - `${audioBuffer.length}; expected == ${ - audioStreamOptions.length}`); - } + currentRequestId = requestId; - chrome.ttsEngine.sendTtsAudio(requestId, { - audioBuffer, - charIndex: charIndex !== undefined ? charIndex : -1, - isLastBuffer: !!isLastBuffer - }); - } - }; + const sendTtsAudio = function(audioBufferParams) { + const {audioBuffer, charIndex, isLastBuffer} = audioBufferParams; + if (currentRequestId == requestId) { + if (!audioBuffer) { + throw new Error('Invalid audio buffer: ' + audioBuffer); + } - const sendError = function(errorMessage = '') { - chrome.ttsEngine.sendTtsEvent(requestId, {type: 'error', errorMessage}); - }; + if (audioBuffer.length !== audioStreamOptions.bufferSize) { + throw new Error( + `Invalid audio buffer size ` + + `${audioBuffer.length}; expected == ${ + audioStreamOptions.length}`); + } - dispatch([text, options, audioStreamOptions, sendTtsAudio, sendError]); -}); + chrome.ttsEngine.sendTtsAudio(requestId, { + audioBuffer, + charIndex: charIndex !== undefined ? charIndex : -1, + isLastBuffer: !!isLastBuffer + }); + } + }; + + const sendError = function(errorMessage = '') { + chrome.ttsEngine.sendTtsEvent(requestId, {type: 'error', errorMessage}); + }; + + dispatch([text, options, audioStreamOptions, sendTtsAudio, sendError]); + });
diff --git a/chrome/renderer/resources/extensions/web_view/chrome_web_view.js b/chrome/renderer/resources/extensions/web_view/chrome_web_view.js index 4255ef5..32507420 100644 --- a/chrome/renderer/resources/extensions/web_view/chrome_web_view.js +++ b/chrome/renderer/resources/extensions/web_view/chrome_web_view.js
@@ -32,23 +32,17 @@ } // This event is exposed as <webview>.contextMenus.onClicked. -function createContextMenusOnClickedEvent(webViewInstanceId, - opt_eventName, - opt_argSchemas, - opt_eventOptions) { +function createContextMenusOnClickedEvent( + webViewInstanceId, opt_eventName, opt_argSchemas, opt_eventOptions) { var subEventName = GetUniqueSubEventName(opt_eventName); - var newEvent = - bindingUtil.createCustomEvent(subEventName, false, false); + var newEvent = bindingUtil.createCustomEvent(subEventName, false, false); var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId); if (view) { - view.events.addScopedListener( - ContextMenusEvent, - $Function.bind(function() { - // Re-dispatch to subEvent's listeners. - $Function.apply(newEvent.dispatch, newEvent, $Array.slice(arguments)); - }, newEvent), - {instanceId: webViewInstanceId}); + view.events.addScopedListener(ContextMenusEvent, $Function.bind(function() { + // Re-dispatch to subEvent's listeners. + $Function.apply(newEvent.dispatch, newEvent, $Array.slice(arguments)); + }, newEvent), {instanceId: webViewInstanceId}); } return newEvent; } @@ -57,8 +51,7 @@ function createContextMenusOnContextMenuEvent( webViewInstanceId, opt_eventName, opt_argSchemas, opt_eventOptions) { var subEventName = GetUniqueSubEventName(opt_eventName); - var newEvent = - bindingUtil.createCustomEvent(subEventName, false, false); + var newEvent = bindingUtil.createCustomEvent(subEventName, false, false); var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId); if (view) { @@ -66,7 +59,9 @@ ContextMenusHandlerEvent, $Function.bind(function(e) { var defaultPrevented = false; var event = { - preventDefault: function() { defaultPrevented = true; } + preventDefault: function() { + defaultPrevented = true; + } }; // Re-dispatch to subEvent's listeners. @@ -203,12 +198,8 @@ // Expose <webview>.contextMenus object. $Object.defineProperty( - this.element, - 'contextMenus', - { - get: createContextMenus(), - enumerable: true - }); + this.element, 'contextMenus', + {get: createContextMenus(), enumerable: true}); }; exports.$set('WebViewContextMenusImpl', WebViewContextMenusImpl);
diff --git a/chrome/renderer/resources/extensions/web_view/chrome_web_view_internal_custom_bindings.js b/chrome/renderer/resources/extensions/web_view/chrome_web_view_internal_custom_bindings.js index eeb2d5a3..4c41c999 100644 --- a/chrome/renderer/resources/extensions/web_view/chrome_web_view_internal_custom_bindings.js +++ b/chrome/renderer/resources/extensions/web_view/chrome_web_view_internal_custom_bindings.js
@@ -7,8 +7,8 @@ apiBridge.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; - var handlers = - contextMenusHandlers.create(/*webViewNamespace=*/'chromeWebViewInternal'); + var handlers = contextMenusHandlers.create( + /*webViewNamespace=*/ 'chromeWebViewInternal'); apiFunctions.setHandleRequest( 'contextMenusCreate', handlers.requestHandlers.create);
diff --git a/chrome/renderer/resources/extensions/webrtc_desktop_capture_private_custom_bindings.js b/chrome/renderer/resources/extensions/webrtc_desktop_capture_private_custom_bindings.js index 7f945afa..ecfb95b 100644 --- a/chrome/renderer/resources/extensions/webrtc_desktop_capture_private_custom_bindings.js +++ b/chrome/renderer/resources/extensions/webrtc_desktop_capture_private_custom_bindings.js
@@ -19,16 +19,16 @@ } } - apiFunctions.setHandleRequest('chooseDesktopMedia', - function(sources, request, callback) { - var id = idGenerator.GetNextId(); - pendingRequests[id] = callback; - bindingUtil.sendRequest( - 'webrtcDesktopCapturePrivate.chooseDesktopMedia', - [id, sources, request, $Function.bind(onRequestResult, null, id)], - undefined); - return id; - }); + apiFunctions.setHandleRequest( + 'chooseDesktopMedia', function(sources, request, callback) { + var id = idGenerator.GetNextId(); + pendingRequests[id] = callback; + bindingUtil.sendRequest( + 'webrtcDesktopCapturePrivate.chooseDesktopMedia', + [id, sources, request, $Function.bind(onRequestResult, null, id)], + undefined); + return id; + }); apiFunctions.setHandleRequest('cancelChooseDesktopMedia', function(id) { if (id in pendingRequests) {
diff --git a/chrome/renderer/resources/extensions/webrtc_logging_private_custom_bindings.js b/chrome/renderer/resources/extensions/webrtc_logging_private_custom_bindings.js index e165160..0de38fb 100644 --- a/chrome/renderer/resources/extensions/webrtc_logging_private_custom_bindings.js +++ b/chrome/renderer/resources/extensions/webrtc_logging_private_custom_bindings.js
@@ -9,6 +9,6 @@ apiBridge.registerCustomHook(function(binding, id, contextType) { var apiFunctions = binding.apiFunctions; - apiFunctions.setCustomCallback('getLogsDirectory', - getBindDirectoryEntryCallback()); + apiFunctions.setCustomCallback( + 'getLogsDirectory', getBindDirectoryEntryCallback()); });
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index c432f70..5e45faa5 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2446,6 +2446,7 @@ "//chrome/browser/ui/signin", "//chrome/browser/ui/signin:browser_tests", "//chrome/browser/ui/startup:startup_tab", + "//chrome/browser/ui/sync:browser_tests", "//chrome/browser/ui/tab_contents:browser_tests", "//chrome/browser/ui/tab_contents:browser_tests", "//chrome/browser/ui/tab_sharing", @@ -3553,7 +3554,6 @@ "../browser/ui/promos/ios_promos_utils_browsertest.cc", "../browser/ui/renderer_event_injection_browsertest.cc", "../browser/ui/startup/startup_browser_creator_browsertest.cc", - "../browser/ui/sync/one_click_signin_links_delegate_impl_browsertest.cc", "../browser/ui/tab_modal_confirm_dialog_browsertest.cc", "../browser/ui/tab_modal_confirm_dialog_browsertest.h", "../browser/ui/tab_ui_helper_browsertest.cc", @@ -3948,6 +3948,7 @@ "//chrome/browser/ui/passwords/bubble_controllers", "//chrome/browser/ui/profiles", "//chrome/browser/ui/search", + "//chrome/browser/ui/sync", "//chrome/browser/ui/toolbar", "//chrome/browser/ui/toolbar/chrome_labs", "//chrome/browser/ui/toolbar/pinned_toolbar", @@ -5458,7 +5459,6 @@ "//chrome/browser/ui/ash/login:test_support", "//chrome/browser/ui/ash/login/login_screen_extension_ui", "//chrome/browser/ui/ash/multi_user", - "//chrome/browser/ui/ash/multi_user:test_support", "//chrome/browser/ui/ash/network", "//chrome/browser/ui/ash/quick_answers", "//chrome/browser/ui/ash/quick_answers/test:mock_quick_answers_client", @@ -6587,7 +6587,6 @@ "../browser/ui/passwords/display_account_info_unittest.cc", "../browser/ui/passwords/manage_passwords_state_unittest.cc", "../browser/ui/passwords/settings/password_manager_porter_unittest.cc", - "../browser/ui/sync/tab_contents_synced_tab_delegate_unittest.cc", "../browser/ui/webui/chrome_urls/chrome_urls_handler_unittest.cc", "../browser/ui/webui/fileicon_source_unittest.cc", "../browser/ui/webui/log_web_ui_url_unittest.cc", @@ -6928,6 +6927,7 @@ "//chrome/browser/ui/safety_hub:test_support", "//chrome/browser/ui/search_engines:unit_tests", "//chrome/browser/ui/serial:unit_tests", + "//chrome/browser/ui/sync:unit_tests", "//chrome/browser/ui/toolbar/chrome_labs", "//chrome/browser/ui/toolbar/pinned_toolbar", "//chrome/browser/ui/webui", @@ -7965,6 +7965,7 @@ "../browser/download/download_commands_unittest.cc", "../browser/download/download_dir_policy_handler_unittest.cc", "../browser/download/download_ui_context_menu_unittest.cc", + "../browser/download/download_ui_enterprise_util_unittest.cc", "../browser/download/download_warning_desktop_hats_utils_unittest.cc", "../browser/enterprise/reporting/extension_info_unittest.cc", "../browser/enterprise/reporting/extension_request/extension_request_notification_unittest.cc", @@ -8032,8 +8033,6 @@ "../browser/platform_util_unittest.cc", "../browser/policy/policy_path_parser_unittest.cc", "../browser/policy/webhid_device_policy_handler_unittest.cc", - "../browser/private_network_access/private_network_device_chooser_controller_unittest.cc", - "../browser/private_network_access/private_network_device_permission_context_unittest.cc", "../browser/profile_resetter/profile_resetter_unittest.cc", "../browser/profile_resetter/reset_report_uploader_unittest.cc", "../browser/profiles/guest_profile_creation_logger_unittest.cc", @@ -8118,7 +8117,6 @@ "../browser/ui/passwords/well_known_change_password_navigation_throttle_unittest.cc", "../browser/ui/recently_audible_helper_unittest.cc", "../browser/ui/startup/launch_mode_recorder_unittest.cc", - "../browser/ui/sync/profile_signin_confirmation_helper_unittest.cc", "../browser/ui/tabs/organization/tab_organization_service_unittest.cc", "../browser/ui/tabs/organization/tab_organization_unittest.cc", "../browser/ui/tabs/organization/trigger_policies_unittest.cc", @@ -8289,6 +8287,7 @@ "//chrome/browser/ui/search:test_support_ui", "//chrome/browser/ui/search:unit_tests", "//chrome/browser/ui/startup:startup_tab", + "//chrome/browser/ui/sync", "//chrome/browser/ui/tab_sharing", "//chrome/browser/ui/tab_sharing:unit_tests", "//chrome/browser/ui/tabs:tab_group", @@ -8351,7 +8350,6 @@ if (is_linux || is_mac || is_win) { sources += [ "../browser/supervised_user/linux_mac_windows/supervised_user_extensions_metrics_delegate_impl_unittest.cc", - "../browser/ui/sync/sync_passphrase_dialog_unittest.cc", "../browser/ui/webui/settings/accessibility_main_handler_unittest.cc", ] } @@ -11178,7 +11176,6 @@ if (is_mac || is_linux || is_win) { sources += [ - "../browser/ui/sync/sync_passphrase_dialog_browsertest.cc", "../browser/ui/views/default_link_capturing_interactive_uitest.cc", "../browser/ui/views/media_preview/permission_prompt_preview_browsertest.cc", "../browser/ui/views/web_apps/web_app_navigation_capturing_iph_interactive_uitest.cc", @@ -11288,6 +11285,7 @@ "//chrome/browser/ui/profiles", "//chrome/browser/ui/search:interactive_ui_tests", "//chrome/browser/ui/startup:startup_tab", + "//chrome/browser/ui/sync:interactive_ui_tests", "//chrome/browser/ui/tab_contents", "//chrome/browser/ui/tabs:interactive_ui_tests", "//chrome/browser/ui/tabs:tab_strip",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiLocatorHelper.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiLocatorHelper.java index f508f982..0e52a7a 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiLocatorHelper.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/pagecontroller/utils/UiLocatorHelper.java
@@ -320,28 +320,23 @@ /** * Delegate to be used with getCustomElements. + * * @param <T> The type of the element. */ - public static interface CustomElementMaker<T> { + public interface CustomElementMaker<T> { /** * Should construct an element given a node. - * @param root The input node. - * @param isLastAttempt getCustomElements may call this delegate - * multiple times if errors are thrown from this - * method and timeout has not been reached. If - * isLastAttempt is true, then it indicates that - * getCustomElements will not call this delegate - * again. For example the delegate can return null - * on the lastAttempt if it still encounters errors - * which indicates that a properly formed element is - * not found on the page, this case could happen if - * an element gets cutoff at a scroll boundary. - * @return The element if construction is successful, null - * otherwise. - * @throws UiLocationException Should throw a UiLocationException or - * UiStaleObjectException if getCustomElements - * should re-obtain a root using its provided - * locator. + * + * @param root The input node. + * @param isLastAttempt getCustomElements may call this delegate multiple times if errors + * are thrown from this method and timeout has not been reached. If isLastAttempt is + * true, then it indicates that getCustomElements will not call this delegate again. For + * example the delegate can return null on the lastAttempt if it still encounters errors + * which indicates that a properly formed element is not found on the page, this case + * could happen if an element gets cutoff at a scroll boundary. + * @return The element if construction is successful, null otherwise. + * @throws UiLocationException Should throw a UiLocationException or UiStaleObjectException + * if getCustomElements should re-obtain a root using its provided locator. */ T makeElement(UiObject2 root, boolean isLastAttempt); } @@ -394,9 +389,10 @@ /** * Define a conversion method creates an object from info in a UiObject2 node. + * * @param <T> Type of the object. */ - private static interface ElementConverter<T> { + private interface ElementConverter<T> { T convert(UiObject2 object2); }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/BasePageStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/BasePageStation.java index 2043f867..8178286 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/BasePageStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/BasePageStation.java
@@ -21,6 +21,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tab.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.test.transit.ChromeActivityTabModelBoundStation; @@ -396,7 +397,7 @@ } @Override - public void didSelectTab(Tab tab, int type, int lastId) { + public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { if (mTabsSelected.contains(tab)) { // We get multiple (2-3 depending on the case) didSelectTab when selecting a Tab, so // filter out redundant callbacks to make sure we wait for different Tabs.
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index 73e26f8..b03bdf3 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h
@@ -148,6 +148,7 @@ const gfx::PointF& point) override {} void PreHandleDragExit() override {} + void HandleDragEnded() override {} content::KeyboardEventProcessingResult PreHandleKeyboardEvent( const input::NativeWebKeyboardEvent& event) override; bool HandleKeyboardEvent(const input::NativeWebKeyboardEvent& event) override;
diff --git a/chrome/test/data/webui/new_tab_page/composebox/composebox_test.ts b/chrome/test/data/webui/new_tab_page/composebox/composebox_test.ts index 444fbb7..1db6026 100644 --- a/chrome/test/data/webui/new_tab_page/composebox/composebox_test.ts +++ b/chrome/test/data/webui/new_tab_page/composebox/composebox_test.ts
@@ -170,6 +170,48 @@ assertStyle(composeboxElement.$.submitIcon, 'cursor', 'pointer'); }); + [new File(['foo'], 'foo.jpg', {type: 'image/jpeg'}), + new File(['foo'], 'foo.pdf', {type: 'application/pdf'})] + .forEach((file) => { + test( + `announce file upload started and completed: ${file.type}`, + async () => { + createComposeboxElement(); + + let announcementCount = 0; + const updateAnnouncementCount = () => { + announcementCount += 1; + }; + document.body.addEventListener( + 'cr-a11y-announcer-messages-sent', updateAnnouncementCount); + let announcementPromise = eventToPromise( + 'cr-a11y-announcer-messages-sent', document.body); + + const id = generateZeroId(); + await uploadFileAndVerify(id, file); + + let announcement = await announcementPromise; + assertEquals(announcementCount, 1); + assertTrue(!!announcement); + assertEquals(announcement.detail.messages.length, 1); + + callbackRouterRemote.onFileUploadStatusChanged( + id, FileUploadStatus.kUploadSuccessful, null); + await callbackRouterRemote.$.flushForTesting(); + + announcementPromise = eventToPromise( + 'cr-a11y-announcer-messages-sent', document.body); + announcement = await announcementPromise; + assertEquals(announcementCount, 2); + assertTrue(!!announcement); + assertEquals(announcement.detail.messages.length, 1); + + // Cleanup event listener. + document.body.removeEventListener( + 'cr-a11y-announcer-messages-sent', updateAnnouncementCount); + }); + }); + test('upload empty file fails', async () => { createComposeboxElement(); const file = new File([''], 'foo.jpg', {type: 'image/jpeg'}); @@ -232,7 +274,6 @@ const file = new File(['foo'], 'foo.jpg', {type: 'image/jpeg'}); await uploadFileAndVerify(id, file); - // These statuses callbackRouterRemote.onFileUploadStatusChanged( id, fileUploadStatus as FileUploadStatus, fileUploadErrorType as FileUploadErrorType | null);
diff --git a/clank b/clank index 6ba3341..2c52569 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 6ba3341efc52c965dd551f0fd5b16df1e5097d39 +Subproject commit 2c5256966ea2fdf7cf1e7ca7363eff4e495e7db3
diff --git a/components/account_id/account_id_literal.h b/components/account_id/account_id_literal.h index 467e53d..9a4e9f17 100644 --- a/components/account_id/account_id_literal.h +++ b/components/account_id/account_id_literal.h
@@ -27,6 +27,7 @@ } const std::string_view GetUserEmail() const { return user_email_; } + const GaiaId::Literal GetGaiaId() const { return gaia_id_; } // Allows implicit conversion so functions taking AccountId can use the // constexpr literal.
diff --git a/components/autofill/core/browser/foundations/browser_autofill_manager.cc b/components/autofill/core/browser/foundations/browser_autofill_manager.cc index fcb738a..7d6b312 100644 --- a/components/autofill/core/browser/foundations/browser_autofill_manager.cc +++ b/components/autofill/core/browser/foundations/browser_autofill_manager.cc
@@ -492,18 +492,10 @@ // due to an unrecognized autocomplete attribute. Note that in the context // of Autofill, the popup for credit card related fields is not getting // suppressed due to an unrecognized autocomplete attribute. - // TODO(crbug.com/40853053): Revisit here to see whether we should offer - // IBAN filling for fields with unrecognized autocomplete attribute if (suppress_reason == SuppressReason::kAutocompleteUnrecognized) { return false; } - // Therefore, we check the attribute explicitly. - if (autofill_field && - autofill_field->Type().html_type() == HtmlFieldType::kUnrecognized) { - return false; - } - // Finally, check that the scheme is secure. return suppress_reason != SuppressReason::kInsecureForm; }
diff --git a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc index 513e5e8b..16bd576 100644 --- a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc +++ b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc
@@ -963,10 +963,9 @@ uint64_t extracted_amount_in_micros) { Suggestion bnpl_suggestion(SuggestionType::kBnplEntry); bnpl_suggestion.icon = Suggestion::Icon::kBnpl; - bnpl_suggestion.main_text = - Suggestion::Text(l10n_util::GetStringUTF16( - IDS_AUTOFILL_BNPL_CREDIT_CARD_SUGGESTION_MAIN_TEXT), - Suggestion::Text::IsPrimary(true)); + bnpl_suggestion.main_text = Suggestion::Text( + l10n_util::GetStringUTF16(IDS_AUTOFILL_BNPL_PAY_LATER_OPTIONS_TEXT), + Suggestion::Text::IsPrimary(true)); bnpl_suggestion.labels = {{Suggestion::Text( l10n_util::GetStringFUTF16(IDS_AUTOFILL_BNPL_CREDIT_CARD_SUGGESTION_LABEL, GetBnplPriceLowerBound(bnpl_issuers)))}};
diff --git a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc index 55239cfc..71c6326 100644 --- a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc +++ b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc
@@ -1627,8 +1627,7 @@ updated_suggestions[current_suggestion_index++], EqualsSuggestion( SuggestionType::kBnplEntry, - l10n_util::GetStringUTF16( - IDS_AUTOFILL_BNPL_CREDIT_CARD_SUGGESTION_MAIN_TEXT), + l10n_util::GetStringUTF16(IDS_AUTOFILL_BNPL_PAY_LATER_OPTIONS_TEXT), Suggestion::Icon::kBnpl, {{Suggestion::Text(l10n_util::GetStringFUTF16( IDS_AUTOFILL_BNPL_CREDIT_CARD_SUGGESTION_LABEL, u"$34"))}}));
diff --git a/components/autofill/core/browser/ui/addresses/autofill_address_util_unittest.cc b/components/autofill/core/browser/ui/addresses/autofill_address_util_unittest.cc index 9dbc464..034430a 100644 --- a/components/autofill/core/browser/ui/addresses/autofill_address_util_unittest.cc +++ b/components/autofill/core/browser/ui/addresses/autofill_address_util_unittest.cc
@@ -63,7 +63,8 @@ i18n::TypeForField(::i18n::addressinput::AddressField::POSTAL_CODE)); } -TEST_F(AddressFormattingTest, GetEnvelopeStyleAddressSanity) { +// TODO(crbug.com/433964259): Test is flaky. +TEST_F(AddressFormattingTest, FLAKY_GetEnvelopeStyleAddressSanity) { AutofillProfile profile = test::GetFullProfile(); std::u16string address = GetEnvelopeStyleAddress(profile, GetLocale(), /*include_recipient=*/true,
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index 05dd22b..eba103b 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -241,7 +241,7 @@ // UI message. BASE_FEATURE(kAutofillEnableShowSaveCardSecurelyMessage, "AutofillEnableShowSaveCardSecurelyMessage", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // When enabled, Pix bank accounts are synced from Chrome Sync backend and // stored in the local db.
diff --git a/components/autofill_payments_strings.grdp b/components/autofill_payments_strings.grdp index a6a02e7a..0bb4c8b 100644 --- a/components/autofill_payments_strings.grdp +++ b/components/autofill_payments_strings.grdp
@@ -1045,17 +1045,14 @@ </message> <!-- Buy now pay later related strings --> - <message name="IDS_AUTOFILL_BNPL_CREDIT_CARD_SUGGESTION_MAIN_TEXT" desc="Main text for the Buy Now Pay Later option in the autofill credit card popup. If the option is selected, a pop up will be shown to allow users choose a Buy Now Pay Later issuer."> - Pay over time options + <message name="IDS_AUTOFILL_BNPL_PAY_LATER_OPTIONS_TEXT" desc="Main text for the Buy Now Pay Later option in the autofill credit card popup and in the settings page BNPL toggle. If the option is selected, a pop up will be shown to allow users choose a Buy Now Pay Later issuer."> + Pay later options </message> <message name="IDS_AUTOFILL_BNPL_CREDIT_CARD_SUGGESTION_LABEL" desc="One line label shows the minimum qualifying amount for the Buy Now Pay Later option in the autofill credit card popup. If the option is selected, a pop up will be shown to allow users choose a Buy Now Pay Later issuer."> Available for purchases over <ph name="RANGE_MINIMUM">$1<ex>$35</ex></ph> </message> - <message name="IDS_AUTOFILL_BNPL_SETTINGS_LABEL" desc="Label for the Buy Now Pay Later preference in the payments settings page. When enabled, users can checkout with external BNPL issuers using a pay-over-time payment option."> - Pay over time - </message> - <message name="IDS_AUTOFILL_BNPL_SETTINGS_SUBLABEL" desc="Sublabel for the Buy Now Pay Later preference in the payments settings page, including a hyperlink to learn more about pay over time. When enabled, users can checkout with external BNPL issuers using a pay-over-time payment option."> - Show <ph name="PAY_OVER_TIME_HELP_LINK_BEGIN"><a href="$1" aria-description="$2"></ph>pay over time<ph name="PAY_OVER_TIME_HELP_LINK_END"></a></ph> options at checkout + <message name="IDS_AUTOFILL_BNPL_SETTINGS_SUBLABEL" desc="Sublabel for the Buy Now Pay Later preference in the payments settings page, including a hyperlink to learn more about pay later options. When enabled, users can checkout with external BNPL issuers using a Buy Now Pay Later option."> + Show <ph name="PAY_LATER_OPTIONS_HELP_LINK_BEGIN"><a href="$1" aria-description="$2"></ph>pay later options<ph name="PAY_LATER_OPTIONS_HELP_LINK_END"></a></ph> at checkout </message> <message name="IDS_AUTOFILL_BNPL_AFFIRM" desc="Name of Buy Now Pay Later provider Affirm."> Affirm
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_CREDIT_CARD_SUGGESTION_MAIN_TEXT.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_CREDIT_CARD_SUGGESTION_MAIN_TEXT.png.sha1 deleted file mode 100644 index a6dbd6f3..0000000 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_CREDIT_CARD_SUGGESTION_MAIN_TEXT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -2a905f33a2a421ba5f56a30707d93101500c5b1c \ No newline at end of file
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_PAY_LATER_OPTIONS_TEXT.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_PAY_LATER_OPTIONS_TEXT.png.sha1 new file mode 100644 index 0000000..61f0d3efb --- /dev/null +++ b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_PAY_LATER_OPTIONS_TEXT.png.sha1
@@ -0,0 +1 @@ +162280ab85d6cf25efa8a7b55bd74d7149bd21d1 \ No newline at end of file
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_SETTINGS_LABEL.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_SETTINGS_LABEL.png.sha1 deleted file mode 100644 index 2d1bb20..0000000 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_SETTINGS_LABEL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -4ccc650337a63f04d8bac372b9223dcd58dc1038 \ No newline at end of file
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_SETTINGS_SUBLABEL.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_SETTINGS_SUBLABEL.png.sha1 index bd580ab..2f7a34b 100644 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_SETTINGS_SUBLABEL.png.sha1 +++ b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_BNPL_SETTINGS_SUBLABEL.png.sha1
@@ -1 +1 @@ -a3507a3ab87f45427c4eaac528742fa3c9792b41 \ No newline at end of file +39c7c780d47f6955cac6efc86e34bb5be7c54bba \ No newline at end of file
diff --git a/components/content_settings/core/browser/content_settings_default_provider.cc b/components/content_settings/core/browser/content_settings_default_provider.cc index 28693f8f..2b4bbab 100644 --- a/components/content_settings/core/browser/content_settings_default_provider.cc +++ b/components/content_settings/core/browser/content_settings_default_provider.cc
@@ -65,6 +65,9 @@ constexpr char kObsoleteFederatedIdentityDefaultPref[] = "profile.default_content_setting_values.fedcm_active_session"; +constexpr char kObsoletePrivateNetworkGuardDefaultPref[] = + "profile.default_content_setting_values.private_network_guard"; + #if !BUILDFLAG(IS_IOS) // This setting was accidentally bound to a UI surface intended for a different // setting (https://crbug.com/364820109). It should not have been settable @@ -132,6 +135,7 @@ #endif // !BUILDFLAG(IS_ANDROID) #endif // !BUILDFLAG(IS_IOS) registry->RegisterIntegerPref(kObsoleteFederatedIdentityDefaultPref, 0); + registry->RegisterIntegerPref(kObsoletePrivateNetworkGuardDefaultPref, 0); #if !BUILDFLAG(IS_IOS) // TODO(https://crbug.com/367181093): clean this up. @@ -389,6 +393,7 @@ #endif // !BUILDFLAG(IS_ANDROID) #endif // !BUILDFLAG(IS_IOS) prefs_->ClearPref(kObsoleteFederatedIdentityDefaultPref); + prefs_->ClearPref(kObsoletePrivateNetworkGuardDefaultPref); #if !BUILDFLAG(IS_IOS) // TODO(https://crbug.com/367181093): clean this up.
diff --git a/components/content_settings/core/browser/content_settings_pref_provider.cc b/components/content_settings/core/browser/content_settings_pref_provider.cc index 5f08e77..89695a6 100644 --- a/components/content_settings/core/browser/content_settings_pref_provider.cc +++ b/components/content_settings/core/browser/content_settings_pref_provider.cc
@@ -56,6 +56,8 @@ "all_screens"; constexpr char kObsoleteFederatedIdentityActiveSesssionExceptionsPref[] = "profile.content_settings.exceptions.fedcm_active_session"; +constexpr char kObsoletePrivateNetworkChooserDataPref[] = + "profile.content_settings.exceptions.private_network_chooser_data"; #if !BUILDFLAG(IS_IOS) // This setting was accidentally bound to a UI surface intended for a different @@ -103,6 +105,7 @@ kObsoleteGetDisplayMediaSetAutoSelectAllScreensAllowedForUrlsExceptionsPref); registry->RegisterListPref( kObsoleteFederatedIdentityActiveSesssionExceptionsPref); + registry->RegisterDictionaryPref(kObsoletePrivateNetworkChooserDataPref); #if !BUILDFLAG(IS_IOS) // TODO(https://crbug.com/367181093): clean this up. registry->RegisterBooleanPref(kBug364820109AlreadyWorkedAroundPref, false); @@ -442,6 +445,7 @@ prefs_->ClearPref( kObsoleteGetDisplayMediaSetAutoSelectAllScreensAllowedForUrlsExceptionsPref); prefs_->ClearPref(kObsoleteFederatedIdentityActiveSesssionExceptionsPref); + prefs_->ClearPref(kObsoletePrivateNetworkChooserDataPref); #if !BUILDFLAG(IS_IOS) // TODO(https://crbug.com/367181093): clean this up.
diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc index a1e50e1..c9b9e27 100644 --- a/components/content_settings/core/browser/content_settings_registry.cc +++ b/components/content_settings/core/browser/content_settings_registry.cc
@@ -629,15 +629,6 @@ ContentSettingsInfo::INHERIT_IN_INCOGNITO, PermissionSettingsInfo::EXCEPTIONS_ON_SECURE_AND_INSECURE_ORIGINS); - Register(ContentSettingsType::PRIVATE_NETWORK_GUARD, "private-network-guard", - CONTENT_SETTING_ASK, WebsiteSettingsInfo::UNSYNCABLE, - /*allowlisted_primary_schemes=*/{}, - /*valid_settings=*/{CONTENT_SETTING_BLOCK, CONTENT_SETTING_ASK}, - WebsiteSettingsInfo::TOP_ORIGIN_ONLY_SCOPE, - WebsiteSettingsRegistry::DESKTOP, - ContentSettingsInfo::INHERIT_IF_LESS_PERMISSIVE, - PermissionSettingsInfo::EXCEPTIONS_ON_SECURE_ORIGINS_ONLY); - const auto auto_dark_web_content_setting = #if BUILDFLAG(IS_ANDROID) content_settings::kDarkenWebsitesCheckboxOptOut.Get()
diff --git a/components/content_settings/core/browser/content_settings_registry_unittest.cc b/components/content_settings/core/browser/content_settings_registry_unittest.cc index 1b1a23b..62c608e 100644 --- a/components/content_settings/core/browser/content_settings_registry_unittest.cc +++ b/components/content_settings/core/browser/content_settings_registry_unittest.cc
@@ -108,20 +108,6 @@ // Check the WebsiteSettingsInfo is registered correctly. EXPECT_EQ(website_settings_registry()->Get(ContentSettingsType::COOKIES), website_settings_info); - - // Check that PRIVATE_NETWORK_GUARD is registered correctly. -#if !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID) - info = registry()->Get(ContentSettingsType::PRIVATE_NETWORK_GUARD); - ASSERT_TRUE(info); - - // Check the other properties are populated correctly. - EXPECT_TRUE(info->IsSettingValid(CONTENT_SETTING_BLOCK)); - EXPECT_TRUE(info->IsSettingValid(CONTENT_SETTING_ASK)); - EXPECT_FALSE(info->IsSettingValid(CONTENT_SETTING_SESSION_ONLY)); - EXPECT_FALSE(info->IsSettingValid(CONTENT_SETTING_ALLOW)); - EXPECT_EQ(ContentSettingsInfo::INHERIT_IF_LESS_PERMISSIVE, - info->incognito_behavior()); -#endif } TEST_F(ContentSettingsRegistryTest, Iteration) { @@ -215,9 +201,6 @@ #if !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID) info = registry()->Get(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD); EXPECT_FALSE(info->IsDefaultSettingValid(CONTENT_SETTING_ALLOW)); - - info = registry()->Get(ContentSettingsType::PRIVATE_NETWORK_GUARD); - EXPECT_FALSE(info->IsDefaultSettingValid(CONTENT_SETTING_ALLOW)); #endif }
diff --git a/components/content_settings/core/browser/content_settings_uma_util.cc b/components/content_settings/core/browser/content_settings_uma_util.cc index bf90825..cad1940 100644 --- a/components/content_settings/core/browser/content_settings_uma_util.cc +++ b/components/content_settings/core/browser/content_settings_uma_util.cc
@@ -105,8 +105,8 @@ {ContentSettingsType::NOTIFICATION_INTERACTIONS, 86}, {ContentSettingsType::REDUCED_ACCEPT_LANGUAGE, 87}, {ContentSettingsType::NOTIFICATION_PERMISSION_REVIEW, 88}, - {ContentSettingsType::PRIVATE_NETWORK_GUARD, 89}, - {ContentSettingsType::PRIVATE_NETWORK_CHOOSER_DATA, 90}, + // Removed PRIVATE_NETWORK_GUARD in M140 + // Removed PRIVATE_NETWORK_CHOOSER_DATA in M140 {ContentSettingsType::FEDERATED_IDENTITY_IDENTITY_PROVIDER_SIGNIN_STATUS, 91}, {ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS, 92},
diff --git a/components/content_settings/core/browser/website_settings_registry.cc b/components/content_settings/core/browser/website_settings_registry.cc index 48a2a25..6ea1950a 100644 --- a/components/content_settings/core/browser/website_settings_registry.cc +++ b/components/content_settings/core/browser/website_settings_registry.cc
@@ -277,11 +277,6 @@ WebsiteSettingsInfo::GENERIC_SINGLE_ORIGIN_SCOPE, DESKTOP | PLATFORM_ANDROID, WebsiteSettingsInfo::DONT_INHERIT_IN_INCOGNITO); - Register(ContentSettingsType::PRIVATE_NETWORK_CHOOSER_DATA, - "private-network-chooser-data", base::Value(), - WebsiteSettingsInfo::UNSYNCABLE, WebsiteSettingsInfo::NOT_LOSSY, - WebsiteSettingsInfo::TOP_ORIGIN_ONLY_SCOPE, DESKTOP, - WebsiteSettingsInfo::DONT_INHERIT_IN_INCOGNITO); Register( ContentSettingsType::FEDERATED_IDENTITY_IDENTITY_PROVIDER_SIGNIN_STATUS, "fedcm-idp-signin", base::Value(), WebsiteSettingsInfo::UNSYNCABLE,
diff --git a/components/content_settings/core/common/content_settings_types.mojom b/components/content_settings/core/common/content_settings_types.mojom index 12a13c6417..ff15725 100644 --- a/components/content_settings/core/common/content_settings_types.mojom +++ b/components/content_settings/core/common/content_settings_types.mojom
@@ -305,11 +305,6 @@ // store origin blocklist from review notification permissions feature. NOTIFICATION_PERMISSION_REVIEW, - // Website setting to store permissions granted to access particular devices - // in private network. - PRIVATE_NETWORK_GUARD, - PRIVATE_NETWORK_CHOOSER_DATA, - // Website setting which stores whether the browser has observed the user // signing into an identity-provider based on observing the IdP-SignIn-Status // HTTP header.
diff --git a/components/cronet/gn2bp/run_gn2bp.py b/components/cronet/gn2bp/run_gn2bp.py index 456aeb6..7dffce0 100755 --- a/components/cronet/gn2bp/run_gn2bp.py +++ b/components/cronet/gn2bp/run_gn2bp.py
@@ -156,23 +156,16 @@ GN2BP_MODULE_PREFIX=f'{import_channel}_cronet_')) -def _gen_androidtest_xml(import_channel: str): +def _gen_androidtest_xml(): """Generate AndroidTest.xml, required to run test in Android.""" - test_server_folder = None - if import_channel == 'tot': - test_server_folder = '/storage/emulated/0/chromium_tests_root/components/cronet/android/test/test_server' - else: - test_server_folder = '/storage/emulated/0/chromium_tests_root/components/cronet/testing/test_server' androidtest_xml_template_path = os.path.join(REPOSITORY_ROOT, 'components', 'cronet', 'gn2bp', 'templates', 'AndroidTest.xml.template') androidtest_xml_template_contents = cronet_utils.read_file( androidtest_xml_template_path) androidtest_xml_path = os.path.join(REPOSITORY_ROOT, 'AndroidTest.xml') - cronet_utils.write_file( - androidtest_xml_path, - string.Template(androidtest_xml_template_contents).substitute( - TEST_SERVER_FOLDER=test_server_folder)) + cronet_utils.write_file(androidtest_xml_path, + androidtest_xml_template_contents) def _gen_boringssl(import_channel: str): """Generate boringssl Android build files.""" @@ -437,7 +430,7 @@ channel=args.channel) _gen_boringssl(args.channel) _gen_extras_bp(args.channel) - _gen_androidtest_xml(args.channel) + _gen_androidtest_xml() if not args.skip_copybara: _run_copybara_to_aosp(
diff --git a/components/cronet/gn2bp/templates/AndroidTest.xml.template b/components/cronet/gn2bp/templates/AndroidTest.xml.template index 980bad1..1eca0f97 100644 --- a/components/cronet/gn2bp/templates/AndroidTest.xml.template +++ b/components/cronet/gn2bp/templates/AndroidTest.xml.template
@@ -22,7 +22,7 @@ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"> <option name="push-file" key="net" value="/storage/emulated/0/chromium_tests_root/net" /> - <option name="push-file" key="test_server" value="${TEST_SERVER_FOLDER}" /> + <option name="push-file" key="test_server" value="/storage/emulated/0/chromium_tests_root/components/cronet/android/test/test_server" /> </target_preparer> <!-- Tethering/Connectivity is a SDK 30+ module however Cronet is installed on 31+ due to b/270049141. --> <object type="module_controller"
diff --git a/components/dom_distiller/core/BUILD.gn b/components/dom_distiller/core/BUILD.gn index 2a78afad..0216fe5a 100644 --- a/components/dom_distiller/core/BUILD.gn +++ b/components/dom_distiller/core/BUILD.gn
@@ -119,6 +119,7 @@ "distillable_page_detector_unittest.cc", "distilled_content_store_unittest.cc", "distilled_page_prefs_unittests.cc", + "distiller_page_unittest.cc", "distiller_unittest.cc", "distiller_url_fetcher_unittest.cc", "dom_distiller_request_view_base_unittest.cc",
diff --git a/components/dom_distiller/core/distiller_page.cc b/components/dom_distiller/core/distiller_page.cc index 4a9dcec..d0f1b60 100644 --- a/components/dom_distiller/core/distiller_page.cc +++ b/components/dom_distiller/core/distiller_page.cc
@@ -15,6 +15,7 @@ #include "base/json/json_writer.h" #include "base/location.h" #include "base/logging.h" +#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" #include "base/strings/to_string.h" @@ -87,6 +88,19 @@ return true; } +// This enum is used to record histograms for OnDistillationDone results. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. + +// LINT.IfChange(DistillationParseResult) +enum class DistillationParseResult { + kSuccess = 0, + kParseFailure = 1, + kNoData = 2, + kMaxValue = kNoData, +}; +// LINT.ThenChange(//tools/metrics/histograms/metadata/accessibility/enums.xml:DistillationParseResult) + } // namespace DistillerPageFactory::~DistillerPageFactory() = default; @@ -120,8 +134,11 @@ std::unique_ptr<dom_distiller::proto::DomDistillerResult> distiller_result( new dom_distiller::proto::DomDistillerResult()); bool found_content; + DistillationParseResult result; + if (value->is_none()) { found_content = false; + result = DistillationParseResult::kNoData; } else { found_content = ShouldUseReadabilityDistiller() @@ -129,11 +146,17 @@ *value, distiller_result.get()) : dom_distiller::proto::json::DomDistillerResult::ReadFromValue( *value, distiller_result.get()); - if (!found_content) { + if (found_content) { + result = DistillationParseResult::kSuccess; + } else { DVLOG(1) << "Unable to parse DomDistillerResult."; + result = DistillationParseResult::kParseFailure; } } + // Record result for page distillation + base::UmaHistogramEnumeration("DomDistiller.Distillation.Result", result); + base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, base::BindOnce(std::move(distiller_page_callback_), std::move(distiller_result), found_content));
diff --git a/components/dom_distiller/core/distiller_page_unittest.cc b/components/dom_distiller/core/distiller_page_unittest.cc new file mode 100644 index 0000000..b7b20126 --- /dev/null +++ b/components/dom_distiller/core/distiller_page_unittest.cc
@@ -0,0 +1,124 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/dom_distiller/core/distiller_page.h" + +#include "base/functional/callback_helpers.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/task_environment.h" +#include "base/values.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/dom_distiller_js/dom_distiller.pb.h" +#include "url/gurl.h" + +namespace dom_distiller { + +namespace { + +enum class DistillationParseResult { + kSuccess = 0, + kParseFailure = 1, + kNoResult = 2, +}; + +// This is a minimal concrete class that inherits from DistillerPage. It +// overrides the implementation of distillation to immediately call the +// completion handler, simulating a success or failure result for the test. +class TestDistillerPage : public DistillerPage { + public: + // This enum controls which distillation outcome the mock will simulate. + enum class SimulatedResult { kSuccess, kParseFailure, kNoResult }; + + TestDistillerPage() = default; + + // Configures the mock to simulate a specific result. + void SetNextResult(SimulatedResult result) { simulate_result_ = result; } + + bool ShouldFetchOfflineData() override { return false; } + + // The overridden implementation now simulates one of three outcomes based on + // the configuration set by SetNextResult(). + void DistillPageImpl(const GURL& url, const std::string& script) override { + switch (simulate_result_) { + case SimulatedResult::kSuccess: { + // A valid (but empty) dictionary simulates a parsable result from the + // distiller, leading to `kSuccess`. + const base::Value success_value(base::Value::Type::DICT); + OnDistillationDone(url, &success_value); + break; + } + case SimulatedResult::kParseFailure: { + // An invalid type (e.g., a string instead of a dict) will cause a + // parse failure, leading to `kParseFailure`. + const base::Value parse_failure_value("not a dictionary"); + OnDistillationDone(url, &parse_failure_value); + break; + } + case SimulatedResult::kNoResult: { + // A NONE value simulates the distiller returning nothing, which leads + // to `kNoResult`. + const base::Value no_result_value(base::Value::Type::NONE); + OnDistillationDone(url, &no_result_value); + break; + } + } + } + + private: + SimulatedResult simulate_result_ = SimulatedResult::kSuccess; +}; + +class DistillerPageTest : public testing::Test { + protected: + DistillerPageTest() = default; + + base::test::TaskEnvironment task_environment_; + base::HistogramTester histogram_tester_; +}; + +// Test that the kSuccess value is recorded when distillation is successful. +TEST_F(DistillerPageTest, RecordsSuccessMetric) { + TestDistillerPage distiller_page; + distiller_page.SetNextResult(TestDistillerPage::SimulatedResult::kSuccess); + + distiller_page.DistillPage(GURL("http://example.com/success"), + dom_distiller::proto::DomDistillerOptions(), + base::DoNothing()); + + // Check that the UMA metric was recorded with the correct enum value. + histogram_tester_.ExpectUniqueSample("DomDistiller.Distillation.Result", + DistillationParseResult::kSuccess, 1); +} + +// Test that the kParseFailure value is recorded when the result is unparsable. +TEST_F(DistillerPageTest, RecordsParseFailureMetric) { + TestDistillerPage distiller_page; + distiller_page.SetNextResult( + TestDistillerPage::SimulatedResult::kParseFailure); + + distiller_page.DistillPage(GURL("http://example.com/failure"), + dom_distiller::proto::DomDistillerOptions(), + base::DoNothing()); + + histogram_tester_.ExpectUniqueSample("DomDistiller.Distillation.Result", + DistillationParseResult::kParseFailure, + 1); +} + +// Test that the kNoResult value is recorded when the distiller returns nothing. +TEST_F(DistillerPageTest, RecordsNoResultMetric) { + TestDistillerPage distiller_page; + distiller_page.SetNextResult(TestDistillerPage::SimulatedResult::kNoResult); + + distiller_page.DistillPage(GURL("http://example.com/no-result"), + dom_distiller::proto::DomDistillerOptions(), + base::DoNothing()); + + histogram_tester_.ExpectUniqueSample("DomDistiller.Distillation.Result", + DistillationParseResult::kNoResult, 1); +} + +} // namespace + +} // namespace dom_distiller
diff --git a/components/enterprise/common/proto/synced/browser_events.proto b/components/enterprise/common/proto/synced/browser_events.proto index 342835e8..595537d 100644 --- a/components/enterprise/common/proto/synced/browser_events.proto +++ b/components/enterprise/common/proto/synced/browser_events.proto
@@ -462,6 +462,7 @@ UNKNOWN = 5; DANGEROUS_FILE_TYPE = 6; DANGEROUS_URL = 7; + DANGEROUS_ACCOUNT_COMPROMISE = 8; } // Category of dangerous download.
diff --git a/components/facilitated_payments/android/device_delegate_android.cc b/components/facilitated_payments/android/device_delegate_android.cc index cb3d342..77514d2 100644 --- a/components/facilitated_payments/android/device_delegate_android.cc +++ b/components/facilitated_payments/android/device_delegate_android.cc
@@ -29,9 +29,16 @@ DeviceDelegateAndroid::~DeviceDelegateAndroid() = default; -bool DeviceDelegateAndroid::IsPixAccountLinkingSupported() const { +WalletEligibilityForPixAccountLinking +DeviceDelegateAndroid::IsPixAccountLinkingSupported() const { JNIEnv* env = base::android::AttachCurrentThread(); - return Java_DeviceDelegate_isWalletEligibleForPixAccountLinking(env); + jint eligibility = + Java_DeviceDelegate_getWalletEligibilityForPixAccountLinking(env); + CHECK(eligibility >= static_cast<jint>( + WalletEligibilityForPixAccountLinking::kEligible) && + eligibility <= static_cast<jint>(WalletEligibilityForPixAccountLinking:: + kWalletVersionNotSupported)); + return static_cast<WalletEligibilityForPixAccountLinking>(eligibility); } void DeviceDelegateAndroid::LaunchPixAccountLinkingPage(std::string email) {
diff --git a/components/facilitated_payments/android/device_delegate_android.h b/components/facilitated_payments/android/device_delegate_android.h index ef00006..6f5afe11 100644 --- a/components/facilitated_payments/android/device_delegate_android.h +++ b/components/facilitated_payments/android/device_delegate_android.h
@@ -27,9 +27,10 @@ DeviceDelegateAndroid& operator=(const DeviceDelegateAndroid&) = delete; ~DeviceDelegateAndroid() override; - // Returns true if Google Wallet is installed, and its version supports Pix - // account linking. - bool IsPixAccountLinkingSupported() const override; + // Returns eligible if Google Wallet is installed, and its version supports + // Pix account linking. + WalletEligibilityForPixAccountLinking IsPixAccountLinkingSupported() + const override; // Opens the Pix account linking page in Google Wallet. The `email` is set to // the gaia account that the user logged into.
diff --git a/components/facilitated_payments/android/java/BUILD.gn b/components/facilitated_payments/android/java/BUILD.gn index 4741f6c..a9ba1ce 100644 --- a/components/facilitated_payments/android/java/BUILD.gn +++ b/components/facilitated_payments/android/java/BUILD.gn
@@ -6,6 +6,11 @@ import("//build/config/android/rules.gni") import("//third_party/jni_zero/jni_zero.gni") +java_cpp_enum("java_enum_srcjar") { + sources = + [ "//components/facilitated_payments/core/browser/device_delegate.h" ] +} + android_library("java") { sources = [ "src/org/chromium/components/facilitated_payments/DeviceDelegate.java", @@ -26,7 +31,10 @@ "//ui/android:ui_no_recycler_view_java", "//url:url_java", ] - srcjar_deps = [ ":jni_headers" ] + srcjar_deps = [ + ":java_enum_srcjar", + ":jni_headers", + ] } generate_jni("jni_headers") {
diff --git a/components/facilitated_payments/android/java/src/org/chromium/components/facilitated_payments/DeviceDelegate.java b/components/facilitated_payments/android/java/src/org/chromium/components/facilitated_payments/DeviceDelegate.java index e2351c9..f1eb218 100644 --- a/components/facilitated_payments/android/java/src/org/chromium/components/facilitated_payments/DeviceDelegate.java +++ b/components/facilitated_payments/android/java/src/org/chromium/components/facilitated_payments/DeviceDelegate.java
@@ -45,21 +45,23 @@ * The Pix account linking prompt redirects to the Google Wallet app on acceptance. Checks if * Wallet is eligible for Pix account linking. * - * @return True if Google Wallet is installed, and the Wallet version supports Pix account - * linking. + * @return An {@link WalletEligibilityForPixAccountLinking} indicating eligibility. */ @CalledByNative - private static boolean isWalletEligibleForPixAccountLinking() { + private static @WalletEligibilityForPixAccountLinking int + getWalletEligibilityForPixAccountLinking() { PackageInfo walletPackageInfo = PackageUtils.getPackageInfo(GOOGLE_WALLET_PACKAGE_NAME, /* flags= */ 0); // {@link PackageInfo} is null if the package is not installed. if (walletPackageInfo == null) { - return false; + return WalletEligibilityForPixAccountLinking.WALLET_NOT_INSTALLED; } // Verify Google Wallet version supports Pix account linking. - return PackageUtils.packageVersionCode(walletPackageInfo) - >= PIX_MIN_SUPPORTED_WALLET_VERSION; + if (PackageUtils.packageVersionCode(walletPackageInfo) < PIX_MIN_SUPPORTED_WALLET_VERSION) { + return WalletEligibilityForPixAccountLinking.WALLET_VERSION_NOT_SUPPORTED; + } + return WalletEligibilityForPixAccountLinking.ELIGIBLE; } @CalledByNative
diff --git a/components/facilitated_payments/core/browser/device_delegate.h b/components/facilitated_payments/core/browser/device_delegate.h index fbbd6ba..5449fea 100644 --- a/components/facilitated_payments/core/browser/device_delegate.h +++ b/components/facilitated_payments/core/browser/device_delegate.h
@@ -15,6 +15,13 @@ namespace payments::facilitated { +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.facilitated_payments +enum class WalletEligibilityForPixAccountLinking { + kEligible = 0, + kWalletNotInstalled = 1, + kWalletVersionNotSupported = 2 +}; + // Abstract base class for device-specific facilitated payments operations. // This class defines the interface for operations that require interaction // with the underlying device or platform, such as checking and opening other @@ -26,7 +33,8 @@ virtual ~DeviceDelegate() = default; // Returns true if Pix account linking is supported by the device. - virtual bool IsPixAccountLinkingSupported() const = 0; + virtual WalletEligibilityForPixAccountLinking IsPixAccountLinkingSupported() + const = 0; // Takes user to the Pix account linking page. The `email` is used to provide // the gaia account that the user is signed into.
diff --git a/components/facilitated_payments/core/browser/mock_device_delegate.h b/components/facilitated_payments/core/browser/mock_device_delegate.h index c3db6e6..bb1574c 100644 --- a/components/facilitated_payments/core/browser/mock_device_delegate.h +++ b/components/facilitated_payments/core/browser/mock_device_delegate.h
@@ -19,7 +19,10 @@ MockDeviceDelegate(); ~MockDeviceDelegate() override; - MOCK_METHOD(bool, IsPixAccountLinkingSupported, (), (const, override)); + MOCK_METHOD(WalletEligibilityForPixAccountLinking, + IsPixAccountLinkingSupported, + (), + (const, override)); MOCK_METHOD(void, LaunchPixAccountLinkingPage, (std::string), (override)); MOCK_METHOD(void, SetOnReturnToChromeCallbackAndObserveAppState,
diff --git a/components/facilitated_payments/core/browser/pix_account_linking_manager.cc b/components/facilitated_payments/core/browser/pix_account_linking_manager.cc index 0e9e1af..580b9562a 100644 --- a/components/facilitated_payments/core/browser/pix_account_linking_manager.cc +++ b/components/facilitated_payments/core/browser/pix_account_linking_manager.cc
@@ -12,6 +12,7 @@ #include "base/time/time.h" #include "components/autofill/core/browser/data_manager/payments/payments_data_manager.h" #include "components/autofill/core/browser/payments/payments_util.h" +#include "components/facilitated_payments/core/browser/device_delegate.h" #include "components/facilitated_payments/core/browser/facilitated_payments_client.h" #include "components/facilitated_payments/core/metrics/facilitated_payments_metrics.h" #include "url/origin.h" @@ -38,16 +39,32 @@ // Reset to default state to prepare for a new account linking flow. Reset(); pix_payment_page_origin_ = pix_payment_page_origin; - if (!client_->GetDeviceDelegate()->IsPixAccountLinkingSupported()) { - return; + + WalletEligibilityForPixAccountLinking wallet_eligibility = + client_->GetDeviceDelegate()->IsPixAccountLinkingSupported(); + switch (wallet_eligibility) { + case WalletEligibilityForPixAccountLinking::kWalletNotInstalled: + LogPixAccountLinkingFlowExitedReason( + PixAccountLinkingFlowExitedReason::kWalletNotInstalled); + return; + case WalletEligibilityForPixAccountLinking::kWalletVersionNotSupported: + LogPixAccountLinkingFlowExitedReason( + PixAccountLinkingFlowExitedReason::kWalletVersionNotSupported); + return; + case WalletEligibilityForPixAccountLinking::kEligible: + break; } + if (!client_->GetPaymentsDataManager() ->IsFacilitatedPaymentsPixAccountLinkingUserPrefEnabled()) { + LogPixAccountLinkingFlowExitedReason( + PixAccountLinkingFlowExitedReason::kUserOptedOut); return; } if (!client_->HasScreenlockOrBiometricSetup()) { - // TODO(crbug.com/419108993): Add metrics. + LogPixAccountLinkingFlowExitedReason( + PixAccountLinkingFlowExitedReason::kNoScreenlockOrBiometricSetup); return; } @@ -99,13 +116,15 @@ // account linking, exit. if (!is_eligible_for_pix_account_linking_.has_value() || !is_eligible_for_pix_account_linking_.value()) { + LogPixAccountLinkingFlowExitedReason( + PixAccountLinkingFlowExitedReason::kServerSideIneligible); return; } // If the user has switched to a different tab, don't show the prompt. if (!client_->IsWebContentsVisibleOrOccluded()) { - // TODO(crbug.com/419108993): Add metrics for when the prompt is not shown - // because the tab is not active. + LogPixAccountLinkingFlowExitedReason( + PixAccountLinkingFlowExitedReason::kTabIsNotActive); return; } @@ -114,8 +133,8 @@ // URLs have the same scheme, the same host, and the same port. if (!pix_payment_page_origin_.IsSameOriginWith( client_->GetLastCommittedOrigin())) { - // TODO(crbug.com/419108993): Add metrics for when the prompt is not shown - // because the user is on a different website. + LogPixAccountLinkingFlowExitedReason( + PixAccountLinkingFlowExitedReason::kUserSwitchedWebsite); return; }
diff --git a/components/facilitated_payments/core/browser/pix_account_linking_manager_unittest.cc b/components/facilitated_payments/core/browser/pix_account_linking_manager_unittest.cc index 6d77ea55..357c57a9 100644 --- a/components/facilitated_payments/core/browser/pix_account_linking_manager_unittest.cc +++ b/components/facilitated_payments/core/browser/pix_account_linking_manager_unittest.cc
@@ -13,6 +13,7 @@ #include "components/autofill/core/browser/payments/payments_customer_data.h" #include "components/autofill/core/browser/test_utils/autofill_test_utils.h" #include "components/autofill/core/common/autofill_prefs.h" +#include "components/facilitated_payments/core/browser/device_delegate.h" #include "components/facilitated_payments/core/browser/mock_device_delegate.h" #include "components/facilitated_payments/core/browser/mock_facilitated_payments_client.h" #include "components/facilitated_payments/core/browser/network_api/mock_facilitated_payments_network_interface.h" @@ -65,7 +66,8 @@ ON_CALL(client_, GetLastCommittedOrigin) .WillByDefault(testing::ReturnRef(kPixPaymentPageOrigin)); ON_CALL(*device_delegate(), IsPixAccountLinkingSupported) - .WillByDefault(testing::Return(true)); + .WillByDefault( + testing::Return(WalletEligibilityForPixAccountLinking::kEligible)); ON_CALL(client(), IsWebContentsVisibleOrOccluded) .WillByDefault(testing::Return(true)); // Simulate the payments server returns that the user is eligible for Pix @@ -139,7 +141,8 @@ TEST_F(PixAccountLinkingManagerTest, PixAccountLinkingNotSupported_PromptNotShown) { ON_CALL(*device_delegate(), IsPixAccountLinkingSupported) - .WillByDefault(testing::Return(false)); + .WillByDefault(testing::Return( + WalletEligibilityForPixAccountLinking::kWalletNotInstalled)); EXPECT_CALL(client(), ShowPixAccountLinkingPrompt).Times(0); @@ -342,6 +345,15 @@ std::move(on_return_to_chrome_callback).Run(); } +TEST_F(PixAccountLinkingManagerTest, ScreenlockNotEnabled_PromptNotShown) { + ON_CALL(client(), HasScreenlockOrBiometricSetup) + .WillByDefault(testing::Return(false)); + + EXPECT_CALL(client(), ShowPixAccountLinkingPrompt).Times(0); + + manager()->MaybeShowPixAccountLinkingPrompt(kPixPaymentPageOrigin); +} + TEST_F(PixAccountLinkingManagerTest, PromptAcceptedLogged) { base::HistogramTester histogram_tester; @@ -381,16 +393,6 @@ /*expected_bucket_count=*/0); } -TEST_F(PixAccountLinkingManagerTest, ScreenlockNotEnabled_PromptNotShown) { - ON_CALL(client(), HasScreenlockOrBiometricSetup) - .WillByDefault(testing::Return(false)); - - EXPECT_CALL(client(), ShowPixAccountLinkingPrompt).Times(0); - - manager()->MaybeShowPixAccountLinkingPrompt(kPixPaymentPageOrigin); - task_environment_.FastForwardBy(kShowPromptDelay); -} - class PixAccountLinkingManagerParameterizedTest : public PixAccountLinkingManagerTest, public testing::WithParamInterface<bool> {}; @@ -420,7 +422,7 @@ PixAccountLinkingManagerParameterizedTest, testing::Bool()); -TEST_F(PixAccountLinkingManagerTest, FlowExitedReason_UserDeclinedLogged) { +TEST_F(PixAccountLinkingManagerTest, PromptDeclined_ExitedReasonLogged) { base::HistogramTester histogram_tester; manager()->MaybeShowPixAccountLinkingPrompt(kPixPaymentPageOrigin); @@ -441,6 +443,134 @@ /*expected_count=*/0); } +TEST_F(PixAccountLinkingManagerTest, WalletNotInstalled_ExitedReasonLogged) { + base::HistogramTester histogram_tester; + ON_CALL(*device_delegate(), IsPixAccountLinkingSupported) + .WillByDefault(testing::Return( + WalletEligibilityForPixAccountLinking::kWalletNotInstalled)); + + manager()->MaybeShowPixAccountLinkingPrompt(kPixPaymentPageOrigin); + + histogram_tester.ExpectUniqueSample( + "FacilitatedPayments.Pix.AccountLinking.FlowExitedReason", + /*sample=*/PixAccountLinkingFlowExitedReason::kWalletNotInstalled, + /*expected_bucket_count=*/1); +} + +TEST_F(PixAccountLinkingManagerTest, + WalletVersionNotSupported_ExitedReasonLogged) { + base::HistogramTester histogram_tester; + ON_CALL(*device_delegate(), IsPixAccountLinkingSupported) + .WillByDefault(testing::Return( + WalletEligibilityForPixAccountLinking::kWalletVersionNotSupported)); + + manager()->MaybeShowPixAccountLinkingPrompt(kPixPaymentPageOrigin); + + histogram_tester.ExpectUniqueSample( + "FacilitatedPayments.Pix.AccountLinking.FlowExitedReason", + /*sample=*/PixAccountLinkingFlowExitedReason::kWalletVersionNotSupported, + /*expected_bucket_count=*/1); +} + +TEST_F(PixAccountLinkingManagerTest, + PixAccountLinkingPrefDisabled_ExitedReasonLogged) { + base::HistogramTester histogram_tester; + autofill::prefs::SetFacilitatedPaymentsPixAccountLinking(pref_service_.get(), + false); + + manager()->MaybeShowPixAccountLinkingPrompt(kPixPaymentPageOrigin); + + histogram_tester.ExpectUniqueSample( + "FacilitatedPayments.Pix.AccountLinking.FlowExitedReason", + /*sample=*/PixAccountLinkingFlowExitedReason::kUserOptedOut, + /*expected_bucket_count=*/1); +} + +TEST_F(PixAccountLinkingManagerTest, ScreenlockNotEnabled_ExitedReasonLogged) { + base::HistogramTester histogram_tester; + ON_CALL(client(), HasScreenlockOrBiometricSetup) + .WillByDefault(testing::Return(false)); + + manager()->MaybeShowPixAccountLinkingPrompt(kPixPaymentPageOrigin); + + histogram_tester.ExpectUniqueSample( + "FacilitatedPayments.Pix.AccountLinking.FlowExitedReason", + /*sample=*/ + PixAccountLinkingFlowExitedReason::kNoScreenlockOrBiometricSetup, + /*expected_bucket_count=*/1); +} + +TEST_F(PixAccountLinkingManagerTest, + ServerEligibilityCheckNotCompleted_ExitedReasonLogged) { + base::HistogramTester histogram_tester; + // Simulate that the payments server hasn't yet returned eligibility. + EXPECT_CALL( + *multiple_request_payments_network_interface(), + GetDetailsForCreatePaymentInstrument(testing::_, testing::_, testing::_)) + .WillOnce(testing::Return( + base::StrongAlias<autofill::payments::RequestIdTag, std::string>())); + + manager()->MaybeShowPixAccountLinkingPrompt(kPixPaymentPageOrigin); + + histogram_tester.ExpectUniqueSample( + "FacilitatedPayments.Pix.AccountLinking.FlowExitedReason", + /*sample=*/PixAccountLinkingFlowExitedReason::kServerSideIneligible, + /*expected_bucket_count=*/1); +} + +TEST_F(PixAccountLinkingManagerTest, + ServerEligibilityCheckReturnsIneligible_ExitedReasonLogged) { + base::HistogramTester histogram_tester; + // Simulate that the payments server hasn't yet returned eligibility. + EXPECT_CALL( + *multiple_request_payments_network_interface(), + GetDetailsForCreatePaymentInstrument(testing::_, testing::_, testing::_)) + .WillOnce(testing::Invoke([](long, auto callback, const std::string&) { + std::move(callback).Run(autofill::payments::PaymentsAutofillClient:: + PaymentsRpcResult::kSuccess, + false); + return base::StrongAlias<autofill::payments::RequestIdTag, + std::string>(); + })); + + manager()->MaybeShowPixAccountLinkingPrompt(kPixPaymentPageOrigin); + + histogram_tester.ExpectUniqueSample( + "FacilitatedPayments.Pix.AccountLinking.FlowExitedReason", + /*sample=*/PixAccountLinkingFlowExitedReason::kServerSideIneligible, + /*expected_bucket_count=*/1); +} + +TEST_F(PixAccountLinkingManagerTest, TabNotActive_ExitedReasonLogged) { + base::HistogramTester histogram_tester; + ON_CALL(client(), IsWebContentsVisibleOrOccluded) + .WillByDefault(testing::Return(false)); + + manager()->MaybeShowPixAccountLinkingPrompt(kPixPaymentPageOrigin); + + histogram_tester.ExpectUniqueSample( + "FacilitatedPayments.Pix.AccountLinking.FlowExitedReason", + /*sample=*/PixAccountLinkingFlowExitedReason::kTabIsNotActive, + /*expected_bucket_count=*/1); +} + +TEST_F(PixAccountLinkingManagerTest, DifferentOrigin_ExitedReasonLogged) { + base::HistogramTester histogram_tester; + // Simulate that when the user returns to Chrome, they are on a different + // website. + url::Origin different_website_origin = + url::Origin::Create(GURL("https://www.different.com")); + ON_CALL(client(), GetLastCommittedOrigin) + .WillByDefault(testing::ReturnRef(different_website_origin)); + + manager()->MaybeShowPixAccountLinkingPrompt(kPixPaymentPageOrigin); + + histogram_tester.ExpectUniqueSample( + "FacilitatedPayments.Pix.AccountLinking.FlowExitedReason", + /*sample=*/PixAccountLinkingFlowExitedReason::kUserSwitchedWebsite, + /*expected_bucket_count=*/1); +} + class PixAccountLinkingManagerTestForExitedReasons : public PixAccountLinkingManagerTest, public testing::WithParamInterface<
diff --git a/components/facilitated_payments/core/metrics/facilitated_payments_metrics.h b/components/facilitated_payments/core/metrics/facilitated_payments_metrics.h index f4d9bc6e..7e50bc8 100644 --- a/components/facilitated_payments/core/metrics/facilitated_payments_metrics.h +++ b/components/facilitated_payments/core/metrics/facilitated_payments_metrics.h
@@ -130,7 +130,14 @@ kScreenClosedNotByUser = 1, kScreenClosedByUser = 2, kUserDeclined = 3, - kMaxValue = kUserDeclined + kWalletNotInstalled = 4, + kWalletVersionNotSupported = 5, + kUserOptedOut = 6, + kNoScreenlockOrBiometricSetup = 7, + kServerSideIneligible = 8, + kTabIsNotActive = 9, + kUserSwitchedWebsite = 10, + kMaxValue = kUserSwitchedWebsite }; // LINT.ThenChange(/tools/metrics/histograms/metadata/facilitated_payments/enums.xml:FacilitatedPayments.Pix.AccountLinking.FlowExitedReason)
diff --git a/components/facilitated_payments/core/metrics/facilitated_payments_metrics_unittest.cc b/components/facilitated_payments/core/metrics/facilitated_payments_metrics_unittest.cc index ffe87a2..e726e8a 100644 --- a/components/facilitated_payments/core/metrics/facilitated_payments_metrics_unittest.cc +++ b/components/facilitated_payments/core/metrics/facilitated_payments_metrics_unittest.cc
@@ -227,10 +227,18 @@ INSTANTIATE_TEST_SUITE_P( FacilitatedPaymentsMetricsTest, FacilitatedPaymentsMetricsPixAccountLinkingFlowExitedReasonTest, - testing::Values(PixAccountLinkingFlowExitedReason::kScreenNotShown, - PixAccountLinkingFlowExitedReason::kScreenClosedNotByUser, - PixAccountLinkingFlowExitedReason::kScreenClosedByUser, - PixAccountLinkingFlowExitedReason::kUserDeclined)); + testing::Values( + PixAccountLinkingFlowExitedReason::kScreenNotShown, + PixAccountLinkingFlowExitedReason::kScreenClosedNotByUser, + PixAccountLinkingFlowExitedReason::kScreenClosedByUser, + PixAccountLinkingFlowExitedReason::kUserDeclined, + PixAccountLinkingFlowExitedReason::kWalletNotInstalled, + PixAccountLinkingFlowExitedReason::kWalletVersionNotSupported, + PixAccountLinkingFlowExitedReason::kUserOptedOut, + PixAccountLinkingFlowExitedReason::kNoScreenlockOrBiometricSetup, + PixAccountLinkingFlowExitedReason::kServerSideIneligible, + PixAccountLinkingFlowExitedReason::kTabIsNotActive, + PixAccountLinkingFlowExitedReason::kUserSwitchedWebsite)); TEST(FacilitatedPaymentsMetricsTest, LogGetDetailsForCreatePaymentInstrumentResultAndLatency) {
diff --git a/components/omnibox/composebox/composebox_query_controller_unittest.cc b/components/omnibox/composebox/composebox_query_controller_unittest.cc index d185f1a..190d2ae 100644 --- a/components/omnibox/composebox/composebox_query_controller_unittest.cc +++ b/components/omnibox/composebox/composebox_query_controller_unittest.cc
@@ -46,7 +46,7 @@ #endif // !BUILDFLAG(IS_IOS) constexpr char kQuerySubmissionTimeQueryParameter[] = "qsubts"; -constexpr char kUserPerceivedQuerySubmissionTimeQueryParameter[] = "pqsubts"; +constexpr char kClientUploadDurationQueryParameter[] = "cud"; constexpr char kSessionIdQueryParameterKey[] = "gsessionid"; constexpr char kVariationsHeaderKey[] = "X-Client-Data"; constexpr char kTestUser[] = "test_user@gmail.com"; @@ -815,11 +815,9 @@ EXPECT_TRUE(net::GetValueForKeyInQuery( aim_url, kQuerySubmissionTimeQueryParameter, &qsubts_value)); - std::string pqsubts_value; + std::string cud_value; EXPECT_TRUE(net::GetValueForKeyInQuery( - aim_url, kUserPerceivedQuerySubmissionTimeQueryParameter, - &pqsubts_value)); - EXPECT_EQ(pqsubts_value, "1000"); + aim_url, kClientUploadDurationQueryParameter, &cud_value)); } TEST_F(ComposeboxQueryControllerTest, @@ -898,11 +896,9 @@ EXPECT_TRUE(net::GetValueForKeyInQuery( aim_url, kQuerySubmissionTimeQueryParameter, &qsubts_value)); - std::string pqsubts_value; + std::string cud_value; EXPECT_TRUE(net::GetValueForKeyInQuery( - aim_url, kUserPerceivedQuerySubmissionTimeQueryParameter, - &pqsubts_value)); - EXPECT_EQ(pqsubts_value, "1000"); + aim_url, kClientUploadDurationQueryParameter, &cud_value)); } TEST_F(ComposeboxQueryControllerTest, QuerySubmitted) { @@ -935,11 +931,9 @@ EXPECT_TRUE(net::GetValueForKeyInQuery( aim_url, kQuerySubmissionTimeQueryParameter, &qsubts_value)); - std::string pqsubts_value; + std::string cud_value; EXPECT_TRUE(net::GetValueForKeyInQuery( - aim_url, kUserPerceivedQuerySubmissionTimeQueryParameter, - &pqsubts_value)); - EXPECT_EQ(pqsubts_value, "1000"); + aim_url, kClientUploadDurationQueryParameter, &cud_value)); } TEST_F(ComposeboxQueryControllerTest, QuerySubmittedWithUploadedPdf) { @@ -987,11 +981,9 @@ EXPECT_TRUE(net::GetValueForKeyInQuery( aim_url, kQuerySubmissionTimeQueryParameter, &qsubts_value)); - std::string pqsubts_value; + std::string cud_value; EXPECT_TRUE(net::GetValueForKeyInQuery( - aim_url, kUserPerceivedQuerySubmissionTimeQueryParameter, - &pqsubts_value)); - EXPECT_EQ(pqsubts_value, "1000"); + aim_url, kClientUploadDurationQueryParameter, &cud_value)); } #if !BUILDFLAG(IS_IOS) @@ -1046,11 +1038,10 @@ EXPECT_TRUE(net::GetValueForKeyInQuery( aim_url, kQuerySubmissionTimeQueryParameter, &qsubts_value)); - std::string pqsubts_value; + std::string cud_value; EXPECT_TRUE(net::GetValueForKeyInQuery( - aim_url, kUserPerceivedQuerySubmissionTimeQueryParameter, - &pqsubts_value)); - EXPECT_EQ(pqsubts_value, "1000"); + aim_url, kClientUploadDurationQueryParameter, + &cud_value)); } #endif // !BUILDFLAG(IS_IOS)
diff --git a/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc b/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc index ff09a4e..4e65dea 100644 --- a/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc +++ b/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc
@@ -227,7 +227,6 @@ WebFeature::kWebCodecsVideoFrameFromImage, WebFeature::kWebCodecsVideoFrameFromBuffer, WebFeature::kPrivateNetworkAccessPreflightWarning, - WebFeature::kPrivateNetworkAccessPermissionPrompt, WebFeature::kWebBluetoothGetAvailability, WebFeature::kCookieHasNotBeenRefreshedIn201To300Days, WebFeature::kCookieHasNotBeenRefreshedIn301To350Days,
diff --git a/components/permissions/prediction_service/permissions_aiv3_handler.cc b/components/permissions/prediction_service/permissions_aiv3_handler.cc index 8c276f9..7b4f208 100644 --- a/components/permissions/prediction_service/permissions_aiv3_handler.cc +++ b/components/permissions/prediction_service/permissions_aiv3_handler.cc
@@ -67,13 +67,54 @@ void PermissionsAiv3Handler::ExecuteModel(ExecutionCallback callback, std::unique_ptr<SkBitmap> snapshot) { if (snapshot.get()) { + base::UmaHistogramBoolean( + "Permissions.AIv3.ModelExecutionAlreadyInProgress", + is_execution_in_progress_); + // If an execution is already in progress, there is no way to cancel it and + // we cannot wait until it is done because this will add extra latency, so + // we will return an empty response to the callback. + if (is_execution_in_progress_) { + VLOG(1) << "[PermissionsAIv3] ExecuteModel: Execution already in " + "progress. Returning empty response."; + // The callback is no longer valid because a new execution was requested + // while the previous one was still in progress. + is_callback_valid_ = false; + std::move(callback).Run(std::nullopt); + return; + } + is_execution_in_progress_ = true; + is_callback_valid_ = true; + ModelInput input; input.snapshot = *snapshot; input.metadata = model_metadata_; - ExecuteModelWithInput(std::move(callback), input); + + ExecutionCallback on_complete_callback = + base::BindOnce(&PermissionsAiv3Handler::OnModelExecutionComplete, + weak_factory_.GetWeakPtr(), std::move(callback)); + + ExecuteModelWithInput(std::move(on_complete_callback), input); } else { std::move(callback).Run(std::nullopt); } } +void PermissionsAiv3Handler::OnModelExecutionComplete( + ExecutionCallback original_callback, + const std::optional<PermissionRequestRelevance>& relevance) { + is_execution_in_progress_ = false; + + if (is_callback_valid_) { + std::move(original_callback).Run(relevance); + } else { + VLOG(1) << "[PermissionsAIv3] OnModelExecutionComplete: Callback is no " + "longer valid. Ignoring the result."; + // The callback is no longer valid because a new execution was requested + // while the previous one was still in progress. We will return an empty + // response to the callback because there is no UI to which the relevance + // can be applied. + std::move(original_callback).Run(std::nullopt); + } +} + } // namespace permissions
diff --git a/components/permissions/prediction_service/permissions_aiv3_handler.h b/components/permissions/prediction_service/permissions_aiv3_handler.h index e5f2ce7..42557c5 100644 --- a/components/permissions/prediction_service/permissions_aiv3_handler.h +++ b/components/permissions/prediction_service/permissions_aiv3_handler.h
@@ -47,7 +47,26 @@ std::unique_ptr<SkBitmap> snapshot); private: + // Called when the model execution is complete. This is a wrapper around the + // callback provided to `ExecuteModel` that verifies that the callback is + // still valid. + void OnModelExecutionComplete( + ExecutionCallback original_callback, + const std::optional<PermissionRequestRelevance>& relevance); + std::optional<PermissionsAiv3ModelMetadata> model_metadata_; + + // Because there is no way to cancel a model execution once it has started, we + // will return an empty response to the new callback if a new execution is + // requested while the previous one is still in progress. + bool is_execution_in_progress_ = false; + + // Whether the callback passed to ExecuteModel is still valid. It is no longer + // valid if a new execution is requested while the previous one is still in + // progress. + bool is_callback_valid_ = true; + + base::WeakPtrFactory<PermissionsAiv3Handler> weak_factory_{this}; }; } // namespace permissions
diff --git a/components/permissions/prediction_service/permissions_aiv3_handler_unittest.cc b/components/permissions/prediction_service/permissions_aiv3_handler_unittest.cc index 2c8d337..070bd01 100644 --- a/components/permissions/prediction_service/permissions_aiv3_handler_unittest.cc +++ b/components/permissions/prediction_service/permissions_aiv3_handler_unittest.cc
@@ -13,6 +13,7 @@ #include "base/test/test_future.h" #include "components/optimization_guide/core/delivery/test_model_info_builder.h" #include "components/optimization_guide/core/delivery/test_optimization_guide_model_provider.h" +#include "components/optimization_guide/core/inference/model_handler.h" #include "components/optimization_guide/core/inference/test_model_handler.h" #include "components/optimization_guide/proto/common_types.pb.h" #include "components/permissions/prediction_service/permissions_ai_encoder_base.h" @@ -46,6 +47,9 @@ auto& kImageInputWidth = PermissionsAiv3Encoder::kImageInputWidth; auto& kImageInputHeight = PermissionsAiv3Encoder::kImageInputHeight; +constexpr char kModelExecutionAlreadyInProgressHistogram[] = + "Permissions.AIv3.ModelExecutionAlreadyInProgress"; + PermissionsAiv3ModelMetadata BuildMetadataFromValues( const std::array<float, 4>& thresholds) { PermissionsAiv3ModelMetadata metadata; @@ -60,6 +64,37 @@ return metadata; } +class PermissionsAiv3HandlerMock : public PermissionsAiv3Handler { + public: + PermissionsAiv3HandlerMock( + optimization_guide::OptimizationGuideModelProvider* model_provider, + optimization_guide::proto::OptimizationTarget optimization_target, + RequestType request_type, + std::unique_ptr<PermissionsAiv3Encoder> model_executor) + : PermissionsAiv3Handler(model_provider, + optimization_target, + request_type, + std::move(model_executor)) {} + + // This is a mock implementation of ExecuteModelWithInput that does not + // schedule the real model execution but captures the callback. This gives the + // test control over the duration of the model execution and can be used to + // simulate the model execution being stuck (or simply too long). + void ExecuteModelWithInput( + ExecutionCallback callback, + const PermissionsAiv3Encoder::ModelInput& input) override { + callback_ = std::move(callback); + } + + void ReleaseCallback(PermissionRequestRelevance relevance) { + EXPECT_TRUE(callback_); + std::move(callback_).Run(relevance); + } + + private: + ExecutionCallback callback_; +}; + class PermissionsAiv3EncoderFake : public PermissionsAiv3Encoder { public: explicit PermissionsAiv3EncoderFake(RequestType type) @@ -157,6 +192,10 @@ : notification_model_handler_.get(); } + optimization_guide::TestOptimizationGuideModelProvider* GetModelProvider() { + return model_provider_.get(); + } + protected: raw_ptr<PermissionsAiv3EncoderFake> geolocation_encoder_mock_; raw_ptr<PermissionsAiv3EncoderFake> notification_encoder_mock_; @@ -340,5 +379,95 @@ EXPECT_TRUE(flag); } +// This test verifies an edge case when the permission model handler receives +// multiple overlapping request for the on-device model execution. Multiple +// requests means that the UI was updated faster than the model produces content +// evaluation. In other words the callback that is stored in the model execution +// class refers to a stailed UI and the result of the execution should be +// ignored. +TEST_F(Aiv3HandlerTest, ModelHandlerPreventsConcurrentExecutions) { + base::HistogramTester histograms; + + auto geolocation_encoder_mock = + std::make_unique<PermissionsAiv3EncoderFake>(RequestType::kGeolocation); + std::unique_ptr<PermissionsAiv3HandlerMock> model_handler_mock = + std::make_unique<PermissionsAiv3HandlerMock>( + GetModelProvider(), + /*optimization_target=*/kOptTargetGeolocation, + /*request_type=*/RequestType::kGeolocation, + std::move(geolocation_encoder_mock)); + + // Because of `PermissionsAiv3EncoderFake` the first execution will be hold + // until manually released to simulate a long execution so that we can test + // the concurrent execution prevention logic. + ModelCallbackFuture future1; + // The image size is arbitrary and does not affect the test. + auto snapshot1 = + test::BuildBitmap(/*width=*/32, /*height=*/32, kDefaultColor); + model_handler_mock->ExecuteModel(future1.GetCallback(), std::move(snapshot1)); + + // Request the second model execution while the first one is still in + // progress. The second execution should be cancelled with `std::nullopt` + // result. + ModelCallbackFuture future2; + // The image size is arbitrary and does not affect the test. + auto snapshot2 = + test::BuildBitmap(/*width=*/32, /*height=*/32, kDefaultColor); + model_handler_mock->ExecuteModel(future2.GetCallback(), std::move(snapshot2)); + EXPECT_EQ(future2.Take(), std::nullopt); + + // Any return value is OK as it should be ignored and replaced with + // `std::nullopt`. + model_handler_mock->ReleaseCallback(PermissionRequestRelevance::kUnspecified); + // Because the callback was released after the second execution was requested, + // the first execution should return `std::nullopt` result. + EXPECT_EQ(future1.Take(), std::nullopt); + + histograms.ExpectBucketCount( + "Permissions.AIv3.ModelExecutionAlreadyInProgress", true, 1u); + + histograms.ExpectBucketCount(kModelExecutionAlreadyInProgressHistogram, false, + 1u); +} + +// This test verifies the default behavior of the permission model handler +// without any concurrent executions. This is needed to make sure there is no +// regression in the default behavior and a correct value is properly delivered +// from the on-device model to the callback. +TEST_F(Aiv3HandlerTest, ModelHandlerSingleExecutions) { + base::HistogramTester histograms; + + auto geolocation_encoder_mock = + std::make_unique<PermissionsAiv3EncoderFake>(RequestType::kGeolocation); + std::unique_ptr<PermissionsAiv3HandlerMock> model_handler_mock = + std::make_unique<PermissionsAiv3HandlerMock>( + GetModelProvider(), + /*optimization_target=*/kOptTargetGeolocation, + /*request_type=*/RequestType::kGeolocation, + std::move(geolocation_encoder_mock)); + + // Because of `PermissionsAiv3EncoderFake` the first execution will be hold + // until manually released. In this case we release the callback before we + // try to execute the model again. + ModelCallbackFuture future1; + // The image size is arbitrary and does not affect the test. + auto snapshot1 = + test::BuildBitmap(/*width=*/32, /*height=*/32, kDefaultColor); + model_handler_mock->ExecuteModel(future1.GetCallback(), std::move(snapshot1)); + + // The manual release without a concurrent request should return the + // correct relevance. + model_handler_mock->ReleaseCallback(PermissionRequestRelevance::kVeryLow); + // Because the callback was released uninterrupted, the execution should + // return the correct result. + EXPECT_EQ(future1.Take(), PermissionRequestRelevance::kVeryLow); + + histograms.ExpectBucketCount(kModelExecutionAlreadyInProgressHistogram, true, + 0u); + + histograms.ExpectBucketCount(kModelExecutionAlreadyInProgressHistogram, false, + 1u); +} + } // namespace } // namespace permissions
diff --git a/components/permissions_strings.grdp b/components/permissions_strings.grdp index 5ea3b73..2add28f4 100644 --- a/components/permissions_strings.grdp +++ b/components/permissions_strings.grdp
@@ -306,13 +306,6 @@ Finding USB devices... </message> - <message name="IDS_PRIVATE_NETWORK_DEVICE_CHOOSER_PROMPT_ORIGIN" desc="Text on a popup permission prompt asking the user whether they want to allow the site to access a private network device."> - <ph name="Origin">$1<ex>www.google.com</ex></ph> wants to access a device on your network: - </message> - <message name="IDS_PRIVATE_NETWORK_DEVICE_CHOOSER_CONNECT_BUTTON_TEXT" desc="Label on the button that closes the private network chooser popup and connects the selected device."> - Connect - </message> - <if expr="not is_android"> <message name="IDS_GEOLOCATION_PERMISSION_CHIP" desc="Button text representing a request for the user's physical location from a website. When clicked, shows a permission prompt bubble with more information."> Use your location?
diff --git a/components/permissions_strings_grdp/IDS_PRIVATE_NETWORK_DEVICE_CHOOSER_CONNECT_BUTTON_TEXT.png.sha1 b/components/permissions_strings_grdp/IDS_PRIVATE_NETWORK_DEVICE_CHOOSER_CONNECT_BUTTON_TEXT.png.sha1 deleted file mode 100644 index 20765a7..0000000 --- a/components/permissions_strings_grdp/IDS_PRIVATE_NETWORK_DEVICE_CHOOSER_CONNECT_BUTTON_TEXT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e85e759ce08b832f935bf83fa95fef76f8778433 \ No newline at end of file
diff --git a/components/permissions_strings_grdp/IDS_PRIVATE_NETWORK_DEVICE_CHOOSER_PROMPT_ORIGIN.png.sha1 b/components/permissions_strings_grdp/IDS_PRIVATE_NETWORK_DEVICE_CHOOSER_PROMPT_ORIGIN.png.sha1 deleted file mode 100644 index 20765a7..0000000 --- a/components/permissions_strings_grdp/IDS_PRIVATE_NETWORK_DEVICE_CHOOSER_PROMPT_ORIGIN.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e85e759ce08b832f935bf83fa95fef76f8778433 \ No newline at end of file
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index f2e1768b..d98b648 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -186,8 +186,6 @@ BROWSER = 3; // Register for desktop Chrome browser user policies. ANDROID_BROWSER = 4; // Register for Android Chrome browser user policies. IOS_BROWSER = 6; // Register for iOS Chrome browser user policies. - ANDROID_DESKTOP_BROWSER = - 7; // Register for Android Desktop Chrome browser user policies. } // NOTE: we also use this field to detect client version. If this // field is missing, then the request comes from TT. We will remove
diff --git a/components/safe_browsing/content/browser/client_side_detection_host.cc b/components/safe_browsing/content/browser/client_side_detection_host.cc index 75b4bda..fcf842f 100644 --- a/components/safe_browsing/content/browser/client_side_detection_host.cc +++ b/components/safe_browsing/content/browser/client_side_detection_host.cc
@@ -544,16 +544,6 @@ PreClassificationCheckResult::NO_CLASSIFY_MATCH_HC_ALLOWLIST; } - if (phishing_detection_request_type_ == - ClientSideDetectionType::FULLSCREEN_API) { - // The purpose of triggering preclassification for fullscreen API to have - // an initial assessment on how often we'll be hitting the allowlist and - // triggering the classification. We will not go further than checking for - // this metric for now. - DontClassifyForPhishing( - PreClassificationCheckResult::NO_CLASSIFY_ALLOWLIST_METRIC); - } - CheckCache(phishing_reason); } @@ -565,6 +555,17 @@ if (!ShouldClassifyForPhishing()) { return; // No point in doing anything else. } + + if (phishing_detection_request_type_ == + ClientSideDetectionType::FULLSCREEN_API) { + // The purpose of triggering preclassification for fullscreen API to have + // an initial assessment on how often we'll be hitting the allowlist and + // triggering the classification. We will not go further than checking for + // this metric for now. + DontClassifyForPhishing( + PreClassificationCheckResult::NO_CLASSIFY_ALLOWLIST_METRIC); + } + // For trigger model requests, if result is cached, we don't want to run // classification again. In that case we're just trying to show the warning. // If we're dumping features for debugging, ignore the cache.
diff --git a/components/search_engines/util.cc b/components/search_engines/util.cc index c2550b6..643bdf8 100644 --- a/components/search_engines/util.cc +++ b/components/search_engines/util.cc
@@ -45,7 +45,7 @@ constexpr char kVisualInputTypeQueryParameterPdfValue[] = "pdf"; constexpr char kVisualInputTypeQueryParameterImageValue[] = "img"; constexpr char kQuerySubmissionTimeQueryParameter[] = "qsubts"; -constexpr char kUserPerceivedQuerySubmissionTimeQueryParameter[] = "pqsubts"; +constexpr char kClientUploadDurationQueryParameter[] = "cud"; // Computes whether updates to the search engines database are needed. // @@ -613,12 +613,15 @@ result_url = net::AppendOrReplaceQueryParameter(result_url, "udm", "50"); result_url = net::AppendOrReplaceQueryParameter(result_url, "aep", aim_entrypoint); + base::Time query_submission_time = base::Time::Now(); + result_url = net::AppendOrReplaceQueryParameter( + result_url, kClientUploadDurationQueryParameter, + base::NumberToString( + (query_submission_time - query_start_time).InMilliseconds())); result_url = net::AppendOrReplaceQueryParameter( result_url, kQuerySubmissionTimeQueryParameter, - base::NumberToString(base::Time::Now().InMillisecondsSinceUnixEpoch())); - result_url = net::AppendOrReplaceQueryParameter( - result_url, kUserPerceivedQuerySubmissionTimeQueryParameter, - base::NumberToString(query_start_time.InMillisecondsSinceUnixEpoch())); + base::NumberToString( + query_submission_time.InMillisecondsSinceUnixEpoch())); return result_url; }
diff --git a/components/sharing_message/sharing_fcm_sender_unittest.cc b/components/sharing_message/sharing_fcm_sender_unittest.cc index 314d2878..31363584 100644 --- a/components/sharing_message/sharing_fcm_sender_unittest.cc +++ b/components/sharing_message/sharing_fcm_sender_unittest.cc
@@ -25,7 +25,6 @@ #include "components/sync_device_info/fake_device_info_sync_service.h" #include "components/sync_device_info/fake_local_device_info_provider.h" #include "components/sync_preferences/testing_pref_service_syncable.h" -#include "crypto/ec_private_key.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc b/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc index 66dad34..c584d163 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc
@@ -1080,14 +1080,7 @@ TEST_F(AttributionStorageSqlTest, DeleteAggregatableAttributionReport) { OpenDatabase(); - storage()->StoreSource(TestAggregatableSourceProvider().GetBuilder().Build()); - - EXPECT_THAT(storage()->MaybeCreateAndStoreReport( - DefaultAggregatableTriggerBuilder().Build()), - AllOf(CreateReportEventLevelStatusIs( - AttributionTrigger::EventLevelResult::kSuccess), - CreateReportAggregatableStatusIs( - AttributionTrigger::AggregatableResult::kSuccess))); + AddEventAndAggregatableReportsToStorage(); std::vector<AttributionReport> reports = storage()->GetAttributionReports(base::Time::Max()); @@ -1142,17 +1135,7 @@ ExpiredSourceWithPendingAggregatableAttribution_NotDeleted) { OpenDatabase(); - storage()->StoreSource(TestAggregatableSourceProvider() - .GetBuilder() - .SetExpiry(base::Milliseconds(3)) - .Build()); - - EXPECT_THAT(storage()->MaybeCreateAndStoreReport( - DefaultAggregatableTriggerBuilder().Build()), - AllOf(CreateReportEventLevelStatusIs( - AttributionTrigger::EventLevelResult::kSuccess), - CreateReportAggregatableStatusIs( - AttributionTrigger::AggregatableResult::kSuccess))); + AddEventAndAggregatableReportsToStorage(); std::vector<AttributionReport> reports = storage()->GetAttributionReports(base::Time::Max());
diff --git a/content/browser/bluetooth/web_bluetooth_service_impl_browsertest.cc b/content/browser/bluetooth/web_bluetooth_service_impl_browsertest.cc index 14afbe5..a8a78af 100644 --- a/content/browser/bluetooth/web_bluetooth_service_impl_browsertest.cc +++ b/content/browser/bluetooth/web_bluetooth_service_impl_browsertest.cc
@@ -421,7 +421,8 @@ auto result = EvalJs(prerendered_frame_host, R"( navigator.bluetooth.requestLEScan({acceptAllAdvertisements: true});)", content::EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE); - EXPECT_THAT(result.error, ::testing::HasSubstr(kUserGestureError)); + EXPECT_THAT(result, + EvalJsResult::ErrorIs(::testing::HasSubstr(kUserGestureError))); // The prerendering doesn't show the bluetoothscanning prompt. EXPECT_FALSE(GetBluetoothDelegate()->showed_bluetooth_scanning_prompt()); @@ -518,7 +519,8 @@ navigator.bluetooth.requestDevice({ filters: [{name: 'Test Device', services: ['heart_rate']}]}))", content::EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE); - EXPECT_THAT(result.error, ::testing::HasSubstr(kUserGestureError)); + EXPECT_THAT(result, + EvalJsResult::ErrorIs(::testing::HasSubstr(kUserGestureError))); // WebBluetoothService is not created for `prerendered_frame_host`. EXPECT_EQ(GetWebBluetoothServiceOverride(prerendered_frame_host), nullptr); @@ -710,7 +712,8 @@ auto result = content::EvalJs(render_frame_host, R"( navigator.bluetooth.requestDevice({ filters: [{name: 'Test Device', services: ['heart_rate']}]}))"); - EXPECT_THAT(result.error, ::testing::HasSubstr(kFencedFrameError)); + EXPECT_THAT(result, + EvalJsResult::ErrorIs(::testing::HasSubstr(kFencedFrameError))); // No service should be created, as this is a fenced-frame EXPECT_EQ(nullptr, GetWebBluetoothServiceOverride(render_frame_host));
diff --git a/content/browser/cache_storage/cache_storage_cache_unittest.cc b/content/browser/cache_storage/cache_storage_cache_unittest.cc index e6365947..c544771 100644 --- a/content/browser/cache_storage/cache_storage_cache_unittest.cc +++ b/content/browser/cache_storage/cache_storage_cache_unittest.cc
@@ -222,18 +222,18 @@ void Close() override { entry_->Close(); } std::string GetKey() const override { return entry_->GetKey(); } base::Time GetLastUsed() const override { return entry_->GetLastUsed(); } - int32_t GetDataSize(int index) const override { + int64_t GetDataSize(int index) const override { return entry_->GetDataSize(index); } int ReadData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback) override { return entry_->ReadData(index, offset, buf, buf_len, std::move(callback)); } int WriteData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback,
diff --git a/content/browser/child_process_host_impl.cc b/content/browser/child_process_host_impl.cc index 5b31b47..39de45a 100644 --- a/content/browser/child_process_host_impl.cc +++ b/content/browser/child_process_host_impl.cc
@@ -213,14 +213,6 @@ return opening_channel_; } -bool ChildProcessHostImpl::Send(IPC::Message* message) { - if (!channel_) { - delete message; - return false; - } - return channel_->Send(message); -} - // static ChildProcessId ChildProcessHost::GenerateChildProcessUniqueId() { CHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/content/browser/child_process_host_impl.h b/content/browser/child_process_host_impl.h index 92b77397c..8ef9d089 100644 --- a/content/browser/child_process_host_impl.h +++ b/content/browser/child_process_host_impl.h
@@ -67,7 +67,6 @@ static uint64_t ChildProcessUniqueIdToTracingProcessId(int child_process_id); // ChildProcessHost implementation - bool Send(IPC::Message* message) override; void ForceShutdown() override; std::optional<mojo::OutgoingInvitation>& GetMojoInvitation() override; void CreateChannelMojo() override;
diff --git a/content/browser/fenced_frame/fenced_frame_browsertest.cc b/content/browser/fenced_frame/fenced_frame_browsertest.cc index 2df765e..18c29e8 100644 --- a/content/browser/fenced_frame/fenced_frame_browsertest.cc +++ b/content/browser/fenced_frame/fenced_frame_browsertest.cc
@@ -4276,10 +4276,10 @@ const peerConnection = new RTCPeerConnection(configuration); )"); - EXPECT_THAT( - result.error, - testing::HasSubstr("Failed to construct 'RTCPeerConnection': " - "RTCPeerConnection is not allowed in fenced frames.")); + EXPECT_THAT(result, + EvalJsResult::ErrorIs(testing::HasSubstr( + "Failed to construct 'RTCPeerConnection': " + "RTCPeerConnection is not allowed in fenced frames."))); } namespace { @@ -6207,11 +6207,11 @@ // Shared storage get is denied. EvalJsResult get_result = EvalJs(ff1, "sharedStorage.get('test');"); EXPECT_THAT( - get_result.error, - testing::HasSubstr( + get_result, + EvalJsResult::ErrorIs(testing::HasSubstr( "sharedStorage.get() is not allowed in a fenced frame until " "network access for it and all descendent frames has been " - "revoked with window.fence.disableUntrustedNetwork()")); + "revoked with window.fence.disableUntrustedNetwork()"))); })); // Embedder initiates nested fenced frame navigation. @@ -7421,9 +7421,8 @@ // When eventData exceeds the length limit, a security error is thrown // instead of a console error. EXPECT_FALSE(result.error.empty()); - EXPECT_THAT( - result.error, - testing::HasSubstr(GetErrorPattern(step.report_event_result))); + EXPECT_THAT(result, EvalJsResult::ErrorIs(testing::HasSubstr( + GetErrorPattern(step.report_event_result)))); continue; }
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index 054081f..4accb4a 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -1350,11 +1350,10 @@ } // Now attempt to read the large value again and expect an error. - EvalJsResult result = EvalJs(shell(), "readData()"); - EXPECT_THAT( - result.error, - testing::HasSubstr("NotReadableError: Data lost due to missing file. " - "Affected record should be considered irrecoverable")); + EXPECT_THAT(EvalJs(shell(), "readData()"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "NotReadableError: Data lost due to missing file. " + "Affected record should be considered irrecoverable"))); // Verify that the right set of histograms were recorded. content::FetchHistogramsFromChildProcesses();
diff --git a/content/browser/interest_group/auction_runner_unittest.cc b/content/browser/interest_group/auction_runner_unittest.cc index f819ab3..6e89ded 100644 --- a/content/browser/interest_group/auction_runner_unittest.cc +++ b/content/browser/interest_group/auction_runner_unittest.cc
@@ -120,6 +120,10 @@ #include "third_party/zlib/google/compression_utils.h" #include "url/origin.h" +#if BUILDFLAG(IS_MAC) +#include "base/mac/mac_util.h" +#endif + using auction_worklet::TestDevToolsAgentClient; using testing::HasSubstr; @@ -21914,6 +21918,14 @@ } TEST_F(AuctionRunnerTest, RecencyPassedReportWin) { +// TODO(crbug.com/433968045): This test fails on macOS 26 due to +// a test timeout. Re-enable once the timeout is fixed. +#if BUILDFLAG(IS_MAC) + if (base::mac::MacOSMajorVersion() == 26) { + GTEST_SKIP() << "Disabled on macOS Tahoe."; + } +#endif + // Due to noising, recency is only correctly passed 99% of the time. // // Since the noising pseudorandom number generator is uniform, in 30 runs, the
diff --git a/content/browser/network_service_client.cc b/content/browser/network_service_client.cc index 75ee30ce..05709c61 100644 --- a/content/browser/network_service_client.cc +++ b/content/browser/network_service_client.cc
@@ -300,15 +300,6 @@ auth_challenge_responder_remote->OnAuthCredentials(std::nullopt); } -void NetworkServiceClient::OnPrivateNetworkAccessPermissionRequired( - const GURL& url, - const net::IPAddress& ip_address, - const std::optional<std::string>& private_network_device_id, - const std::optional<std::string>& private_network_device_name, - OnPrivateNetworkAccessPermissionRequiredCallback callback) { - std::move(callback).Run(false); -} - void NetworkServiceClient::OnLocalNetworkAccessPermissionRequired( OnLocalNetworkAccessPermissionRequiredCallback callback) { std::move(callback).Run(false);
diff --git a/content/browser/network_service_client.h b/content/browser/network_service_client.h index cbfb159..ec3e34a1 100644 --- a/content/browser/network_service_client.h +++ b/content/browser/network_service_client.h
@@ -108,12 +108,6 @@ const scoped_refptr<net::HttpResponseHeaders>& head_headers, mojo::PendingRemote<network::mojom::AuthChallengeResponder> auth_challenge_responder) override; - void OnPrivateNetworkAccessPermissionRequired( - const GURL& url, - const net::IPAddress& ip_address, - const std::optional<std::string>& private_network_device_id, - const std::optional<std::string>& private_network_device_name, - OnPrivateNetworkAccessPermissionRequiredCallback callback) override; void OnLocalNetworkAccessPermissionRequired( OnLocalNetworkAccessPermissionRequiredCallback callback) override; void OnClearSiteData(
diff --git a/content/browser/security/coop/cross_origin_opener_policy_browsertest.cc b/content/browser/security/coop/cross_origin_opener_policy_browsertest.cc index 73d42d410..8aae644 100644 --- a/content/browser/security/coop/cross_origin_opener_policy_browsertest.cc +++ b/content/browser/security/coop/cross_origin_opener_policy_browsertest.cc
@@ -4523,8 +4523,9 @@ g_iframe.contentWindow.postMessage(sab,"*"); )"); - EXPECT_THAT(postSharedArrayBuffer.error, - HasSubstr("Failed to execute 'postMessage' on 'Window':")); + EXPECT_THAT(postSharedArrayBuffer, + EvalJsResult::ErrorIs( + HasSubstr("Failed to execute 'postMessage' on 'Window':"))); } // Transfer a SharedArrayBuffer in between two COOP+COEP document with a @@ -4813,8 +4814,9 @@ g_iframe.contentWindow.postMessage(sab,"*"); )"); - EXPECT_THAT(postSharedArrayBuffer.error, - HasSubstr("Failed to execute 'postMessage' on 'Window'")); + EXPECT_THAT(postSharedArrayBuffer, + EvalJsResult::ErrorIs( + HasSubstr("Failed to execute 'postMessage' on 'Window'"))); #endif // !BUILDFLAG(IS_ANDROID) }
diff --git a/content/browser/shared_storage/shared_storage_browsertest.cc b/content/browser/shared_storage/shared_storage_browsertest.cc index 88e67ab..e46197d 100644 --- a/content/browser/shared_storage/shared_storage_browsertest.cc +++ b/content/browser/shared_storage/shared_storage_browsertest.cc
@@ -480,11 +480,10 @@ .spec(), " HTTP status = 404 Not Found.\"\n"}); - EvalJsResult result = EvalJs(shell(), R"( + EXPECT_THAT(EvalJs(shell(), R"( sharedStorage.worklet.addModule('shared_storage/nonexistent_module.js'); - )"); - - EXPECT_EQ(expected_error, result.error); + )"), + EvalJsResult::ErrorIs(expected_error)); EXPECT_EQ(1u, test_runtime_manager().GetAttachedWorkletHostsCount()); EXPECT_EQ(0u, test_runtime_manager().GetKeepAliveWorkletHostsCount()); @@ -540,13 +539,11 @@ WebContentsConsoleObserver console_observer(shell()->web_contents()); - EvalJsResult result = EvalJs(shell(), R"( + EXPECT_THAT(EvalJs(shell(), R"( sharedStorage.worklet.addModule('shared_storage/erroneous_module.js'); - )"); - - EXPECT_THAT( - result.error, - testing::HasSubstr("ReferenceError: undefinedVariable is not defined")); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "ReferenceError: undefinedVariable is not defined"))); EXPECT_EQ(1u, test_runtime_manager().GetAttachedWorkletHostsCount()); EXPECT_EQ(0u, test_runtime_manager().GetKeepAliveWorkletHostsCount()); @@ -581,13 +578,11 @@ sharedStorage.worklet.addModule('shared_storage/simple_module.js'); )")); - EvalJsResult result = EvalJs(shell(), R"( + EXPECT_THAT(EvalJs(shell(), R"( sharedStorage.worklet.addModule('shared_storage/simple_module.js'); - )"); - - EXPECT_THAT( - result.error, - testing::HasSubstr("addModule() can only be invoked once per worklet")); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "addModule() can only be invoked once per worklet"))); EXPECT_EQ(1u, test_runtime_manager().GetAttachedWorkletHostsCount()); EXPECT_EQ(0u, test_runtime_manager().GetKeepAliveWorkletHostsCount()); @@ -768,16 +763,14 @@ WebContentsConsoleObserver console_observer(shell()->web_contents()); - EvalJsResult result = EvalJs(shell(), R"( + EXPECT_THAT( + EvalJs(shell(), R"( sharedStorage.run( 'test-operation', {data: {'customKey': 'customValue'}, keepAlive: true}); - )"); - - EXPECT_THAT( - result.error, - testing::HasSubstr( - "sharedStorage.worklet.addModule() has to be called before run()")); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "sharedStorage.worklet.addModule() has to be called before run()"))); EXPECT_TRUE(ExecJs(shell(), R"( sharedStorage.worklet.addModule('shared_storage/simple_module.js'); @@ -826,16 +819,14 @@ sharedStorage.worklet.addModule('shared_storage/simple_module.js'); )")); - EvalJsResult result = EvalJs(shell(), R"( + EXPECT_THAT(EvalJs(shell(), R"( function testFunction() {} sharedStorage.run( 'test-operation', {data: {'customKey': testFunction}}); - )"); - - EXPECT_THAT( - result.error, - testing::HasSubstr("function testFunction() {} could not be cloned")); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "function testFunction() {} could not be cloned"))); histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 0); @@ -1195,12 +1186,12 @@ EXPECT_EQ("Finish executing 'test-operation'", base::UTF16ToUTF8(console_observer.messages()[4].message)); - EvalJsResult result = EvalJs(shell(), R"( + EXPECT_THAT(EvalJs(shell(), R"( sharedStorage.run( 'test-operation', {data: {'customKey': 'customValue'}}); - )"); - EXPECT_THAT(result.error, - testing::HasSubstr(kSharedStorageWorkletExpiredMessage)); + )"), + EvalJsResult::ErrorIs( + testing::HasSubstr(kSharedStorageWorkletExpiredMessage))); WaitForHistograms({kTimingRunExecutedInWorkletHistogram}); histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1); @@ -1267,12 +1258,12 @@ EXPECT_EQ("Finish executing 'test-operation'", base::UTF16ToUTF8(console_observer.messages()[4].message)); - EvalJsResult result = EvalJs(shell(), R"( + EXPECT_THAT(EvalJs(shell(), R"( sharedStorage.run( 'test-operation', {data: {'customKey': 'customValue'}}); - )"); - EXPECT_THAT(result.error, - testing::HasSubstr(kSharedStorageWorkletExpiredMessage)); + )"), + EvalJsResult::ErrorIs( + testing::HasSubstr(kSharedStorageWorkletExpiredMessage))); WaitForHistograms({kTimingRunExecutedInWorkletHistogram}); histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1); @@ -2570,7 +2561,7 @@ TestSelectURLFencedFrameConfigObserver config_observer2( GetStoragePartition()); - EvalJsResult result2 = EvalJs(shell(), R"( + EXPECT_THAT(EvalJs(shell(), R"( (async function() { window.select_url_result = await sharedStorage.selectURL( 'test-url-selection-operation', @@ -2590,10 +2581,9 @@ } return window.select_url_result; })() - )"); - - EXPECT_THAT(result2.error, - testing::HasSubstr(kSharedStorageWorkletExpiredMessage)); + )"), + EvalJsResult::ErrorIs( + testing::HasSubstr(kSharedStorageWorkletExpiredMessage))); EXPECT_FALSE(config_observer2.ConfigObserved()); @@ -2697,10 +2687,9 @@ TestSelectURLFencedFrameConfigObserver config_observer2( GetStoragePartition()); - EvalJsResult result2 = EvalJs(shell(), select_url_script); - - EXPECT_THAT(result2.error, - testing::HasSubstr(kSharedStorageWorkletExpiredMessage)); + EXPECT_THAT(EvalJs(shell(), select_url_script), + EvalJsResult::ErrorIs( + testing::HasSubstr(kSharedStorageWorkletExpiredMessage))); EXPECT_FALSE(config_observer2.ConfigObserved()); @@ -2763,7 +2752,7 @@ TestSelectURLFencedFrameConfigObserver config_observer(GetStoragePartition()); - EvalJsResult result = EvalJs(shell(), R"( + EXPECT_THAT(EvalJs(shell(), R"( (async function() { window.select_url_result = await sharedStorage.selectURL( 'test-url-selection-operation', @@ -2783,10 +2772,9 @@ } return window.select_url_result; })() - )"); - - EXPECT_THAT(result.error, - testing::HasSubstr(kSharedStorageWorkletExpiredMessage)); + )"), + EvalJsResult::ErrorIs( + testing::HasSubstr(kSharedStorageWorkletExpiredMessage))); EXPECT_FALSE(config_observer.ConfigObserved()); @@ -2981,7 +2969,7 @@ TestSelectURLFencedFrameConfigObserver config_observer(GetStoragePartition()); - EvalJsResult result = EvalJs(shell(), R"( + EXPECT_THAT(EvalJs(shell(), R"( (async function() { window.select_url_result = await sharedStorage.selectURL( 'test-url-selection-operation', @@ -3001,10 +2989,9 @@ } return window.select_url_result; })() - )"); - - EXPECT_THAT(result.error, - testing::HasSubstr(kSharedStorageWorkletExpiredMessage)); + )"), + EvalJsResult::ErrorIs( + testing::HasSubstr(kSharedStorageWorkletExpiredMessage))); EXPECT_FALSE(config_observer.ConfigObserved()); @@ -3247,12 +3234,12 @@ EXPECT_EQ(0u, test_runtime_manager().GetAttachedWorkletHostsCount()); EXPECT_EQ(0u, test_runtime_manager().GetKeepAliveWorkletHostsCount()); - EvalJsResult result2 = EvalJs(shell(), R"( + EXPECT_THAT(EvalJs(shell(), R"( sharedStorage.run( 'test-operation', {data: {'customKey': 'customValue'}}); - )"); - EXPECT_THAT(result2.error, - testing::HasSubstr(kSharedStorageWorkletExpiredMessage)); + )"), + EvalJsResult::ErrorIs( + testing::HasSubstr(kSharedStorageWorkletExpiredMessage))); EXPECT_EQ(0u, test_runtime_manager().GetAttachedWorkletHostsCount()); EXPECT_EQ(0u, test_runtime_manager().GetKeepAliveWorkletHostsCount()); @@ -3362,12 +3349,12 @@ EXPECT_EQ(0u, test_runtime_manager().GetAttachedWorkletHostsCount()); EXPECT_EQ(0u, test_runtime_manager().GetKeepAliveWorkletHostsCount()); - EvalJsResult result2 = EvalJs(shell(), R"( + EXPECT_THAT(EvalJs(shell(), R"( sharedStorage.run( 'test-operation', {data: {'customKey': 'customValue'}}); - )"); - EXPECT_THAT(result2.error, - testing::HasSubstr(kSharedStorageWorkletExpiredMessage)); + )"), + EvalJsResult::ErrorIs( + testing::HasSubstr(kSharedStorageWorkletExpiredMessage))); EXPECT_EQ(0u, test_runtime_manager().GetAttachedWorkletHostsCount()); EXPECT_EQ(0u, test_runtime_manager().GetKeepAliveWorkletHostsCount()); @@ -4704,11 +4691,9 @@ kEmptyAccessControlAllowOriginReplacement, "Shared-Storage-Cross-Origin-Worklet-Allowed: ?1"))); - EvalJsResult result = EvalJs( - shell(), - JsReplace("sharedStorage.createWorklet($1)", module_script_url.spec())); - - EXPECT_THAT(result.error, testing::HasSubstr("Failed to load")); + EXPECT_THAT(EvalJs(shell(), JsReplace("sharedStorage.createWorklet($1)", + module_script_url.spec())), + EvalJsResult::ErrorIs(testing::HasSubstr("Failed to load"))); } IN_PROC_BROWSER_TEST_P( @@ -4724,13 +4709,13 @@ kEmptyAccessControlAllowOriginReplacement, "Shared-Storage-Cross-Origin-Worklet-Allowed: ?1"))); - EvalJsResult result = EvalJs( - shell(), - JsReplace( - "sharedStorage.createWorklet($1, {dataOrigin: 'context-origin'})", - module_script_url.spec())); - - EXPECT_THAT(result.error, testing::HasSubstr("Failed to load")); + EXPECT_THAT( + EvalJs( + shell(), + JsReplace( + "sharedStorage.createWorklet($1, {dataOrigin: 'context-origin'})", + module_script_url.spec())), + EvalJsResult::ErrorIs(testing::HasSubstr("Failed to load"))); } IN_PROC_BROWSER_TEST_P( @@ -4746,13 +4731,13 @@ kEmptyAccessControlAllowOriginReplacement, "Shared-Storage-Cross-Origin-Worklet-Allowed: ?1"))); - EvalJsResult result = EvalJs( - shell(), - JsReplace( - "sharedStorage.createWorklet($1, {dataOrigin: 'script-origin'})", - module_script_url.spec())); - - EXPECT_THAT(result.error, testing::HasSubstr("Failed to load")); + EXPECT_THAT( + EvalJs( + shell(), + JsReplace( + "sharedStorage.createWorklet($1, {dataOrigin: 'script-origin'})", + module_script_url.spec())), + EvalJsResult::ErrorIs(testing::HasSubstr("Failed to load"))); } IN_PROC_BROWSER_TEST_P( @@ -4771,12 +4756,12 @@ url::Origin custom_data_origin = url::Origin::Create(https_server()->GetURL("c.test", kSimplePagePath)); - EvalJsResult result = EvalJs( - shell(), - JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", - module_script_url.spec(), custom_data_origin.Serialize())); - - EXPECT_THAT(result.error, testing::HasSubstr("Failed to load")); + EXPECT_THAT( + EvalJs( + shell(), + JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", + module_script_url.spec(), custom_data_origin.Serialize())), + EvalJsResult::ErrorIs(testing::HasSubstr("Failed to load"))); } IN_PROC_BROWSER_TEST_P( @@ -4792,13 +4777,13 @@ "Access-Control-Allow-Origin: *", kEmptySharedStorageCrossOriginAllowedReplacement))); - EvalJsResult result = EvalJs( - shell(), - JsReplace( - "sharedStorage.createWorklet($1, {dataOrigin: 'script-origin'})", - module_script_url.spec())); - - EXPECT_THAT(result.error, testing::HasSubstr("Failed to load")); + EXPECT_THAT( + EvalJs( + shell(), + JsReplace( + "sharedStorage.createWorklet($1, {dataOrigin: 'script-origin'})", + module_script_url.spec())), + EvalJsResult::ErrorIs(testing::HasSubstr("Failed to load"))); } IN_PROC_BROWSER_TEST_P( @@ -5330,11 +5315,9 @@ kEmptyAccessControlAllowOriginReplacement, kEmptySharedStorageCrossOriginAllowedReplacement))); - EvalJsResult result = - EvalJs(shell(), JsReplace("sharedStorage.worklet.addModule($1)", - module_script_url.spec())); - - EXPECT_THAT(result.error, testing::HasSubstr("Failed to load")); + EXPECT_THAT(EvalJs(shell(), JsReplace("sharedStorage.worklet.addModule($1)", + module_script_url.spec())), + EvalJsResult::ErrorIs(testing::HasSubstr("Failed to load"))); } IN_PROC_BROWSER_TEST_P(SharedStorageBrowserTest, @@ -6662,13 +6645,12 @@ FrameTreeNode* iframe_node2 = CreateIFrame(PrimaryFrameTreeNodeRoot(), redirect_urls_.back()); - EvalJsResult result = EvalJs(iframe_node2, R"( + EXPECT_THAT(EvalJs(iframe_node2, R"( sharedStorage.worklet.addModule('/shared_storage/simple_module.js'); - )"); - - EXPECT_THAT(result.error, - testing::HasSubstr("The \"shared-storage\" Permissions Policy " - "denied the method")); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "The \"shared-storage\" Permissions Policy " + "denied the method"))); } IN_PROC_BROWSER_TEST_F( @@ -6774,14 +6756,13 @@ FrameTreeNode* iframe_node2 = CreateIFrame(PrimaryFrameTreeNodeRoot(), redirect_urls_.front()); - EvalJsResult result = EvalJs(iframe_node2, R"( - sharedStorage.worklet.addModule('/shared_storage/simple_module.js'); - )"); - // c.test does not have permission to use shared storage. - EXPECT_THAT(result.error, - testing::HasSubstr("The \"shared-storage\" Permissions Policy " - "denied the method")); + EXPECT_THAT(EvalJs(iframe_node2, R"( + sharedStorage.worklet.addModule('/shared_storage/simple_module.js'); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "The \"shared-storage\" Permissions Policy " + "denied the method"))); // Create an iframe that's same-origin to the second redirect URL. FrameTreeNode* iframe_node3 = @@ -6856,13 +6837,12 @@ FrameTreeNode* iframe_node1 = CreateIFrame(PrimaryFrameTreeNodeRoot(), subresource_or_subframe_url_); - EvalJsResult result = EvalJs(iframe_node1, R"( + EXPECT_THAT(EvalJs(iframe_node1, R"( sharedStorage.worklet.addModule('/shared_storage/simple_module.js'); - )"); - - EXPECT_THAT(result.error, - testing::HasSubstr("The \"shared-storage\" Permissions Policy " - "denied the method")); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "The \"shared-storage\" Permissions Policy " + "denied the method"))); // Create an iframe that's same-origin to the redirect URL. FrameTreeNode* iframe_node2 = @@ -7963,13 +7943,12 @@ FrameTreeNode* iframe_node2 = CreateIFrame(PrimaryFrameTreeNodeRoot(), redirect_urls_.back()); - EvalJsResult result = EvalJs(iframe_node2, R"( + EXPECT_THAT(EvalJs(iframe_node2, R"( sharedStorage.worklet.addModule('/shared_storage/simple_module.js'); - )"); - - EXPECT_THAT(result.error, - testing::HasSubstr("The \"shared-storage\" Permissions Policy " - "denied the method")); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "The \"shared-storage\" Permissions Policy " + "denied the method"))); } IN_PROC_BROWSER_TEST_F( @@ -8075,14 +8054,13 @@ FrameTreeNode* iframe_node2 = CreateIFrame(PrimaryFrameTreeNodeRoot(), redirect_urls_.front()); - EvalJsResult result = EvalJs(iframe_node2, R"( - sharedStorage.worklet.addModule('/shared_storage/simple_module.js'); - )"); - // c.test does not have permission to use shared storage. - EXPECT_THAT(result.error, - testing::HasSubstr("The \"shared-storage\" Permissions Policy " - "denied the method")); + EXPECT_THAT(EvalJs(iframe_node2, R"( + sharedStorage.worklet.addModule('/shared_storage/simple_module.js'); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "The \"shared-storage\" Permissions Policy " + "denied the method"))); // Create an iframe that's same-origin to the second redirect URL. FrameTreeNode* iframe_node3 = @@ -8157,13 +8135,12 @@ FrameTreeNode* iframe_node1 = CreateIFrame(PrimaryFrameTreeNodeRoot(), subresource_or_subframe_url_); - EvalJsResult result = EvalJs(iframe_node1, R"( + EXPECT_THAT(EvalJs(iframe_node1, R"( sharedStorage.worklet.addModule('/shared_storage/simple_module.js'); - )"); - - EXPECT_THAT(result.error, - testing::HasSubstr("The \"shared-storage\" Permissions Policy " - "denied the method")); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "The \"shared-storage\" Permissions Policy " + "denied the method"))); // Create an iframe that's same-origin to the redirect URL. FrameTreeNode* iframe_node2 = @@ -8932,13 +8909,12 @@ FrameTreeNode* iframe_node2 = CreateIFrame(PrimaryFrameTreeNodeRoot(), redirect_urls_.back()); - EvalJsResult result = EvalJs(iframe_node2, R"( + EXPECT_THAT(EvalJs(iframe_node2, R"( sharedStorage.worklet.addModule('/shared_storage/simple_module.js'); - )"); - - EXPECT_THAT(result.error, - testing::HasSubstr("The \"shared-storage\" Permissions Policy " - "denied the method")); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "The \"shared-storage\" Permissions Policy " + "denied the method"))); } IN_PROC_BROWSER_TEST_F( @@ -9044,14 +9020,13 @@ FrameTreeNode* iframe_node3 = CreateIFrame(PrimaryFrameTreeNodeRoot(), redirect_urls_.front()); - EvalJsResult result = EvalJs(iframe_node3, R"( - sharedStorage.worklet.addModule('/shared_storage/simple_module.js'); - )"); - // c.test does not have permission to use shared storage. - EXPECT_THAT(result.error, - testing::HasSubstr("The \"shared-storage\" Permissions Policy " - "denied the method")); + EXPECT_THAT(EvalJs(iframe_node3, R"( + sharedStorage.worklet.addModule('/shared_storage/simple_module.js'); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "The \"shared-storage\" Permissions Policy " + "denied the method"))); // Create an iframe that's same-origin to the second redirect URL. FrameTreeNode* iframe_node4 = @@ -9126,13 +9101,12 @@ FrameTreeNode* iframe_node2 = CreateIFrame(PrimaryFrameTreeNodeRoot(), subresource_or_subframe_url_); - EvalJsResult result = EvalJs(iframe_node2, R"( + EXPECT_THAT(EvalJs(iframe_node2, R"( sharedStorage.worklet.addModule('/shared_storage/simple_module.js'); - )"); - - EXPECT_THAT(result.error, - testing::HasSubstr("The \"shared-storage\" Permissions Policy " - "denied the method")); + )"), + EvalJsResult::ErrorIs(testing::HasSubstr( + "The \"shared-storage\" Permissions Policy " + "denied the method"))); // Create an iframe that's same-origin to the redirect URL. FrameTreeNode* iframe_node3 = @@ -9340,15 +9314,13 @@ url::Origin custom_data_origin = url::Origin::Create(https_server()->GetURL("c.test", kSimplePagePath)); - EvalJsResult result = EvalJs( - shell(), - JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", - module_script_url.spec(), custom_data_origin.Serialize())); - EXPECT_THAT( - result.error, - testing::HasSubstr( - "no response, an invalid response, or an unexpected mime type")); + EvalJs( + shell(), + JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", + module_script_url.spec(), custom_data_origin.Serialize())), + EvalJsResult::ErrorIs(testing::HasSubstr( + "no response, an invalid response, or an unexpected mime type"))); } IN_PROC_BROWSER_TEST_P(SharedStorageCreateWorkletCustomDataOriginBrowserTest, @@ -9363,15 +9335,13 @@ url::Origin custom_data_origin = url::Origin::Create(https_server()->GetURL("c.test", kSimplePagePath)); - EvalJsResult result = EvalJs( - shell(), - JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", - module_script_url.spec(), custom_data_origin.Serialize())); - EXPECT_THAT( - result.error, - testing::HasSubstr( - "because there was no parse result or the result was not a list")); + EvalJs( + shell(), + JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", + module_script_url.spec(), custom_data_origin.Serialize())), + EvalJsResult::ErrorIs(testing::HasSubstr( + "because there was no parse result or the result was not a list"))); } IN_PROC_BROWSER_TEST_P(SharedStorageCreateWorkletCustomDataOriginBrowserTest, @@ -9386,12 +9356,12 @@ url::Origin custom_data_origin = url::Origin::Create(https_server()->GetURL("c.test", kSimplePagePath)); - EvalJsResult result = EvalJs( - shell(), - JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", - module_script_url.spec(), custom_data_origin.Serialize())); - - EXPECT_THAT(result.error, testing::HasSubstr("is an empty list")); + EXPECT_THAT( + EvalJs( + shell(), + JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", + module_script_url.spec(), custom_data_origin.Serialize())), + EvalJsResult::ErrorIs(testing::HasSubstr("is an empty list"))); } IN_PROC_BROWSER_TEST_P(SharedStorageCreateWorkletCustomDataOriginBrowserTest, @@ -9406,13 +9376,13 @@ url::Origin custom_data_origin = url::Origin::Create(https_server()->GetURL("c.test", kSimplePagePath)); - EvalJsResult result = EvalJs( - shell(), - JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", - module_script_url.spec(), custom_data_origin.Serialize())); - - EXPECT_THAT(result.error, - testing::HasSubstr("non-dictionary item was encountered")); + EXPECT_THAT( + EvalJs( + shell(), + JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", + module_script_url.spec(), custom_data_origin.Serialize())), + EvalJsResult::ErrorIs( + testing::HasSubstr("non-dictionary item was encountered"))); } IN_PROC_BROWSER_TEST_P(SharedStorageCreateWorkletCustomDataOriginBrowserTest, @@ -9427,14 +9397,13 @@ url::Origin custom_data_origin = url::Origin::Create(https_server()->GetURL("c.test", kSimplePagePath)); - EvalJsResult result = EvalJs( - shell(), - JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", - module_script_url.spec(), custom_data_origin.Serialize())); - EXPECT_THAT( - result.error, - testing::HasSubstr("dictionary item's `scriptOrigin` key was not found")); + EvalJs( + shell(), + JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", + module_script_url.spec(), custom_data_origin.Serialize())), + EvalJsResult::ErrorIs(testing::HasSubstr( + "dictionary item's `scriptOrigin` key was not found"))); } IN_PROC_BROWSER_TEST_P(SharedStorageCreateWorkletCustomDataOriginBrowserTest, @@ -9449,15 +9418,13 @@ url::Origin custom_data_origin = url::Origin::Create(https_server()->GetURL("c.test", kSimplePagePath)); - EvalJsResult result = EvalJs( - shell(), - JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", - module_script_url.spec(), custom_data_origin.Serialize())); - EXPECT_THAT( - result.error, - testing::HasSubstr( - "`scriptOrigin` key was not found, or its value was an empty list")); + EvalJs( + shell(), + JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", + module_script_url.spec(), custom_data_origin.Serialize())), + EvalJsResult::ErrorIs(testing::HasSubstr( + "`scriptOrigin` key was not found, or its value was an empty list"))); } IN_PROC_BROWSER_TEST_P(SharedStorageCreateWorkletCustomDataOriginBrowserTest, @@ -9472,14 +9439,13 @@ url::Origin custom_data_origin = url::Origin::Create(https_server()->GetURL("c.test", kSimplePagePath)); - EvalJsResult result = EvalJs( - shell(), - JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", - module_script_url.spec(), custom_data_origin.Serialize())); - - EXPECT_THAT(result.error, - testing::HasSubstr( - "dictionary item's `contextOrigin` key was not found")); + EXPECT_THAT( + EvalJs( + shell(), + JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", + module_script_url.spec(), custom_data_origin.Serialize())), + EvalJsResult::ErrorIs(testing::HasSubstr( + "dictionary item's `contextOrigin` key was not found"))); } IN_PROC_BROWSER_TEST_P(SharedStorageCreateWorkletCustomDataOriginBrowserTest, @@ -9494,15 +9460,14 @@ url::Origin custom_data_origin = url::Origin::Create(https_server()->GetURL("c.test", kSimplePagePath)); - EvalJsResult result = EvalJs( - shell(), - JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", - module_script_url.spec(), custom_data_origin.Serialize())); - EXPECT_THAT( - result.error, - testing::HasSubstr( - "`contextOrigin` key was not found, or its value was an empty list")); + EvalJs( + shell(), + JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", + module_script_url.spec(), custom_data_origin.Serialize())), + EvalJsResult::ErrorIs(testing::HasSubstr( + "`contextOrigin` key was not found, or its value was " + "an empty list"))); } IN_PROC_BROWSER_TEST_P(SharedStorageCreateWorkletCustomDataOriginBrowserTest, @@ -9517,12 +9482,12 @@ url::Origin custom_data_origin = url::Origin::Create(https_server()->GetURL("c.test", kSimplePagePath)); - EvalJsResult result = EvalJs( - shell(), - JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", - module_script_url.spec(), custom_data_origin.Serialize())); - - EXPECT_THAT(result.error, testing::HasSubstr("has not been allowed")); + EXPECT_THAT( + EvalJs( + shell(), + JsReplace("sharedStorage.createWorklet($1, {dataOrigin: $2})", + module_script_url.spec(), custom_data_origin.Serialize())), + EvalJsResult::ErrorIs(testing::HasSubstr("has not been allowed"))); } IN_PROC_BROWSER_TEST_P(SharedStorageCreateWorkletCustomDataOriginBrowserTest,
diff --git a/content/browser/shared_storage/shared_storage_fenced_frame_browsertest.cc b/content/browser/shared_storage/shared_storage_fenced_frame_browsertest.cc index 6588e92..3360071 100644 --- a/content/browser/shared_storage/shared_storage_fenced_frame_browsertest.cc +++ b/content/browser/shared_storage/shared_storage_fenced_frame_browsertest.cc
@@ -1144,9 +1144,9 @@ )"); EXPECT_THAT( - result.error, - testing::HasSubstr( - "The \"shared-storage\" Permissions Policy denied the method")); + result, + EvalJsResult::ErrorIs(testing::HasSubstr( + "The \"shared-storage\" Permissions Policy denied the method"))); } IN_PROC_BROWSER_TEST_F(SharedStorageFencedFrameInteractionBrowserTest, @@ -1194,10 +1194,10 @@ ); )"); - EXPECT_THAT(result.error, - testing::HasSubstr( + EXPECT_THAT(result, + EvalJsResult::ErrorIs(testing::HasSubstr( "selectURL() is called in a context with a fenced frame " - "depth (2) exceeding the maximum allowed number (1).")); + "depth (2) exceeding the maximum allowed number (1)."))); } IN_PROC_BROWSER_TEST_F(SharedStorageFencedFrameInteractionBrowserTest, @@ -1683,10 +1683,10 @@ sharedStorage.get('test'); )"); - EXPECT_THAT( - get_result.error, - testing::HasSubstr("Cannot call get() in a fenced frame with feature " - "FencedFramesLocalUnpartitionedDataAccess disabled.")); + EXPECT_THAT(get_result, + EvalJsResult::ErrorIs(testing::HasSubstr( + "Cannot call get() in a fenced frame with feature " + "FencedFramesLocalUnpartitionedDataAccess disabled."))); // Check that a histogram was logged for the failed get() operation. content::FetchHistogramsFromChildProcesses(); @@ -1765,11 +1765,11 @@ )"); EXPECT_THAT( - get_result.error, - testing::HasSubstr( + get_result, + EvalJsResult::ErrorIs(testing::HasSubstr( "sharedStorage.get() is not allowed in a fenced frame until network " "access for it and all descendent frames has been revoked with " - "window.fence.disableUntrustedNetwork()")); + "window.fence.disableUntrustedNetwork()"))); // Check that a histogram was logged for the get() result. content::FetchHistogramsFromChildProcesses(); @@ -1824,9 +1824,9 @@ sharedStorage.get('test'); )"); - EXPECT_THAT( - get_result_main_frame.error, - testing::HasSubstr("Cannot call get() outside of a fenced frame.")); + EXPECT_THAT(get_result_main_frame, + EvalJsResult::ErrorIs(testing::HasSubstr( + "Cannot call get() outside of a fenced frame."))); // The "Blink.FencedFrame.SharedStorageGetInFencedFrameOutcome" histogram // should not log since get() was not called from within a fenced frame. @@ -1851,9 +1851,9 @@ sharedStorage.get('test'); )"); - EXPECT_THAT( - get_result_iframe.error, - testing::HasSubstr("Cannot call get() outside of a fenced frame.")); + EXPECT_THAT(get_result_iframe, + EvalJsResult::ErrorIs(testing::HasSubstr( + "Cannot call get() outside of a fenced frame."))); // The "Blink.FencedFrame.SharedStorageGetInFencedFrameOutcome" histogram // should not log since get() was not called from within a fenced frame. @@ -1909,8 +1909,8 @@ sharedStorage.get('test'); )"); - EXPECT_THAT(get_result.error, - testing::HasSubstr("is not allowed in an opaque origin context")); + EXPECT_THAT(get_result, EvalJsResult::ErrorIs(testing::HasSubstr( + "is not allowed in an opaque origin context"))); // The "Blink.FencedFrame.SharedStorageGetInFencedFrameOutcome" histogram // should not log since opaque origins are treated as being outside of a @@ -1957,11 +1957,11 @@ )"); EXPECT_THAT( - get_result.error, - testing::HasSubstr( + get_result, + EvalJsResult::ErrorIs(testing::HasSubstr( "sharedStorage.get() is not allowed in a fenced frame until network " "access for it and all descendent frames has been revoked with " - "window.fence.disableUntrustedNetwork()")); + "window.fence.disableUntrustedNetwork()"))); // Check that a histogram was logged for the get() result. content::FetchHistogramsFromChildProcesses(); @@ -2027,10 +2027,10 @@ ); )"); - EXPECT_THAT(result.error, - testing::HasSubstr( + EXPECT_THAT(result, + EvalJsResult::ErrorIs(testing::HasSubstr( "selectURL() is called in a context with a fenced frame " - "depth (1) exceeding the maximum allowed number (0).")); + "depth (1) exceeding the maximum allowed number (0)."))); } class SharedStorageReportEventBrowserTest
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 86920cc9..e8e0b0be 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -121,7 +121,6 @@ #include "content/public/browser/permission_descriptor_util.h" #include "content/public/browser/permission_result.h" #include "content/public/browser/private_aggregation_data_model.h" -#include "content/public/browser/private_network_device_delegate.h" #include "content/public/browser/runtime_feature_state/runtime_feature_state_document_data.h" #include "content/public/browser/service_process_host.h" #include "content/public/browser/session_storage_usage_info.h" @@ -164,7 +163,6 @@ #include "third_party/blink/public/common/permissions/permission_utils.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-shared.h" -#include "third_party/blink/public/mojom/private_network_device/private_network_device.mojom.h" #include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h" #include "url/scheme_host_port.h" @@ -2161,50 +2159,6 @@ first_auth_attempt, frame_tree_node_id); // deletes self } -void StoragePartitionImpl::OnPrivateNetworkAccessPermissionRequired( - const GURL& url, - const net::IPAddress& ip_address, - const std::optional<std::string>& private_network_device_id, - const std::optional<std::string>& private_network_device_name, - OnPrivateNetworkAccessPermissionRequiredCallback callback) { - if (!base::FeatureList::IsEnabled( - network::features::kPrivateNetworkAccessPermissionPrompt)) { - std::move(callback).Run(false); - return; - } - - if (url_loader_network_observers_.empty()) { - std::move(callback).Run(false); - return; - } - const URLLoaderNetworkContext& context = - url_loader_network_observers_.current_context(); - - if (context.type() != ContextType::kRenderFrameHostContext || - !context.navigation_or_document()) { - std::move(callback).Run(false); - return; - } - RenderFrameHost* render_frame_host = - context.navigation_or_document()->GetDocument(); - if (!render_frame_host) { - std::move(callback).Run(false); - return; - } - auto device = blink::mojom::PrivateNetworkDevice::New( - private_network_device_id, private_network_device_name, ip_address); - - PrivateNetworkDeviceDelegate* delegate = - GetContentClient()->browser()->GetPrivateNetworkDeviceDelegate(); - if (!delegate) { - std::move(callback).Run(false); - return; - } - - delegate->RequestPermission(*render_frame_host, std::move(device), - std::move(callback)); -} - void StoragePartitionImpl::OnLocalNetworkAccessPermissionRequired( OnLocalNetworkAccessPermissionRequiredCallback callback) { if (!base::FeatureList::IsEnabled(
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h index 94b1629..190a9a22 100644 --- a/content/browser/storage_partition_impl.h +++ b/content/browser/storage_partition_impl.h
@@ -372,12 +372,6 @@ const scoped_refptr<net::HttpResponseHeaders>& head_headers, mojo::PendingRemote<network::mojom::AuthChallengeResponder> auth_challenge_responder) override; - void OnPrivateNetworkAccessPermissionRequired( - const GURL& url, - const net::IPAddress& ip_address, - const std::optional<std::string>& private_network_device_id, - const std::optional<std::string>& private_network_device_name, - OnPrivateNetworkAccessPermissionRequiredCallback callback) override; void OnLocalNetworkAccessPermissionRequired( OnLocalNetworkAccessPermissionRequiredCallback callback) override; void OnClearSiteData(
diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc index 88973d07..11afe0e6 100644 --- a/content/browser/storage_partition_impl_unittest.cc +++ b/content/browser/storage_partition_impl_unittest.cc
@@ -2573,25 +2573,6 @@ EXPECT_FALSE(SharedStorageExistsForOrigin(kOrigin3)); } -TEST_F(StoragePartitionImplTest, PrivateNetworkAccessPermission) { - base::test::ScopedFeatureList features; - features.InitAndEnableFeature( - network::features::kPrivateNetworkAccessPermissionPrompt); - - StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( - browser_context()->GetDefaultStoragePartition()); - - mojo::Remote<network::mojom::URLLoaderNetworkServiceObserver> observer( - partition->CreateURLLoaderNetworkObserverForServiceWorker( - network::mojom::kBrowserProcessId, url::Origin())); - - base::test::TestFuture<bool> grant_permission; - observer->OnPrivateNetworkAccessPermissionRequired( - GURL(), net::IPAddress(192, 163, 1, 1), "test-id", "test-name", - base::BindOnce(grant_permission.GetCallback())); - EXPECT_FALSE(grant_permission.Get()); -} - // Local network access tests require there to be a (minimal) frame setup. using StoragePartitionImplLocalNetworkAccessTest = RenderViewHostTestHarness;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 6e468ab..a36a8a4 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -6860,6 +6860,10 @@ } void WebContentsImpl::SystemDragEnded(RenderWidgetHost* source_rwh) { + if (delegate_) { + delegate_->HandleDragEnded(); + } + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SystemDragEnded", "render_widget_host", source_rwh); if (source_rwh) {
diff --git a/content/browser/webui/web_ui_browsertest.cc b/content/browser/webui/web_ui_browsertest.cc index 5126e3f..843e9f1 100644 --- a/content/browser/webui/web_ui_browsertest.cc +++ b/content/browser/webui/web_ui_browsertest.cc
@@ -1123,7 +1123,8 @@ std::string expected_failure = "a JavaScript error: \"SecurityError: Failed to construct 'SharedWorker'"; - EXPECT_THAT(result.error, ::testing::StartsWith(expected_failure)); + EXPECT_THAT(result, + EvalJsResult::ErrorIs(::testing::StartsWith(expected_failure))); } // Test that we can start a Shared Worker from a chrome-untrusted:// iframe. @@ -1200,7 +1201,8 @@ "'SharedWorker': " "Script at 'chrome-untrusted://untrusted/web_ui_shared_worker.js' cannot " "be accessed from origin 'chrome://trusted'"; - EXPECT_THAT(result.error, ::testing::StartsWith(expected_failure)); + EXPECT_THAT(result, + EvalJsResult::ErrorIs(::testing::StartsWith(expected_failure))); } // Verify that pages with scheme other than "chrome-untrusted://" cannot create @@ -1219,7 +1221,8 @@ "'SharedWorker': " "Script at 'chrome-untrusted://untrusted/web_ui_shared_worker.js' cannot " "be accessed from origin 'http://localhost"; - EXPECT_THAT(result.error, ::testing::StartsWith(expected_failure)); + EXPECT_THAT(result, + EvalJsResult::ErrorIs(::testing::StartsWith(expected_failure))); } // Verify that pages with scheme "chrome-untrusted://" cannot create a @@ -1237,7 +1240,8 @@ "'SharedWorker': Script " "at 'chrome://trusted/web_ui_shared_worker.js' cannot be accessed from " "origin 'chrome-untrusted://untrusted'."; - EXPECT_THAT(result.error, ::testing::StartsWith(expected_failure)); + EXPECT_THAT(result, + EvalJsResult::ErrorIs(::testing::StartsWith(expected_failure))); } #endif // !BUILDFLAG(IS_ANDROID) @@ -1265,7 +1269,8 @@ std::string expected_failure = "a JavaScript error: \"SecurityError: Failed to construct 'Worker'"; - EXPECT_THAT(result.error, ::testing::StartsWith(expected_failure)); + EXPECT_THAT(result, + EvalJsResult::ErrorIs(::testing::StartsWith(expected_failure))); } // Test that we can start a Worker from a chrome-untrusted:// iframe. @@ -1339,7 +1344,8 @@ "a JavaScript error: \"SecurityError: Failed to construct 'Worker': " "Script at 'chrome-untrusted://untrusted/web_ui_dedicated_worker.js' " "cannot be accessed from origin 'chrome://trusted'"; - EXPECT_THAT(result.error, ::testing::StartsWith(expected_failure)); + EXPECT_THAT(result, + EvalJsResult::ErrorIs(::testing::StartsWith(expected_failure))); } // Verify that pages with scheme other than "chrome-untrusted://" cannot create @@ -1357,7 +1363,8 @@ "a JavaScript error: \"SecurityError: Failed to construct 'Worker': " "Script at 'chrome-untrusted://untrusted/web_ui_dedicated_worker.js' " "cannot be accessed from origin 'http://localhost"; - EXPECT_THAT(result.error, ::testing::StartsWith(expected_failure)); + EXPECT_THAT(result, + EvalJsResult::ErrorIs(::testing::StartsWith(expected_failure))); } // Verify that pages with scheme "chrome-untrusted://" cannot create a Worker @@ -1377,7 +1384,8 @@ "Script " "at 'chrome://trusted/web_ui_dedicated_worker.js' cannot be accessed " "from origin 'chrome-untrusted://untrusted'."; - EXPECT_THAT(result.error, ::testing::StartsWith(expected_failure)); + EXPECT_THAT(result, + EvalJsResult::ErrorIs(::testing::StartsWith(expected_failure))); } } // namespace content
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 4b382218..75c7ddb 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -403,9 +403,6 @@ raw_ref(features::kTrustedTypesFromLiteral)}, {"MediaStreamTrackTransfer", raw_ref(features::kMediaStreamTrackTransfer)}, - {"PrivateNetworkAccessPermissionPrompt", - raw_ref(network::features::kPrivateNetworkAccessPermissionPrompt), - kSetOnlyIfOverridden}, {"ExperimentalMachineLearningNeuralNetwork", raw_ref(webnn::mojom::features:: kExperimentalWebMachineLearningNeuralNetwork),
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index 75342ae7..672d1e3 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -347,7 +347,6 @@ "privacy_sandbox_invoking_api.h", "private_aggregation_data_model.cc", "private_aggregation_data_model.h", - "private_network_device_delegate.h", "process_allocation_context.cc", "process_allocation_context.h", "process_visibility_util.h",
diff --git a/content/public/browser/child_process_host.h b/content/public/browser/child_process_host.h index 4840239..e4bebcd 100644 --- a/content/public/browser/child_process_host.h +++ b/content/public/browser/child_process_host.h
@@ -43,9 +43,9 @@ // the launched child process, with the other end held by the ChildProcessHost // (the primordial pipe is a content.mojom.ChildProcess pipe). // -class CONTENT_EXPORT ChildProcessHost : public IPC::Sender { +class CONTENT_EXPORT ChildProcessHost { public: - ~ChildProcessHost() override; + virtual ~ChildProcessHost(); // This is a value never returned as the unique id of any child processes of // any kind, including the values returned by
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index cc734c00..5fb9980 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -43,7 +43,6 @@ #include "content/public/browser/page_navigator.h" #include "content/public/browser/prefetch_service_delegate.h" #include "content/public/browser/prerender_web_contents_delegate.h" -#include "content/public/browser/private_network_device_delegate.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/responsiveness_calculator_delegate.h" #include "content/public/browser/sms_fetcher.h" @@ -1268,11 +1267,6 @@ return nullptr; } -PrivateNetworkDeviceDelegate* -ContentBrowserClient::GetPrivateNetworkDeviceDelegate() { - return nullptr; -} - FontAccessDelegate* ContentBrowserClient::GetFontAccessDelegate() { return nullptr; }
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index a6faa64..7e95357 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -254,7 +254,6 @@ class PrefetchServiceDelegate; class PrerenderWebContentsDelegate; class PresentationObserver; -class PrivateNetworkDeviceDelegate; class ReceiverPresentationServiceDelegate; class RenderFrameHost; class RenderProcessHost; @@ -2360,10 +2359,6 @@ // Allows the embedder to provide an implementation of the WebUSB API. virtual UsbDelegate* GetUsbDelegate(); - // Allows the embedder to provide an implementation of the Private Network - // Device API. - virtual PrivateNetworkDeviceDelegate* GetPrivateNetworkDeviceDelegate(); - // Allows the embedder to provide an implementation of the Local Font Access // API. virtual FontAccessDelegate* GetFontAccessDelegate();
diff --git a/content/public/browser/private_network_device_delegate.h b/content/public/browser/private_network_device_delegate.h deleted file mode 100644 index 44e0227..0000000 --- a/content/public/browser/private_network_device_delegate.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_PUBLIC_BROWSER_PRIVATE_NETWORK_DEVICE_DELEGATE_H_ -#define CONTENT_PUBLIC_BROWSER_PRIVATE_NETWORK_DEVICE_DELEGATE_H_ - -#include "base/functional/callback.h" -#include "content/common/content_export.h" -#include "third_party/blink/public/mojom/private_network_device/private_network_device.mojom.h" - -namespace content { - -class RenderFrameHost; - -// Interface provided by the content embedder to support the private network -// access user permission. -class CONTENT_EXPORT PrivateNetworkDeviceDelegate { - public: - virtual ~PrivateNetworkDeviceDelegate() = default; - - // Request permission for the Private Network Device. - // |callback| accepts a bool specifying whether the user granted permission. - // - // TODO(crbug.com/40272624): Check if there's permission in the storage - // already. If not, show the chooser. - virtual void RequestPermission(RenderFrameHost& frame, - blink::mojom::PrivateNetworkDevicePtr device, - base::OnceCallback<void(bool)> callback) = 0; -}; - -} // namespace content - -#endif // CONTENT_PUBLIC_BROWSER_PRIVATE_NETWORK_DEVICE_DELEGATE_H_
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index 4c687a84..a4b8c5f 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h
@@ -314,6 +314,7 @@ virtual void PreHandleDragUpdate(const DropData& drop_data, const gfx::PointF& client_pt) {} virtual void PreHandleDragExit() {} + virtual void HandleDragEnded() {} // Allows delegates to handle keyboard events before sending to the renderer. // See enum for description of return values.
diff --git a/content/public/browser/web_contents_view_delegate.cc b/content/public/browser/web_contents_view_delegate.cc index 04b00d1..226e0cb0 100644 --- a/content/public/browser/web_contents_view_delegate.cc +++ b/content/public/browser/web_contents_view_delegate.cc
@@ -65,4 +65,6 @@ return std::move(callback).Run(drop_data); } +void WebContentsViewDelegate::WebContentsDragEnded() {} + } // namespace content
diff --git a/content/public/browser/web_contents_view_delegate.h b/content/public/browser/web_contents_view_delegate.h index a3292f6..6882ab9 100644 --- a/content/public/browser/web_contents_view_delegate.h +++ b/content/public/browser/web_contents_view_delegate.h
@@ -100,6 +100,9 @@ // callback once done. virtual void OnPerformingDrop(const DropData& drop_data, DropCompletionCallback callback); + + // Notifies the delegate that the drag operation has ended. + virtual void WebContentsDragEnded(); }; } // namespace content
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index fa643bd..778e24e2 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -597,6 +597,12 @@ "LazyInitializeMediaControls", base::FEATURE_ENABLED_BY_DEFAULT); +// If this is enabled, LoadingPredictor restricts the number of preconnects for +// the same destination to one. +BASE_FEATURE(kLoadingPredictorLimitPreconnectSocketCount, + "LoadingPredictorLimitPreconnectSocketCount", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kLogJsConsoleMessages, "LogJsConsoleMessages", #if BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_DESKTOP_ANDROID) @@ -1102,7 +1108,7 @@ // SiteInstance. BASE_FEATURE(kDefaultSiteInstanceGroups, "DefaultSiteInstanceGroups", - base::FEATURE_ENABLED_BY_DEFAULT); + base::FEATURE_DISABLED_BY_DEFAULT); // Controls whether to isolate sites of documents that specify an eligible // Cross-Origin-Opener-Policy header. Note that this is only intended to be
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 14cc0de..2fa3503 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -145,6 +145,8 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kIsolateOrigins); CONTENT_EXPORT extern const char kIsolateOriginsFieldTrialParamName[]; CONTENT_EXPORT BASE_DECLARE_FEATURE(kLazyInitializeMediaControls); +CONTENT_EXPORT BASE_DECLARE_FEATURE( + kLoadingPredictorLimitPreconnectSocketCount); CONTENT_EXPORT BASE_DECLARE_FEATURE(kLogJsConsoleMessages); CONTENT_EXPORT BASE_DECLARE_FEATURE(kLowerPAMemoryLimitForNonMainRenderers); CONTENT_EXPORT BASE_DECLARE_FEATURE(kMBIMode);
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 58624de..87b1b6e 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -864,6 +864,10 @@ return testing::AllOf(IsOk(), testing::Field(&EvalJsResult::value_, m)); } static auto IsError() { return testing::Not(IsOk()); } + template <typename M> + static auto ErrorIs(M m) { + return testing::AllOf(IsError(), testing::Field(&EvalJsResult::error, m)); + } // Extract a result value of the requested type, or die trying. //
diff --git a/content/renderer/render_thread_impl_browsertest.cc b/content/renderer/render_thread_impl_browsertest.cc index dae0319..cd0fa6f 100644 --- a/content/renderer/render_thread_impl_browsertest.cc +++ b/content/renderer/render_thread_impl_browsertest.cc
@@ -198,8 +198,6 @@ const base::Process& GetProcess() override { return null_process_; } protected: - IPC::Sender* sender() { return process_host_.get(); } - void SetBackgroundState(base::Process::Priority process_priority) { mojom::Renderer* renderer_interface = thread_; const mojom::RenderProcessVisibleState visible_state =
diff --git a/crypto/BUILD.gn b/crypto/BUILD.gn index 11aed54..fc0fec6 100644 --- a/crypto/BUILD.gn +++ b/crypto/BUILD.gn
@@ -25,8 +25,6 @@ "aes_ctr.cc", "aes_ctr.h", "crypto_export.h", - "ec_private_key.cc", - "ec_private_key.h", "evp.cc", "evp.h", "features.cc", @@ -177,7 +175,6 @@ "aead_unittest.cc", "aes_cbc_unittest.cc", "aes_ctr_unittest.cc", - "ec_private_key_unittest.cc", "evp_unittest.cc", "hash_unittest.cc", "hmac_unittest.cc",
diff --git a/crypto/ec_private_key.cc b/crypto/ec_private_key.cc deleted file mode 100644 index d43b8ea7..0000000 --- a/crypto/ec_private_key.cc +++ /dev/null
@@ -1,119 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - -#include "crypto/ec_private_key.h" - -#include <stddef.h> -#include <stdint.h> - -#include <array> -#include <utility> - -#include "base/check_op.h" -#include "crypto/openssl_util.h" -#include "third_party/boringssl/src/include/openssl/bytestring.h" -#include "third_party/boringssl/src/include/openssl/ec.h" -#include "third_party/boringssl/src/include/openssl/ec_key.h" -#include "third_party/boringssl/src/include/openssl/evp.h" -#include "third_party/boringssl/src/include/openssl/mem.h" -#include "third_party/boringssl/src/include/openssl/pkcs8.h" - -namespace crypto { - -ECPrivateKey::~ECPrivateKey() = default; - -// static -std::unique_ptr<ECPrivateKey> ECPrivateKey::Create() { - OpenSSLErrStackTracer err_tracer(FROM_HERE); - - bssl::UniquePtr<EC_KEY> ec_key( - EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); - if (!ec_key || !EC_KEY_generate_key(ec_key.get())) - return nullptr; - - std::unique_ptr<ECPrivateKey> result(new ECPrivateKey()); - result->key_.reset(EVP_PKEY_new()); - if (!result->key_ || !EVP_PKEY_set1_EC_KEY(result->key_.get(), ec_key.get())) - return nullptr; - - CHECK_EQ(EVP_PKEY_EC, EVP_PKEY_id(result->key_.get())); - return result; -} - -// static -std::unique_ptr<ECPrivateKey> ECPrivateKey::CreateFromPrivateKeyInfo( - base::span<const uint8_t> input) { - OpenSSLErrStackTracer err_tracer(FROM_HERE); - - CBS cbs; - CBS_init(&cbs, input.data(), input.size()); - bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_private_key(&cbs)); - if (!pkey || CBS_len(&cbs) != 0 || EVP_PKEY_id(pkey.get()) != EVP_PKEY_EC) - return nullptr; - - std::unique_ptr<ECPrivateKey> result(new ECPrivateKey()); - result->key_ = std::move(pkey); - return result; -} - -std::unique_ptr<ECPrivateKey> ECPrivateKey::Copy() const { - std::unique_ptr<ECPrivateKey> copy(new ECPrivateKey()); - copy->key_ = bssl::UpRef(key_); - return copy; -} - -bool ECPrivateKey::ExportPrivateKey(std::vector<uint8_t>* output) const { - OpenSSLErrStackTracer err_tracer(FROM_HERE); - uint8_t* der; - size_t der_len; - bssl::ScopedCBB cbb; - if (!CBB_init(cbb.get(), 0) || - !EVP_marshal_private_key(cbb.get(), key_.get()) || - !CBB_finish(cbb.get(), &der, &der_len)) { - return false; - } - output->assign(der, der + der_len); - OPENSSL_free(der); - return true; -} - -bool ECPrivateKey::ExportPublicKey(std::vector<uint8_t>* output) const { - OpenSSLErrStackTracer err_tracer(FROM_HERE); - uint8_t* der; - size_t der_len; - bssl::ScopedCBB cbb; - if (!CBB_init(cbb.get(), 0) || - !EVP_marshal_public_key(cbb.get(), key_.get()) || - !CBB_finish(cbb.get(), &der, &der_len)) { - return false; - } - output->assign(der, der + der_len); - OPENSSL_free(der); - return true; -} - -bool ECPrivateKey::ExportRawPublicKey(std::string* output) const { - OpenSSLErrStackTracer err_tracer(FROM_HERE); - - std::array<uint8_t, 65> buf; - EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key_.get()); - if (!EC_POINT_point2oct(EC_KEY_get0_group(ec_key), - EC_KEY_get0_public_key(ec_key), - POINT_CONVERSION_UNCOMPRESSED, buf.data(), buf.size(), - /*ctx=*/nullptr)) { - return false; - } - - output->assign(buf.begin(), buf.end()); - return true; -} - -ECPrivateKey::ECPrivateKey() = default; - -} // namespace crypto
diff --git a/crypto/ec_private_key.h b/crypto/ec_private_key.h deleted file mode 100644 index 19e872d8..0000000 --- a/crypto/ec_private_key.h +++ /dev/null
@@ -1,69 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// This interface is deprecated and being removed: https://crbug.com/425863216. -// New users should use crypto/keypair instead. - -#ifndef CRYPTO_EC_PRIVATE_KEY_H_ -#define CRYPTO_EC_PRIVATE_KEY_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <memory> -#include <string> -#include <vector> - -#include "base/containers/span.h" -#include "build/build_config.h" -#include "crypto/crypto_export.h" -#include "third_party/boringssl/src/include/openssl/base.h" - -namespace crypto { - -// Encapsulates an elliptic curve (EC) private key. Can be used to generate new -// keys, export keys to other formats, or to extract a public key. -// TODO(https://crbug.com/425863216): Delete this. -class CRYPTO_EXPORT ECPrivateKey { - public: - ECPrivateKey(const ECPrivateKey&) = delete; - ECPrivateKey& operator=(const ECPrivateKey&) = delete; - - ~ECPrivateKey(); - - // Creates a new random instance. Can return nullptr if initialization fails. - // The created key will use the NIST P-256 curve. - static std::unique_ptr<ECPrivateKey> Create(); - - // Create a new instance by importing an existing private key. The format is - // an ASN.1-encoded PrivateKeyInfo block from PKCS #8. This can return - // nullptr if initialization fails. - static std::unique_ptr<ECPrivateKey> CreateFromPrivateKeyInfo( - base::span<const uint8_t> input); - - // Returns a copy of the object. - std::unique_ptr<ECPrivateKey> Copy() const; - - EVP_PKEY* key() const { return key_.get(); } - - // Exports the private key to a PKCS #8 PrivateKeyInfo block. - bool ExportPrivateKey(std::vector<uint8_t>* output) const; - - // Exports the public key to an X.509 SubjectPublicKeyInfo block. - bool ExportPublicKey(std::vector<uint8_t>* output) const; - - // Exports the public key as an EC point in X9.62 uncompressed form. Note this - // includes the leading 0x04 byte. - bool ExportRawPublicKey(std::string* output) const; - - private: - // Constructor is private. Use one of the Create*() methods above instead. - ECPrivateKey(); - - bssl::UniquePtr<EVP_PKEY> key_; -}; - -} // namespace crypto - -#endif // CRYPTO_EC_PRIVATE_KEY_H_
diff --git a/crypto/ec_private_key_unittest.cc b/crypto/ec_private_key_unittest.cc deleted file mode 100644 index a10977c..0000000 --- a/crypto/ec_private_key_unittest.cc +++ /dev/null
@@ -1,178 +0,0 @@ -// Copyright 2011 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "crypto/ec_private_key.h" - -#include <stdint.h> - -#include <memory> -#include <vector> - -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -void ExpectKeysEqual(const crypto::ECPrivateKey* keypair1, - const crypto::ECPrivateKey* keypair2) { - std::vector<uint8_t> privkey1; - std::vector<uint8_t> privkey2; - EXPECT_TRUE(keypair1->ExportPrivateKey(&privkey1)); - EXPECT_TRUE(keypair2->ExportPrivateKey(&privkey2)); - EXPECT_EQ(privkey1, privkey2); - - std::vector<uint8_t> pubkey1; - std::vector<uint8_t> pubkey2; - EXPECT_TRUE(keypair1->ExportPublicKey(&pubkey1)); - EXPECT_TRUE(keypair2->ExportPublicKey(&pubkey2)); - EXPECT_EQ(pubkey1, pubkey2); - - std::string raw_pubkey1; - std::string raw_pubkey2; - EXPECT_TRUE(keypair1->ExportRawPublicKey(&raw_pubkey1)); - EXPECT_TRUE(keypair2->ExportRawPublicKey(&raw_pubkey2)); - EXPECT_EQ(raw_pubkey1, raw_pubkey2); -} - -} // namespace - -// Generate random private keys. Export, then re-import in several ways. We -// should get back the same exact public key, and the private key should have -// the same value and elliptic curve params. -TEST(ECPrivateKeyUnitTest, InitRandomTest) { - std::unique_ptr<crypto::ECPrivateKey> keypair(crypto::ECPrivateKey::Create()); - ASSERT_TRUE(keypair); - - // Re-import as a PrivateKeyInfo. - std::vector<uint8_t> privkey; - EXPECT_TRUE(keypair->ExportPrivateKey(&privkey)); - std::unique_ptr<crypto::ECPrivateKey> keypair_copy = - crypto::ECPrivateKey::CreateFromPrivateKeyInfo(privkey); - ASSERT_TRUE(keypair_copy); - ExpectKeysEqual(keypair.get(), keypair_copy.get()); -} - -TEST(ECPrivateKeyUnitTest, Copy) { - std::unique_ptr<crypto::ECPrivateKey> keypair1( - crypto::ECPrivateKey::Create()); - std::unique_ptr<crypto::ECPrivateKey> keypair2(keypair1->Copy()); - ASSERT_TRUE(keypair1); - ASSERT_TRUE(keypair2); - - ExpectKeysEqual(keypair1.get(), keypair2.get()); -} - -TEST(ECPrivateKeyUnitTest, CreateFromPrivateKeyInfo) { - static const uint8_t kPrivateKeyInfo[] = { - 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, - 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, - 0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20, - 0x07, 0x0f, 0x08, 0x72, 0x7a, 0xd4, 0xa0, 0x4a, 0x9c, 0xdd, 0x59, 0xc9, - 0x4d, 0x89, 0x68, 0x77, 0x08, 0xb5, 0x6f, 0xc9, 0x5d, 0x30, 0x77, 0x0e, - 0xe8, 0xd1, 0xc9, 0xce, 0x0a, 0x8b, 0xb4, 0x6a, 0xa1, 0x44, 0x03, 0x42, - 0x00, 0x04, 0xe6, 0x2b, 0x69, 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f, - 0x1e, 0x0d, 0x94, 0x8a, 0x4c, 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d, - 0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e, 0x9d, 0xdc, 0xba, 0x5a, 0x01, 0xe7, - 0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9, 0xc3, 0xc4, 0xa3, 0x1e, 0x56, 0xe2, - 0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a, 0x1c, 0xf5, 0x1d, 0x7e, 0xf1, 0x94, - 0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1, - }; - static const uint8_t kSubjectPublicKeyInfo[] = { - 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, - 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, - 0x42, 0x00, 0x04, 0xe6, 0x2b, 0x69, 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, - 0x2f, 0x1e, 0x0d, 0x94, 0x8a, 0x4c, 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e, - 0x0d, 0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e, 0x9d, 0xdc, 0xba, 0x5a, 0x01, - 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9, 0xc3, 0xc4, 0xa3, 0x1e, 0x56, - 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a, 0x1c, 0xf5, 0x1d, 0x7e, 0xf1, - 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1, - }; - static const uint8_t kRawPublicKey[] = { - 0x04, 0xe6, 0x2b, 0x69, 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f, - 0x1e, 0x0d, 0x94, 0x8a, 0x4c, 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e, - 0x0d, 0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e, 0x9d, 0xdc, 0xba, 0x5a, - 0x01, 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9, 0xc3, 0xc4, 0xa3, - 0x1e, 0x56, 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a, 0x1c, 0xf5, - 0x1d, 0x7e, 0xf1, 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1, - }; - - std::unique_ptr<crypto::ECPrivateKey> key = - crypto::ECPrivateKey::CreateFromPrivateKeyInfo(std::vector<uint8_t>( - std::begin(kPrivateKeyInfo), std::end(kPrivateKeyInfo))); - ASSERT_TRUE(key); - - std::vector<uint8_t> public_key; - ASSERT_TRUE(key->ExportPublicKey(&public_key)); - EXPECT_EQ(std::vector<uint8_t>(std::begin(kSubjectPublicKeyInfo), - std::end(kSubjectPublicKeyInfo)), - public_key); - - std::string raw_public_key; - ASSERT_TRUE(key->ExportRawPublicKey(&raw_public_key)); - EXPECT_EQ(std::string(reinterpret_cast<const char*>(kRawPublicKey), - sizeof(kRawPublicKey)), - raw_public_key); -} - -TEST(ECPrivateKeyUnitTest, RSAPrivateKeyInfo) { - static const uint8_t kPrivateKeyInfo[] = { - 0x30, 0x82, 0x02, 0x78, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, - 0x02, 0x62, 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, - 0x00, 0xb8, 0x7f, 0x2b, 0x20, 0xdc, 0x7c, 0x9b, 0x0c, 0xdc, 0x51, 0x61, - 0x99, 0x0d, 0x36, 0x0f, 0xd4, 0x66, 0x88, 0x08, 0x55, 0x84, 0xd5, 0x3a, - 0xbf, 0x2b, 0xa4, 0x64, 0x85, 0x7b, 0x0c, 0x04, 0x13, 0x3f, 0x8d, 0xf4, - 0xbc, 0x38, 0x0d, 0x49, 0xfe, 0x6b, 0xc4, 0x5a, 0xb0, 0x40, 0x53, 0x3a, - 0xd7, 0x66, 0x09, 0x0f, 0x9e, 0x36, 0x74, 0x30, 0xda, 0x8a, 0x31, 0x4f, - 0x1f, 0x14, 0x50, 0xd7, 0xc7, 0x20, 0x94, 0x17, 0xde, 0x4e, 0xb9, 0x57, - 0x5e, 0x7e, 0x0a, 0xe5, 0xb2, 0x65, 0x7a, 0x89, 0x4e, 0xb6, 0x47, 0xff, - 0x1c, 0xbd, 0xb7, 0x38, 0x13, 0xaf, 0x47, 0x85, 0x84, 0x32, 0x33, 0xf3, - 0x17, 0x49, 0xbf, 0xe9, 0x96, 0xd0, 0xd6, 0x14, 0x6f, 0x13, 0x8d, 0xc5, - 0xfc, 0x2c, 0x72, 0xba, 0xac, 0xea, 0x7e, 0x18, 0x53, 0x56, 0xa6, 0x83, - 0xa2, 0xce, 0x93, 0x93, 0xe7, 0x1f, 0x0f, 0xe6, 0x0f, 0x02, 0x03, 0x01, - 0x00, 0x01, 0x02, 0x81, 0x80, 0x03, 0x61, 0x89, 0x37, 0xcb, 0xf2, 0x98, - 0xa0, 0xce, 0xb4, 0xcb, 0x16, 0x13, 0xf0, 0xe6, 0xaf, 0x5c, 0xc5, 0xa7, - 0x69, 0x71, 0xca, 0xba, 0x8d, 0xe0, 0x4d, 0xdd, 0xed, 0xb8, 0x48, 0x8b, - 0x16, 0x93, 0x36, 0x95, 0xc2, 0x91, 0x40, 0x65, 0x17, 0xbd, 0x7f, 0xd6, - 0xad, 0x9e, 0x30, 0x28, 0x46, 0xe4, 0x3e, 0xcc, 0x43, 0x78, 0xf9, 0xfe, - 0x1f, 0x33, 0x23, 0x1e, 0x31, 0x12, 0x9d, 0x3c, 0xa7, 0x08, 0x82, 0x7b, - 0x7d, 0x25, 0x4e, 0x5e, 0x19, 0xa8, 0x9b, 0xed, 0x86, 0xb2, 0xcb, 0x3c, - 0xfe, 0x4e, 0xa1, 0xfa, 0x62, 0x87, 0x3a, 0x17, 0xf7, 0x60, 0xec, 0x38, - 0x29, 0xe8, 0x4f, 0x34, 0x9f, 0x76, 0x9d, 0xee, 0xa3, 0xf6, 0x85, 0x6b, - 0x84, 0x43, 0xc9, 0x1e, 0x01, 0xff, 0xfd, 0xd0, 0x29, 0x4c, 0xfa, 0x8e, - 0x57, 0x0c, 0xc0, 0x71, 0xa5, 0xbb, 0x88, 0x46, 0x29, 0x5c, 0xc0, 0x4f, - 0x01, 0x02, 0x41, 0x00, 0xf5, 0x83, 0xa4, 0x64, 0x4a, 0xf2, 0xdd, 0x8c, - 0x2c, 0xed, 0xa8, 0xd5, 0x60, 0x5a, 0xe4, 0xc7, 0xcc, 0x61, 0xcd, 0x38, - 0x42, 0x20, 0xd3, 0x82, 0x18, 0xf2, 0x35, 0x00, 0x72, 0x2d, 0xf7, 0x89, - 0x80, 0x67, 0xb5, 0x93, 0x05, 0x5f, 0xdd, 0x42, 0xba, 0x16, 0x1a, 0xea, - 0x15, 0xc6, 0xf0, 0xb8, 0x8c, 0xbc, 0xbf, 0x54, 0x9e, 0xf1, 0xc1, 0xb2, - 0xb3, 0x8b, 0xb6, 0x26, 0x02, 0x30, 0xc4, 0x81, 0x02, 0x41, 0x00, 0xc0, - 0x60, 0x62, 0x80, 0xe1, 0x22, 0x78, 0xf6, 0x9d, 0x83, 0x18, 0xeb, 0x72, - 0x45, 0xd7, 0xc8, 0x01, 0x7f, 0xa9, 0xca, 0x8f, 0x7d, 0xd6, 0xb8, 0x31, - 0x2b, 0x84, 0x7f, 0x62, 0xd9, 0xa9, 0x22, 0x17, 0x7d, 0x06, 0x35, 0x6c, - 0xf3, 0xc1, 0x94, 0x17, 0x85, 0x5a, 0xaf, 0x9c, 0x5c, 0x09, 0x3c, 0xcf, - 0x2f, 0x44, 0x9d, 0xb6, 0x52, 0x68, 0x5f, 0xf9, 0x59, 0xc8, 0x84, 0x2b, - 0x39, 0x22, 0x8f, 0x02, 0x41, 0x00, 0xb2, 0x04, 0xe2, 0x0e, 0x56, 0xca, - 0x03, 0x1a, 0xc0, 0xf9, 0x12, 0x92, 0xa5, 0x6b, 0x42, 0xb8, 0x1c, 0xda, - 0x4d, 0x93, 0x9d, 0x5f, 0x6f, 0xfd, 0xc5, 0x58, 0xda, 0x55, 0x98, 0x74, - 0xfc, 0x28, 0x17, 0x93, 0x1b, 0x75, 0x9f, 0x50, 0x03, 0x7f, 0x7e, 0xae, - 0xc8, 0x95, 0x33, 0x75, 0x2c, 0xd6, 0xa4, 0x35, 0xb8, 0x06, 0x03, 0xba, - 0x08, 0x59, 0x2b, 0x17, 0x02, 0xdc, 0x4c, 0x7a, 0x50, 0x01, 0x02, 0x41, - 0x00, 0x9d, 0xdb, 0x39, 0x59, 0x09, 0xe4, 0x30, 0xa0, 0x24, 0xf5, 0xdb, - 0x2f, 0xf0, 0x2f, 0xf1, 0x75, 0x74, 0x0d, 0x5e, 0xb5, 0x11, 0x73, 0xb0, - 0x0a, 0xaa, 0x86, 0x4c, 0x0d, 0xff, 0x7e, 0x1d, 0xb4, 0x14, 0xd4, 0x09, - 0x91, 0x33, 0x5a, 0xfd, 0xa0, 0x58, 0x80, 0x9b, 0xbe, 0x78, 0x2e, 0x69, - 0x82, 0x15, 0x7c, 0x72, 0xf0, 0x7b, 0x18, 0x39, 0xff, 0x6e, 0xeb, 0xc6, - 0x86, 0xf5, 0xb4, 0xc7, 0x6f, 0x02, 0x41, 0x00, 0x8d, 0x1a, 0x37, 0x0f, - 0x76, 0xc4, 0x82, 0xfa, 0x5c, 0xc3, 0x79, 0x35, 0x3e, 0x70, 0x8a, 0xbf, - 0x27, 0x49, 0xb0, 0x99, 0x63, 0xcb, 0x77, 0x5f, 0xa8, 0x82, 0x65, 0xf6, - 0x03, 0x52, 0x51, 0xf1, 0xae, 0x2e, 0x05, 0xb3, 0xc6, 0xa4, 0x92, 0xd1, - 0xce, 0x6c, 0x72, 0xfb, 0x21, 0xb3, 0x02, 0x87, 0xe4, 0xfd, 0x61, 0xca, - 0x00, 0x42, 0x19, 0xf0, 0xda, 0x5a, 0x53, 0xe3, 0xb1, 0xc5, 0x15, 0xf3, - }; - - std::unique_ptr<crypto::ECPrivateKey> key = - crypto::ECPrivateKey::CreateFromPrivateKeyInfo(std::vector<uint8_t>( - std::begin(kPrivateKeyInfo), std::end(kPrivateKeyInfo))); - EXPECT_FALSE(key); -}
diff --git a/device/fido/cable/v2_handshake.cc b/device/fido/cable/v2_handshake.cc index 1ebea4a..d8a28eb4 100644 --- a/device/fido/cable/v2_handshake.cc +++ b/device/fido/cable/v2_handshake.cc
@@ -14,10 +14,12 @@ #include <algorithm> #include <array> #include <bit> +#include <string_view> #include <type_traits> #include <variant> #include "base/base64url.h" +#include "base/containers/span.h" #include "base/feature_list.h" #include "base/numerics/byte_conversions.h" #include "base/numerics/safe_conversions.h" @@ -134,7 +136,8 @@ static_assert(sizeof(result) <= sizeof(digest), ""); memcpy(&result, digest, sizeof(result)); - static const char kBase32Chars[33] = "abcdefghijklmnopqrstuvwxyz234567"; + static const std::string_view kBase32Chars = + "abcdefghijklmnopqrstuvwxyz234567"; const int tld_value = result & 3; result >>= 2; @@ -501,8 +504,9 @@ v >> (kChunkSize * 8) != 0) { return std::nullopt; } - const uint8_t* const v_bytes = reinterpret_cast<uint8_t*>(&v); - ret.insert(ret.end(), v_bytes, v_bytes + kChunkSize); + const base::span<const uint8_t> v_bytes = + base::as_writable_byte_span(base::span_from_ref(v)).first(kChunkSize); + ret.insert(ret.end(), v_bytes.begin(), v_bytes.end()); in = in.substr(kChunkDigits); } @@ -537,8 +541,10 @@ return std::nullopt; } - const uint8_t* const v_bytes = reinterpret_cast<uint8_t*>(&v); - ret.insert(ret.end(), v_bytes, v_bytes + remaining_bytes); + const base::span<const uint8_t> v_bytes = + base::as_writable_byte_span(base::span_from_ref(v)) + .first(remaining_bytes); + ret.insert(ret.end(), v_bytes.begin(), v_bytes.end()); } return ret;
diff --git a/device/fido/cable/v2_handshake_unittest.cc b/device/fido/cable/v2_handshake_unittest.cc index 1b5c3ee..f763e78 100644 --- a/device/fido/cable/v2_handshake_unittest.cc +++ b/device/fido/cable/v2_handshake_unittest.cc
@@ -10,8 +10,10 @@ #include "device/fido/cable/v2_handshake.h" #include <algorithm> +#include <array> #include <string_view> +#include "base/containers/auto_spanification_helper.h" #include "base/containers/contains.h" #include "base/rand_util.h" #include "base/test/scoped_feature_list.h" @@ -408,18 +410,17 @@ } TEST(CableV2Encoding, Digits) { - uint8_t test_data[24]; + std::array<uint8_t, 24> test_data; base::RandBytes(test_data); // |BytesToDigits| and |DigitsToBytes| should round-trip. - for (size_t i = 0; i < sizeof(test_data); i++) { + for (size_t i = 0; i < base::SpanificationSizeofForStdArray(test_data); i++) { std::string digits = - qr::BytesToDigits(base::span<const uint8_t>(test_data, i)); + qr::BytesToDigits(base::span<const uint8_t>(test_data.data(), i)); std::optional<std::vector<uint8_t>> test_data_again = qr::DigitsToBytes(digits); ASSERT_TRUE(test_data_again.has_value()); - ASSERT_EQ(test_data_again.value(), - std::vector<uint8_t>(test_data, test_data + i)); + ASSERT_EQ(test_data_again, base::span(test_data).first(i)); } // |DigitsToBytes| should reject non-digit inputs.
diff --git a/device/gamepad/nintendo_controller.cc b/device/gamepad/nintendo_controller.cc index c3c7233..30080ea 100644 --- a/device/gamepad/nintendo_controller.cc +++ b/device/gamepad/nintendo_controller.cc
@@ -13,6 +13,7 @@ #include <array> #include <utility> +#include "base/containers/span.h" #include "base/functional/bind.h" #include "base/task/single_thread_task_runner.h" #include "device/gamepad/gamepad_data_fetcher.h" @@ -300,8 +301,8 @@ } // Unpack a 6-byte MAC address. -uint64_t UnpackSwitchMacAddress(const uint8_t* data) { - DCHECK(data); +uint64_t UnpackSwitchMacAddress(base::span<const uint8_t, 6> data) { + DCHECK(!data.empty()); uint64_t acc = data[5]; acc = (acc << 8) | data[4]; acc = (acc << 8) | data[3]; @@ -313,9 +314,9 @@ // Unpack the analog stick parameters into |cal|. void UnpackSwitchAnalogStickParameters( - const uint8_t* data, + base::span<const uint8_t> data, NintendoController::SwitchCalibrationData& cal) { - DCHECK(data); + DCHECK(!data.empty()); // Only fetch the dead zone and range ratio. The other parameters are unknown. UnpackShorts(data[3], data[4], data[5], &cal.dead_zone, &cal.range_ratio); if (cal.dead_zone == kCalBogusValue) { @@ -327,9 +328,9 @@ // Unpack the IMU calibration data into |cal| void UnpackSwitchImuCalibration( - const uint8_t* data, + base::span<const uint8_t> data, NintendoController::SwitchCalibrationData& cal) { - DCHECK(data); + DCHECK(!data.empty()); // 24 bytes, as 4 groups of 3 16-bit little-endian values. cal.accelerometer_origin_x = (data[1] << 8) | data[0]; cal.accelerometer_origin_y = (data[3] << 8) | data[2]; @@ -347,9 +348,9 @@ // Unpack the IMU horizontal offsets into |cal|. void UnpackSwitchImuHorizontalOffsets( - const uint8_t* data, + base::span<const uint8_t> data, NintendoController::SwitchCalibrationData& cal) { - DCHECK(data); + DCHECK(!data.empty()); // 6 bytes, as 3 16-bit little-endian values. cal.horizontal_offset_x = (data[1] << 8) | data[0]; cal.horizontal_offset_y = (data[3] << 8) | data[2]; @@ -358,9 +359,9 @@ // Unpack the analog stick calibration data into |cal|. void UnpackSwitchAnalogStickCalibration( - const uint8_t* data, + base::span<const uint8_t> data, NintendoController::SwitchCalibrationData& cal) { - DCHECK(data); + DCHECK(!data.empty()); // 18 bytes, as 2 groups of 6 packed 12-bit values. UnpackShorts(data[0], data[1], data[2], &cal.lx_max, &cal.ly_max); UnpackShorts(data[3], data[4], data[5], &cal.lx_center, &cal.ly_center);
diff --git a/docs/trace_events.md b/docs/trace_events.md index 6cf7ee42..9436ba62 100644 --- a/docs/trace_events.md +++ b/docs/trace_events.md
@@ -55,6 +55,8 @@ as `TRACE_EVENT0/1/2`, `TRACE_EVENT_ASYNC_BEGIN0/1/2` or any other macro that has 0/1/2 suffix. * These macros are deprecated and should not be used in new code. + * Do not emit synchronous events when a thread is idle. This yields misleading + process activity summary shown by perfetto UI. ### Static Strings * **Always Use Static Strings:** For event names, *always* use static strings.
diff --git a/extensions/README.md b/extensions/README.md index 31a029b..4583f54 100644 --- a/extensions/README.md +++ b/extensions/README.md
@@ -1,6 +1,5 @@ -This will become a reusable extensions module. It implements the core parts of -Chrome's extension system, and can be used with any host of the -[content module](/content/README.md). +This directory implements the core parts of Chrome's extension system, and can +be used with any host of the [content module](/content/README.md). Some extensions code that is not Chrome-specific still lives in [//chrome/browser/extensions](/chrome/browser/extensions) and will be moved @@ -8,10 +7,13 @@ Technical Documentation: -* [Extension and App Types](/extensions/docs/extension_and_app_types.md) +* [Build flags](/extensions/docs/buildflags.md) - ENABLE_EXTENSIONS, + ENABLE_EXTENSIONS_CORE, etc. -* [Features System](/chrome/common/extensions/api/_features.md) +* [Extension and App Types](/extensions/docs/extension_and_app_types.md) -* [Bindings System](/extensions/renderer/bindings.md) +* [Features System](/chrome/common/extensions/api/_features.md) -* [Extension events](/extensions/docs/events.md) +* [Bindings System](/extensions/renderer/bindings.md) + +* [Extension events](/extensions/docs/events.md)
diff --git a/extensions/docs/buildflags.md b/extensions/docs/buildflags.md new file mode 100644 index 0000000..8d13c2e --- /dev/null +++ b/extensions/docs/buildflags.md
@@ -0,0 +1,28 @@ +As of August 2025, the extensions team is working to add support for an +experimental desktop Android build configuration. Because there's too much +extensions code to convert at once, the team is doing it gradually, via build +flags and their corresponding GN arguments. + +`ENABLE_EXTENSIONS` - Historically all extensions code was guarded by this build +flag. There are too many uses in the code base to change its meaning all at +once. What it means now is extensions for Win/Mac/Linux/ChromeOS but *not* +desktop Android. When used in an //extensions directory it means extensions code +that runs on Win/Mac/Linux/ChromeOS and the team intends to port it to desktop +Android. + +`ENABLE_EXTENSIONS_CORE` - All new code should use this. It means extensions +code for all platforms: Win/Mac/Linux/ChromeOS/desktop Android. You will need to +include the header `extensions/buildflags/buildflag.h` to use this flag. + +`ENABLE_DESKTOP_ANDROID_EXTENSIONS` - Rarely used. Indicates a piece of +extensions code that only runs on the desktop Android build. + +`IS_ANDROID` - Rarely used. Most often indicates code that has fundamental +platform differences, such as for code that has (non-abstracted) UI dependencies +or other low-level platform changes. In the long run, this should be used in the +same types of situations you'd see IS_WIN or other platforms. Also occasionally +used to exclude code that is only supported under manifest V2, because desktop +Android only supports manifest V3. + +The plan in the long run is to convert almost everything to +`ENABLE_EXTENSIONS_CORE`, then rename that flag back to `ENABLE_EXTENSIONS`.
diff --git a/extensions/renderer/api/messaging/one_time_message_handler.cc b/extensions/renderer/api/messaging/one_time_message_handler.cc index 79c8574d..7990d0a7 100644 --- a/extensions/renderer/api/messaging/one_time_message_handler.cc +++ b/extensions/renderer/api/messaging/one_time_message_handler.cc
@@ -9,6 +9,7 @@ #include <vector> #include "base/containers/contains.h" +#include "base/debug/crash_logging.h" #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/supports_user_data.h" @@ -172,8 +173,39 @@ return false; } +base::debug::CrashKeyString* GetPromiseRejectFeatureEnabledCrashKey() { + static auto* crash_key = base::debug::AllocateCrashKeyString( + "ext_promise_reject_feature_enabled", base::debug::CrashKeySize::Size256); + return crash_key; +} + } // namespace +namespace debug { + +// Helper for adding a crash keys when we encounter unexpected state in promise +// support for rejections. +// +// It is only created when the callback for a promise rejection is called to +// process the rejection's reason/value. +// +// All keys are logged every time this class is instantiated. +class ScopedPromiseRejectedResponseCrashKeys { + public: + explicit ScopedPromiseRejectedResponseCrashKeys( + bool promise_support_feature_enabled) + : promise_reject_feature_enabled_crash_key_( + GetPromiseRejectFeatureEnabledCrashKey(), + promise_support_feature_enabled ? "true" : "false") {} + ~ScopedPromiseRejectedResponseCrashKeys() = default; + + private: + // Records if the promise support feature was enabled as "true" or "false". + base::debug::ScopedCrashKeyString promise_reject_feature_enabled_crash_key_; +}; + +} // namespace debug + OneTimeMessageHandler::OneTimeMessageHandler( NativeExtensionBindingsSystem* bindings_system) : bindings_system_(bindings_system) {} @@ -733,6 +765,8 @@ return; } + debug::ScopedPromiseRejectedResponseCrashKeys(base::FeatureList::IsEnabled( + extensions_features::kRuntimeOnMessagePromiseReturnSupport)); v8::Local<v8::Value> promise_reject_reason; // This is safe to CHECK() because when a promise rejects it always provides a // value. Even if `reject()` (with no argument) is called we see `undefined`
diff --git a/gpu/command_buffer/service/shared_image_interface_in_process.cc b/gpu/command_buffer/service/shared_image_interface_in_process.cc index 0f38249..a8ad2d4 100644 --- a/gpu/command_buffer/service/shared_image_interface_in_process.cc +++ b/gpu/command_buffer/service/shared_image_interface_in_process.cc
@@ -124,35 +124,6 @@ completion.Wait(); } -const SharedImageCapabilities& -SharedImageInterfaceInProcess::GetCapabilities() { - base::WaitableEvent completion( - base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - - if (!shared_image_capabilities_) { - shared_image_capabilities_ = std::make_unique<SharedImageCapabilities>(); - task_sequence_->ScheduleTask( - base::BindOnce(&SharedImageInterfaceInProcess::GetCapabilitiesOnGpu, - this, &completion, shared_image_capabilities_.get()), - /*sync_token_fences=*/{}, SyncToken()); - completion.Wait(); - } - return *shared_image_capabilities_; -} - -void SharedImageInterfaceInProcess::GetCapabilitiesOnGpu( - base::WaitableEvent* completion, - SharedImageCapabilities* out_capabilities) { - if (!GetSharedImageFactory()) { - return; - } - - DCHECK(shared_image_factory_); - *out_capabilities = shared_image_factory_->MakeCapabilities(); - completion->Signal(); -} - void SharedImageInterfaceInProcess::SetUpOnGpu( std::unique_ptr<SetUpOnGpuParams> params) { DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_);
diff --git a/gpu/command_buffer/service/shared_image_interface_in_process.h b/gpu/command_buffer/service/shared_image_interface_in_process.h index 93edd2b..405e09e 100644 --- a/gpu/command_buffer/service/shared_image_interface_in_process.h +++ b/gpu/command_buffer/service/shared_image_interface_in_process.h
@@ -63,9 +63,6 @@ SharedImageInterfaceInProcess& operator=( const SharedImageInterfaceInProcess&) = delete; - // SharedImageInterface: - const SharedImageCapabilities& GetCapabilities() override; - protected: ~SharedImageInterfaceInProcess() override; @@ -96,9 +93,6 @@ void SetUpOnGpu(std::unique_ptr<SetUpOnGpuParams> params); void DestroyOnGpu(base::WaitableEvent* completion); - void GetCapabilitiesOnGpu(base::WaitableEvent* completion, - SharedImageCapabilities* out_capabilities); - // Used to schedule work on the gpu thread. This is a raw pointer for now // since the ownership of SingleTaskSequence would be the same as the // SharedImageInterfaceInProcess. @@ -118,7 +112,6 @@ scoped_refptr<SharedContextState> context_state_; ScopedSyncPointClientState sync_point_client_state_; std::unique_ptr<SharedImageFactory> shared_image_factory_; - std::unique_ptr<SharedImageCapabilities> shared_image_capabilities_; }; } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_interface_in_process_base.cc b/gpu/command_buffer/service/shared_image_interface_in_process_base.cc index 31abcf52..e3c477e 100644 --- a/gpu/command_buffer/service/shared_image_interface_in_process_base.cc +++ b/gpu/command_buffer/service/shared_image_interface_in_process_base.cc
@@ -27,6 +27,7 @@ #include "gpu/command_buffer/common/command_buffer_id.h" #include "gpu/command_buffer/common/constants.h" #include "gpu/command_buffer/common/mailbox.h" +#include "gpu/command_buffer/common/shared_image_capabilities.h" #include "gpu/command_buffer/common/shared_image_pool_id.h" #include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/common/sync_token.h" @@ -46,13 +47,34 @@ SharedImageInterfaceInProcessBase::SharedImageInterfaceInProcessBase( CommandBufferNamespace namespace_id, CommandBufferId command_buffer_id, + bool verify_creation_sync_token, + SharedImageCapabilities shared_image_capabilities) + : namespace_id_(namespace_id), + command_buffer_id_(command_buffer_id), + verify_creation_sync_token_(verify_creation_sync_token), + shared_image_capabilities_(std::move(shared_image_capabilities)), + shared_image_capabilities_ready_( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::SIGNALED) { + DETACH_FROM_SEQUENCE(gpu_sequence_checker_); +} + +SharedImageInterfaceInProcessBase::SharedImageInterfaceInProcessBase( + CommandBufferNamespace namespace_id, + CommandBufferId command_buffer_id, bool verify_creation_sync_token) : namespace_id_(namespace_id), command_buffer_id_(command_buffer_id), - verify_creation_sync_token_(verify_creation_sync_token) { + verify_creation_sync_token_(verify_creation_sync_token), + shared_image_capabilities_ready_( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED) { DETACH_FROM_SEQUENCE(gpu_sequence_checker_); } +SharedImageInterfaceInProcessBase::~SharedImageInterfaceInProcessBase() = + default; + scoped_refptr<ClientSharedImage> SharedImageInterfaceInProcessBase::CreateSharedImage( const SharedImageInfo& si_info, @@ -503,4 +525,36 @@ NOTREACHED(); } +const SharedImageCapabilities& +SharedImageInterfaceInProcessBase::GetCapabilities() { + // Return fast on already-initialized common case. + if (shared_image_capabilities_ready_.IsSignaled()) { + return shared_image_capabilities_; + } + + ScheduleGpuTask( + base::BindOnce( + &SharedImageInterfaceInProcessBase::GetCapabilitiesOnGpuThread, this), + /*sync_token_fences=*/{}, SyncToken()); + + shared_image_capabilities_ready_.Wait(); + return shared_image_capabilities_; +} + +void SharedImageInterfaceInProcessBase::GetCapabilitiesOnGpuThread() { + // `GetCapabilitiesOnGpuThread()` may be scheduled by multiple threads, + // so quick return if it's already been run. + if (shared_image_capabilities_ready_.IsSignaled()) { + return; + } + + SharedImageFactory* shared_image_factory = GetSharedImageFactory(); + if (shared_image_factory) { + shared_image_capabilities_ = shared_image_factory->MakeCapabilities(); + } + // Fallback to default-initialized version if no factory. + + shared_image_capabilities_ready_.Signal(); +} + } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_interface_in_process_base.h b/gpu/command_buffer/service/shared_image_interface_in_process_base.h index fa73979..2e8ac03a 100644 --- a/gpu/command_buffer/service/shared_image_interface_in_process_base.h +++ b/gpu/command_buffer/service/shared_image_interface_in_process_base.h
@@ -10,6 +10,7 @@ #include "gpu/command_buffer/client/shared_image_interface.h" #include "gpu/command_buffer/common/command_buffer_id.h" #include "gpu/command_buffer/common/constants.h" +#include "gpu/command_buffer/common/shared_image_capabilities.h" #include "gpu/gpu_gles2_export.h" namespace gpu { @@ -85,18 +86,24 @@ SyncToken GenVerifiedSyncToken() final; void VerifySyncToken(SyncToken& sync_token) final; void WaitSyncToken(const SyncToken& sync_token) final; - // subclasses responsible for: - // `const SharedImageCapabilities& GetCapabilities() override;` + const SharedImageCapabilities& GetCapabilities() final; protected: - // `MakeSyncToken()` will create a sync token with `namespace_id` and - // `command_buffer_id`; `GenCreationSyncToken()` will verify that sync token - // or not based on `verify_creation_sync_token`. + // `MakeSyncToken()` creates a sync token with `namespace_id` and + // `command_buffer_id`; `GenCreationSyncToken()` verifies that sync token + // or not based on `verify_creation_sync_token`. If + // `shared_image_capabilities` is not provided to the constructor it will be + // lazily-created on the GPU thread. + SharedImageInterfaceInProcessBase( + CommandBufferNamespace namespace_id, + CommandBufferId command_buffer_id, + bool verify_creation_sync_token, + SharedImageCapabilities shared_image_capabilities); SharedImageInterfaceInProcessBase(CommandBufferNamespace namespace_id, CommandBufferId command_buffer_id, bool verify_creation_sync_token); - ~SharedImageInterfaceInProcessBase() override = default; + ~SharedImageInterfaceInProcessBase() override; // Schedule the `task` on the GPU, waiting on `sync_token_fences` and // signalling `release` when done. @@ -163,6 +170,8 @@ void DestroySharedImageOnGpuThread(const Mailbox& mailbox); + void GetCapabilitiesOnGpuThread(); + SyncToken MakeSyncToken(uint64_t release_id) { return {namespace_id_, command_buffer_id_, release_id}; } @@ -181,6 +190,12 @@ const CommandBufferNamespace namespace_id_; const CommandBufferId command_buffer_id_; const bool verify_creation_sync_token_; + + // This should only be non-default initialized at construction or from the GPU + // thread. `shared_image_capabilities_ready_.IsSignalled()` indicates that it + // is safe to read from. + SharedImageCapabilities shared_image_capabilities_; + base::WaitableEvent shared_image_capabilities_ready_; }; } // namespace gpu
diff --git a/gpu/ipc/service/gpu_channel_shared_image_interface.cc b/gpu/ipc/service/gpu_channel_shared_image_interface.cc index 31193b3..7a90b067 100644 --- a/gpu/ipc/service/gpu_channel_shared_image_interface.cc +++ b/gpu/ipc/service/gpu_channel_shared_image_interface.cc
@@ -8,6 +8,7 @@ #include "build/build_config.h" #include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/client/client_shared_image.h" +#include "gpu/command_buffer/common/shared_image_capabilities.h" #include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/common/sync_token.h" #include "gpu/command_buffer/service/scheduler.h" @@ -38,16 +39,15 @@ CommandBufferIdFromChannelAndRoute( shared_image_stub->channel()->client_id(), g_next_id.GetNext() + 1), - /*verify_creation_sync_token=*/true), + /*verify_creation_sync_token=*/true, + shared_image_stub->factory()->MakeCapabilities()), shared_image_stub_(shared_image_stub), scheduler_(shared_image_stub->channel()->scheduler()), sequence_(scheduler_->CreateSequence( SchedulingPriority::kLow, shared_image_stub->channel()->task_runner(), CommandBufferNamespace::GPU_CHANNEL_SHARED_IMAGE_INTERFACE, - command_buffer_id())), - shared_image_capabilities_( - shared_image_stub->factory()->MakeCapabilities()) { + command_buffer_id())) { DETACH_FROM_SEQUENCE(gpu_sequence_checker_); } @@ -55,11 +55,6 @@ scheduler_->DestroySequence(sequence_); } -const SharedImageCapabilities& -GpuChannelSharedImageInterface::GetCapabilities() { - return shared_image_capabilities_; -} - // Public functions specific to GpuChannelSharedImageInterface: #if BUILDFLAG(IS_ANDROID) scoped_refptr<ClientSharedImage>
diff --git a/gpu/ipc/service/gpu_channel_shared_image_interface.h b/gpu/ipc/service/gpu_channel_shared_image_interface.h index 26ba856..b7524f4 100644 --- a/gpu/ipc/service/gpu_channel_shared_image_interface.h +++ b/gpu/ipc/service/gpu_channel_shared_image_interface.h
@@ -45,9 +45,6 @@ GpuChannelSharedImageInterface& operator=( const GpuChannelSharedImageInterface&) = delete; - // SharedImageInterface: - const SharedImageCapabilities& GetCapabilities() override; - // Public functions specific to GpuChannelSharedImageInterface: #if BUILDFLAG(IS_ANDROID) scoped_refptr<ClientSharedImage> CreateSharedImageForAndroidVideo( @@ -84,7 +81,6 @@ raw_ptr<Scheduler> scheduler_; const SequenceId sequence_; - SharedImageCapabilities shared_image_capabilities_; }; } // namespace gpu
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md index c31d77b..01c8cdb 100644 --- a/infra/config/generated/cq-builders.md +++ b/infra/config/generated/cq-builders.md
@@ -450,30 +450,6 @@ * [gpu-fyi-cq-android-arm64](https://ci.chromium.org/p/chromium/builders/try/gpu-fyi-cq-android-arm64) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""gpu-fyi-cq-android-arm64"")) Location filters: - * [`//cc/.+`](https://cs.chromium.org/chromium/src/cc/) - * [`//chrome/browser/vr/.+`](https://cs.chromium.org/chromium/src/chrome/browser/vr/) - * [`//content/browser/xr/.+`](https://cs.chromium.org/chromium/src/content/browser/xr/) - * [`//components/viz/.+`](https://cs.chromium.org/chromium/src/components/viz/) - * [`//content/test/data/gpu/.+`](https://cs.chromium.org/chromium/src/content/test/data/gpu/) - * [`//content/test/gpu/.+`](https://cs.chromium.org/chromium/src/content/test/gpu/) - * [`//gpu/.+`](https://cs.chromium.org/chromium/src/gpu/) - * [`//media/audio/.+`](https://cs.chromium.org/chromium/src/media/audio/) - * [`//media/base/.+`](https://cs.chromium.org/chromium/src/media/base/) - * [`//media/capture/.+`](https://cs.chromium.org/chromium/src/media/capture/) - * [`//media/filters/.+`](https://cs.chromium.org/chromium/src/media/filters/) - * [`//media/gpu/.+`](https://cs.chromium.org/chromium/src/media/gpu/) - * [`//media/mojo/.+`](https://cs.chromium.org/chromium/src/media/mojo/) - * [`//media/renderers/.+`](https://cs.chromium.org/chromium/src/media/renderers/) - * [`//media/video/.+`](https://cs.chromium.org/chromium/src/media/video/) - * [`//services/viz/.+`](https://cs.chromium.org/chromium/src/services/viz/) - * [`//testing/trigger_scripts/.+`](https://cs.chromium.org/chromium/src/testing/trigger_scripts/) - * [`//third_party/blink/renderer/modules/mediastream/.+`](https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/mediastream/) - * [`//third_party/blink/renderer/modules/webcodecs/.+`](https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/webcodecs/) - * [`//third_party/blink/renderer/modules/webgl/.+`](https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/webgl/) - * [`//third_party/blink/renderer/modules/webgpu/.+`](https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/webgpu/) - * [`//third_party/blink/renderer/platform/graphics/gpu/.+`](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/graphics/gpu/) - * [`//tools/clang/scripts/update.py`](https://cs.chromium.org/search?q=+file:tools/clang/scripts/update.py) - * [`//ui/gl/.+`](https://cs.chromium.org/chromium/src/ui/gl/) * exclude: [`//.*\.md`](https://cs.chromium.org/search?q=+file:.*\.md) * [ios-simulator-full-configs](https://ci.chromium.org/p/chromium/builders/try/ios-simulator-full-configs) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""ios-simulator-full-configs""))
diff --git a/infra/config/generated/cq-usage/full.cfg b/infra/config/generated/cq-usage/full.cfg index 503b9faa..e2f1535e 100644 --- a/infra/config/generated/cq-usage/full.cfg +++ b/infra/config/generated/cq-usage/full.cfg
@@ -2337,150 +2337,6 @@ gerrit_host_regexp: ".*" gerrit_project_regexp: ".*" gerrit_ref_regexp: ".*" - path_regexp: "cc/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "chrome/browser/vr/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "content/browser/xr/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "components/viz/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "content/test/data/gpu/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "content/test/gpu/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "gpu/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/audio/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/base/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/capture/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/filters/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/gpu/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/mojo/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/renderers/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/video/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "services/viz/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "testing/trigger_scripts/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "third_party/blink/renderer/modules/mediastream/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "third_party/blink/renderer/modules/webcodecs/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "third_party/blink/renderer/modules/webgl/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "third_party/blink/renderer/modules/webgpu/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "third_party/blink/renderer/platform/graphics/gpu/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "tools/clang/scripts/update.py" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "ui/gl/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" path_regexp: ".*\\.md" exclude: true }
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index 6c826f2..73dc63a 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -3795,150 +3795,6 @@ gerrit_host_regexp: ".*" gerrit_project_regexp: ".*" gerrit_ref_regexp: ".*" - path_regexp: "cc/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "chrome/browser/vr/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "content/browser/xr/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "components/viz/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "content/test/data/gpu/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "content/test/gpu/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "gpu/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/audio/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/base/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/capture/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/filters/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/gpu/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/mojo/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/renderers/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "media/video/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "services/viz/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "testing/trigger_scripts/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "third_party/blink/renderer/modules/mediastream/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "third_party/blink/renderer/modules/webcodecs/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "third_party/blink/renderer/modules/webgl/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "third_party/blink/renderer/modules/webgpu/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "third_party/blink/renderer/platform/graphics/gpu/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "tools/clang/scripts/update.py" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" - path_regexp: "ui/gl/.+" - } - location_filters { - gerrit_host_regexp: ".*" - gerrit_project_regexp: ".*" - gerrit_ref_regexp: ".*" path_regexp: ".*\\.md" exclude: true }
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star index a00ab4e..9ebf3a9 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -1566,31 +1566,33 @@ max_concurrent_builds = 10, tryjob = try_.job( location_filters = [ + # TODO(crbug.com/433899671): Re-enable once the culprit CL has been + # reverted and the builder is healthy enough to block CL submission. # Inclusion filters. - cq.location_filter(path_regexp = "cc/.+"), - cq.location_filter(path_regexp = "chrome/browser/vr/.+"), - cq.location_filter(path_regexp = "content/browser/xr/.+"), - cq.location_filter(path_regexp = "components/viz/.+"), - cq.location_filter(path_regexp = "content/test/data/gpu/.+"), - cq.location_filter(path_regexp = "content/test/gpu/.+"), - cq.location_filter(path_regexp = "gpu/.+"), - cq.location_filter(path_regexp = "media/audio/.+"), - cq.location_filter(path_regexp = "media/base/.+"), - cq.location_filter(path_regexp = "media/capture/.+"), - cq.location_filter(path_regexp = "media/filters/.+"), - cq.location_filter(path_regexp = "media/gpu/.+"), - cq.location_filter(path_regexp = "media/mojo/.+"), - cq.location_filter(path_regexp = "media/renderers/.+"), - cq.location_filter(path_regexp = "media/video/.+"), - cq.location_filter(path_regexp = "services/viz/.+"), - cq.location_filter(path_regexp = "testing/trigger_scripts/.+"), - cq.location_filter(path_regexp = "third_party/blink/renderer/modules/mediastream/.+"), - cq.location_filter(path_regexp = "third_party/blink/renderer/modules/webcodecs/.+"), - cq.location_filter(path_regexp = "third_party/blink/renderer/modules/webgl/.+"), - cq.location_filter(path_regexp = "third_party/blink/renderer/modules/webgpu/.+"), - cq.location_filter(path_regexp = "third_party/blink/renderer/platform/graphics/gpu/.+"), - cq.location_filter(path_regexp = "tools/clang/scripts/update.py"), - cq.location_filter(path_regexp = "ui/gl/.+"), + # cq.location_filter(path_regexp = "cc/.+"), + # cq.location_filter(path_regexp = "chrome/browser/vr/.+"), + # cq.location_filter(path_regexp = "content/browser/xr/.+"), + # cq.location_filter(path_regexp = "components/viz/.+"), + # cq.location_filter(path_regexp = "content/test/data/gpu/.+"), + # cq.location_filter(path_regexp = "content/test/gpu/.+"), + # cq.location_filter(path_regexp = "gpu/.+"), + # cq.location_filter(path_regexp = "media/audio/.+"), + # cq.location_filter(path_regexp = "media/base/.+"), + # cq.location_filter(path_regexp = "media/capture/.+"), + # cq.location_filter(path_regexp = "media/filters/.+"), + # cq.location_filter(path_regexp = "media/gpu/.+"), + # cq.location_filter(path_regexp = "media/mojo/.+"), + # cq.location_filter(path_regexp = "media/renderers/.+"), + # cq.location_filter(path_regexp = "media/video/.+"), + # cq.location_filter(path_regexp = "services/viz/.+"), + # cq.location_filter(path_regexp = "testing/trigger_scripts/.+"), + # cq.location_filter(path_regexp = "third_party/blink/renderer/modules/mediastream/.+"), + # cq.location_filter(path_regexp = "third_party/blink/renderer/modules/webcodecs/.+"), + # cq.location_filter(path_regexp = "third_party/blink/renderer/modules/webgl/.+"), + # cq.location_filter(path_regexp = "third_party/blink/renderer/modules/webgpu/.+"), + # cq.location_filter(path_regexp = "third_party/blink/renderer/platform/graphics/gpu/.+"), + # cq.location_filter(path_regexp = "tools/clang/scripts/update.py"), + # cq.location_filter(path_regexp = "ui/gl/.+"), # Exclusion filters. cq.location_filter(exclude = True, path_regexp = ".*\\.md"),
diff --git a/internal b/internal index 5460c98..e80ad25 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit 5460c98a4b486ab3baedaa8a7251467c9cb09532 +Subproject commit e80ad25a3bbf0c883f0a2649187857d38c710529
diff --git a/ios/chrome/browser/authentication/ui_bundled/signin/signin_utils.h b/ios/chrome/browser/authentication/ui_bundled/signin/signin_utils.h index 8454733..b44e6727 100644 --- a/ios/chrome/browser/authentication/ui_bundled/signin/signin_utils.h +++ b/ios/chrome/browser/authentication/ui_bundled/signin/signin_utils.h
@@ -152,7 +152,8 @@ void LogFullscreenSigninPromoManagerMigrationDone(); // Fetches asynchronously the unsynced data types for a sign-out or a profile -// switching. And calls `callback`. +// switching. And calls `callback` with the set of data type from +// `TypesRequiringUnsyncedDataCheckOnSignout` containing unsynced data. void FetchUnsyncedDataForSignOutOrProfileSwitching( syncer::SyncService* sync_service, UnsyncedDataForSignoutOrProfileSwitchingCallback callback); @@ -163,6 +164,10 @@ ChangeProfileReason reason, ChangeProfileContinuation continuation); +// Whether there exists a scene with a profile different from the one of this +// scene where the user is signed-in. +bool DifferentUserIsSignedInInAnotherScene(SceneState* scene_state); + } // namespace signin #endif // IOS_CHROME_BROWSER_AUTHENTICATION_UI_BUNDLED_SIGNIN_SIGNIN_UTILS_H_
diff --git a/ios/chrome/browser/authentication/ui_bundled/signin/signin_utils.mm b/ios/chrome/browser/authentication/ui_bundled/signin/signin_utils.mm index b2c9ad4..94d77f7 100644 --- a/ios/chrome/browser/authentication/ui_bundled/signin/signin_utils.mm +++ b/ios/chrome/browser/authentication/ui_bundled/signin/signin_utils.mm
@@ -570,4 +570,21 @@ std::move(continuation)); } +bool DifferentUserIsSignedInInAnotherScene(SceneState* scene_state) { + ProfileIOS* profile = scene_state.profileState.profile; + AppState* app_state = scene_state.profileState.appState; + for (ProfileState* profile_state in app_state.profileStates) { + if (profile == profile_state.profile) { + continue; + } + + auto* identity_manager = + IdentityManagerFactory::GetForProfile(profile_state.profile); + if (identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)) { + return true; + } + } + return false; +} + } // namespace signin
diff --git a/ios/chrome/browser/browser_view/ui_bundled/BUILD.gn b/ios/chrome/browser/browser_view/ui_bundled/BUILD.gn index 7e9bed98..5dc0869 100644 --- a/ios/chrome/browser/browser_view/ui_bundled/BUILD.gn +++ b/ios/chrome/browser/browser_view/ui_bundled/BUILD.gn
@@ -429,7 +429,6 @@ "//ios/chrome/browser/view_source/model", "//ios/chrome/browser/web/model", "//ios/chrome/browser/web/model:delegate", - "//ios/chrome/browser/web/model:page_placeholder", "//ios/chrome/browser/web_state_list/model/web_usage_enabler", "//ios/chrome/common/ui/reauthentication", "//ios/chrome/test:block_cleanup_test",
diff --git a/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm index a0c1672..d39ea57 100644 --- a/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm +++ b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm
@@ -313,7 +313,6 @@ #import "ios/chrome/browser/voice/ui_bundled/text_to_speech_playback_controller_factory.h" #import "ios/chrome/browser/web/model/choose_file/choose_file_tab_helper.h" #import "ios/chrome/browser/web/model/font_size/font_size_tab_helper.h" -#import "ios/chrome/browser/web/model/page_placeholder_browser_agent.h" #import "ios/chrome/browser/web/model/page_placeholder_tab_helper.h" #import "ios/chrome/browser/web/model/print/print_tab_helper.h" #import "ios/chrome/browser/web/model/repost_form_tab_helper.h" @@ -1308,8 +1307,6 @@ self.browser->GetWebStateList()->AsWeakPtr(); _viewControllerDependencies.voiceSearchController = _voiceSearchController; _viewControllerDependencies.safeAreaProvider = _safeAreaProvider; - _viewControllerDependencies.pagePlaceholderBrowserAgent = - PagePlaceholderBrowserAgent::FromBrowser(self.browser); } - (void)updateViewControllerDependencies { @@ -1377,7 +1374,6 @@ _viewControllerDependencies.layoutGuideCenter = nil; _viewControllerDependencies.voiceSearchController = nil; _viewControllerDependencies.safeAreaProvider = nil; - _viewControllerDependencies.pagePlaceholderBrowserAgent = nil; [_voiceSearchController dismissMicPermissionHelp]; [_voiceSearchController disconnect];
diff --git a/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator_unittest.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator_unittest.mm index c851bea5..63f38f0 100644 --- a/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator_unittest.mm +++ b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator_unittest.mm
@@ -203,7 +203,7 @@ // Force the WebStateObserver callbacks that simulate a page load. web::WebStateObserver* ntpHelper = - (web::WebStateObserver*)NewTabPageTabHelper::FromWebState(web_state); + NewTabPageTabHelper::FromWebState(web_state); web::FakeNavigationContext context; context.SetUrl(url); context.SetIsSameDocument(false);
diff --git a/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.mm index 8bd94c3..12f005db 100644 --- a/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.mm +++ b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.mm
@@ -90,8 +90,6 @@ #import "ios/chrome/browser/url_loading/model/url_loading_browser_agent.h" #import "ios/chrome/browser/url_loading/model/url_loading_params.h" #import "ios/chrome/browser/voice/ui_bundled/voice_search_notification_names.h" -#import "ios/chrome/browser/web/model/page_placeholder_browser_agent.h" -#import "ios/chrome/browser/web/model/page_placeholder_tab_helper.h" #import "ios/chrome/browser/web/model/web_navigation_browser_agent.h" #import "ios/chrome/browser/web/model/web_navigation_util.h" #import "ios/chrome/browser/web_state_list/model/web_usage_enabler/web_usage_enabler_browser_agent.h" @@ -240,9 +238,6 @@ // Used to get the layout guide center. LayoutGuideCenter* _layoutGuideCenter; - // Used to add or cancel a page placeholder for next navigation. - raw_ptr<PagePlaceholderBrowserAgent> _pagePlaceholderBrowserAgent; - // Whether the Lens Overlay is currently active and visible for the browser // view. BOOL _lensOverlayVisible; @@ -391,7 +386,6 @@ _webStateList = dependencies.webStateList; _voiceSearchController = dependencies.voiceSearchController; self.safeAreaProvider = dependencies.safeAreaProvider; - _pagePlaceholderBrowserAgent = dependencies.pagePlaceholderBrowserAgent; self.inNewTabAnimation = NO; self.fullscreenController = dependencies.fullscreenController; @@ -726,7 +720,6 @@ if (active) { // Force loading the view in case it was not loaded yet. [self loadViewIfNeeded]; - _pagePlaceholderBrowserAgent->AddPagePlaceholder(); if (self.viewForCurrentWebState) { [self displayTabView]; } @@ -2314,9 +2307,6 @@ } [self displayTabView]; - if (!self.inNewTabAnimation) { - _pagePlaceholderBrowserAgent->CancelPagePlaceholder(); - } } - (void)initiateNewTabForegroundAnimationForWebState:(web::WebState*)webState {
diff --git a/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_unittest.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_unittest.mm index 1ac9ae1..c513129 100644 --- a/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_unittest.mm +++ b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_unittest.mm
@@ -80,7 +80,6 @@ #import "ios/chrome/browser/toolbar/ui_bundled/toolbar_coordinator.h" #import "ios/chrome/browser/url_loading/model/new_tab_animation_tab_helper.h" #import "ios/chrome/browser/url_loading/model/url_loading_notifier_browser_agent.h" -#import "ios/chrome/browser/web/model/page_placeholder_browser_agent.h" #import "ios/chrome/browser/web/model/web_navigation_browser_agent.h" #import "ios/chrome/browser/web/model/web_state_update_browser_agent.h" #import "ios/chrome/browser/web_state_list/model/web_usage_enabler/web_usage_enabler_browser_agent.h" @@ -158,7 +157,6 @@ LensBrowserAgent::CreateForBrowser(browser_.get()); WebNavigationBrowserAgent::CreateForBrowser(browser_.get()); TabUsageRecorderBrowserAgent::CreateForBrowser(browser_.get()); - PagePlaceholderBrowserAgent::CreateForBrowser(browser_.get()); StartSurfaceRecentTabBrowserAgent::CreateForBrowser(browser_.get()); OmniboxPositionBrowserAgent::CreateForBrowser(browser_.get()); BrowserViewVisibilityNotifierBrowserAgent::CreateForBrowser(browser_.get()); @@ -284,8 +282,6 @@ tab_usage_recorder_browser_agent_ = TabUsageRecorderBrowserAgent::FromBrowser(browser_.get()); - page_placeholder_browser_agent_ = - PagePlaceholderBrowserAgent::FromBrowser(browser_.get()); NTPCoordinator_ = [[NewTabPageCoordinator alloc] initWithBrowser:browser_.get() componentFactory:[[NewTabPageComponentFactory alloc] init]]; @@ -305,7 +301,6 @@ LayoutGuideCenterForBrowser(browser_.get()); dependencies.webStateList = browser_->GetWebStateList()->AsWeakPtr(); dependencies.safeAreaProvider = safe_area_provider_; - dependencies.pagePlaceholderBrowserAgent = page_placeholder_browser_agent_; dependencies.applicationCommandsHandler = mock_application_handler_; dependencies.ntpCoordinator = NTPCoordinator_; @@ -375,7 +370,7 @@ std::unique_ptr<web::WebState> CreateOffTheRecordWebState() { web::WebState::CreateParams params( - GetProfile()->CreateOffTheRecordBrowserStateWithTestingFactories( + GetProfile()->CreateOffTheRecordProfileWithTestingFactories( {TestProfileIOS::TestingFactory{ TipsManagerIOSFactory::GetInstance(), TipsManagerIOSFactory::GetDefaultFactory()}})); @@ -445,7 +440,6 @@ NewTabPageCoordinator* NTPCoordinator_; raw_ptr<TabUsageRecorderBrowserAgent> tab_usage_recorder_browser_agent_; SafeAreaProvider* safe_area_provider_; - raw_ptr<PagePlaceholderBrowserAgent> page_placeholder_browser_agent_; id mock_application_handler_; };
diff --git a/ios/chrome/browser/intelligence/bwg/ui/bwg_consent_view_controller.mm b/ios/chrome/browser/intelligence/bwg/ui/bwg_consent_view_controller.mm index b1aec77..db3f854 100644 --- a/ios/chrome/browser/intelligence/bwg/ui/bwg_consent_view_controller.mm +++ b/ios/chrome/browser/intelligence/bwg/ui/bwg_consent_view_controller.mm
@@ -322,17 +322,9 @@ _isAccountManaged ? IDS_IOS_BWG_CONSENT_MANAGED_SECOND_BOX_TITLE : IDS_IOS_BWG_CONSENT_NON_MANAGED_SECOND_BOX_TITLE); - NSString* symbolName; - if (_isAccountManaged) { - symbolName = kBuilding2Symbol; - } else if (@available(iOS 18, *)) { - symbolName = kCounterClockWiseSymbol; - } else { - symbolName = kHistorySymbol; - } - - UIImageView* secondIconImageView = [[UIImageView alloc] - initWithImage:DefaultSymbolWithConfiguration(symbolName, config)]; + UIImageView* secondIconImageView = + [[UIImageView alloc] initWithImage:DefaultSymbolWithConfiguration( + [self secondSymbolName], config)]; secondIconImageView.contentMode = UIViewContentModeScaleAspectFit; @@ -382,6 +374,17 @@ return horizontalStackView; } +// Gets the second SF Symbol name. +- (NSString*)secondSymbolName { + if (_isAccountManaged) { + return kBuilding2Symbol; + } + if (@available(iOS 18, *)) { + return kCounterClockWiseSymbol; + } + return kHistorySymbol; +} + // Creates the first box view containing the text and the title. - (UIView*)createFirstBoxWithTitle:(NSString*)titleText bodyText:(NSString*)bodyText {
diff --git a/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.mm b/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.mm index 9e781f6b..fe3db6f 100644 --- a/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.mm +++ b/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.mm
@@ -171,7 +171,7 @@ LensOverlayNetworkIssuePresenter* _networkIssuePresenter; /// Presenter for the results page. - LensOverlayResultsPagePresenter* _resultsPagePresenter; + id<LensOverlayResultsPagePresenting> _resultsPagePresenter; /// Presenter for the lens container. LensOverlayContainerPresenter* _containerPresenter;
diff --git a/ios/chrome/browser/lens_overlay/ui/BUILD.gn b/ios/chrome/browser/lens_overlay/ui/BUILD.gn index d6c280b..f28adac 100644 --- a/ios/chrome/browser/lens_overlay/ui/BUILD.gn +++ b/ios/chrome/browser/lens_overlay/ui/BUILD.gn
@@ -22,10 +22,13 @@ "lens_overlay_bottom_sheet_presentation_delegate.h", "lens_overlay_error_handler.h", "lens_overlay_result_consumer.h", + "lens_overlay_results_page_presenting.h", "lens_result_page_mutator.h", "lens_toolbar_consumer.h", "lens_toolbar_mutator.h", ] + public_deps = + [ "//ios/chrome/browser/lens_overlay/model:detent_state_header" ] frameworks = [ "UIKit.framework" ] }
diff --git a/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenter.h b/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenter.h index f1e4928..fe49ac49 100644 --- a/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenter.h +++ b/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenter.h
@@ -7,29 +7,14 @@ #import <UIKit/UIKit.h> -#import "ios/chrome/browser/lens_overlay/model/lens_overlay_sheet_detent_state.h" -#import "ios/chrome/browser/lens_overlay/ui/lens_overlay_bottom_sheet_presentation_delegate.h" +#import "ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenting.h" -@protocol LensOverlayResultsPagePresenterDelegate; @class LensResultPageViewController; @class LensOverlayContainerViewController; -@class SceneState; // Presenter for the Lens results bottom sheet. @interface LensOverlayResultsPagePresenter - : NSObject <LensOverlayBottomSheetPresentationDelegate> - -// Whether the results page is currently presented. -@property(nonatomic, assign, readonly) BOOL isResultPageVisible; - -// Current sheet dimension. -@property(nonatomic, readonly) SheetDimensionState sheetDimension; - -// Delegate for the presenter events. -@property(nonatomic, weak) id<LensOverlayResultsPagePresenterDelegate> delegate; - -// The current height of the results page. -@property(nonatomic, readonly) CGFloat presentedResultsPageHeight; + : NSObject <LensOverlayResultsPagePresenting> // Creates a new instance of the presenter. - (instancetype)initWithBaseViewController: @@ -37,19 +22,6 @@ resultPageViewController: (LensResultPageViewController*)resultViewController; -// Presents the result page over the base view controller. -- (void)presentResultsPageAnimated:(BOOL)animated - maximizeSheet:(BOOL)maximizeSheet - startInTranslate:(BOOL)startInTranslate - completion:(void (^)(void))completion; - -// Readjusts the presentation if there was a change in window dimensions. -- (void)readjustPresentationIfNeeded; - -// Dismisses the presented page from the base view controller. -- (void)dismissResultsPageAnimated:(BOOL)animated - completion:(void (^)(void))completion; - @end #endif // IOS_CHROME_BROWSER_LENS_OVERLAY_UI_LENS_OVERLAY_RESULTS_PAGE_PRESENTER_H_
diff --git a/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenter.mm b/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenter.mm index 258a5cd..e3a1b4a 100644 --- a/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenter.mm +++ b/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenter.mm
@@ -91,6 +91,9 @@ UINavigationController* _presentationNavigationController; } +@synthesize delegate = _delegate; +@synthesize presentedResultsPageHeight = _presentedResultsPageHeight; + - (instancetype)initWithBaseViewController: (LensOverlayContainerViewController*)baseViewController resultPageViewController:
diff --git a/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenter_delegate.h b/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenter_delegate.h index 5425c80..e2afd9c6 100644 --- a/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenter_delegate.h +++ b/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenter_delegate.h
@@ -9,7 +9,7 @@ #import "ios/chrome/browser/lens_overlay/model/lens_overlay_sheet_detent_state.h" -@class LensOverlayResultsPagePresenter; +@protocol LensOverlayResultsPagePresenting; // The methods adopted by the object you use to manage user interactions with // the Lens result page. @@ -18,22 +18,22 @@ // Informs the delegate that a user swipe has caused the bottom sheet to cross // the close threshold, resulting in its dismissal. - (void)lensOverlayResultsPagePresenterWillInitiateGestureDrivenDismiss: - (LensOverlayResultsPagePresenter*)presenter; + (id<LensOverlayResultsPagePresenting>)presenter; // Tells the delegate that the results bottom sheet detent dimension has // changed. - (void)lensOverlayResultsPagePresenter: - (LensOverlayResultsPagePresenter*)presenter + (id<LensOverlayResultsPagePresenting>)presenter didUpdateDimensionState:(SheetDimensionState)state; // Asks the delegate to update the vertical occlusion offset to the given value. - (void)lensOverlayResultsPagePresenter: - (LensOverlayResultsPagePresenter*)presenter + (id<LensOverlayResultsPagePresenting>)presenter updateVerticalOcclusionOffset:(CGFloat)offsetNeeded; // Tells the delegate that the layout guide for the visible area was adjusted. - (void)lensOverlayResultsPagePresenter: - (LensOverlayResultsPagePresenter*)presenter + (id<LensOverlayResultsPagePresenting>)presenter didAdjustVisibleAreaLayoutGuide:(UILayoutGuide*)visibleAreaLayoutGuide; @end
diff --git a/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenting.h b/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenting.h new file mode 100644 index 0000000..e31f7c98 --- /dev/null +++ b/ios/chrome/browser/lens_overlay/ui/lens_overlay_results_page_presenting.h
@@ -0,0 +1,46 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_LENS_OVERLAY_UI_LENS_OVERLAY_RESULTS_PAGE_PRESENTING_H_ +#define IOS_CHROME_BROWSER_LENS_OVERLAY_UI_LENS_OVERLAY_RESULTS_PAGE_PRESENTING_H_ + +#import <UIKit/UIKit.h> + +#import "ios/chrome/browser/lens_overlay/model/lens_overlay_sheet_detent_state.h" +#import "ios/chrome/browser/lens_overlay/ui/lens_overlay_bottom_sheet_presentation_delegate.h" + +@protocol LensOverlayResultsPagePresenterDelegate; + +// Protocol for presenting the Lens results bottom sheet. +@protocol LensOverlayResultsPagePresenting < + LensOverlayBottomSheetPresentationDelegate> + +// Whether the results page is currently presented. +@property(nonatomic, assign, readonly) BOOL isResultPageVisible; + +// Current sheet dimension. +@property(nonatomic, readonly) SheetDimensionState sheetDimension; + +// Delegate for the presenter events. +@property(nonatomic, weak) id<LensOverlayResultsPagePresenterDelegate> delegate; + +// The current height of the results page. +@property(nonatomic, readonly) CGFloat presentedResultsPageHeight; + +// Presents the result page over the base view controller. +- (void)presentResultsPageAnimated:(BOOL)animated + maximizeSheet:(BOOL)maximizeSheet + startInTranslate:(BOOL)startInTranslate + completion:(void (^)(void))completion; + +// Readjusts the presentation if there was a change in window dimensions. +- (void)readjustPresentationIfNeeded; + +// Dismisses the presented page from the base view controller. +- (void)dismissResultsPageAnimated:(BOOL)animated + completion:(void (^)(void))completion; + +@end + +#endif // IOS_CHROME_BROWSER_LENS_OVERLAY_UI_LENS_OVERLAY_RESULTS_PAGE_PRESENTING_H_
diff --git a/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory_unittest.mm b/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory_unittest.mm index d2eea3e5..57191bb 100644 --- a/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory_unittest.mm +++ b/ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory_unittest.mm
@@ -146,11 +146,10 @@ WaitForServiceInit(); ProfileIOS* otr_profile = - profile_data_->profile - ->CreateOffTheRecordBrowserStateWithTestingFactories( - {TestProfileIOS::TestingFactory{ - SegmentationPlatformServiceFactory::GetInstance(), - SegmentationPlatformServiceFactory::GetDefaultFactory()}}); + profile_data_->profile->CreateOffTheRecordProfileWithTestingFactories( + {TestProfileIOS::TestingFactory{ + SegmentationPlatformServiceFactory::GetInstance(), + SegmentationPlatformServiceFactory::GetDefaultFactory()}}); ASSERT_FALSE( SegmentationPlatformServiceFactory::GetForProfile(otr_profile)); }
diff --git a/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_command_handler.h b/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_command_handler.h index 8f67851..83f3ee4 100644 --- a/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_command_handler.h +++ b/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_command_handler.h
@@ -11,12 +11,13 @@ // Protocol to communicate user actions from the mediator to its coordinator. @protocol GoogleServicesSettingsCommandHandler <NSObject> -// Presents the sign-out dialog to the user. +// Presents the sign-out dialog to the user if any profile is signed-in in +// another scene. Otherwise directly call completion with success=YES. // `targetRect` rect in table view system coordinate to display the signout // popover dialog. -- (void)showSignOutFromTargetRect:(CGRect)targetRect - completion: - (signin_ui::SignoutCompletionCallback)completion; +- (void)maybeShowSignOutFromTargetRect:(CGRect)targetRect + completion:(signin_ui::SignoutCompletionCallback) + completion; @end
diff --git a/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_coordinator.mm b/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_coordinator.mm index 07b7b62..cd40802 100644 --- a/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_coordinator.mm +++ b/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_coordinator.mm
@@ -142,15 +142,19 @@ self.viewController); } -#pragma mark - GoogleServicesSettingsCommandHandler +#pragma mark - GoogleServicesSettingsCommandHandler - helper - (void)showSignOutFromTargetRect:(CGRect)targetRect + warning:(BOOL)warning completion: (signin_ui::SignoutCompletionCallback)completion { - DCHECK(completion); - BOOL shouldClearDataOnSignOut = - self.authService->ShouldClearDataForSignedInPeriodOnSignOut(); - + if (self.signOutCoordinator) { + // Showing the sign-out button may be asynchronous because we need to check + // whether there are any unsynced data. This can lead to the user + // triple-tapping on the "Allow chrome sign-in" toggle. If so, let’s keep + // the first sign-out coordinator. + return; + } self.signOutCoordinator = [[ActionSheetCoordinator alloc] initWithBaseViewController:self.viewController browser:self.browser @@ -162,7 +166,7 @@ // Because setting `title` to nil automatically forces the title-style text on // `message` in the UIAlertController, the attributed message below // specifically denotes the font style to apply. - if (shouldClearDataOnSignOut) { + if (warning) { // If `kIdentityDiscAccountMenu` is enabled, signing out may also cause tabs // to be closed, see `MainControllerAuthenticationServiceDelegate:: // ClearBrowsingDataForSignedinPeriod`. @@ -201,6 +205,44 @@ [self.signOutCoordinator start]; } +#pragma mark - GoogleServicesSettingsCommandHandler + +- (void)maybeShowSignOutFromTargetRect:(CGRect)targetRect + completion:(signin_ui::SignoutCompletionCallback) + completion { + DCHECK(completion); + BOOL shouldClearDataOnSignOut = + self.authService->ShouldClearDataForSignedInPeriodOnSignOut(); + if (shouldClearDataOnSignOut || + signin::DifferentUserIsSignedInInAnotherScene(self.sceneState)) { + // Either `shouldClearDataOnSignOut` holds, or another scene is signed-in + // with another account. In both case, we must ask the user to confirm and + // warn them there is a possibility of loss of unsynced data. + [self showSignOutFromTargetRect:targetRect + warning:YES + completion:completion]; + return; + } + if (!self.authService->HasPrimaryIdentity(signin::ConsentLevel::kSignin)) { + // We don’t need to ask the user to confirm as they are not signed-in in any + // active scene. + completion(/*success=*/YES, self.sceneState); + return; + } + + // Finally, check for unsynced data in the current profile. + syncer::SyncService* syncService = + SyncServiceFactory::GetForProfile(self.profile); + __weak __typeof(self) weakSelf = self; + auto callback = base::BindOnce(^(syncer::DataTypeSet set) { + [weakSelf showSignOutFromTargetRect:targetRect + warning:!set.empty() + completion:completion]; + }); + signin::FetchUnsyncedDataForSignOutOrProfileSwitching(syncService, + std::move(callback)); +} + // Signs the user out of Chrome, only clears data for managed accounts. - (void)signOutWithCompletion:(signin_ui::SignoutCompletionCallback)completion { DCHECK(completion);
diff --git a/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_mediator.mm b/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_mediator.mm index fb95451a8..2efe0a4ef 100644 --- a/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_mediator.mm +++ b/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_mediator.mm
@@ -113,8 +113,6 @@ @interface GoogleServicesSettingsMediator () <BooleanObserver> -// Returns YES if the user is authenticated. -@property(nonatomic, assign, readonly) BOOL hasPrimaryIdentity; // ** Non personalized section. // Preference value for the "Allow Chrome Sign-in" feature. @property(nonatomic, strong, readonly) @@ -298,10 +296,6 @@ #pragma mark - Properties -- (BOOL)hasPrimaryIdentity { - return self.authService->HasPrimaryIdentity(signin::ConsentLevel::kSignin); -} - - (ItemArray)nonPersonalizedItems { if (!_nonPersonalizedItems) { NSMutableArray* items = [NSMutableArray array]; @@ -513,27 +507,29 @@ - (void)handleUpdateIsSigninAllowedValue:(BOOL)value targetRect:(CGRect)targetRect item:(SyncSwitchItem*)item { - __weak __typeof(self) weakSelf = self; - if (self.hasPrimaryIdentity) { - // If there is a primary identity, sign-in must be already on. So the value - // is toggled to off. - CHECK(!value, base::NotFatalUntil::M145); - void (^completion)(BOOL, SceneState*) = - ^(BOOL success, SceneState* scene_state) { - BOOL newValue = !success; - // The pref change is in this block in order to ensure it is done even - // if weakSelf was set to nil. - GetApplicationContext()->GetLocalState()->SetBoolean( - prefs::kSigninAllowedOnDevice, newValue); - [weakSelf signoutCompletionWithToggledToValue:newValue - success:success - item:item]; - }; - [self.commandHandler showSignOutFromTargetRect:targetRect - completion:completion]; - } else { - self.allowChromeSigninPreference.value = value; + if (value) { + // The user can always allow sign-in. + self.allowChromeSigninPreference.value = YES; + return; } + // Before signing-out, we need to check whether the user accepts to sign-out, + // here or in another profile. Furthermore, we must warn the user that this + // could cause loss of unsynced data if either there are unsynced data here or + // if another profile is signed-in. + __weak __typeof(self) weakSelf = self; + void (^completion)(BOOL, SceneState*) = + ^(BOOL success, SceneState* scene_state) { + BOOL newValue = !success; + // The pref change is in this block in order to ensure it is done even + // if weakSelf was set to nil. + GetApplicationContext()->GetLocalState()->SetBoolean( + prefs::kSigninAllowedOnDevice, newValue); + [weakSelf signoutCompletionWithToggledToValue:newValue + success:success + item:item]; + }; + [self.commandHandler maybeShowSignOutFromTargetRect:targetRect + completion:completion]; } - (void)signoutCompletionWithToggledToValue:(BOOL)newValue
diff --git a/ios/chrome/browser/shared/coordinator/scene/BUILD.gn b/ios/chrome/browser/shared/coordinator/scene/BUILD.gn index 44e43d9..5898e13 100644 --- a/ios/chrome/browser/shared/coordinator/scene/BUILD.gn +++ b/ios/chrome/browser/shared/coordinator/scene/BUILD.gn
@@ -200,7 +200,6 @@ "//ios/chrome/browser/tab_switcher/ui_bundled:utils", "//ios/chrome/browser/tab_switcher/ui_bundled/tab_grid", "//ios/chrome/browser/url_loading/model", - "//ios/chrome/browser/web/model:page_placeholder", "//ios/chrome/browser/web_state_list/model:session_metrics", "//ios/chrome/browser/web_state_list/model/web_usage_enabler", "//ios/chrome/browser/whats_new/coordinator/promo",
diff --git a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm index 2d3b622e..223abfa 100644 --- a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm +++ b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
@@ -199,7 +199,6 @@ #import "ios/chrome/browser/url_loading/model/scene_url_loading_service.h" #import "ios/chrome/browser/url_loading/model/url_loading_browser_agent.h" #import "ios/chrome/browser/url_loading/model/url_loading_params.h" -#import "ios/chrome/browser/web/model/page_placeholder_browser_agent.h" #import "ios/chrome/browser/web_state_list/model/session_metrics.h" #import "ios/chrome/browser/web_state_list/model/web_usage_enabler/web_usage_enabler_browser_agent.h" #import "ios/chrome/browser/whats_new/coordinator/promo/whats_new_scene_agent.h" @@ -3726,11 +3725,6 @@ } } } else { - if (!self.currentInterface.viewController.presentedViewController) { - PagePlaceholderBrowserAgent* pagePlaceholderBrowserAgent = - PagePlaceholderBrowserAgent::FromBrowser(targetInterface.browser); - pagePlaceholderBrowserAgent->ExpectNewForegroundTab(); - } [self setCurrentInterfaceForMode:targetMode]; [self openOrReuseTabInMode:targetMode withUrlLoadParams:urlLoadParams @@ -3738,16 +3732,6 @@ } } -- (void)expectNewForegroundTabForMode:(ApplicationMode)targetMode { - WrangledBrowser* interface = targetMode == ApplicationMode::INCOGNITO - ? self.incognitoInterface - : self.mainInterface; - DCHECK(interface); - PagePlaceholderBrowserAgent* pagePlaceholderBrowserAgent = - PagePlaceholderBrowserAgent::FromBrowser(interface.browser); - pagePlaceholderBrowserAgent->ExpectNewForegroundTab(); -} - - (void)openNewTabFromOriginPoint:(CGPoint)originPoint focusOmnibox:(BOOL)focusOmnibox inheritOpener:(BOOL)inheritOpener {
diff --git a/ios/chrome/browser/shared/model/profile/profile_keyed_service_factory_ios_unittest.cc b/ios/chrome/browser/shared/model/profile/profile_keyed_service_factory_ios_unittest.cc index f52606b..16528d4f 100644 --- a/ios/chrome/browser/shared/model/profile/profile_keyed_service_factory_ios_unittest.cc +++ b/ios/chrome/browser/shared/model/profile/profile_keyed_service_factory_ios_unittest.cc
@@ -105,7 +105,6 @@ std::get<ServiceCreation>(GetParam()), std::get<TestingCreation>(GetParam())) { test_profile_ = TestProfileIOS::Builder().Build(); - test_profile_->CreateOffTheRecordBrowserStateWithTestingFactories(); } DummyServiceFactory& factory() { return dummy_service_factory_; }
diff --git a/ios/chrome/browser/shared/model/profile/profile_keyed_service_utils_unittest.cc b/ios/chrome/browser/shared/model/profile/profile_keyed_service_utils_unittest.cc index 0e6d61a..8a7010b 100644 --- a/ios/chrome/browser/shared/model/profile/profile_keyed_service_utils_unittest.cc +++ b/ios/chrome/browser/shared/model/profile/profile_keyed_service_utils_unittest.cc
@@ -4,7 +4,7 @@ #include "ios/chrome/browser/shared/model/profile/profile_keyed_service_utils.h" -#import "base/memory/raw_ptr.h" +#include "base/memory/raw_ptr.h" #include "ios/chrome/browser/shared/model/profile/test/test_profile_ios.h" #include "ios/web/public/test/web_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" @@ -14,7 +14,6 @@ public: ProfileKeyedServiceUtilsTest() { test_profile_ = TestProfileIOS::Builder().Build(); - test_profile_->CreateOffTheRecordBrowserStateWithTestingFactories(); } ProfileIOS* GetRegularProfile() { return test_profile_.get(); }
diff --git a/ios/chrome/browser/shared/model/profile/refcounted_profile_keyed_service_factory_ios_unittest.cc b/ios/chrome/browser/shared/model/profile/refcounted_profile_keyed_service_factory_ios_unittest.cc index b2922bb..5dc642c 100644 --- a/ios/chrome/browser/shared/model/profile/refcounted_profile_keyed_service_factory_ios_unittest.cc +++ b/ios/chrome/browser/shared/model/profile/refcounted_profile_keyed_service_factory_ios_unittest.cc
@@ -114,7 +114,6 @@ std::get<ServiceCreation>(GetParam()), std::get<TestingCreation>(GetParam())) { test_profile_ = TestProfileIOS::Builder().Build(); - test_profile_->CreateOffTheRecordBrowserStateWithTestingFactories(); } DummyServiceFactory& factory() { return dummy_service_factory_; }
diff --git a/ios/chrome/browser/shared/model/profile/test/test_profile_ios.h b/ios/chrome/browser/shared/model/profile/test/test_profile_ios.h index e7cab13..f83482a1 100644 --- a/ios/chrome/browser/shared/model/profile/test/test_profile_ios.h +++ b/ios/chrome/browser/shared/model/profile/test/test_profile_ios.h
@@ -128,21 +128,6 @@ // This method will be called without factories if the // method `GetOffTheRecordProfile()` is called on // this object. - // TODO(crbug.com/358299863): Remove this function once fully migrated. - TestProfileIOS* CreateOffTheRecordBrowserStateWithTestingFactories( - TestingFactories testing_factories = {}); - - // Creates an off-the-record TestProfileIOS for - // the current object, installing `testing_factories` - // first. - // - // This is an error to call this method if the current - // TestProfileIOS already has a off-the-record - // object, or is itself off-the-record. - // - // This method will be called without factories if the - // method `GetOffTheRecordProfile()` is called on - // this object. TestProfileIOS* CreateOffTheRecordProfileWithTestingFactories( TestingFactories testing_factories = {});
diff --git a/ios/chrome/browser/shared/model/profile/test/test_profile_ios.mm b/ios/chrome/browser/shared/model/profile/test/test_profile_ios.mm index 604ecf7..7bbcc3cf 100644 --- a/ios/chrome/browser/shared/model/profile/test/test_profile_ios.mm +++ b/ios/chrome/browser/shared/model/profile/test/test_profile_ios.mm
@@ -219,13 +219,6 @@ return base::SingleThreadTaskRunner::GetCurrentDefault(); } -TestProfileIOS* -TestProfileIOS::CreateOffTheRecordBrowserStateWithTestingFactories( - TestingFactories testing_factories) { - return CreateOffTheRecordProfileWithTestingFactories( - std::move(testing_factories)); -} - ProfileIOS* TestProfileIOS::GetOriginalProfile() { if (IsOffTheRecord()) { return original_profile_; @@ -246,7 +239,7 @@ return otr_profile_.get(); } - return CreateOffTheRecordBrowserStateWithTestingFactories(); + return CreateOffTheRecordProfileWithTestingFactories(); } void TestProfileIOS::DestroyOffTheRecordProfile() {
diff --git a/ios/chrome/browser/sharing_message/model/ios_sharing_device_registration_impl.mm b/ios/chrome/browser/sharing_message/model/ios_sharing_device_registration_impl.mm index 3b3486f6..eafe036 100644 --- a/ios/chrome/browser/sharing_message/model/ios_sharing_device_registration_impl.mm +++ b/ios/chrome/browser/sharing_message/model/ios_sharing_device_registration_impl.mm
@@ -27,7 +27,6 @@ #import "components/sharing_message/sharing_utils.h" #import "components/sync/service/sync_service.h" #import "components/sync_device_info/device_info.h" -#import "crypto/ec_private_key.h" using instance_id::InstanceID; using sync_pb::SharingSpecificFields;
diff --git a/ios/chrome/browser/side_swipe/ui_bundled/side_swipe_mediator.mm b/ios/chrome/browser/side_swipe/ui_bundled/side_swipe_mediator.mm index d89cb64..9fb5f34 100644 --- a/ios/chrome/browser/side_swipe/ui_bundled/side_swipe_mediator.mm +++ b/ios/chrome/browser/side_swipe/ui_bundled/side_swipe_mediator.mm
@@ -23,7 +23,6 @@ #import "ios/chrome/browser/side_swipe/ui_bundled/side_swipe_mediator+Testing.h" #import "ios/chrome/browser/side_swipe/ui_bundled/side_swipe_util.h" #import "ios/chrome/browser/snapshots/model/snapshot_tab_helper.h" -#import "ios/chrome/browser/web/model/page_placeholder_tab_helper.h" #import "ios/chrome/browser/web/model/web_navigation_util.h" #import "ios/web/public/navigation/navigation_item.h" #import "ios/web/public/web_state_observer_bridge.h" @@ -211,21 +210,11 @@ if (!self.activeWebState || newTabIndex == WebStateList::kInvalidIndex) { return; } - // Disable overlay preview mode for last selected tab. - PagePlaceholderTabHelper::FromWebState(self.activeWebState) - ->CancelPlaceholderForNextNavigation(); - - web::WebState* webState = _webStateList->GetWebStateAt(newTabIndex); - // Enable overlay preview mode for selected tab. - PagePlaceholderTabHelper::FromWebState(webState) - ->AddPlaceholderForNextNavigation(); _webStateList->ActivateWebStateAt(newTabIndex); } - (void)didCompleteTabSwitchWithSwipe { - PagePlaceholderTabHelper::FromWebState(self.activeWebState) - ->CancelPlaceholderForNextNavigation(); } - (int)activeTabIndex {
diff --git a/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios.h b/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios.h index fe2fff3..dda09f59 100644 --- a/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios.h +++ b/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios.h
@@ -16,15 +16,12 @@ class GaiaAuthFetcherIOSBridge; class GURL; +class ProfileIOS; namespace network { class SharedURLLoaderFactory; } // namespace network -namespace web { -class BrowserState; -} // namespace web - // Specialization of GaiaAuthFetcher on iOS. // // Authenticate a user against the Google Accounts ClientLogin API @@ -38,7 +35,7 @@ GaiaAuthConsumer* consumer, gaia::GaiaSource source, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - web::BrowserState* browser_state); + ProfileIOS* profile); GaiaAuthFetcherIOS(const GaiaAuthFetcherIOS&) = delete; GaiaAuthFetcherIOS& operator=(const GaiaAuthFetcherIOS&) = delete; @@ -63,7 +60,6 @@ net::Error net_error, int response_code) override; - raw_ptr<web::BrowserState> browser_state_; std::unique_ptr<GaiaAuthFetcherIOSBridge> bridge_; };
diff --git a/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios.mm b/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios.mm index 1c2b6693..8f04d6f 100644 --- a/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios.mm +++ b/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios.mm
@@ -8,18 +8,19 @@ #import "base/apple/foundation_util.h" #import "base/logging.h" +#import "ios/chrome/browser/shared/model/profile/profile_ios.h" #import "ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge.h" -#import "ios/web/public/browser_state.h" #import "services/network/public/cpp/shared_url_loader_factory.h" GaiaAuthFetcherIOS::GaiaAuthFetcherIOS( GaiaAuthConsumer* consumer, gaia::GaiaSource source, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - web::BrowserState* browser_state) + ProfileIOS* profile) : GaiaAuthFetcher(consumer, source, url_loader_factory), - browser_state_(browser_state), - bridge_(new GaiaAuthFetcherIOSNSURLSessionBridge(this, browser_state_)) {} + bridge_(std::make_unique<GaiaAuthFetcherIOSNSURLSessionBridge>(this, + profile)) { +} GaiaAuthFetcherIOS::~GaiaAuthFetcherIOS() {}
diff --git a/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge.h b/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge.h index 0a87a95..2044ac9 100644 --- a/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge.h +++ b/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge.h
@@ -18,10 +18,7 @@ @class GaiaAuthFetcherIOSURLSessionDelegate; @class NSHTTPURLResponse; @class NSURLSession; - -namespace web { -class BrowserState; -} +class ProfileIOS; // Specialization of GaiaAuthFetcher on iOS, using NSURLSession to send // requests. @@ -29,7 +26,7 @@ public: GaiaAuthFetcherIOSNSURLSessionBridge( GaiaAuthFetcherIOSBridge::GaiaAuthFetcherIOSBridgeDelegate* delegate, - web::BrowserState* browser_state); + ProfileIOS* profile); GaiaAuthFetcherIOSNSURLSessionBridge( const GaiaAuthFetcherIOSNSURLSessionBridge&) = delete; @@ -106,8 +103,8 @@ virtual NSURLSession* CreateNSURLSession( id<NSURLSessionTaskDelegate> url_session_delegate); - // Browser state associated with the bridge. - raw_ptr<web::BrowserState> browser_state_; + // Profile associated with the bridge. + raw_ptr<ProfileIOS> profile_; // Request currently processed by the bridge. Request request_;
diff --git a/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge.mm b/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge.mm index 86ea311..7bdb1848 100644 --- a/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge.mm +++ b/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge.mm
@@ -11,8 +11,8 @@ #import "base/functional/callback_helpers.h" #import "base/strings/sys_string_conversions.h" #import "components/signin/core/browser/chrome_connected_header_helper.h" +#import "ios/chrome/browser/shared/model/profile/profile_ios.h" #import "ios/net/cookies/system_cookie_util.h" -#import "ios/web/public/browser_state.h" #import "ios/web/public/web_client.h" #import "net/base/apple/url_conversions.h" #import "net/http/http_request_headers.h" @@ -96,8 +96,8 @@ GaiaAuthFetcherIOSNSURLSessionBridge::GaiaAuthFetcherIOSNSURLSessionBridge( GaiaAuthFetcherIOSBridge::GaiaAuthFetcherIOSBridgeDelegate* delegate, - web::BrowserState* browser_state) - : GaiaAuthFetcherIOSBridge(delegate), browser_state_(browser_state) { + ProfileIOS* profile) + : GaiaAuthFetcherIOSBridge(delegate), profile_(profile) { url_session_delegate_ = [[GaiaAuthFetcherIOSURLSessionDelegate alloc] init]; url_session_delegate_.bridge = this; } @@ -114,8 +114,7 @@ DCHECK(!request_.pending); request_ = Request(url, headers, body, should_use_xml_http_request); - network::mojom::CookieManager* cookie_manager = - browser_state_->GetCookieManager(); + network::mojom::CookieManager* cookie_manager = profile_->GetCookieManager(); net::CookieOptions options; options.set_include_httponly(); options.set_same_site_cookie_context( @@ -181,8 +180,7 @@ NSArray* cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:response.allHeaderFields forURL:response.URL]; - network::mojom::CookieManager* cookie_manager = - browser_state_->GetCookieManager(); + network::mojom::CookieManager* cookie_manager = profile_->GetCookieManager(); for (NSHTTPCookie* cookie : cookies) { std::unique_ptr<net::CanonicalCookie> canonical_cookie = net::CanonicalCookieFromSystemCookie(cookie, base::Time::Now());
diff --git a/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm b/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm index 2d18888..f6e5ae2 100644 --- a/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm +++ b/ios/chrome/browser/signin/model/gaia_auth_fetcher_ios_ns_url_session_bridge_unittests.mm
@@ -108,7 +108,7 @@ public: TestGaiaAuthFetcherIOSNSURLSessionBridge( GaiaAuthFetcherIOSBridge::GaiaAuthFetcherIOSBridgeDelegate* delegate, - web::BrowserState* browser_state, + ProfileIOS* profile, GaiaAuthFetcherIOSNSURLSessionBridgeTest* test); // GaiaAuthFetcherIOSNSURLSessionBridge. @@ -183,10 +183,9 @@ TestGaiaAuthFetcherIOSNSURLSessionBridge:: TestGaiaAuthFetcherIOSNSURLSessionBridge( GaiaAuthFetcherIOSBridge::GaiaAuthFetcherIOSBridgeDelegate* delegate, - web::BrowserState* browser_state, + ProfileIOS* profile, GaiaAuthFetcherIOSNSURLSessionBridgeTest* test) - : GaiaAuthFetcherIOSNSURLSessionBridge(delegate, browser_state), - test_(test) {} + : GaiaAuthFetcherIOSNSURLSessionBridge(delegate, profile), test_(test) {} NSURLSession* TestGaiaAuthFetcherIOSNSURLSessionBridge::CreateNSURLSession( id<NSURLSessionTaskDelegate> url_session_delegate) { @@ -205,9 +204,10 @@ web_state_->GetView(); web_state_->SetKeepRenderProcessAlive(true); - delegate_.reset(new FakeGaiaAuthFetcherIOSBridgeDelegate()); - ns_url_session_bridge_.reset(new TestGaiaAuthFetcherIOSNSURLSessionBridge( - delegate_.get(), profile_.get(), this)); + delegate_ = std::make_unique<FakeGaiaAuthFetcherIOSBridgeDelegate>(); + ns_url_session_bridge_ = + std::make_unique<TestGaiaAuthFetcherIOSNSURLSessionBridge>( + delegate_.get(), profile_.get(), this); url_session_configuration_ = NSURLSessionConfiguration.ephemeralSessionConfiguration; url_session_configuration_.HTTPShouldSetCookies = YES;
diff --git a/ios/chrome/browser/supervised_user/model/child_account_service_factory_unittest.mm b/ios/chrome/browser/supervised_user/model/child_account_service_factory_unittest.mm index eecc089e..599c649 100644 --- a/ios/chrome/browser/supervised_user/model/child_account_service_factory_unittest.mm +++ b/ios/chrome/browser/supervised_user/model/child_account_service_factory_unittest.mm
@@ -14,7 +14,6 @@ public: ChildAccountServiceFactoryTest() { profile_ = TestProfileIOS::Builder().Build(); - profile_->CreateOffTheRecordBrowserStateWithTestingFactories(); } ProfileIOS* GetRegularProfile() { return profile_.get(); }
diff --git a/ios/chrome/browser/supervised_user/model/list_family_members_service_factory_unittest.mm b/ios/chrome/browser/supervised_user/model/list_family_members_service_factory_unittest.mm index ef2c757..588bd42c 100644 --- a/ios/chrome/browser/supervised_user/model/list_family_members_service_factory_unittest.mm +++ b/ios/chrome/browser/supervised_user/model/list_family_members_service_factory_unittest.mm
@@ -14,7 +14,6 @@ public: ListFamilyMembersServiceFactoryTest() { profile_ = (TestProfileIOS::Builder().Build()); - profile_->CreateOffTheRecordBrowserStateWithTestingFactories(); } ProfileIOS* GetRegularProfile() { return profile_.get(); }
diff --git a/ios/chrome/browser/supervised_user/model/supervised_user_metrics_service_factory_unittest.mm b/ios/chrome/browser/supervised_user/model/supervised_user_metrics_service_factory_unittest.mm index a9c7fc2..4819b86 100644 --- a/ios/chrome/browser/supervised_user/model/supervised_user_metrics_service_factory_unittest.mm +++ b/ios/chrome/browser/supervised_user/model/supervised_user_metrics_service_factory_unittest.mm
@@ -32,8 +32,7 @@ // with an off-the-record ProfileIOS. TEST_F(SupervisedUserMetricsServiceFactoryTest, ReturnsNullOnOffTheRecordBrowserState) { - ProfileIOS* otr_profile = - profile_->CreateOffTheRecordBrowserStateWithTestingFactories(); + ProfileIOS* otr_profile = profile_->GetOffTheRecordProfile(); CHECK(otr_profile); supervised_user::SupervisedUserMetricsService* service = SupervisedUserMetricsServiceFactory::GetForProfile(otr_profile);
diff --git a/ios/chrome/browser/supervised_user/model/supervised_user_service_factory_unittest.mm b/ios/chrome/browser/supervised_user/model/supervised_user_service_factory_unittest.mm index bc41bce..cf2e903 100644 --- a/ios/chrome/browser/supervised_user/model/supervised_user_service_factory_unittest.mm +++ b/ios/chrome/browser/supervised_user/model/supervised_user_service_factory_unittest.mm
@@ -22,7 +22,6 @@ public: SupervisedUserServiceFactoryTest() { profile_ = TestProfileIOS::Builder().Build(); - profile_->CreateOffTheRecordBrowserStateWithTestingFactories(); } ProfileIOS* GetRegularProfile() { return profile_.get(); }
diff --git a/ios/chrome/browser/url_loading/model/scene_url_loading_service.h b/ios/chrome/browser/url_loading/model/scene_url_loading_service.h index a4aa3ff..1c320cb 100644 --- a/ios/chrome/browser/url_loading/model/scene_url_loading_service.h +++ b/ios/chrome/browser/url_loading/model/scene_url_loading_service.h
@@ -50,10 +50,6 @@ focusOmnibox:(BOOL)focusOmnibox inheritOpener:(BOOL)inheritOpener; -// Informs the BVC that a new foreground tab is about to be opened in given -// `targetMode`. -- (void)expectNewForegroundTabForMode:(ApplicationMode)targetMode; - // Returns the URL Loading browser agent to load a tab in `incognito` or not. - (UrlLoadingBrowserAgent*)browserAgentForIncognito:(BOOL)incognito;
diff --git a/ios/chrome/browser/url_loading/model/scene_url_loading_service.mm b/ios/chrome/browser/url_loading/model/scene_url_loading_service.mm index f984f42e..1dc565e 100644 --- a/ios/chrome/browser/url_loading/model/scene_url_loading_service.mm +++ b/ios/chrome/browser/url_loading/model/scene_url_loading_service.mm
@@ -80,7 +80,6 @@ // Not for this profile, switch and try again. ApplicationMode mode = params.in_incognito ? ApplicationMode::INCOGNITO : ApplicationMode::NORMAL; - [delegate_ expectNewForegroundTabForMode:mode]; [delegate_ setCurrentInterfaceForMode:mode]; LoadUrlInNewTab(params); return;
diff --git a/ios/chrome/browser/web/model/BUILD.gn b/ios/chrome/browser/web/model/BUILD.gn index b54cb28..18df33e 100644 --- a/ios/chrome/browser/web/model/BUILD.gn +++ b/ios/chrome/browser/web/model/BUILD.gn
@@ -126,9 +126,6 @@ ] deps = [ "//base", - "//ios/chrome/browser/sessions/model:restoration_observer", - "//ios/chrome/browser/sessions/model:session_restoration_service", - "//ios/chrome/browser/sessions/model:session_restoration_service_factory", "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/model/url:constants", "//ios/chrome/browser/shared/model/web_state_list",
diff --git a/ios/chrome/browser/web/model/page_placeholder_browser_agent.h b/ios/chrome/browser/web/model/page_placeholder_browser_agent.h index c536ef93..c56904a 100644 --- a/ios/chrome/browser/web/model/page_placeholder_browser_agent.h +++ b/ios/chrome/browser/web/model/page_placeholder_browser_agent.h
@@ -8,38 +8,19 @@ #include "base/memory/raw_ptr.h" #include "base/scoped_multi_source_observation.h" #include "base/scoped_observation.h" -#include "ios/chrome/browser/sessions/model/session_restoration_observer.h" #include "ios/chrome/browser/shared/model/browser/browser_observer.h" #include "ios/chrome/browser/shared/model/browser/browser_user_data.h" #include "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer.h" #include "ios/web/public/web_state_observer.h" -class SessionRestorationService; - // Browser agent used to add or cancel a page placeholder for next navigation. class PagePlaceholderBrowserAgent final : public BrowserUserData<PagePlaceholderBrowserAgent>, - public SessionRestorationObserver, public web::WebStateObserver, public WebStateListObserver { public: ~PagePlaceholderBrowserAgent() final; - // Used to inform that a new foreground tab is about to be opened. - void ExpectNewForegroundTab(); - - // Adds a page placeholder. - void AddPagePlaceholder(); - - // Cancels the page placeholder. - void CancelPagePlaceholder(); - - // SessionRestorationObserver implementation. - void WillStartSessionRestoration(Browser* browser) final; - void SessionRestorationFinished( - Browser* browser, - const std::vector<web::WebState*>& restored_web_states) final; - // WebStateListObserver implementation. void WebStateListDidChange(WebStateList* web_state_list, const WebStateListChange& change, @@ -54,23 +35,15 @@ explicit PagePlaceholderBrowserAgent(Browser* browser); - // Helper called when starting to observe an unrealized WebState. - void StartObservingWebState(web::WebState* web_state); + // Helper called when a WebState is inserted in the WebStateList. + void WebStateInserted(web::WebState* web_state, bool force_placeholder); - // Helper called when stopping to observe WebState (either because - // it became realized, was detached or destroyed). - void StopObservingWebState(web::WebState* web_state); + // Helper called when a WebState is removed from the WebStateList. + void WebStateRemoved(web::WebState* web_state); // Adds placeholder for next navigation to WebState. void AddPlaceholderToWebState(web::WebState* web_state); - // Removes placeholder for next navigation from WebState. - void RemovePlaceholderFromWebState(web::WebState* web_state); - - // Observation for SessionRestorationService events. - base::ScopedObservation<SessionRestorationService, SessionRestorationObserver> - session_restoration_service_observation_{this}; - // Observation of the WebStateList. base::ScopedObservation<WebStateList, WebStateListObserver> web_state_list_observation_{this}; @@ -78,9 +51,6 @@ // Observation for unrealized WebStates. base::ScopedMultiSourceObservation<web::WebState, web::WebStateObserver> web_state_observations_{this}; - - // True if waiting for a foreground tab due to expectNewForegroundTab. - bool expecting_foreground_tab_ = false; }; #endif // IOS_CHROME_BROWSER_WEB_MODEL_PAGE_PLACEHOLDER_BROWSER_AGENT_H_
diff --git a/ios/chrome/browser/web/model/page_placeholder_browser_agent.mm b/ios/chrome/browser/web/model/page_placeholder_browser_agent.mm index a4f57b9..3f0b1485 100644 --- a/ios/chrome/browser/web/model/page_placeholder_browser_agent.mm +++ b/ios/chrome/browser/web/model/page_placeholder_browser_agent.mm
@@ -6,8 +6,6 @@ #import "base/check.h" #import "base/check_op.h" -#import "ios/chrome/browser/sessions/model/session_restoration_service.h" -#import "ios/chrome/browser/sessions/model/session_restoration_service_factory.h" #import "ios/chrome/browser/shared/model/browser/browser.h" #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" @@ -23,94 +21,44 @@ << "PagePlaceholderBrowserAgent created for a Browser with a non-empty " "WebStateList."; - ProfileIOS* profile = browser_->GetProfile(); - session_restoration_service_observation_.Observe( - SessionRestorationServiceFactory::GetForProfile(profile)); + web_state_list_observation_.Observe(browser_->GetWebStateList()); } PagePlaceholderBrowserAgent::~PagePlaceholderBrowserAgent() = default; -#pragma mark - Public - -void PagePlaceholderBrowserAgent::ExpectNewForegroundTab() { - expecting_foreground_tab_ = true; -} - -void PagePlaceholderBrowserAgent::AddPagePlaceholder() { - web::WebState* web_state = browser_->GetWebStateList()->GetActiveWebState(); - if (web_state && expecting_foreground_tab_) { - PagePlaceholderTabHelper::FromWebState(web_state) - ->AddPlaceholderForNextNavigation(); - } -} - -void PagePlaceholderBrowserAgent::CancelPagePlaceholder() { - if (!expecting_foreground_tab_) { - return; - } - - // Now that the new tab has been displayed, return to normal. Rather than - // keep a reference to the previous tab, just turn off preview mode for all - // tabs (since doing so is a no-op for the tabs that don't have it set). - expecting_foreground_tab_ = false; - - WebStateList* web_state_list = browser_->GetWebStateList(); - const int web_state_list_size = web_state_list->count(); - for (int index = 0; index < web_state_list_size; ++index) { - RemovePlaceholderFromWebState(web_state_list->GetWebStateAt(index)); - } -} - -#pragma mark - SessionRestorationObserver - -void PagePlaceholderBrowserAgent::WillStartSessionRestoration( - Browser* browser) { - // Nothing to do. -} - -void PagePlaceholderBrowserAgent::SessionRestorationFinished( - Browser* browser, - const std::vector<web::WebState*>& restored_web_states) { - // Ignore the event if it does not correspond to the browser this - // object is bound to (which can happen with the optimised session - // storage code). - if (browser_.get() != browser) { - return; - } - - // Setup the placeholder for the restored tabs if necessary. - for (web::WebState* web_state : restored_web_states) { - AddPlaceholderToWebState(web_state); - } -} - void PagePlaceholderBrowserAgent::WebStateListDidChange( WebStateList* web_state_list, const WebStateListChange& change, const WebStateListStatus& status) { - CHECK(CreateTabHelperOnlyForRealizedWebStates()); switch (change.type()) { case WebStateListChange::Type::kStatusOnly: // Nothing to do. break; - case WebStateListChange::Type::kDetach: - StopObservingWebState( - change.As<WebStateListChangeDetach>().detached_web_state()); + case WebStateListChange::Type::kDetach: { + const auto& detach_change = change.As<WebStateListChangeDetach>(); + WebStateRemoved(detach_change.detached_web_state()); break; + } case WebStateListChange::Type::kMove: // Nothing do do. break; - case WebStateListChange::Type::kReplace: - StopObservingWebState( - change.As<WebStateListChangeReplace>().replaced_web_state()); + case WebStateListChange::Type::kReplace: { + const bool force_placeholder = web_state_list->IsBatchInProgress(); + const auto& replace_change = change.As<WebStateListChangeReplace>(); + WebStateInserted(replace_change.inserted_web_state(), force_placeholder); + WebStateRemoved(replace_change.replaced_web_state()); break; + } - case WebStateListChange::Type::kInsert: - // Nothing to do. + case WebStateListChange::Type::kInsert: { + const bool force_placeholder = web_state_list->IsBatchInProgress(); + const auto& insert_change = change.As<WebStateListChangeInsert>(); + WebStateInserted(insert_change.inserted_web_state(), force_placeholder); break; + } case WebStateListChange::Type::kGroupCreate: // Nothing to do. @@ -132,60 +80,43 @@ void PagePlaceholderBrowserAgent::WebStateRealized(web::WebState* web_state) { CHECK(CreateTabHelperOnlyForRealizedWebStates()); + web_state_observations_.RemoveObservation(web_state); AddPlaceholderToWebState(web_state); - StopObservingWebState(web_state); } void PagePlaceholderBrowserAgent::WebStateDestroyed(web::WebState* web_state) { CHECK(CreateTabHelperOnlyForRealizedWebStates()); - StopObservingWebState(web_state); + web_state_observations_.RemoveObservation(web_state); } -void PagePlaceholderBrowserAgent::StartObservingWebState( - web::WebState* web_state) { - CHECK(CreateTabHelperOnlyForRealizedWebStates()); - if (!web_state_observations_.IsObservingAnySource()) { - web_state_list_observation_.Observe(browser_->GetWebStateList()); +void PagePlaceholderBrowserAgent::WebStateInserted(web::WebState* web_state, + bool force_placeholder) { + if (CreateTabHelperOnlyForRealizedWebStates()) { + if (!web_state->IsRealized()) { + web_state_observations_.AddObservation(web_state); + return; + } } - web_state_observations_.AddObservation(web_state); + + if (!web_state->IsRealized() || force_placeholder) { + AddPlaceholderToWebState(web_state); + } } -void PagePlaceholderBrowserAgent::StopObservingWebState( - web::WebState* web_state) { - CHECK(CreateTabHelperOnlyForRealizedWebStates()); - if (web_state_observations_.IsObservingSource(web_state)) { - web_state_observations_.RemoveObservation(web_state); - if (!web_state_observations_.IsObservingAnySource()) { - web_state_list_observation_.Reset(); +void PagePlaceholderBrowserAgent::WebStateRemoved(web::WebState* web_state) { + if (CreateTabHelperOnlyForRealizedWebStates()) { + if (!web_state->IsRealized()) { + web_state_observations_.RemoveObservation(web_state); + return; } } } void PagePlaceholderBrowserAgent::AddPlaceholderToWebState( web::WebState* web_state) { - if (CreateTabHelperOnlyForRealizedWebStates()) { - if (!web_state->IsRealized()) { - StartObservingWebState(web_state); - return; - } - } - const GURL& visible_url = web_state->GetVisibleURL(); if (visible_url.is_valid() && visible_url != kChromeUINewTabURL) { PagePlaceholderTabHelper::FromWebState(web_state) ->AddPlaceholderForNextNavigation(); } } - -void PagePlaceholderBrowserAgent::RemovePlaceholderFromWebState( - web::WebState* web_state) { - if (CreateTabHelperOnlyForRealizedWebStates()) { - if (!web_state->IsRealized()) { - StopObservingWebState(web_state); - return; - } - } - - PagePlaceholderTabHelper::FromWebState(web_state) - ->CancelPlaceholderForNextNavigation(); -}
diff --git a/ios/chrome/browser/web/model/page_placeholder_tab_helper.h b/ios/chrome/browser/web/model/page_placeholder_tab_helper.h index b53a549..b819017c 100644 --- a/ios/chrome/browser/web/model/page_placeholder_tab_helper.h +++ b/ios/chrome/browser/web/model/page_placeholder_tab_helper.h
@@ -62,6 +62,7 @@ void AddPlaceholder(); void RemovePlaceholder(); + void FetchPlaceholderIfNecessary(); // Adds the given `snapshot` image to the `web_state_`'s view. The // `web_state_`'s view must be visible, and it must be in a view hierarchy @@ -69,7 +70,7 @@ void DisplaySnapshotImage(UIImage* snapshot); // Display image in a placeholder after retrieval from SnapshotTabHelper. - void OnImageRetrieved(UIImage* image); + void OnImageRetrieved(int request_id, UIImage* image); // WebState this tab helper is attached to. raw_ptr<web::WebState> web_state_ = nullptr; @@ -83,6 +84,17 @@ // true if placeholder must be displayed during the next navigation. bool add_placeholder_for_next_navigation_ = false; + // true if placeholder is being fetched. + bool placeholder_fetch_in_progress_ = false; + + // Integer incremented each time AddPlaceholderForNextNavigation() + // is called. Used to track that OnImageRetrieved(...) is for the + // expected request. + int placeholder_request_id_ = 0; + + // Cached snapshot. + UIImage* cached_placeholder_image_; + base::WeakPtrFactory<PagePlaceholderTabHelper> weak_factory_; };
diff --git a/ios/chrome/browser/web/model/page_placeholder_tab_helper.mm b/ios/chrome/browser/web/model/page_placeholder_tab_helper.mm index 361726c5..24b3324 100644 --- a/ios/chrome/browser/web/model/page_placeholder_tab_helper.mm +++ b/ios/chrome/browser/web/model/page_placeholder_tab_helper.mm
@@ -15,10 +15,10 @@ namespace { // Placeholder will not be displayed longer than this time. -constexpr base::TimeDelta kPlaceholderMaxDisplayTime = base::Seconds(1.5); +constexpr base::TimeDelta kPlaceholderMaxTimeout = base::Seconds(1.5); // Placeholder removal will include a fade-out animation of this length. -const NSTimeInterval kPlaceholderFadeOutAnimationLengthInSeconds = 0.5; +constexpr base::TimeDelta kFadeOutAnimationDuration = base::Seconds(0.5); } // namespace PagePlaceholderTabHelper::PagePlaceholderTabHelper(web::WebState* web_state) @@ -31,10 +31,19 @@ } void PagePlaceholderTabHelper::AddPlaceholderForNextNavigation() { - add_placeholder_for_next_navigation_ = true; + if (!add_placeholder_for_next_navigation_) { + ++placeholder_request_id_; + cached_placeholder_image_ = nil; + add_placeholder_for_next_navigation_ = true; + if (web_state_->IsRealized()) { + FetchPlaceholderIfNecessary(); + } + } } void PagePlaceholderTabHelper::CancelPlaceholderForNextNavigation() { + cached_placeholder_image_ = nil; + placeholder_fetch_in_progress_ = false; add_placeholder_for_next_navigation_ = false; if (displaying_placeholder_) { RemovePlaceholder(); @@ -73,9 +82,15 @@ RemovePlaceholder(); } -void PagePlaceholderTabHelper::OnImageRetrieved(UIImage* image) { - if (displaying_placeholder()) { - DisplaySnapshotImage(image); +void PagePlaceholderTabHelper::OnImageRetrieved(int request_id, + UIImage* image) { + if (request_id == placeholder_request_id_) { + placeholder_fetch_in_progress_ = false; + if (displaying_placeholder_) { + DisplaySnapshotImage(image); + } else if (add_placeholder_for_next_navigation_) { + cached_placeholder_image_ = image; + } } } @@ -91,35 +106,15 @@ add_placeholder_for_next_navigation_ = false; displaying_placeholder_ = true; - // Lazily create the placeholder view. - if (!placeholder_view_) { - placeholder_view_ = [[TopAlignedImageView alloc] init]; - placeholder_view_.backgroundColor = [UIColor whiteColor]; - placeholder_view_.translatesAutoresizingMaskIntoConstraints = NO; - } - // Update placeholder view's image and display it on top of WebState's view. - SnapshotTabHelper* snapshotTabHelper = - SnapshotTabHelper::FromWebState(web_state_); - if (snapshotTabHelper) { - // Show grey snapshots only for the WebStates that haven't been loaded - if (web_state_->IsLoading()) { - snapshotTabHelper->RetrieveGreySnapshot(base::CallbackToBlock( - base::BindOnce(&PagePlaceholderTabHelper::OnImageRetrieved, - weak_factory_.GetWeakPtr()))); - } else { - snapshotTabHelper->RetrieveColorSnapshot(base::CallbackToBlock( - base::BindOnce(&PagePlaceholderTabHelper::OnImageRetrieved, - weak_factory_.GetWeakPtr()))); - } - } + FetchPlaceholderIfNecessary(); // Remove placeholder if it takes too long to load the page. base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( FROM_HERE, base::BindOnce(&PagePlaceholderTabHelper::RemovePlaceholder, weak_factory_.GetWeakPtr()), - kPlaceholderMaxDisplayTime); + kPlaceholderMaxTimeout); } void PagePlaceholderTabHelper::DisplaySnapshotImage(UIImage* snapshot) { @@ -135,6 +130,14 @@ displaying_placeholder_ = false; return; } + + // Lazily create the placeholder view. + if (!placeholder_view_) { + placeholder_view_ = [[TopAlignedImageView alloc] init]; + placeholder_view_.backgroundColor = [UIColor whiteColor]; + placeholder_view_.translatesAutoresizingMaskIntoConstraints = NO; + } + placeholder_view_.image = snapshot; [web_state_view addSubview:placeholder_view_]; AddSameConstraints(guide, placeholder_view_); @@ -149,7 +152,7 @@ // Remove placeholder view with a fade-out animation. __weak UIView* weak_placeholder_view = placeholder_view_; - [UIView animateWithDuration:kPlaceholderFadeOutAnimationLengthInSeconds + [UIView animateWithDuration:kFadeOutAnimationDuration.InSecondsF() animations:^{ weak_placeholder_view.alpha = 0.0f; } @@ -158,3 +161,31 @@ weak_placeholder_view.alpha = 1.0f; }]; } + +void PagePlaceholderTabHelper::FetchPlaceholderIfNecessary() { + if (placeholder_fetch_in_progress_) { + return; + } + + if (cached_placeholder_image_) { + OnImageRetrieved(placeholder_request_id_, cached_placeholder_image_); + cached_placeholder_image_ = nil; + return; + } + + auto* snapshot_tab_helper = SnapshotTabHelper::FromWebState(web_state_); + if (!snapshot_tab_helper) { + return; + } + + placeholder_fetch_in_progress_ = true; + if (!web_state_->IsRealized() || web_state_->IsLoading()) { + snapshot_tab_helper->RetrieveGreySnapshot(base::CallbackToBlock( + base::BindOnce(&PagePlaceholderTabHelper::OnImageRetrieved, + weak_factory_.GetWeakPtr(), placeholder_request_id_))); + } else { + snapshot_tab_helper->RetrieveColorSnapshot(base::CallbackToBlock( + base::BindOnce(&PagePlaceholderTabHelper::OnImageRetrieved, + weak_factory_.GetWeakPtr(), placeholder_request_id_))); + } +}
diff --git a/ios/chrome/browser/whats_new/ui/whats_new_instructions_view_controller.mm b/ios/chrome/browser/whats_new/ui/whats_new_instructions_view_controller.mm index c8d1650..86c6125 100644 --- a/ios/chrome/browser/whats_new/ui/whats_new_instructions_view_controller.mm +++ b/ios/chrome/browser/whats_new/ui/whats_new_instructions_view_controller.mm
@@ -17,7 +17,8 @@ namespace { constexpr CGFloat kPreferredCornerRadius = 20; -constexpr CGFloat kDismissSymbolSize = 22; +constexpr CGFloat kDismissSymbolSizeIOS18 = 22; +constexpr CGFloat kDismissSymbolSizeIOS26 = 16; NSString* const kWhatsNewInstructionsLabelAccessibilityIdentifier = @"WhatsNewTitleAccessibilityIdentifier"; } // namespace @@ -77,9 +78,20 @@ _alertScreen.titleView = self.titleLabel; _alertScreen.actionHandler = self.actionHandler; _alertScreen.showDismissBarButton = YES; - UIImage* xmarkSymbol = SymbolWithPalette( - DefaultSymbolWithPointSize(kXMarkCircleFillSymbol, kDismissSymbolSize), - @[ [UIColor colorNamed:kGrey600Color] ]); + + UIImage* xmarkSymbol; + if (@available(iOS 26, *)) { + UIImageConfiguration* configuration = [UIImageSymbolConfiguration + configurationWithPointSize:kDismissSymbolSizeIOS26 + weight:UIImageSymbolWeightLight + scale:UIImageSymbolScaleUnspecified]; + xmarkSymbol = DefaultSymbolWithConfiguration(kXMarkSymbol, configuration); + } else { + xmarkSymbol = + SymbolWithPalette(DefaultSymbolWithPointSize(kXMarkCircleFillSymbol, + kDismissSymbolSizeIOS18), + @[ [UIColor colorNamed:kGrey600Color] ]); + } _alertScreen.customDismissBarButtonImage = xmarkSymbol; _alertScreen.topAlignedLayout = YES;
diff --git a/ios/chrome/test/earl_grey/chrome_test_case.mm b/ios/chrome/test/earl_grey/chrome_test_case.mm index d7670e3..27cf297 100644 --- a/ios/chrome/test/earl_grey/chrome_test_case.mm +++ b/ios/chrome/test/earl_grey/chrome_test_case.mm
@@ -29,6 +29,7 @@ #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case_app_interface.h" #import "ios/chrome/test/earl_grey/scoped_allow_crash_on_startup.h" +#import "ios/chrome/test/scoped_eg_synchronization_disabler.h" #import "ios/testing/earl_grey/app_launch_manager.h" #import "ios/testing/earl_grey/earl_grey_test.h" #import "ios/third_party/edo/src/Service/Sources/EDOClientService.h" @@ -291,6 +292,10 @@ if ([[GREY_REMOTE_CLASS_IN_APP(UIDevice) currentDevice] orientation] != _originalOrientation) { + // Synchronization off due to an infinite spinner if the keyboard is + // visible. + ScopedSynchronizationDisabler disabler; + // Rotate the device back to the original orientation, since some tests // attempt to run in other orientations. [EarlGrey rotateDeviceToOrientation:_originalOrientation error:nil];
diff --git a/ios_internal b/ios_internal index c07b97c..590133c 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit c07b97cf7d062f9164993da5913b2613f152a425 +Subproject commit 590133c247d87e501608f31c698216719413be5f
diff --git a/net/disk_cache/blockfile/entry_impl.cc b/net/disk_cache/blockfile/entry_impl.cc index 3511cc1de..f761a6b 100644 --- a/net/disk_cache/blockfile/entry_impl.cc +++ b/net/disk_cache/blockfile/entry_impl.cc
@@ -815,7 +815,7 @@ return Time::FromInternalValue(node->Data()->last_used); } -int32_t EntryImpl::GetDataSize(int index) const { +int64_t EntryImpl::GetDataSize(int index) const { if (index < 0 || index >= kNumStreams) return 0; @@ -824,12 +824,17 @@ } int EntryImpl::ReadData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback) { + if (offset > std::numeric_limits<int32_t>::max()) { + return net::ERR_INVALID_ARGUMENT; + } + if (callback.is_null()) - return ReadDataImpl(index, offset, buf, buf_len, std::move(callback)); + return ReadDataImpl(index, base::checked_cast<int32_t>(offset), buf, + buf_len, std::move(callback)); DCHECK(node_.Data()->dirty || read_only_); if (index < 0 || index >= kNumStreams) @@ -847,20 +852,25 @@ if (!background_queue_.get()) return net::ERR_UNEXPECTED; - background_queue_->ReadData(this, index, offset, buf, buf_len, - std::move(callback)); + background_queue_->ReadData(this, index, base::checked_cast<int32_t>(offset), + buf, buf_len, std::move(callback)); return net::ERR_IO_PENDING; } int EntryImpl::WriteData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback, bool truncate) { + // TODO(crbug.com/391398191): Support `offset` larger than int32_t max. + if (offset > std::numeric_limits<int32_t>::max()) { + return net::ERR_INVALID_ARGUMENT; + } + if (callback.is_null()) { - return WriteDataImpl(index, offset, buf, buf_len, std::move(callback), - truncate); + return WriteDataImpl(index, base::checked_cast<int32_t>(offset), buf, + buf_len, std::move(callback), truncate); } DCHECK(node_.Data()->dirty || read_only_); @@ -877,8 +887,8 @@ if (!background_queue_.get()) return net::ERR_UNEXPECTED; - background_queue_->WriteData(this, index, offset, buf, buf_len, truncate, - std::move(callback)); + background_queue_->WriteData(this, index, base::checked_cast<int32_t>(offset), + buf, buf_len, truncate, std::move(callback)); return net::ERR_IO_PENDING; }
diff --git a/net/disk_cache/blockfile/entry_impl.h b/net/disk_cache/blockfile/entry_impl.h index 212b4fa9..ab4e458 100644 --- a/net/disk_cache/blockfile/entry_impl.h +++ b/net/disk_cache/blockfile/entry_impl.h
@@ -173,14 +173,14 @@ void Close() override; std::string GetKey() const override; base::Time GetLastUsed() const override; - int32_t GetDataSize(int index) const override; + int64_t GetDataSize(int index) const override; int ReadData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback) override; int WriteData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback,
diff --git a/net/disk_cache/disk_cache.h b/net/disk_cache/disk_cache.h index c3e250f0..fe34bd61 100644 --- a/net/disk_cache/disk_cache.h +++ b/net/disk_cache/disk_cache.h
@@ -347,36 +347,40 @@ virtual base::Time GetLastUsed() const = 0; // Returns the size of the cache data with the given index. - virtual int32_t GetDataSize(int index) const = 0; + virtual int64_t GetDataSize(int index) const = 0; - // Copies cached data into the given buffer of length |buf_len|. Returns the + // Copies cached data into the given buffer of length `buf_len`. Returns the // number of bytes read or a network error code. If this function returns // ERR_IO_PENDING, the completion callback will be called on the current - // thread when the operation completes, and a reference to |buf| will be + // thread when the operation completes, and a reference to `buf` will be // retained until the callback is called. Note that as long as the function // does not complete immediately, the callback will always be invoked, even // after Close has been called; in other words, the caller may close this // entry without having to wait for all the callbacks, and still rely on the // cleanup performed from the callback code. + // Note that `offset` larger than int32 max is supported only by Simple Cache + // backend. It will return ERR_INVALID_ARGUMENT for other backends. virtual int ReadData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback) = 0; - // Copies data from the given buffer of length |buf_len| into the cache. + // Copies data from the given buffer of length `buf_len` into the cache. // Returns the number of bytes written or a network error code. If this // function returns ERR_IO_PENDING, the completion callback will be called // on the current thread when the operation completes, and a reference to - // |buf| will be retained until the callback is called. Note that as long as + // `buf` will be retained until the callback is called. Note that as long as // the function does not complete immediately, the callback will always be // invoked, even after Close has been called; in other words, the caller may // close this entry without having to wait for all the callbacks, and still // rely on the cleanup performed from the callback code. // If truncate is true, this call will truncate the stored data at the end of // what we are writing here. + // Note that `offset` larger than int32 max is supported only by Simple Cache + // backend. It will return ERR_INVALID_ARGUMENT for other backends. virtual int WriteData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback,
diff --git a/net/disk_cache/entry_unittest.cc b/net/disk_cache/entry_unittest.cc index 8bfa7ed..d2329af 100644 --- a/net/disk_cache/entry_unittest.cc +++ b/net/disk_cache/entry_unittest.cc
@@ -2786,6 +2786,153 @@ CacheGiantEntry(); } +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_WIN) +// Android build does not support 64 bits offset file read, so this test does +// not work. +// This test is too slow on Windows which ends up with Timeout. +// Writing to a large offset can be slow on some filesystems if they don't +// efficiently support sparse files. +TEST_F(DiskCacheEntryTest, SimpleCacheLargeOffsetIO) { + SetBackendToTest(BackendToTest::kSimple); + SetMaxSize(100LL * 1024 * 1024 * 1024); + InitCache(); + + std::string key("the first key"); + disk_cache::Entry* entry; + ASSERT_THAT(CreateEntry(key, &entry), IsOk()); + + // Write 4 MB so that we cover multiple entries. + static constexpr int kSize = 4 * 1024 * 1024; + + auto buf_1 = CacheTestCreateAndFillBuffer(kSize, false); + auto buf_2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize); + + // Write data from 4GB - 2MB to 4GB + 2MB. + constexpr int64_t kOffset = 4LL * 1024 * 1024 * 1024 - 2 * 1024 * 1024; + + net::TestCompletionCallback cb; + + int ret = entry->WriteData(0, 0, buf_1.get(), kSize, cb.callback(), false); + EXPECT_EQ(kSize, cb.GetResult(ret)); + + ret = entry->ReadData(0, 0, buf_2.get(), kSize, cb.callback()); + + ASSERT_EQ(kSize, cb.GetResult(ret)); + EXPECT_EQ(buf_1->first(kSize), buf_2->span()); + + entry->Close(); + ASSERT_THAT(OpenEntry(key, &entry), IsOk()); + + ret = entry->WriteData(1, kOffset, buf_1.get(), kSize, cb.callback(), false); + EXPECT_EQ(kSize, cb.GetResult(ret)); + EXPECT_EQ(kOffset + kSize, entry->GetDataSize(1)); + + entry->Close(); + ASSERT_THAT(OpenEntry(key, &entry), IsOk()); + + buf_2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize); + ret = entry->ReadData(0, 0, buf_2.get(), kSize, cb.callback()); + + ASSERT_EQ(kSize, cb.GetResult(ret)); + EXPECT_EQ(buf_1->first(kSize), buf_2->span()); + + buf_2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize); + ret = entry->ReadData(1, kOffset, buf_2.get(), kSize, cb.callback()); + + ASSERT_EQ(kSize, cb.GetResult(ret)); + EXPECT_EQ(buf_1->first(kSize), buf_2->span()); + + entry->Close(); +} +#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_WIN) + +TEST_F(DiskCacheEntryTest, SimpleCacheInvalidLargeOffsetWriteToStream0) { + SetBackendToTest(BackendToTest::kSimple); + SetMaxSize(100LL * 1024 * 1024 * 1024); + InitCache(); + + std::string key("the first key"); + disk_cache::Entry* entry; + ASSERT_THAT(CreateEntry(key, &entry), IsOk()); + + // Write 4 MB so that we cover multiple entries. + static constexpr int kSize = 4 * 1024 * 1024; + + auto buf_1 = CacheTestCreateAndFillBuffer(kSize, false); + + // Write data from 4GB - 2MB to 4GB + 2MB. + constexpr int64_t kOffset = 4LL * 1024 * 1024 * 1024 - 2 * 1024 * 1024; + + // Stream 0 data size limitation is int32_t max. If we pass something which + // exceeds the limitation, it should fail. + EXPECT_EQ(net::ERR_INVALID_ARGUMENT, + entry->WriteData(0, kOffset, buf_1.get(), kSize, + net::CompletionOnceCallback(), false)); + entry->Close(); +} + +TEST_P(DiskCacheGenericEntryTest, InvalidLargeOffsetWrite) { + // SimpleCache supports large offset. + if (backend_to_test() == BackendToTest::kSimple) { + return; + } + + InitCache(); + std::string key("the first key"); + disk_cache::Entry* entry; + ASSERT_THAT(CreateEntry(key, &entry), IsOk()); + + // Write 4 MB. + static constexpr size_t kSize = 4 * 1024 * 1024; + auto buf_1 = CacheTestCreateAndFillBuffer(kSize, false); + + // Try to write data from 4GB - 2MB to 4GB + 2MB. + constexpr int64_t offset = + static_cast<int64_t>(std::numeric_limits<int32_t>::max()) + 1; + + for (int i = 0; i < SupportedStreamCount(); ++i) { + EXPECT_EQ(net::ERR_INVALID_ARGUMENT, + entry->WriteData(i, offset, buf_1.get(), kSize, + net::CompletionOnceCallback(), false)); + } + + entry->Close(); +} + +TEST_P(DiskCacheGenericEntryTest, InvalidLargeOffsetRead) { + // SimpleCache supports large offset. + if (backend_to_test() == BackendToTest::kSimple) { + return; + } + + InitCache(); + std::string key("the first key"); + disk_cache::Entry* entry; + ASSERT_THAT(CreateEntry(key, &entry), IsOk()); + + // Write 4 MB. + static constexpr size_t kSize = 4 * 1024 * 1024; + auto buf_1 = CacheTestCreateAndFillBuffer(kSize, false); + auto buf_2 = base::MakeRefCounted<net::IOBufferWithSize>(kSize); + + net::TestCompletionCallback cb; + + int ret = entry->WriteData(0, 0, buf_1.get(), kSize, cb.callback(), false); + EXPECT_EQ(kSize, cb.GetResult(ret)); + + // Try to read data from 4GB - 2MB to 4GB + 2MB. + constexpr int64_t offset = + static_cast<int64_t>(std::numeric_limits<int32_t>::max()) + 1; + + for (int i = 0; i < SupportedStreamCount(); ++i) { + EXPECT_EQ(net::ERR_INVALID_ARGUMENT, + entry->ReadData(i, offset, buf_2.get(), kSize, + net::CompletionOnceCallback())); + } + + entry->Close(); +} + TEST_F(DiskCacheEntryTest, SimpleCacheReadWriteDestroyBuffer) { // Proving that the test works well with optimistic operations enabled is // subtle, instead run only in APP_CACHE mode to disable optimistic @@ -4215,7 +4362,7 @@ base::File::FLAG_READ | base::File::FLAG_OPEN); ASSERT_TRUE(entry_file0.IsValid()); - auto data_size = std::to_array<int32_t>({kSize, stream1_size, 0}); + auto data_size = std::to_array<int64_t>({kSize, stream1_size, 0}); int sparse_data_size = 0; disk_cache::SimpleEntryStat entry_stat(base::Time::Now(), data_size, sparse_data_size);
diff --git a/net/disk_cache/memory/mem_entry_impl.cc b/net/disk_cache/memory/mem_entry_impl.cc index 1ab54c5..d79bfbf 100644 --- a/net/disk_cache/memory/mem_entry_impl.cc +++ b/net/disk_cache/memory/mem_entry_impl.cc
@@ -170,24 +170,37 @@ return last_used_; } -int32_t MemEntryImpl::GetDataSize(int index) const { +int64_t MemEntryImpl::GetDataSize(int index) const { if (index < 0 || index >= kNumStreams) return 0; return data_[index].size(); } int MemEntryImpl::ReadData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback) { + // TODO(crbug.com/391398191): Update the maximum to size_t max when it's + // supported. `offset` must be within size_t range anyway so that the data + // will be in-mmory. + if (offset > std::numeric_limits<int32_t>::max()) { + if (net_log_.IsCapturing()) { + NetLogReadWriteComplete(net_log_, net::NetLogEventType::ENTRY_READ_DATA, + net::NetLogEventPhase::NONE, + net::ERR_INVALID_ARGUMENT); + } + return net::ERR_INVALID_ARGUMENT; + } + if (net_log_.IsCapturing()) { NetLogReadWriteData(net_log_, net::NetLogEventType::ENTRY_READ_DATA, net::NetLogEventPhase::BEGIN, index, offset, buf_len, false); } - int result = InternalReadData(index, offset, buf, buf_len); + int result = InternalReadData(index, base::checked_cast<int32_t>(offset), buf, + buf_len); if (net_log_.IsCapturing()) { NetLogReadWriteComplete(net_log_, net::NetLogEventType::ENTRY_READ_DATA, @@ -197,18 +210,31 @@ } int MemEntryImpl::WriteData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback, bool truncate) { + // TODO(crbug.com/391398191): Update the maximum to size_t max when it's + // supported. `offset` must be within size_t range anyway so that the data + // will be in-mmory. + if (offset > std::numeric_limits<int32_t>::max()) { + if (net_log_.IsCapturing()) { + NetLogReadWriteComplete(net_log_, net::NetLogEventType::ENTRY_READ_DATA, + net::NetLogEventPhase::NONE, + net::ERR_INVALID_ARGUMENT); + } + return net::ERR_INVALID_ARGUMENT; + } + if (net_log_.IsCapturing()) { NetLogReadWriteData(net_log_, net::NetLogEventType::ENTRY_WRITE_DATA, net::NetLogEventPhase::BEGIN, index, offset, buf_len, truncate); } - int result = InternalWriteData(index, offset, buf, buf_len, truncate); + int result = InternalWriteData(index, base::checked_cast<int32_t>(offset), + buf, buf_len, truncate); if (net_log_.IsCapturing()) { NetLogReadWriteComplete(net_log_, net::NetLogEventType::ENTRY_WRITE_DATA,
diff --git a/net/disk_cache/memory/mem_entry_impl.h b/net/disk_cache/memory/mem_entry_impl.h index f97bf0d8..4d996b94 100644 --- a/net/disk_cache/memory/mem_entry_impl.h +++ b/net/disk_cache/memory/mem_entry_impl.h
@@ -104,14 +104,14 @@ void Close() override; std::string GetKey() const override; base::Time GetLastUsed() const override; - int32_t GetDataSize(int index) const override; + int64_t GetDataSize(int index) const override; int ReadData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback) override; int WriteData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback,
diff --git a/net/disk_cache/mock/mock_entry_impl.h b/net/disk_cache/mock/mock_entry_impl.h index aeb4be6..caf2715 100644 --- a/net/disk_cache/mock/mock_entry_impl.h +++ b/net/disk_cache/mock/mock_entry_impl.h
@@ -22,11 +22,11 @@ MOCK_METHOD(void, Doom, (), (override)); MOCK_METHOD(std::string, GetKey, (), (const, override)); MOCK_METHOD(base::Time, GetLastUsed, (), (const, override)); - MOCK_METHOD(int32_t, GetDataSize, (int index), (const, override)); + MOCK_METHOD(int64_t, GetDataSize, (int index), (const, override)); MOCK_METHOD(int, ReadData, (int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback), @@ -34,7 +34,7 @@ MOCK_METHOD(int, WriteData, (int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback,
diff --git a/net/disk_cache/simple/simple_entry_format.h b/net/disk_cache/simple/simple_entry_format.h index 01a7a35..2bde6f16 100644 --- a/net/disk_cache/simple/simple_entry_format.h +++ b/net/disk_cache/simple/simple_entry_format.h
@@ -75,7 +75,8 @@ uint64_t final_magic_number = 0; uint32_t flags = 0; uint32_t data_crc32 = 0; - // |stream_size| is only used in the EOF record for stream 0. + // |stream_size| is only used in the EOF record for stream 0. The value must + // smaller than int32 max. uint32_t stream_size = 0; // Avoid implicit padding so `std::has_unique_object_representations_v<>` will
diff --git a/net/disk_cache/simple/simple_entry_impl.cc b/net/disk_cache/simple/simple_entry_impl.cc index 22e1326..338d0fe 100644 --- a/net/disk_cache/simple/simple_entry_impl.cc +++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -45,6 +45,30 @@ // the cache. constexpr int64_t kMaxSparseDataSizeDivisor = 10; +// Due to the data structure of EntryMetadata limitation, the total size of the +// all data must fit in 38 bits. +// For the file containing Stream 1, we have +// 1. Stream 0: limited to int32 max size +// 2. Stream 1: no limitation +// 3. Stream 2: no limitation +// (Sparse data does not exist at the same time with Stream 1.) +// +// Also, stream 1 data includes the key, header and the file eof. The key is +// int32 max size. +// The size limitation is following: +// (Stream 0: 32 bits) + (Stream 1: 32 bits key + header size + eof size + +// 38 bits content) + (Stream 2) <= 38 bits +// +// Therefore, we set the Stream 1 size limit to the following assuming that +// stream 1 and Stream 2 uses the similar amount of size. +// (38 bits max - stream 0 max (32 bits)) / 2 - key max (32 bits) - header - eof +// +// TODO(crbug.com/391398191): Make the file size limit consistent and move them +// to MaxFileSize in the backend. +constexpr int64_t kStream1SizeLimit = ((1LL << 38) - (1LL << 32)) / 2 - + (1LL << 32) - sizeof(SimpleFileHeader) - + sizeof(SimpleFileEOF); + OpenEntryIndexEnum ComputeIndexState(SimpleBackendImpl* backend, uint64_t entry_hash) { if (!backend->index()->initialized()) @@ -363,14 +387,14 @@ return last_used_; } -int32_t SimpleEntryImpl::GetDataSize(int stream_index) const { +int64_t SimpleEntryImpl::GetDataSize(int stream_index) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_LE(0, data_size_[stream_index]); return data_size_[stream_index]; } int SimpleEntryImpl::ReadData(int stream_index, - int offset, + int64_t offset, net::IOBuffer* buf, int buf_len, CompletionOnceCallback callback) { @@ -412,7 +436,7 @@ } int SimpleEntryImpl::WriteData(int stream_index, - int offset, + int64_t offset, net::IOBuffer* buf, int buf_len, CompletionOnceCallback callback, @@ -435,9 +459,10 @@ return net::ERR_INVALID_ARGUMENT; } - int end_offset; + int64_t end_offset; if (!base::CheckAdd(offset, buf_len).AssignIfValid(&end_offset) || - (backend_.get() && end_offset > backend_->MaxFileSize())) { + (backend_.get() && end_offset > backend_->MaxFileSize()) || + end_offset > kStream1SizeLimit) { if (net_log_.IsCapturing()) { NetLogReadWriteComplete( net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END, @@ -445,6 +470,19 @@ } return net::ERR_FAILED; } + + // Stream 0 data size limitation is int32_t max. + // TODO(crbug.com/433856002): int32 max is too large for stream 0 where stream + // 0 needs consecutive memory space. Set the proper size limitation. + if (stream_index == 0 && end_offset > std::numeric_limits<int32_t>::max()) { + if (net_log_.IsCapturing()) { + NetLogReadWriteComplete( + net_log_, net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END, + net::NetLogEventPhase::NONE, net::ERR_INVALID_ARGUMENT); + } + return net::ERR_INVALID_ARGUMENT; + } + ScopedOperationRunner operation_runner(this); // Stream 0 data is kept in memory, so can be written immediatly if there are @@ -452,7 +490,7 @@ if (stream_index == 0 && state_ == STATE_READY && pending_operations_.size() == 0) { state_ = STATE_IO_PENDING; - SetStream0Data(buf, offset, buf_len, truncate); + SetStream0Data(buf, base::checked_cast<int32_t>(offset), buf_len, truncate); state_ = STATE_READY; return buf_len; } @@ -978,7 +1016,7 @@ int SimpleEntryImpl::ReadDataInternal(bool sync_possible, int stream_index, - int offset, + int64_t offset, net::IOBuffer* buf, int buf_len, net::CompletionOnceCallback callback) { @@ -1011,13 +1049,21 @@ return PostToCallbackIfNeeded(sync_possible, std::move(callback), 0); } - // Truncate read to not go past end of stream. - buf_len = std::min(buf_len, GetDataSize(stream_index) - offset); + // Truncate read to not go past end of stream. Note that `buf_len` must fit + // within int range since it takes the minimum. + buf_len = std::min(static_cast<int64_t>(buf_len), + GetDataSize(stream_index) - offset); // Since stream 0 data is kept in memory, it is read immediately. if (stream_index == 0) { + // Stream 0 data size limitation is int32_t max. + // TODO(crbug.com/433856002): int32 max is too large for stream 0 where + // stream 0 needs consecutive memory space. Set the proper size limitation. + CHECK_LE(GetDataSize(stream_index), std::numeric_limits<int32_t>::max()); + state_ = STATE_IO_PENDING; - ReadFromBuffer(stream_0_data_.get(), offset, buf_len, buf); + ReadFromBuffer(stream_0_data_.get(), static_cast<size_t>(offset), buf_len, + buf); state_ = STATE_READY; return PostToCallbackIfNeeded(sync_possible, std::move(callback), buf_len); } @@ -1025,8 +1071,13 @@ // Sometimes we can read in-ram prefetched stream 1 data immediately, too. if (stream_index == 1) { if (stream_1_prefetch_data_) { + CHECK_EQ(stream_1_prefetch_data_->size(), GetDataSize(1)); + // Prefetch data size limitation is int32_t max. + CHECK_LE(GetDataSize(stream_index), std::numeric_limits<int32_t>::max()); + state_ = STATE_IO_PENDING; - ReadFromBuffer(stream_1_prefetch_data_.get(), offset, buf_len, buf); + ReadFromBuffer(stream_1_prefetch_data_.get(), static_cast<size_t>(offset), + buf_len, buf); state_ = STATE_READY; return PostToCallbackIfNeeded(sync_possible, std::move(callback), buf_len); @@ -1066,7 +1117,7 @@ } void SimpleEntryImpl::WriteDataInternal(int stream_index, - int offset, + int64_t offset, net::IOBuffer* buf, int buf_len, net::CompletionOnceCallback callback, @@ -1099,7 +1150,7 @@ // Since stream 0 data is kept in memory, it will be written immediatly. if (stream_index == 0) { state_ = STATE_IO_PENDING; - SetStream0Data(buf, offset, buf_len, truncate); + SetStream0Data(buf, base::checked_cast<int32_t>(offset), buf_len, truncate); state_ = STATE_READY; if (!callback.is_null()) { base::SequencedTaskRunner::GetCurrentDefault()->PostTask( @@ -1110,7 +1161,7 @@ // Ignore zero-length writes that do not change the file size. if (buf_len == 0) { - int32_t data_size = data_size_[stream_index]; + int64_t data_size = data_size_[stream_index]; if (truncate ? (offset == data_size) : (offset <= data_size)) { if (!callback.is_null()) { base::SequencedTaskRunner::GetCurrentDefault()->PostTask( @@ -1504,7 +1555,7 @@ void SimpleEntryImpl::ReadOperationComplete( int stream_index, - int offset, + int64_t offset, net::CompletionOnceCallback completion_callback, std::unique_ptr<SimpleEntryStat> entry_stat, std::unique_ptr<SimpleSynchronousEntry::ReadResult> read_result) { @@ -1659,28 +1710,28 @@ SimpleBackendImpl* backend_ptr = backend_.get(); if (doom_state_ == DOOM_NONE && backend_ptr) { - backend_ptr->index()->UpdateEntrySize( - entry_hash_, base::checked_cast<uint32_t>(GetDiskUsage())); + backend_ptr->index()->UpdateEntrySize(entry_hash_, GetDiskUsage()); } } -int64_t SimpleEntryImpl::GetDiskUsage() const { - int64_t file_size = 0; - for (int data_size : data_size_) { - file_size += simple_util::GetFileSizeFromDataSize(key_->size(), data_size); +uint64_t SimpleEntryImpl::GetDiskUsage() const { + uint64_t file_size = 0; + for (int64_t data_size : data_size_) { + file_size += base::checked_cast<uint64_t>( + simple_util::GetFileSizeFromDataSize(key_->size(), data_size)); } file_size += sparse_data_size_; return file_size; } void SimpleEntryImpl::ReadFromBuffer(net::GrowableIOBuffer* in_buf, - int offset, + size_t offset, int buf_len, net::IOBuffer* out_buf) { DCHECK_GE(buf_len, 0); - out_buf->span().copy_prefix_from(in_buf->span().subspan( - base::checked_cast<size_t>(offset), base::checked_cast<size_t>(buf_len))); + out_buf->span().copy_prefix_from( + in_buf->span().subspan(offset, base::checked_cast<size_t>(buf_len))); UpdateDataFromEntryStat( SimpleEntryStat(base::Time::Now(), data_size_, sparse_data_size_)); } @@ -1694,8 +1745,16 @@ // changes of the headers. Also, support writes to stream 0 that have // different access patterns, as required by the API contract. // All other clients of the Simple Cache are encouraged to use stream 1. + + // stream 0 data size limitation is int32_t max. + CHECK_LE(GetDataSize(0), std::numeric_limits<int32_t>::max()); + CHECK_LE(0, GetDataSize(0)); + CHECK_LE(0, offset); + CHECK_LE(0, buf_len); + size_t u_offset = static_cast<size_t>(offset); + have_written_[0] = true; - int data_size = GetDataSize(0); + size_t data_size = static_cast<size_t>(GetDataSize(0)); if (offset == 0 && truncate) { stream_0_data_->SetCapacity(buf_len); if (buf_len) { @@ -1704,22 +1763,19 @@ } data_size_[0] = buf_len; } else { - const int buffer_size = - truncate ? offset + buf_len : std::max(offset + buf_len, data_size); - stream_0_data_->SetCapacity(buffer_size); - // If |stream_0_data_| was extended, the extension until offset needs to be + const size_t buffer_size = + truncate ? u_offset + buf_len : std::max(u_offset + buf_len, data_size); + stream_0_data_->SetCapacity(base::checked_cast<int>(buffer_size)); + // If `stream_0_data_` was extended, the extension until offset needs to be // zero-filled. - const int fill_size = offset <= data_size ? 0 : offset - data_size; + const size_t fill_size = u_offset <= data_size ? 0 : u_offset - data_size; if (fill_size > 0) { - std::ranges::fill( - stream_0_data_->span().subspan(base::checked_cast<size_t>(data_size), - base::checked_cast<size_t>(fill_size)), - 0); + std::ranges::fill(stream_0_data_->span().subspan(data_size, fill_size), + 0); } if (buf) { - stream_0_data_->span() - .subspan(base::checked_cast<size_t>(offset)) - .copy_prefix_from(buf->first(base::checked_cast<size_t>(buf_len))); + stream_0_data_->span().subspan(u_offset).copy_prefix_from( + buf->first(base::checked_cast<size_t>(buf_len))); } data_size_[0] = buffer_size; }
diff --git a/net/disk_cache/simple/simple_entry_impl.h b/net/disk_cache/simple/simple_entry_impl.h index a345e63..5bc42d8 100644 --- a/net/disk_cache/simple/simple_entry_impl.h +++ b/net/disk_cache/simple/simple_entry_impl.h
@@ -120,14 +120,14 @@ // GetLastUsed() should not be called in net::APP_CACHE mode since the times // are not updated. base::Time GetLastUsed() const override; - int32_t GetDataSize(int index) const override; + int64_t GetDataSize(int index) const override; int ReadData(int stream_index, - int offset, + int64_t offset, net::IOBuffer* buf, int buf_len, CompletionOnceCallback callback) override; int WriteData(int stream_index, - int offset, + int64_t offset, net::IOBuffer* buf, int buf_len, CompletionOnceCallback callback, @@ -241,13 +241,13 @@ int ReadDataInternal(bool sync_possible, int index, - int offset, + int64_t offset, net::IOBuffer* buf, int buf_len, CompletionOnceCallback callback); void WriteDataInternal(int index, - int offset, + int64_t offset, net::IOBuffer* buf, int buf_len, CompletionOnceCallback callback, @@ -300,7 +300,7 @@ // Called after an asynchronous read. Updates |crc32s_| if possible. void ReadOperationComplete( int stream_index, - int offset, + int64_t offset, CompletionOnceCallback completion_callback, std::unique_ptr<SimpleEntryStat> entry_stat, std::unique_ptr<SimpleSynchronousEntry::ReadResult> read_result); @@ -340,20 +340,21 @@ // operations. void UpdateDataFromEntryStat(const SimpleEntryStat& entry_stat); - int64_t GetDiskUsage() const; + uint64_t GetDiskUsage() const; // Completes a read from the stream data kept in memory, logging metrics // and updating metadata. This assumes the caller has already range-checked // offset and buf_len appropriately, and therefore always reads `buf_len` // bytes. void ReadFromBuffer(net::GrowableIOBuffer* in_buf, - int offset, + size_t offset, int buf_len, net::IOBuffer* out_buf); - // Copies data from |buf| to the internal in-memory buffer for stream 0. If - // |truncate| is set to true, the target buffer will be truncated at |offset| - // + |buf_len| before being written. + // Copies data from `buf` to the internal in-memory buffer for stream 0. If + // `truncate` is set to true, the target buffer will be truncated at `offset` + // + `buf_len` before being written. + // `offset` + `buf_len` must be smaller than int32_t max. void SetStream0Data(net::IOBuffer* buf, int offset, int buf_len, @@ -382,7 +383,7 @@ // synchronous entry at the completion of each item of asynchronous IO. // TODO(clamy): Unify last_used_ with data in the index. base::Time last_used_; - std::array<int32_t, kSimpleEntryStreamCount> data_size_; + std::array<int64_t, kSimpleEntryStreamCount> data_size_; uint64_t sparse_data_size_ = 0; // Number of times this object has been returned from Backend::OpenEntry() and
diff --git a/net/disk_cache/simple/simple_entry_operation.cc b/net/disk_cache/simple/simple_entry_operation.cc index 497f3e3..7ad3035c 100644 --- a/net/disk_cache/simple/simple_entry_operation.cc +++ b/net/disk_cache/simple/simple_entry_operation.cc
@@ -65,7 +65,7 @@ SimpleEntryOperation SimpleEntryOperation::ReadOperation( SimpleEntryImpl* entry, int index, - int offset, + int64_t offset, int length, net::IOBuffer* buf, CompletionOnceCallback callback) { @@ -78,7 +78,7 @@ SimpleEntryOperation SimpleEntryOperation::WriteOperation( SimpleEntryImpl* entry, int index, - int offset, + int64_t offset, int length, net::IOBuffer* buf, bool truncate, @@ -147,7 +147,7 @@ SimpleEntryOperation::SimpleEntryOperation(SimpleEntryImpl* entry, net::IOBuffer* buf, net::CompletionOnceCallback callback, - int offset, + int64_t offset, uint64_t sparse_offset, int length, size_t sparse_length,
diff --git a/net/disk_cache/simple/simple_entry_operation.h b/net/disk_cache/simple/simple_entry_operation.h index 0f034f7c..8a6bb0e 100644 --- a/net/disk_cache/simple/simple_entry_operation.h +++ b/net/disk_cache/simple/simple_entry_operation.h
@@ -64,13 +64,13 @@ static SimpleEntryOperation CloseOperation(SimpleEntryImpl* entry); static SimpleEntryOperation ReadOperation(SimpleEntryImpl* entry, int index, - int offset, + int64_t offset, int length, net::IOBuffer* buf, CompletionOnceCallback callback); static SimpleEntryOperation WriteOperation(SimpleEntryImpl* entry, int index, - int offset, + int64_t offset, int length, net::IOBuffer* buf, bool truncate, @@ -111,7 +111,7 @@ OpenEntryIndexEnum index_state() const { return index_state_; } int index() const { return index_; } - int offset() const { return offset_; } + int64_t offset() const { return offset_; } int64_t sparse_offset() const { return sparse_offset_; } int length() const { return length_; } size_t sparse_length() const { return sparse_length_; } @@ -123,7 +123,7 @@ SimpleEntryOperation(SimpleEntryImpl* entry, net::IOBuffer* buf, CompletionOnceCallback callback, - int offset, + int64_t offset, uint64_t sparse_offset, int length, size_t sparse_length, @@ -143,7 +143,7 @@ EntryResultState entry_result_state_; // Used in write and read operations. - const int offset_; + const int64_t offset_; const int64_t sparse_offset_; const int length_; const size_t sparse_length_;
diff --git a/net/disk_cache/simple/simple_index.cc b/net/disk_cache/simple/simple_index.cc index 4afa606b..fd53e5e 100644 --- a/net/disk_cache/simple/simple_index.cc +++ b/net/disk_cache/simple/simple_index.cc
@@ -566,7 +566,7 @@ } bool SimpleIndex::UpdateEntrySize(uint64_t entry_hash, - base::StrictNumeric<uint32_t> entry_size) { + base::StrictNumeric<uint64_t> entry_size) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto it = entries_set_.find(entry_hash); if (it == entries_set_.end()) @@ -621,11 +621,11 @@ bool SimpleIndex::UpdateEntryIteratorSize( EntrySet::iterator* it, - base::StrictNumeric<uint32_t> entry_size) { + base::StrictNumeric<uint64_t> entry_size) { // Update the total cache size with the new entry size. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_GE(cache_size_, (*it)->second.GetEntrySize()); - uint32_t original_size = (*it)->second.GetEntrySize(); + uint64_t original_size = (*it)->second.GetEntrySize(); // If SetEntrySize fails, we cannot update the entry iterator correctly. if (!(*it)->second.SetEntrySize(entry_size)) {
diff --git a/net/disk_cache/simple/simple_index.h b/net/disk_cache/simple/simple_index.h index efbd2bb..b6ca8a4b 100644 --- a/net/disk_cache/simple/simple_index.h +++ b/net/disk_cache/simple/simple_index.h
@@ -175,7 +175,7 @@ // index. This should be the total disk-file size including all streams of the // entry. bool UpdateEntrySize(uint64_t entry_hash, - base::StrictNumeric<uint32_t> entry_size); + base::StrictNumeric<uint64_t> entry_size); using EntrySet = absl::flat_hash_map<uint64_t, EntryMetadata>; @@ -259,7 +259,7 @@ // Update the size of the entry pointed to by the given iterator. Return // true if the new size actually results in a change. bool UpdateEntryIteratorSize(EntrySet::iterator* it, - base::StrictNumeric<uint32_t> entry_size); + base::StrictNumeric<uint64_t> entry_size); // Must run on IO Thread. void MergeInitializingSet(std::unique_ptr<SimpleIndexLoadResult> load_result);
diff --git a/net/disk_cache/simple/simple_synchronous_entry.cc b/net/disk_cache/simple/simple_synchronous_entry.cc index d5382667..6226daa8 100644 --- a/net/disk_cache/simple/simple_synchronous_entry.cc +++ b/net/disk_cache/simple/simple_synchronous_entry.cc
@@ -240,7 +240,7 @@ SimpleEntryStat::SimpleEntryStat( base::Time last_used, - const std::array<int32_t, kSimpleEntryStreamCount>& data_size, + const std::array<int64_t, kSimpleEntryStreamCount>& data_size, const uint64_t sparse_data_size) : last_used_(last_used), data_size_(data_size), @@ -250,35 +250,34 @@ // since this version of the cache always writes it. In the read case, it may // not be present and these methods can't be relied upon. -int SimpleEntryStat::GetOffsetInFile(size_t key_length, - int offset, - int stream_index) const { - const size_t headers_size = sizeof(SimpleFileHeader) + key_length; - const size_t additional_offset = +int64_t SimpleEntryStat::GetOffsetInFile(size_t key_length, + int64_t offset, + int stream_index) const { + const int64_t headers_size = + sizeof(SimpleFileHeader) + base::checked_cast<int64_t>(key_length); + const int64_t additional_offset = stream_index == 0 ? data_size_[1] + sizeof(SimpleFileEOF) : 0; return headers_size + offset + additional_offset; } -int SimpleEntryStat::GetEOFOffsetInFile(size_t key_length, - int stream_index) const { - size_t additional_offset; - if (stream_index != 0) - additional_offset = 0; - else - additional_offset = sizeof(net::SHA256HashValue); +int64_t SimpleEntryStat::GetEOFOffsetInFile(size_t key_length, + int stream_index) const { + const int64_t additional_offset = + stream_index == 0 ? sizeof(net::SHA256HashValue) : 0; return additional_offset + GetOffsetInFile(key_length, data_size_[stream_index], stream_index); } -int SimpleEntryStat::GetLastEOFOffsetInFile(size_t key_length, - int stream_index) const { - if (stream_index == 1) +int64_t SimpleEntryStat::GetLastEOFOffsetInFile(size_t key_length, + int stream_index) const { + if (stream_index == 1) { return GetEOFOffsetInFile(key_length, 0); + } return GetEOFOffsetInFile(key_length, stream_index); } int64_t SimpleEntryStat::GetFileSize(size_t key_length, int file_index) const { - int32_t total_data_size; + int64_t total_data_size; if (file_index == 0) { total_data_size = data_size_[0] + data_size_[1] + sizeof(net::SHA256HashValue) + sizeof(SimpleFileEOF); @@ -310,12 +309,12 @@ : index(index_p), has_crc32(has_crc32_p), data_crc32(data_crc32_p) {} SimpleSynchronousEntry::ReadRequest::ReadRequest(int index_p, - int offset_p, + int64_t offset_p, int buf_len_p) : index(index_p), offset(offset_p), buf_len(buf_len_p) {} SimpleSynchronousEntry::WriteRequest::WriteRequest(int index_p, - int offset_p, + int64_t offset_p, int buf_len_p, uint32_t previous_crc32_p, bool truncate_p, @@ -660,7 +659,7 @@ return; } } - int offset = in_entry_op.offset; + int64_t offset = in_entry_op.offset; int buf_len = in_entry_op.buf_len; bool truncate = in_entry_op.truncate; bool doomed = in_entry_op.doomed; @@ -731,7 +730,7 @@ index, std::max(out_entry_stat->data_size(index), offset + buf_len)); } else { out_entry_stat->set_data_size(index, offset + buf_len); - int file_eof_offset = + const int64_t file_eof_offset = out_entry_stat->GetLastEOFOffsetInFile(key_size, index); if (!file->SetLength(file_eof_offset)) { RecordWriteResult(cache_type_, SYNC_WRITE_RESULT_TRUNCATE_FAILURE); @@ -1011,7 +1010,8 @@ uint32_t expected_crc32) { DCHECK(initialized_); SimpleFileEOF eof_record; - int file_offset = entry_stat.GetEOFOffsetInFile(key_->size(), stream_index); + int64_t file_offset = + entry_stat.GetEOFOffsetInFile(key_->size(), stream_index); int file_index = GetFileIndexFromStreamIndex(stream_index); int rv = GetEOFRecordData(file, nullptr, file_index, file_offset, &eof_record); @@ -1041,18 +1041,28 @@ SimpleStreamPrefetchData* out) { DCHECK(stream_index == 0 || stream_index == 1); - int stream_size = entry_stat.data_size(stream_index); - int read_size = stream_size + extra_size; + int64_t stream_size = entry_stat.data_size(stream_index); + + // The data must be on GrowableIOBuffer. + // TODO(crbug.com/433856002): int32 max is too large for stream 0 where stream + // 0 needs consecutive memory space. Set the proper size limitation. + if (stream_size + extra_size > std::numeric_limits<int>::max() || + stream_size < 0 || extra_size < 0) { + return net::ERR_INVALID_ARGUMENT; + } + + int read_size = static_cast<int>(stream_size + extra_size); out->data = base::MakeRefCounted<net::GrowableIOBuffer>(); out->data->SetCapacity(read_size); - int file_offset = entry_stat.GetOffsetInFile(key_->size(), 0, stream_index); + int64_t file_offset = + entry_stat.GetOffsetInFile(key_->size(), 0, stream_index); if (!ReadFromFileOrPrefetched(file, prefetch_data, 0, file_offset, read_size, out->data->span())) { return net::ERR_FAILED; } // Check the CRC32. - uint32_t expected_crc32 = simple_util::Crc32(out->data->data(), stream_size); + uint32_t expected_crc32 = simple_util::Crc32(out->data->first(stream_size)); if ((eof_record.flags & SimpleFileEOF::FLAG_HAS_CRC32) && eof_record.data_crc32 != expected_crc32) { DVLOG(1) << "EOF record had bad crc."; @@ -1094,9 +1104,11 @@ if (stream_index == 0) { // Write stream 0 data. - int stream_0_offset = entry_stat.GetOffsetInFile(key.size(), 0, 0); + int64_t stream_0_offset = entry_stat.GetOffsetInFile(key.size(), 0, 0); + // Stream 0 data must be within int range. + CHECK_LE(entry_stat.data_size(0), std::numeric_limits<int>::max()); if (!file->WriteAndCheck(stream_0_offset, - stream_0_data->first(base::checked_cast<size_t>( + stream_0_data->first(static_cast<size_t>( entry_stat.data_size(0))))) { RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); DVLOG(1) << "Could not write stream 0 data."; @@ -1114,8 +1126,8 @@ // if it didn't change if stream 0's position on disk got changed due to // stream 1 write). if (!crc_record.has_crc32) { - crc_record.data_crc32 = - simple_util::Crc32(stream_0_data->data(), entry_stat.data_size(0)); + crc_record.data_crc32 = simple_util::Crc32( + stream_0_data->first(static_cast<size_t>(entry_stat.data_size(0)))); crc_record.has_crc32 = true; } @@ -1124,7 +1136,10 @@ } SimpleFileEOF eof_record; - eof_record.stream_size = entry_stat.data_size(stream_index); + eof_record.stream_size = + stream_index == 0 + ? static_cast<uint32_t>(entry_stat.data_size(stream_index)) + : 0; eof_record.final_magic_number = kSimpleFinalMagicNumber; eof_record.flags = 0; if (crc_record.has_crc32) @@ -1132,7 +1147,8 @@ if (stream_index == 0) eof_record.flags |= SimpleFileEOF::FLAG_HAS_KEY_SHA256; eof_record.data_crc32 = crc_record.data_crc32; - int eof_offset = entry_stat.GetEOFOffsetInFile(key.size(), stream_index); + int64_t eof_offset = + entry_stat.GetEOFOffsetInFile(key.size(), stream_index); // If stream 0 changed size, the file needs to be resized, otherwise the // next open will yield wrong stream sizes. On stream 1 and stream 2 proper // resizing of the file is handled in SimpleSynchronousEntry::WriteData(). @@ -1312,11 +1328,8 @@ // 0, stream 1 and one EOF record. The exact distribution of sizes between // stream 1 and stream 0 is only determined after reading the EOF record // for stream 0 in ReadAndValidateStream0AndMaybe1. - if (!base::IsValueInRangeForNumericType<int>(file_info.size)) { - RecordSyncOpenResult(cache_type_, OPEN_ENTRY_INVALID_FILE_LENGTH); - return false; - } - out_entry_stat->set_data_size(i + 1, static_cast<int>(file_info.size)); + + out_entry_stat->set_data_size(i + 1, file_info.size); } return true; @@ -1488,7 +1501,7 @@ } else { out_entry_stat->set_data_size( 2, GetDataSizeFromFileSize(key_size, out_entry_stat->data_size(2))); - const int32_t data_size_2 = out_entry_stat->data_size(2); + const int64_t data_size_2 = out_entry_stat->data_size(2); int ret_value_stream_2 = net::OK; if (data_size_2 < 0) { DLOG(WARNING) << "Stream 2 file is too small."; @@ -1498,7 +1511,7 @@ SimpleFileEOF eof_record; SimpleFileTracker::FileHandle file = file_tracker_->Acquire( file_operations, this, SubFileForFileIndex(i)); - int file_offset = + int64_t file_offset = out_entry_stat->GetEOFOffsetInFile(key_size, 2 /*stream index*/); ret_value_stream_2 = GetEOFRecordData(file.get(), nullptr, i, file_offset, &eof_record); @@ -1585,16 +1598,17 @@ int SimpleSynchronousEntry::ReadAndValidateStream0AndMaybe1( BackendFileOperations* file_operations, - int file_size, + int64_t file_size, SimpleEntryStat* out_entry_stat, std::array<SimpleStreamPrefetchData, 2>& stream_prefetch_data) { SimpleFileTracker::FileHandle file = file_tracker_->Acquire(file_operations, this, SubFileForFileIndex(0)); - if (!file.IsOK()) + if (!file.IsOK()) { return net::ERR_FAILED; + } // `file_size` must be a non-negative value. - size_t u_file_size = base::checked_cast<size_t>(file_size); + uint64_t u_file_size = base::checked_cast<uint64_t>(file_size); // We may prefetch data from file in a couple cases: // 1) If the file is small enough we may prefetch it entirely. @@ -1632,11 +1646,14 @@ // Prefetch trailer data from the end of the file. prefetch_mode = OPEN_PREFETCH_TRAILER; RecordOpenPrefetchMode(cache_type_, prefetch_mode); - size_t length = - std::min(static_cast<size_t>(trailer_prefetch_size), u_file_size); - uint64_t offset = file_size - length; - if (!prefetch_data.PrefetchFromFile(&file, offset, length)) + // `trailer_prefetch_size is in uint32_t range, so `length` is safe to cast + // to size_t. + size_t length = std::min<size_t>( + static_cast<uint64_t>(trailer_prefetch_size), u_file_size); + uint64_t offset = u_file_size - length; + if (!prefetch_data.PrefetchFromFile(&file, offset, length)) { return net::ERR_FAILED; + } } else { // Do no prefetching. RecordOpenPrefetchMode(cache_type_, prefetch_mode); @@ -1648,12 +1665,14 @@ int rv = GetEOFRecordData( file.get(), &prefetch_data, /* file_index = */ 0, /* file_offset = */ u_file_size - sizeof(SimpleFileEOF), &stream_0_eof); - if (rv != net::OK) + if (rv != net::OK) { return rv; + } - int32_t stream_0_size = stream_0_eof.stream_size; - if (stream_0_size < 0 || stream_0_size > file_size) + int32_t stream_0_size = static_cast<int32_t>(stream_0_eof.stream_size); + if (stream_0_size > file_size) { return net::ERR_FAILED; + } out_entry_stat->set_data_size(0, stream_0_size); // Calculate size for stream 1, now we know stream 0's. @@ -1661,16 +1680,16 @@ bool has_key_sha256 = (stream_0_eof.flags & SimpleFileEOF::FLAG_HAS_KEY_SHA256) == SimpleFileEOF::FLAG_HAS_KEY_SHA256; - int extra_post_stream_0_read = 0; - if (has_key_sha256) - extra_post_stream_0_read += sizeof(net::SHA256HashValue); + const int extra_post_stream_0_read = + has_key_sha256 ? sizeof(net::SHA256HashValue) : 0; const std::string& key = *key_; - int32_t stream1_size = file_size - 2 * sizeof(SimpleFileEOF) - stream_0_size - + int64_t stream1_size = file_size - 2 * sizeof(SimpleFileEOF) - stream_0_size - sizeof(SimpleFileHeader) - key.size() - extra_post_stream_0_read; - if (stream1_size < 0 || stream1_size > file_size) + if (stream1_size < 0 || stream1_size > file_size) { return net::ERR_FAILED; + } out_entry_stat->set_data_size(1, stream1_size); @@ -1678,8 +1697,9 @@ rv = PreReadStreamPayload(file.get(), &prefetch_data, /* stream_index = */ 0, extra_post_stream_0_read, *out_entry_stat, stream_0_eof, &stream_prefetch_data[0]); - if (rv != net::OK) + if (rv != net::OK) { return rv; + } // Note the exact range needed in order to read the EOF record and stream 0. // In APP_CACHE mode this will be stored directly in the index so we can @@ -1689,26 +1709,28 @@ // If prefetch buffer is available, and we have sha256(key) (so we don't need // to look at the header), extract out stream 1 info as well. - int stream_1_offset = out_entry_stat->GetOffsetInFile( + int64_t stream_1_offset = out_entry_stat->GetOffsetInFile( key.size(), /* offset= */ 0, /* stream_index = */ 1); - int stream_1_read_size = + int64_t stream_1_read_size = sizeof(SimpleFileEOF) + out_entry_stat->data_size(/* stream_index = */ 1); if (has_key_sha256 && prefetch_data.HasData(stream_1_offset, stream_1_read_size)) { SimpleFileEOF stream_1_eof; - int stream_1_eof_offset = + int64_t stream_1_eof_offset = out_entry_stat->GetEOFOffsetInFile(key.size(), /* stream_index = */ 1); rv = GetEOFRecordData(file.get(), &prefetch_data, /* file_index = */ 0, stream_1_eof_offset, &stream_1_eof); - if (rv != net::OK) + if (rv != net::OK) { return rv; + } rv = PreReadStreamPayload(file.get(), &prefetch_data, /* stream_index = */ 1, /* extra_size = */ 0, *out_entry_stat, stream_1_eof, &stream_prefetch_data[1]); - if (rv != net::OK) + if (rv != net::OK) { return rv; + } } // If present, check the key SHA256. @@ -1716,7 +1738,7 @@ auto hash_value = crypto::hash::Sha256(key); if (base::byte_span_from_ref(hash_value) != stream_prefetch_data[0].data->span().subspan( - static_cast<uint32_t>(stream_0_size), sizeof(hash_value))) { + static_cast<size_t>(stream_0_size), sizeof(hash_value))) { return net::ERR_FAILED; } @@ -1737,38 +1759,29 @@ base::File* file, PrefetchData* prefetch_data, int file_index, - int offset, - int size, + int64_t offset, + size_t size, base::span<uint8_t> dest) { if (offset < 0 || size < 0) return false; if (size == 0) return true; - base::CheckedNumeric<size_t> start(offset); - size_t start_numeric; - if (!start.AssignIfValid(&start_numeric)) - return false; - - base::CheckedNumeric<size_t> length(size); - size_t length_numeric; - if (!length.AssignIfValid(&length_numeric)) - return false; - // First try to extract the desired range from the PrefetchData. if (file_index == 0 && prefetch_data && - prefetch_data->ReadData(start_numeric, length_numeric, dest)) { + prefetch_data->ReadData(base::checked_cast<uint64_t>(offset), size, + dest)) { return true; } // If we have not prefetched the range then we must read it from disk. - return file->ReadAndCheck(start_numeric, dest.first(length_numeric)); + return file->ReadAndCheck(offset, dest.first(size)); } int SimpleSynchronousEntry::GetEOFRecordData(base::File* file, PrefetchData* prefetch_data, int file_index, - int file_offset, + int64_t file_offset, SimpleFileEOF* eof_record) { if (!ReadFromFileOrPrefetched(file, prefetch_data, file_index, file_offset, sizeof(SimpleFileEOF),
diff --git a/net/disk_cache/simple/simple_synchronous_entry.h b/net/disk_cache/simple/simple_synchronous_entry.h index 1f2189b..6c7a74b0 100644 --- a/net/disk_cache/simple/simple_synchronous_entry.h +++ b/net/disk_cache/simple/simple_synchronous_entry.h
@@ -60,19 +60,21 @@ class NET_EXPORT_PRIVATE SimpleEntryStat { public: SimpleEntryStat(base::Time last_used, - const std::array<int32_t, kSimpleEntryStreamCount>& data_size, + const std::array<int64_t, kSimpleEntryStreamCount>& data_size, const uint64_t sparse_data_size); - int GetOffsetInFile(size_t key_length, int offset, int stream_index) const; - int GetEOFOffsetInFile(size_t key_length, int stream_index) const; - int GetLastEOFOffsetInFile(size_t key_length, int file_index) const; + int64_t GetOffsetInFile(size_t key_length, + int64_t offset, + int stream_index) const; + int64_t GetEOFOffsetInFile(size_t key_length, int stream_index) const; + int64_t GetLastEOFOffsetInFile(size_t key_length, int file_index) const; int64_t GetFileSize(size_t key_length, int file_index) const; base::Time last_used() const { return last_used_; } void set_last_used(base::Time last_used) { last_used_ = last_used; } - int32_t data_size(int stream_index) const { return data_size_[stream_index]; } - void set_data_size(int stream_index, int data_size) { + int64_t data_size(int stream_index) const { return data_size_[stream_index]; } + void set_data_size(int stream_index, int64_t data_size) { data_size_[stream_index] = data_size; } @@ -83,7 +85,7 @@ private: base::Time last_used_; - std::array<int32_t, kSimpleEntryStreamCount> data_size_; + std::array<int64_t, kSimpleEntryStreamCount> data_size_; uint64_t sparse_data_size_; }; @@ -132,9 +134,9 @@ struct ReadRequest { // Also sets request_update_crc to false. - ReadRequest(int index_p, int offset_p, int buf_len_p); + ReadRequest(int index_p, int64_t offset_p, int buf_len_p); int index; - int offset; + int64_t offset; int buf_len; // Partial CRC of data immediately preceeding this read. Only relevant if @@ -153,14 +155,14 @@ struct WriteRequest { WriteRequest(int index_p, - int offset_p, + int64_t offset_p, int buf_len_p, uint32_t previous_crc32_p, bool truncate_p, bool doomed_p, bool request_update_crc_p); int index; - int offset; + int64_t offset; int buf_len; uint32_t previous_crc32; bool truncate; @@ -385,7 +387,7 @@ // crc, but might decide not to. int ReadAndValidateStream0AndMaybe1( BackendFileOperations* file_operations, - int file_size, + int64_t file_size, SimpleEntryStat* out_entry_stat, std::array<SimpleStreamPrefetchData, 2>& stream_prefetch_data); @@ -396,7 +398,7 @@ int GetEOFRecordData(base::File* file, PrefetchData* prefetch_data, int file_index, - int file_offset, + int64_t file_offset, SimpleFileEOF* eof_record); // Reads either from |file_0_prefetch| or |file|. @@ -404,8 +406,8 @@ bool ReadFromFileOrPrefetched(base::File* file, PrefetchData* prefetch_data, int file_index, - int offset, - int size, + int64_t offset, + size_t size, base::span<uint8_t> dest); // Extracts out the payload of stream |stream_index|, reading either from
diff --git a/net/disk_cache/simple/simple_util.cc b/net/disk_cache/simple/simple_util.cc index 1d15a49..ac20cba3 100644 --- a/net/disk_cache/simple/simple_util.cc +++ b/net/disk_cache/simple/simple_util.cc
@@ -86,13 +86,13 @@ return sizeof(SimpleFileHeader) + key_length; } -int32_t GetDataSizeFromFileSize(size_t key_length, int64_t file_size) { +int64_t GetDataSizeFromFileSize(size_t key_length, int64_t file_size) { int64_t data_size = file_size - key_length - sizeof(SimpleFileHeader) - sizeof(SimpleFileEOF); - return base::checked_cast<int32_t>(data_size); + return data_size; } -int64_t GetFileSizeFromDataSize(size_t key_length, int32_t data_size) { +int64_t GetFileSizeFromDataSize(size_t key_length, int64_t data_size) { return data_size + key_length + sizeof(SimpleFileHeader) + sizeof(SimpleFileEOF); }
diff --git a/net/disk_cache/simple/simple_util.h b/net/disk_cache/simple/simple_util.h index 3c7ab10d..5918394 100644 --- a/net/disk_cache/simple/simple_util.h +++ b/net/disk_cache/simple/simple_util.h
@@ -59,13 +59,13 @@ // Given the size of a file holding a stream in the simple backend and the key // to an entry, returns the number of bytes in the stream. -NET_EXPORT_PRIVATE int32_t GetDataSizeFromFileSize(size_t key_length, +NET_EXPORT_PRIVATE int64_t GetDataSizeFromFileSize(size_t key_length, int64_t file_size); // Given the size of a stream in the simple backend and the key to an entry, // returns the number of bytes in the file. NET_EXPORT_PRIVATE int64_t GetFileSizeFromDataSize(size_t key_length, - int32_t data_size); + int64_t data_size); // Given the stream index, returns the number of the file the stream is stored // in.
diff --git a/net/disk_cache/sql/sql_entry_impl.cc b/net/disk_cache/sql/sql_entry_impl.cc index f2fc200..e6e3fa6 100644 --- a/net/disk_cache/sql/sql_entry_impl.cc +++ b/net/disk_cache/sql/sql_entry_impl.cc
@@ -104,7 +104,7 @@ return last_used_; } -int32_t SqlEntryImpl::GetDataSize(int index) const { +int64_t SqlEntryImpl::GetDataSize(int index) const { if (index != 0 && index != 1) { return net::ERR_INVALID_ARGUMENT; } @@ -116,7 +116,7 @@ } int SqlEntryImpl::ReadData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback) { @@ -132,7 +132,13 @@ // the requested range would overflow, the underlying SqlPersistentStore will // truncate the read length to fit within the `int64_t` range, allowing a // partial read up to the maximum possible offset. - if (!buf || buf_len < 0 || offset < 0) { + // + // TODO(crbug.com/422065015): To enable int64_t offset writes for stream 1 in + // the SQL backend, the check for offset against int max should be moved to + // the index == 0 logic path, as stream 1 of SQL backend is designed to handle + // offsets larger than int max. + if (!buf || buf_len < 0 || offset < 0 || + offset > std::numeric_limits<int>::max()) { return net::ERR_INVALID_ARGUMENT; } @@ -145,9 +151,9 @@ if (head_->size() <= offset) { return 0; } - buf_len = std::min(buf_len, head_->size() - offset); + buf_len = std::min(buf_len, head_->size() - static_cast<int>(offset)); buf->first(buf_len).copy_from_nonoverlapping(head_->span().subspan( - base::checked_cast<size_t>(offset), base::checked_cast<size_t>(buf_len))); + static_cast<size_t>(offset), static_cast<size_t>(buf_len))); return buf_len; } @@ -175,7 +181,7 @@ } int SqlEntryImpl::WriteData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback, @@ -185,6 +191,14 @@ (!buf && buf_len > 0) || !base::CheckAdd(offset, buf_len).IsValid()) { return net::ERR_INVALID_ARGUMENT; } + + // TODO(crbug.com/422065015): To enable int64_t offset reads for stream 1 in + // the SQL backend, the check should be moved to the index == 0 logic path, as + // stream 1 of SQL backend is designed to handle offsets larger than int max. + if (offset + buf_len > std::numeric_limits<int>::max()) { + return net::ERR_INVALID_ARGUMENT; + } + if (index == 1) { return WriteDataInternal(offset, buf, buf_len, std::move(callback), truncate, /*sparse_write=*/false); @@ -197,30 +211,29 @@ previous_header_size_in_storage_ = head_->size(); } + size_t u_offset = base::checked_cast<size_t>(offset); + size_t u_buf_len = base::checked_cast<size_t>(buf_len); if (offset == 0 && truncate) { head_->SetCapacity(buf_len); if (buf_len) { - head_->span().copy_from(buf->first(base::checked_cast<size_t>(buf_len))); + head_->span().copy_from(buf->first(u_buf_len)); } } else { - const int original_size = head_->size(); - const int buffer_size = - truncate ? offset + buf_len : std::max(offset + buf_len, original_size); - head_->SetCapacity(buffer_size); + const size_t original_size = head_->size(); + const size_t buffer_size = + truncate ? u_offset + u_buf_len + : std::max(u_offset + u_buf_len, original_size); + head_->SetCapacity(base::checked_cast<int>(buffer_size)); // Fill any gap with zeros if writing beyond current size. - const int fill_size = offset <= original_size ? 0 : offset - original_size; + const size_t fill_size = + u_offset <= original_size ? 0 : u_offset - original_size; if (fill_size > 0) { - std::ranges::fill( - head_->span().subspan(base::checked_cast<size_t>(original_size), - base::checked_cast<size_t>(fill_size)), - 0); + std::ranges::fill(head_->span().subspan(original_size, fill_size), 0); } // Copy new data into the buffer. if (buf) { - head_->span() - .subspan(base::checked_cast<size_t>(offset)) - .copy_prefix_from(buf->first(base::checked_cast<size_t>(buf_len))); + head_->span().subspan(u_offset).copy_prefix_from(buf->first(u_buf_len)); } } return buf_len;
diff --git a/net/disk_cache/sql/sql_entry_impl.h b/net/disk_cache/sql/sql_entry_impl.h index 880f52d6..7e03f2ca 100644 --- a/net/disk_cache/sql/sql_entry_impl.h +++ b/net/disk_cache/sql/sql_entry_impl.h
@@ -48,14 +48,14 @@ void Close() override; std::string GetKey() const override; base::Time GetLastUsed() const override; - int32_t GetDataSize(int index) const override; + int64_t GetDataSize(int index) const override; int ReadData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback) override; int WriteData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback,
diff --git a/net/http/mock_http_cache.cc b/net/http/mock_http_cache.cc index 0fa4ba9..51623cfb 100644 --- a/net/http/mock_http_cache.cc +++ b/net/http/mock_http_cache.cc
@@ -80,13 +80,13 @@ return base::Time::Now(); } -int32_t MockDiskEntry::GetDataSize(int index) const { +int64_t MockDiskEntry::GetDataSize(int index) const { DCHECK(index >= 0 && index < kNumCacheEntryDataIndices); - return static_cast<int32_t>(data_[index].size()); + return static_cast<int64_t>(data_[index].size()); } int MockDiskEntry::ReadData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback) { @@ -100,11 +100,14 @@ if (offset < 0 || offset > static_cast<int>(data_[index].size())) { return ERR_FAILED; } - if (static_cast<size_t>(offset) == data_[index].size()) { + + // `offset` is not larger than int max so it's in size_t range. + if (base::checked_cast<size_t>(offset) == data_[index].size()) { return 0; } - int num = std::min(buf_len, static_cast<int>(data_[index].size()) - offset); + int num = std::min(buf_len, static_cast<int>(data_[index].size()) - + base::checked_cast<int>(offset)); buf->span().copy_prefix_from(base::span(data_[index]) .subspan(base::checked_cast<size_t>(offset), base::checked_cast<size_t>(num))); @@ -132,7 +135,7 @@ } int MockDiskEntry::WriteData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback, @@ -150,8 +153,13 @@ return ERR_FAILED; } - DCHECK_LT(offset + buf_len, kMaxMockCacheEntrySize); - if (offset + buf_len > max_file_size_ && index == 1) { + if (offset + buf_len > kMaxMockCacheEntrySize) { + return net::ERR_INVALID_ARGUMENT; + } + + // `offset` is not larger than int max so it's in size_t range. + if (base::checked_cast<int>(offset) + buf_len > max_file_size_ && + index == 1) { return ERR_FAILED; }
diff --git a/net/http/mock_http_cache.h b/net/http/mock_http_cache.h index 21db02e27..f9211fa3 100644 --- a/net/http/mock_http_cache.h +++ b/net/http/mock_http_cache.h
@@ -61,14 +61,14 @@ void Close() override; std::string GetKey() const override; base::Time GetLastUsed() const override; - int32_t GetDataSize(int index) const override; + int64_t GetDataSize(int index) const override; int ReadData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback) override; int WriteData(int index, - int offset, + int64_t offset, IOBuffer* buf, int buf_len, CompletionOnceCallback callback,
diff --git a/remoting/base/url_loader_network_service_observer.cc b/remoting/base/url_loader_network_service_observer.cc index f681d2b7..b7942552 100644 --- a/remoting/base/url_loader_network_service_observer.cc +++ b/remoting/base/url_loader_network_service_observer.cc
@@ -120,13 +120,6 @@ mojo::PendingRemote<network::mojom::AuthChallengeResponder> auth_challenge_responder) {} -void UrlLoaderNetworkServiceObserver::OnPrivateNetworkAccessPermissionRequired( - const GURL& url, - const net::IPAddress& ip_address, - const std::optional<std::string>& private_network_device_id, - const std::optional<std::string>& private_network_device_name, - OnPrivateNetworkAccessPermissionRequiredCallback callback) {} - void UrlLoaderNetworkServiceObserver::OnLocalNetworkAccessPermissionRequired( OnLocalNetworkAccessPermissionRequiredCallback callback) {}
diff --git a/remoting/base/url_loader_network_service_observer.h b/remoting/base/url_loader_network_service_observer.h index 1b090051b..6e240df8 100644 --- a/remoting/base/url_loader_network_service_observer.h +++ b/remoting/base/url_loader_network_service_observer.h
@@ -57,12 +57,6 @@ const scoped_refptr<net::HttpResponseHeaders>& head_headers, mojo::PendingRemote<network::mojom::AuthChallengeResponder> auth_challenge_responder) override; - void OnPrivateNetworkAccessPermissionRequired( - const GURL& url, - const net::IPAddress& ip_address, - const std::optional<std::string>& private_network_device_id, - const std::optional<std::string>& private_network_device_name, - OnPrivateNetworkAccessPermissionRequiredCallback callback) override; void OnLocalNetworkAccessPermissionRequired( OnLocalNetworkAccessPermissionRequiredCallback callback) override; void OnClearSiteData(
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc index 9f610d4a..43df4417 100644 --- a/services/network/cors/cors_url_loader.cc +++ b/services/network/cors/cors_url_loader.cc
@@ -991,29 +991,6 @@ mojo::PendingRemote<mojom::URLLoaderNetworkServiceObserver> remote_observer; - if (needs_preflight.has_value() && - *needs_preflight == PreflightRequiredReason::kPrivateNetworkAccess) { - // TODO(crbug.com/40229602): Create a base function and clean up all - // need_pna_permission check in the code base. - const mojom::ClientSecurityState* state = GetClientSecurityState(); - const bool needs_pna_permission = - state && PrivateNetworkAccessChecker::NeedPermission( - request_.url, state->is_web_secure_context, - request_.required_ip_address_space); - if (needs_pna_permission && - url_loader_network_service_observer_->is_bound()) { - // Fail the request if `targetAddressSpace` on fetch option is not the - // same as the real target address space. - if (request_.required_ip_address_space != - request_.target_ip_address_space) { - HandleComplete(URLLoaderCompletionStatus( - CorsErrorStatus(mojom::CorsError::kInvalidPrivateNetworkAccess))); - return; - } - (*url_loader_network_service_observer_) - ->Clone(remote_observer.InitWithNewPipeAndPassReceiver()); - } - } context_->cors_preflight_controller()->PerformPreflightCheck( base::BindOnce(&CorsURLLoader::OnPreflightRequestComplete, weak_factory_.GetWeakPtr()), @@ -1402,12 +1379,6 @@ if (!state) { return false; } - // When the PNA permission prompt shown, we should always respect the - // preflight results, otherwise it would be a bypass of mixed content checker. - if (PrivateNetworkAccessChecker::NeedPermission( - request_.url, state->is_web_secure_context, target_address_space)) { - return false; - } return state->private_network_request_policy == mojom::PrivateNetworkRequestPolicy::kPreflightWarn; }
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc index 12456326..0c772c31 100644 --- a/services/network/cors/cors_url_loader_factory.cc +++ b/services/network/cors/cors_url_loader_factory.cc
@@ -839,18 +839,7 @@ return false; } - if (client_security_state_ && - PrivateNetworkAccessChecker::NeedPermission( - request.url, client_security_state_->is_web_secure_context, - request.required_ip_address_space)) { - if (request.required_ip_address_space == mojom::IPAddressSpace::kPublic) { - mojo::ReportBadMessage( - "CorsURLLoaderFactory: required_ip_address_space " - "is set to public."); - return false; - } - } else if (request.target_ip_address_space != - mojom::IPAddressSpace::kUnknown) { + if (request.target_ip_address_space != mojom::IPAddressSpace::kUnknown) { mojo::ReportBadMessage( "CorsURLLoaderFactory: target_ip_address_space is " "set.");
diff --git a/services/network/cors/cors_url_loader_private_network_access_unittest.cc b/services/network/cors/cors_url_loader_private_network_access_unittest.cc index 9265000..56ad66f 100644 --- a/services/network/cors/cors_url_loader_private_network_access_unittest.cc +++ b/services/network/cors/cors_url_loader_private_network_access_unittest.cc
@@ -2065,43 +2065,5 @@ net::ERR_BLOCKED_BY_PRIVATE_NETWORK_ACCESS_CHECKS); } -TEST_F(CorsURLLoaderPrivateNetworkAccessTest, - NoPermissionPromptForNonPnaPreflights) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - features::kPrivateNetworkAccessPermissionPrompt); - - auto initiator = url::Origin::Create(GURL("https://foo.example")); - ResetFactoryParams factory_params; - factory_params.is_trusted = true; - factory_params.client_security_state = mojom::ClientSecurityState::New(); - factory_params.client_security_state->is_web_secure_context = true; - factory_params.url_loader_network_observer = - TestURLLoaderNetworkObserver().Bind(); - ResetFactory(initiator, kRendererProcessId, factory_params); - - ResourceRequest request; - request.mode = mojom::RequestMode::kCorsWithForcedPreflight; - request.required_ip_address_space = mojom::IPAddressSpace::kLocal; - request.target_ip_address_space = mojom::IPAddressSpace::kUnknown; - request.url = GURL("http://example.com/"); - request.request_initiator = initiator; - request.trusted_params = - RequestTrustedParamsBuilder() - .WithClientSecurityState( - ClientSecurityStateBuilder() - .WithPrivateNetworkRequestPolicy( - mojom::PrivateNetworkRequestPolicy::kPreflightBlock) - .WithIsSecureContext(false) - .WithIPAddressSpace(mojom::IPAddressSpace::kUnknown) - .Build()) - .Build(); - - CreateLoaderAndStart(request); - RunUntilCreateLoaderAndStartCalled(); - - EXPECT_EQ(client().completion_status().error_code, net::OK); -} - } // namespace } // namespace network::cors
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc index 3d3b37ec..b73a9613 100644 --- a/services/network/cors/cors_url_loader_unittest.cc +++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -2389,36 +2389,6 @@ "should not call FollowRedirect")); } -TEST_F(CorsURLLoaderTest, PrivateNetworkAccessTargetAddressSpaceCheck) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature( - features::kPrivateNetworkAccessPermissionPrompt); - - auto initiator = url::Origin::Create(GURL("https://foo.example")); - ResetFactoryParams factory_params; - factory_params.is_trusted = true; - factory_params.client_security_state = mojom::ClientSecurityState::New(); - factory_params.client_security_state->is_web_secure_context = true; - ResetFactory(initiator, mojom::kBrowserProcessId, factory_params); - - ResourceRequest request; - request.mode = mojom::RequestMode::kCors; - request.required_ip_address_space = mojom::IPAddressSpace::kLocal; - request.target_ip_address_space = mojom::IPAddressSpace::kLocal; - request.url = GURL("http://foo.example/"); - request.request_initiator = initiator; - request.trusted_params = ResourceRequest::TrustedParams(); - request.trusted_params->client_security_state = - mojom::ClientSecurityState::New(); - request.trusted_params->client_security_state->is_web_secure_context = true; - - BadMessageTestHelper bad_message_helper; - CreateLoaderAndStart(request); - RunUntilCreateLoaderAndStartCalled(); - - EXPECT_EQ(client().completion_status().error_code, net::OK); -} - class StorageAccessHeadersCorsURLLoaderTest : public CorsURLLoaderTest { public: StorageAccessHeadersCorsURLLoaderTest() : CorsURLLoaderTest() {
diff --git a/services/network/cors/preflight_controller.cc b/services/network/cors/preflight_controller.cc index 8f03ca2..fd5e3af 100644 --- a/services/network/cors/preflight_controller.cc +++ b/services/network/cors/preflight_controller.cc
@@ -556,76 +556,7 @@ detected_error_status = std::move(check_error_status); } - // Check if we need user permission to access the private network. This - // only happens if we skipped the mixed content check before sending the - // preflight. - const bool needs_permission = - client_security_state_ && - PrivateNetworkAccessChecker::NeedPermission( - original_request_.url, - client_security_state_->is_web_secure_context, - original_request_.required_ip_address_space); - - if (!needs_permission) { - FinishHandleResponseHeader(net_error, std::move(detected_error_status), - std::move(result)); - return; - } - - // Check if it is valid to show the permission prompt, which means: - // * The target IP address space shouldn't be unknown or public. - // * The preflight response contains `Private-Network-Access-Id` and - // `Private-Network-Access-Name` headers to claim its identity. - // * Able to access permission in the browser process from - // URLLoaderNetworkService. - std::optional<std::string> id = - GetHeaderString(head.headers, header_names::kPrivateNetworkDeviceId); - std::optional<std::string> name = - GetHeaderString(head.headers, header_names::kPrivateNetworkDeviceName); - - // TODO(crbug.com/40272755): `target_ip_address_space` should be - // checked in `CorsURLLoaderFactory`. Remove the following bit after that. - if (!url_loader_network_service_observer_ || - original_request_.target_ip_address_space == - mojom::IPAddressSpace::kUnknown || - original_request_.target_ip_address_space == - mojom::IPAddressSpace::kPublic) { - FinishHandleResponseHeader( - net::ERR_FAILED, - CorsErrorStatus( - mojom::CorsError::kPrivateNetworkAccessPermissionUnavailable), - std::move(result)); - return; - } - - // Ask for private network access permission. - // base::Unretained() is safe because once HandleResponseHeader is called, - // PreflightController will at least keep alive until completion being - // called as a result of HandlePrivateNetworkAccessPermissionResult being - // called. - (*url_loader_network_service_observer_) - .OnPrivateNetworkAccessPermissionRequired( - std::move(original_request_.url), - std::move(head.remote_endpoint.address()), id, name, - base::BindOnce( - &PreflightLoader::HandlePrivateNetworkAccessPermissionResult, - base::Unretained(this), net_error, - std::move(detected_error_status), std::move(result))); - permission_state_ = PermissionState::kRequested; - } - - void HandlePrivateNetworkAccessPermissionResult( - net::Error net_error, - std::optional<CorsErrorStatus> detected_error_status, - std::unique_ptr<PreflightResult> result, - bool permission_granted) { - if (!permission_granted) { - net_error = net::ERR_FAILED; - detected_error_status = CorsErrorStatus( - mojom::CorsError::kPrivateNetworkAccessPermissionDenied); - } - FinishHandleResponseHeader(std::move(net_error), - std::move(detected_error_status), + FinishHandleResponseHeader(net_error, std::move(detected_error_status), std::move(result)); }
diff --git a/services/network/private_network_access_checker.cc b/services/network/private_network_access_checker.cc index 2b1e0dd..7f73d39 100644 --- a/services/network/private_network_access_checker.cc +++ b/services/network/private_network_access_checker.cc
@@ -204,9 +204,7 @@ // // TODO(crbug.com/395895368): consider collapsing the address spaces for LNA // checks. - if ((base::FeatureList::IsEnabled( - features::kPrivateNetworkAccessPermissionPrompt) || - base::FeatureList::IsEnabled(features::kLocalNetworkAccessChecks)) && + if (base::FeatureList::IsEnabled(features::kLocalNetworkAccessChecks) && required_address_space_ != mojom::IPAddressSpace::kUnknown && resource_address_space != required_address_space_) { return Result::kBlockedByTargetIpAddressSpace; @@ -256,15 +254,4 @@ request_initiator_.value().IsSameOriginWith(url); } -bool PrivateNetworkAccessChecker::NeedPermission( - const GURL& url, - bool is_web_secure_context, - mojom::IPAddressSpace target_address_space) { - return base::FeatureList::IsEnabled( - network::features::kPrivateNetworkAccessPermissionPrompt) && - is_web_secure_context && !network::IsUrlPotentiallyTrustworthy(url) && - (target_address_space == mojom::IPAddressSpace::kLoopback || - target_address_space == mojom::IPAddressSpace::kLocal); -} - } // namespace network
diff --git a/services/network/private_network_access_checker.h b/services/network/private_network_access_checker.h index 2511268..03f9ab2 100644 --- a/services/network/private_network_access_checker.h +++ b/services/network/private_network_access_checker.h
@@ -123,10 +123,6 @@ // Returns `kUnknown` if `client_security_state()` is nullptr. mojom::IPAddressSpace ClientAddressSpace() const; - static bool NeedPermission(const GURL& url, - bool is_web_secure_context, - mojom::IPAddressSpace target_address_space); - private: // Returns whether this instance has a client security state containing a // policy set to `kPreflightWarn`.
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc index e4dab2326..6140de9 100644 --- a/services/network/public/cpp/features.cc +++ b/services/network/public/cpp/features.cc
@@ -208,12 +208,6 @@ "PrivateNetworkAccessPreflightShortTimeout", base::FEATURE_DISABLED_BY_DEFAULT); -// When kPrivateNetworkAccessPermissionPrompt is enabled, public secure websites -// are allowed to access private insecure subresources with user's permission. -BASE_FEATURE(kPrivateNetworkAccessPermissionPrompt, - "PrivateNetworkAccessPermissionPrompt", - base::FEATURE_DISABLED_BY_DEFAULT); - // Enables Local Network Access checks. // Blocks local network requests without user permission to prevent exploitation // of vulnerable local devices.
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h index 84f230e..611541f 100644 --- a/services/network/public/cpp/features.h +++ b/services/network/public/cpp/features.h
@@ -85,9 +85,6 @@ BASE_DECLARE_FEATURE(kPrivateNetworkAccessPreflightShortTimeout); COMPONENT_EXPORT(NETWORK_CPP_FLAGS_AND_SWITCHES) -BASE_DECLARE_FEATURE(kPrivateNetworkAccessPermissionPrompt); - -COMPONENT_EXPORT(NETWORK_CPP_FLAGS_AND_SWITCHES) BASE_DECLARE_FEATURE(kLocalNetworkAccessChecks); COMPONENT_EXPORT(NETWORK_CPP_FLAGS_AND_SWITCHES) BASE_DECLARE_FEATURE_PARAM(bool, kLocalNetworkAccessChecksWarn);
diff --git a/services/network/public/mojom/url_loader_network_service_observer.mojom b/services/network/public/mojom/url_loader_network_service_observer.mojom index fcf188b..61cf45f 100644 --- a/services/network/public/mojom/url_loader_network_service_observer.mojom +++ b/services/network/public/mojom/url_loader_network_service_observer.mojom
@@ -131,23 +131,6 @@ HttpResponseHeaders? head_headers, pending_remote<AuthChallengeResponder> auth_challenge_responder); - // Asks the URL loader observer if the caller has permission to access a - // device on the private network. - // - // `url` is the request's URL. - // `ip_address` is the remote IP address from which headers were fetched. - // `private_network_device_id` and `private_network_device_name` are the - // values of the `Private-Network-Access-ID` and `Private-Network-Access-Name` - // headers. - // - // `permission_granted` is a bool specifying whether the user granted private - // network access permission. - OnPrivateNetworkAccessPermissionRequired( - url.mojom.Url url, - network.mojom.IPAddress ip_address, - string? private_network_device_id, - string? private_network_device_name) => (bool permission_granted); - // Asks the URL loader observer if the caller has permission to connect to // devices on the local network. //
diff --git a/services/network/test/test_url_loader_network_observer.cc b/services/network/test/test_url_loader_network_observer.cc index 07d4edd1..89bab2d0b 100644 --- a/services/network/test/test_url_loader_network_observer.cc +++ b/services/network/test/test_url_loader_network_observer.cc
@@ -48,15 +48,6 @@ mojo::PendingRemote<mojom::AuthChallengeResponder> auth_challenge_responder) {} -void TestURLLoaderNetworkObserver::OnPrivateNetworkAccessPermissionRequired( - const GURL& url, - const net::IPAddress& ip_address, - const std::optional<std::string>& private_network_device_id, - const std::optional<std::string>& private_network_device_name, - OnPrivateNetworkAccessPermissionRequiredCallback callback) { - std::move(callback).Run(false); -} - void TestURLLoaderNetworkObserver::OnLocalNetworkAccessPermissionRequired( OnLocalNetworkAccessPermissionRequiredCallback callback) { std::move(callback).Run(false);
diff --git a/services/network/test/test_url_loader_network_observer.h b/services/network/test/test_url_loader_network_observer.h index 03796a2..aa9e5ca 100644 --- a/services/network/test/test_url_loader_network_observer.h +++ b/services/network/test/test_url_loader_network_observer.h
@@ -48,12 +48,6 @@ const scoped_refptr<net::HttpResponseHeaders>& head_headers, mojo::PendingRemote<mojom::AuthChallengeResponder> auth_challenge_responder) override; - void OnPrivateNetworkAccessPermissionRequired( - const GURL& url, - const net::IPAddress& ip_address, - const std::optional<std::string>& private_network_device_id, - const std::optional<std::string>& private_network_device_name, - OnPrivateNetworkAccessPermissionRequiredCallback callback) override; void OnLocalNetworkAccessPermissionRequired( OnLocalNetworkAccessPermissionRequiredCallback callback) override; void OnClearSiteData(
diff --git a/testing/scripts/run_performance_tests.py b/testing/scripts/run_performance_tests.py index 5a55c5a3..8dd7a55d 100755 --- a/testing/scripts/run_performance_tests.py +++ b/testing/scripts/run_performance_tests.py
@@ -748,7 +748,6 @@ self.options = options self._parse_arguments() self.isolated_out_dir = isolated_out_dir - self.network = self._get_network_arg(options.passthrough_args) self.is_chrome = (not self.cb_options.official_browser or self.cb_options.official_browser.startswith('chrome')) self.env = self._create_env_arg() @@ -762,6 +761,7 @@ browser_arg = _get_browser_arg(options.passthrough_args) self.is_android = _is_android(browser_arg) self._find_browser(browser_arg) + self.network = self._get_network_arg(options.passthrough_args) def _parse_arguments(self): parser = argparse.ArgumentParser() @@ -779,7 +779,7 @@ return self._create_fileserver_network(_arg) if _get_arg(args, '--wpr'): return self._create_wpr_network(args) - if self.options.benchmarks.startswith('motionmark'): + if self.options.benchmarks.startswith('motionmark') and not self.is_android: # TODO(crbug.com/413452730): Enable local file server in all platforms. return [] if ((self.options.benchmarks in self.BENCHMARK_FILESERVERS)
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 690d1f5..f84f5c5a 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2258,21 +2258,6 @@ ] } ], - "AutofillEnableShowSaveCardSecurelyMessage": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "AutofillEnableShowSaveCardSecurelyMessage" - ] - } - ] - } - ], "AutofillEnableSupportForParsingWithSharedLabels": [ { "platforms": [
diff --git a/third_party/android_deps/autorolled/BUILD.gn b/third_party/android_deps/autorolled/BUILD.gn index 703e947..6d921d04 100644 --- a/third_party/android_deps/autorolled/BUILD.gn +++ b/third_party/android_deps/autorolled/BUILD.gn
@@ -125,7 +125,7 @@ # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. if (google_play_services_package == "//third_party/android_deps") { android_aar_prebuilt("google_play_services_auth_java") { - aar_path = "autorolled/cipd/libs/com_google_android_gms_play_services_auth/play-services-auth-21.3.0.aar" + aar_path = "autorolled/cipd/libs/com_google_android_gms_play_services_auth/play-services-auth-21.4.0.aar" info_path = "autorolled/committed/libs/com_google_android_gms_play_services_auth/com_google_android_gms_play_services_auth.info" enable_bytecode_checks = false deps = [ @@ -161,7 +161,7 @@ # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. if (google_play_services_package == "//third_party/android_deps") { android_aar_prebuilt("google_play_services_auth_base_java") { - aar_path = "autorolled/cipd/libs/com_google_android_gms_play_services_auth_base/play-services-auth-base-18.1.0.aar" + aar_path = "autorolled/cipd/libs/com_google_android_gms_play_services_auth_base/play-services-auth-base-18.3.0.aar" info_path = "autorolled/committed/libs/com_google_android_gms_play_services_auth_base/com_google_android_gms_play_services_auth_base.info" enable_bytecode_checks = false deps = [ @@ -169,6 +169,7 @@ "$google_play_services_package:google_play_services_basement_java", "$google_play_services_package:google_play_services_tasks_java", "//third_party/androidx:androidx_collection_collection_java", + "//third_party/kotlin_stdlib:kotlin_stdlib_java", ] } } @@ -346,7 +347,7 @@ # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. if (google_play_services_package == "//third_party/android_deps") { android_aar_prebuilt("google_play_services_instantapps_java") { - aar_path = "autorolled/cipd/libs/com_google_android_gms_play_services_instantapps/play-services-instantapps-18.1.0.aar" + aar_path = "autorolled/cipd/libs/com_google_android_gms_play_services_instantapps/play-services-instantapps-18.2.0.aar" info_path = "autorolled/committed/libs/com_google_android_gms_play_services_instantapps/com_google_android_gms_play_services_instantapps.info" enable_bytecode_checks = false deps = [ @@ -431,7 +432,7 @@ # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. if (!defined(material_design_target)) { android_aar_prebuilt("com_google_android_material_material_java") { - aar_path = "autorolled/cipd/libs/com_google_android_material_material/material-1.14.0-alpha02.aar" + aar_path = "autorolled/cipd/libs/com_google_android_material_material/material-1.14.0-alpha03.aar" info_path = "autorolled/committed/libs/com_google_android_material_material/com_google_android_material_material.info" enable_bytecode_checks = false @@ -526,12 +527,11 @@ # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. if (google_play_services_package == "//third_party/android_deps") { android_aar_prebuilt("google_firebase_firebase_messaging_java") { - aar_path = "autorolled/cipd/libs/com_google_firebase_firebase_messaging/firebase-messaging-24.1.2.aar" + aar_path = "autorolled/cipd/libs/com_google_firebase_firebase_messaging/firebase-messaging-25.0.0.aar" info_path = "autorolled/committed/libs/com_google_firebase_firebase_messaging/com_google_firebase_firebase_messaging.info" enable_bytecode_checks = false deps = [ "$google_play_services_package:google_firebase_firebase_common_java", - "$google_play_services_package:google_firebase_firebase_common_ktx_java", "$google_play_services_package:google_firebase_firebase_components_java", "$google_play_services_package:google_firebase_firebase_datatransport_java", "$google_play_services_package:google_firebase_firebase_encoders_java", @@ -559,7 +559,7 @@ # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. if (!defined(android_proto_runtime)) { java_prebuilt("com_google_protobuf_protobuf_javalite_java") { - jar_path = "autorolled/cipd/libs/com_google_protobuf_protobuf_javalite/protobuf-javalite-4.31.1.jar" + jar_path = "autorolled/cipd/libs/com_google_protobuf_protobuf_javalite/protobuf-javalite-4.32.0-RC1.jar" output_name = "com_google_protobuf_protobuf_javalite" supports_android = true requires_android = true @@ -998,7 +998,7 @@ # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. if (google_play_services_package == "//third_party/android_deps") { java_prebuilt("google_firebase_firebase_annotations_java") { - jar_path = "autorolled/cipd/libs/com_google_firebase_firebase_annotations/firebase-annotations-16.2.0.jar" + jar_path = "autorolled/cipd/libs/com_google_firebase_firebase_annotations/firebase-annotations-17.0.0.jar" output_name = "com_google_firebase_firebase_annotations" supports_android = true requires_android = true @@ -1017,7 +1017,7 @@ # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. if (google_play_services_package == "//third_party/android_deps") { android_aar_prebuilt("google_firebase_firebase_common_java") { - aar_path = "autorolled/cipd/libs/com_google_firebase_firebase_common/firebase-common-21.0.0.aar" + aar_path = "autorolled/cipd/libs/com_google_firebase_firebase_common/firebase-common-22.0.0.aar" info_path = "autorolled/committed/libs/com_google_firebase_firebase_common/com_google_firebase_firebase_common.info" enable_bytecode_checks = false @@ -1035,28 +1035,7 @@ "//third_party/android_deps:org_jetbrains_kotlinx_kotlinx_coroutines_play_services_java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_concurrent_concurrent_futures_java", - "//third_party/kotlin_stdlib:kotlin_stdlib_java", - ] - } - } - - # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. - if (google_play_services_package == "//third_party/android_deps") { - android_aar_prebuilt("google_firebase_firebase_common_ktx_java") { - aar_path = "autorolled/cipd/libs/com_google_firebase_firebase_common_ktx/firebase-common-ktx-21.0.0.aar" - info_path = "autorolled/committed/libs/com_google_firebase_firebase_common_ktx/com_google_firebase_firebase_common_ktx.info" - enable_bytecode_checks = false - - # To remove visibility constraint, add this dependency to - # //third_party/android_deps/autorolled/build.gradle. - visibility = [ - ":*", - "//third_party/androidx:*", - ] - deps = [ - "$google_play_services_package:google_firebase_firebase_annotations_java", - "$google_play_services_package:google_firebase_firebase_common_java", - "$google_play_services_package:google_firebase_firebase_components_java", + "//third_party/androidx:androidx_datastore_datastore_preferences_java", "//third_party/kotlin_stdlib:kotlin_stdlib_java", ] } @@ -1065,7 +1044,7 @@ # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. if (google_play_services_package == "//third_party/android_deps") { android_aar_prebuilt("google_firebase_firebase_components_java") { - aar_path = "autorolled/cipd/libs/com_google_firebase_firebase_components/firebase-components-18.0.0.aar" + aar_path = "autorolled/cipd/libs/com_google_firebase_firebase_components/firebase-components-19.0.0.aar" info_path = "autorolled/committed/libs/com_google_firebase_firebase_components/com_google_firebase_firebase_components.info" enable_bytecode_checks = false @@ -1189,7 +1168,7 @@ # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. if (google_play_services_package == "//third_party/android_deps") { android_aar_prebuilt("google_firebase_firebase_installations_java") { - aar_path = "autorolled/cipd/libs/com_google_firebase_firebase_installations/firebase-installations-17.2.0.aar" + aar_path = "autorolled/cipd/libs/com_google_firebase_firebase_installations/firebase-installations-18.0.0.aar" info_path = "autorolled/committed/libs/com_google_firebase_firebase_installations/com_google_firebase_firebase_installations.info" enable_bytecode_checks = false @@ -1202,7 +1181,6 @@ deps = [ "$google_play_services_package:google_firebase_firebase_annotations_java", "$google_play_services_package:google_firebase_firebase_common_java", - "$google_play_services_package:google_firebase_firebase_common_ktx_java", "$google_play_services_package:google_firebase_firebase_components_java", "$google_play_services_package:google_firebase_firebase_installations_interop_java", "$google_play_services_package:google_play_services_tasks_java", @@ -1464,7 +1442,7 @@ # This is generated, do not edit. Update BuildConfigGenerator.groovy instead. java_prebuilt( "org_jetbrains_kotlinx_kotlinx_coroutines_play_services_java") { - jar_path = "autorolled/cipd/libs/org_jetbrains_kotlinx_kotlinx_coroutines_play_services/kotlinx-coroutines-play-services-1.6.4.jar" + jar_path = "autorolled/cipd/libs/org_jetbrains_kotlinx_kotlinx_coroutines_play_services/kotlinx-coroutines-play-services-1.9.0.jar" output_name = "org_jetbrains_kotlinx_kotlinx_coroutines_play_services" supports_android = true requires_android = true
diff --git a/third_party/android_deps/autorolled/VERSION.txt b/third_party/android_deps/autorolled/VERSION.txt index ffb0f8c7..eb60d4c 100644 --- a/third_party/android_deps/autorolled/VERSION.txt +++ b/third_party/android_deps/autorolled/VERSION.txt
@@ -1 +1 @@ -2b93ac4aad7c2ec.c1fd32c1fa3796a \ No newline at end of file +1eb21550563802e.ca6cdf557c4367d \ No newline at end of file
diff --git a/third_party/android_deps/autorolled/additional_readme_paths.json b/third_party/android_deps/autorolled/additional_readme_paths.json index 63e46ba7..5877e556 100644 --- a/third_party/android_deps/autorolled/additional_readme_paths.json +++ b/third_party/android_deps/autorolled/additional_readme_paths.json
@@ -37,7 +37,6 @@ "committed/libs/com_google_errorprone_error_prone_annotations", "committed/libs/com_google_firebase_firebase_annotations", "committed/libs/com_google_firebase_firebase_common", - "committed/libs/com_google_firebase_firebase_common_ktx", "committed/libs/com_google_firebase_firebase_components", "committed/libs/com_google_firebase_firebase_datatransport", "committed/libs/com_google_firebase_firebase_encoders",
diff --git a/third_party/android_deps/autorolled/bill_of_materials.json b/third_party/android_deps/autorolled/bill_of_materials.json index 520c762..451c671 100644 --- a/third_party/android_deps/autorolled/bill_of_materials.json +++ b/third_party/android_deps/autorolled/bill_of_materials.json
@@ -405,29 +405,64 @@ "version": "1.1.0" }, { + "name": "datastore", + "group": "androidx.datastore", + "version": "1.2.0-alpha02" + }, + { "name": "datastore-android", "group": "androidx.datastore", - "version": "1.2.0-SNAPSHOT" + "version": "1.2.0-alpha02" }, { "name": "datastore-core", "group": "androidx.datastore", - "version": "1.2.0-SNAPSHOT" + "version": "1.2.0-alpha02" }, { "name": "datastore-core-android", "group": "androidx.datastore", - "version": "1.2.0-SNAPSHOT" + "version": "1.2.0-alpha02" }, { "name": "datastore-core-okio", "group": "androidx.datastore", - "version": "1.2.0-SNAPSHOT" + "version": "1.2.0-alpha02" }, { "name": "datastore-core-okio-jvm", "group": "androidx.datastore", - "version": "1.2.0-SNAPSHOT" + "version": "1.2.0-alpha02" + }, + { + "name": "datastore-preferences", + "group": "androidx.datastore", + "version": "1.2.0-alpha02" + }, + { + "name": "datastore-preferences-android", + "group": "androidx.datastore", + "version": "1.2.0-alpha02" + }, + { + "name": "datastore-preferences-core", + "group": "androidx.datastore", + "version": "1.2.0-alpha02" + }, + { + "name": "datastore-preferences-core-android", + "group": "androidx.datastore", + "version": "1.2.0-alpha02" + }, + { + "name": "datastore-preferences-external-protobuf", + "group": "androidx.datastore", + "version": "1.2.0-alpha02" + }, + { + "name": "datastore-preferences-proto", + "group": "androidx.datastore", + "version": "1.2.0-alpha02" }, { "name": "documentfile", @@ -812,17 +847,17 @@ { "name": "pdf-document-service", "group": "androidx.pdf", - "version": "1.0.0-SNAPSHOT" + "version": "1.0.0-alpha06" }, { "name": "pdf-viewer", "group": "androidx.pdf", - "version": "1.0.0-SNAPSHOT" + "version": "1.0.0-alpha06" }, { "name": "pdf-viewer-fragment", "group": "androidx.pdf", - "version": "1.0.0-SNAPSHOT" + "version": "1.0.0-alpha06" }, { "name": "preference", @@ -1172,7 +1207,7 @@ { "name": "play-services-auth", "group": "com.google.android.gms", - "version": "21.3.0" + "version": "21.4.0" }, { "name": "play-services-auth-api-phone", @@ -1182,7 +1217,7 @@ { "name": "play-services-auth-base", "group": "com.google.android.gms", - "version": "18.1.0" + "version": "18.3.0" }, { "name": "play-services-auth-blockstore", @@ -1247,7 +1282,7 @@ { "name": "play-services-instantapps", "group": "com.google.android.gms", - "version": "18.1.0" + "version": "18.2.0" }, { "name": "play-services-location", @@ -1287,7 +1322,7 @@ { "name": "material", "group": "com.google.android.material", - "version": "1.14.0-alpha02" + "version": "1.14.0-alpha03" }, { "name": "core-common", @@ -1342,22 +1377,17 @@ { "name": "firebase-annotations", "group": "com.google.firebase", - "version": "16.2.0" + "version": "17.0.0" }, { "name": "firebase-common", "group": "com.google.firebase", - "version": "21.0.0" - }, - { - "name": "firebase-common-ktx", - "group": "com.google.firebase", - "version": "21.0.0" + "version": "22.0.0" }, { "name": "firebase-components", "group": "com.google.firebase", - "version": "18.0.0" + "version": "19.0.0" }, { "name": "firebase-datatransport", @@ -1387,7 +1417,7 @@ { "name": "firebase-installations", "group": "com.google.firebase", - "version": "17.2.0" + "version": "18.0.0" }, { "name": "firebase-installations-interop", @@ -1402,7 +1432,7 @@ { "name": "firebase-messaging", "group": "com.google.firebase", - "version": "24.1.2" + "version": "25.0.0" }, { "name": "failureaccess", @@ -1427,7 +1457,7 @@ { "name": "protobuf-javalite", "group": "com.google.protobuf", - "version": "4.31.1" + "version": "4.32.0-RC1" }, { "name": "protobuf-lite", @@ -1657,7 +1687,7 @@ { "name": "kotlin-stdlib-jdk8", "group": "org.jetbrains.kotlin", - "version": "1.8.22" + "version": "1.8.21" }, { "name": "atomicfu-jvm", @@ -1692,7 +1722,7 @@ { "name": "kotlinx-coroutines-play-services", "group": "org.jetbrains.kotlinx", - "version": "1.6.4" + "version": "1.9.0" }, { "name": "kotlinx-coroutines-reactive",
diff --git a/third_party/android_deps/autorolled/build.gradle b/third_party/android_deps/autorolled/build.gradle index 8060fff..4aa1bb0 100644 --- a/third_party/android_deps/autorolled/build.gradle +++ b/third_party/android_deps/autorolled/build.gradle
@@ -95,11 +95,18 @@ versionCache['androidx.cursoradapter:cursoradapter'] = '1.1.0-SNAPSHOT' versionCache['androidx.customview:customview'] = '1.2.0' versionCache['androidx.customview:customview-poolingcontainer'] = '1.1.0' -versionCache['androidx.datastore:datastore-android'] = '1.2.0-SNAPSHOT' -versionCache['androidx.datastore:datastore-core'] = '1.2.0-SNAPSHOT' -versionCache['androidx.datastore:datastore-core-android'] = '1.2.0-SNAPSHOT' -versionCache['androidx.datastore:datastore-core-okio'] = '1.2.0-SNAPSHOT' -versionCache['androidx.datastore:datastore-core-okio-jvm'] = '1.2.0-SNAPSHOT' +versionCache['androidx.datastore:datastore'] = '1.2.0-alpha02' +versionCache['androidx.datastore:datastore-android'] = '1.2.0-alpha02' +versionCache['androidx.datastore:datastore-core'] = '1.2.0-alpha02' +versionCache['androidx.datastore:datastore-core-android'] = '1.2.0-alpha02' +versionCache['androidx.datastore:datastore-core-okio'] = '1.2.0-alpha02' +versionCache['androidx.datastore:datastore-core-okio-jvm'] = '1.2.0-alpha02' +versionCache['androidx.datastore:datastore-preferences'] = '1.2.0-alpha02' +versionCache['androidx.datastore:datastore-preferences-android'] = '1.2.0-alpha02' +versionCache['androidx.datastore:datastore-preferences-core'] = '1.2.0-alpha02' +versionCache['androidx.datastore:datastore-preferences-core-android'] = '1.2.0-alpha02' +versionCache['androidx.datastore:datastore-preferences-external-protobuf'] = '1.2.0-alpha02' +versionCache['androidx.datastore:datastore-preferences-proto'] = '1.2.0-alpha02' versionCache['androidx.documentfile:documentfile'] = '1.1.0' versionCache['androidx.drawerlayout:drawerlayout'] = '1.3.0-SNAPSHOT' versionCache['androidx.dynamicanimation:dynamicanimation'] = '1.1.0' @@ -176,9 +183,9 @@ versionCache['androidx.paging:paging-compose-android'] = '3.4.0-SNAPSHOT' versionCache['androidx.paging:paging-runtime'] = '3.4.0-SNAPSHOT' versionCache['androidx.palette:palette'] = '1.0.0' -versionCache['androidx.pdf:pdf-document-service'] = '1.0.0-SNAPSHOT' -versionCache['androidx.pdf:pdf-viewer'] = '1.0.0-SNAPSHOT' -versionCache['androidx.pdf:pdf-viewer-fragment'] = '1.0.0-SNAPSHOT' +versionCache['androidx.pdf:pdf-document-service'] = '1.0.0-alpha06' +versionCache['androidx.pdf:pdf-viewer'] = '1.0.0-alpha06' +versionCache['androidx.pdf:pdf-viewer-fragment'] = '1.0.0-alpha06' versionCache['androidx.preference:preference'] = '1.3.0-SNAPSHOT' versionCache['androidx.print:print'] = '1.1.0' versionCache['androidx.privacysandbox.ads:ads-adservices'] = '1.1.0-beta11' @@ -248,9 +255,9 @@ versionCache['com.google.android.datatransport:transport-api'] = '3.1.0' versionCache['com.google.android.datatransport:transport-backend-cct'] = '3.1.9' versionCache['com.google.android.datatransport:transport-runtime'] = '3.1.9' -versionCache['com.google.android.gms:play-services-auth'] = '21.3.0' +versionCache['com.google.android.gms:play-services-auth'] = '21.4.0' versionCache['com.google.android.gms:play-services-auth-api-phone'] = '18.2.0' -versionCache['com.google.android.gms:play-services-auth-base'] = '18.1.0' +versionCache['com.google.android.gms:play-services-auth-base'] = '18.3.0' versionCache['com.google.android.gms:play-services-auth-blockstore'] = '16.4.0' versionCache['com.google.android.gms:play-services-base'] = '18.7.2' versionCache['com.google.android.gms:play-services-basement'] = '18.7.1' @@ -263,7 +270,7 @@ versionCache['com.google.android.gms:play-services-gcm'] = '17.0.0' versionCache['com.google.android.gms:play-services-identity-credentials'] = '16.0.0-alpha08' versionCache['com.google.android.gms:play-services-iid'] = '17.0.0' -versionCache['com.google.android.gms:play-services-instantapps'] = '18.1.0' +versionCache['com.google.android.gms:play-services-instantapps'] = '18.2.0' versionCache['com.google.android.gms:play-services-location'] = '21.3.0' versionCache['com.google.android.gms:play-services-phenotype'] = '17.0.0' versionCache['com.google.android.gms:play-services-stats'] = '17.0.2' @@ -271,7 +278,7 @@ versionCache['com.google.android.gms:play-services-vision'] = '20.1.3' versionCache['com.google.android.gms:play-services-vision-common'] = '19.1.3' versionCache['com.google.android.libraries.identity.googleid:googleid'] = '1.1.1' -versionCache['com.google.android.material:material'] = '1.14.0-alpha02' +versionCache['com.google.android.material:material'] = '1.14.0-alpha03' versionCache['com.google.android.play:core-common'] = '2.0.3' versionCache['com.google.android.play:feature-delivery'] = '2.1.0' versionCache['com.google.android:annotations'] = '4.1.1.4' @@ -282,24 +289,23 @@ versionCache['com.google.code.gson:gson'] = '2.13.1' versionCache['com.google.errorprone:error_prone_annotation'] = '2.38.0' versionCache['com.google.errorprone:error_prone_annotations'] = '2.40.0' -versionCache['com.google.firebase:firebase-annotations'] = '16.2.0' -versionCache['com.google.firebase:firebase-common'] = '21.0.0' -versionCache['com.google.firebase:firebase-common-ktx'] = '21.0.0' -versionCache['com.google.firebase:firebase-components'] = '18.0.0' +versionCache['com.google.firebase:firebase-annotations'] = '17.0.0' +versionCache['com.google.firebase:firebase-common'] = '22.0.0' +versionCache['com.google.firebase:firebase-components'] = '19.0.0' versionCache['com.google.firebase:firebase-datatransport'] = '18.2.0' versionCache['com.google.firebase:firebase-encoders'] = '17.0.0' versionCache['com.google.firebase:firebase-encoders-json'] = '18.0.0' versionCache['com.google.firebase:firebase-encoders-proto'] = '16.0.0' versionCache['com.google.firebase:firebase-iid-interop'] = '17.1.0' -versionCache['com.google.firebase:firebase-installations'] = '17.2.0' +versionCache['com.google.firebase:firebase-installations'] = '18.0.0' versionCache['com.google.firebase:firebase-installations-interop'] = '17.1.1' versionCache['com.google.firebase:firebase-measurement-connector'] = '19.0.0' -versionCache['com.google.firebase:firebase-messaging'] = '24.1.2' +versionCache['com.google.firebase:firebase-messaging'] = '25.0.0' versionCache['com.google.guava:failureaccess'] = '1.0.3' versionCache['com.google.guava:guava'] = '33.4.8-jre' versionCache['com.google.guava:listenablefuture'] = '9999.0-empty-to-avoid-conflict-with-guava' versionCache['com.google.j2objc:j2objc-annotations'] = '3.0.0' -versionCache['com.google.protobuf:protobuf-javalite'] = '4.31.1' +versionCache['com.google.protobuf:protobuf-javalite'] = '4.32.0-RC1' versionCache['com.google.protobuf:protobuf-lite'] = '3.0.1' versionCache['com.google.testparameterinjector:test-parameter-injector'] = '1.18' versionCache['com.googlecode.java-diff-utils:diffutils'] = '1.3.0' @@ -345,14 +351,14 @@ versionCache['org.jetbrains.kotlin:kotlin-stdlib'] = '2.1.21' versionCache['org.jetbrains.kotlin:kotlin-stdlib-common'] = '2.1.20' versionCache['org.jetbrains.kotlin:kotlin-stdlib-jdk7'] = '1.9.0' -versionCache['org.jetbrains.kotlin:kotlin-stdlib-jdk8'] = '1.8.22' +versionCache['org.jetbrains.kotlin:kotlin-stdlib-jdk8'] = '1.8.21' versionCache['org.jetbrains.kotlinx:atomicfu-jvm'] = '0.23.2' versionCache['org.jetbrains.kotlinx:kotlinx-coroutines-android'] = '1.8.1' versionCache['org.jetbrains.kotlinx:kotlinx-coroutines-bom'] = '1.10.2' versionCache['org.jetbrains.kotlinx:kotlinx-coroutines-core'] = '1.10.2' versionCache['org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm'] = '1.8.1' versionCache['org.jetbrains.kotlinx:kotlinx-coroutines-guava'] = '1.8.1' -versionCache['org.jetbrains.kotlinx:kotlinx-coroutines-play-services'] = '1.6.4' +versionCache['org.jetbrains.kotlinx:kotlinx-coroutines-play-services'] = '1.9.0' versionCache['org.jetbrains.kotlinx:kotlinx-coroutines-reactive'] = '1.8.1' versionCache['org.jetbrains.kotlinx:kotlinx-coroutines-rx3'] = '1.8.1' versionCache['org.jetbrains.kotlinx:kotlinx-coroutines-test'] = '1.8.1'
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth/LICENSE b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth/LICENSE index 143db16..e60cb0bd 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth/LICENSE +++ b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth/LICENSE
@@ -6308,6 +6308,104 @@ limitations under the License. +Protocol Buffers: + +Copyright 2008, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The above license applies to all files in this directory and +subdirectories, with exceptions noted below. + +Code generated by the Protocol Buffer compiler is owned by the owner +of the input file used when generating it. This code is not +standalone and requires a support library to be linked with it. This +support library is itself covered by the above license. + +=========================================================================== +rust/utf8.rs +=========================================================================== +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + +Protocol Buffers for Go v2: + +Copyright (c) 2018 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Protocol Buffers for Java: Copyright 2008 Google Inc. All rights reserved. @@ -6550,212 +6648,6 @@ limitations under the License. -Tink: - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - apksig: @@ -7616,4 +7508,413 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and + limitations under the License. + +kotlinx_serialization: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +mobiledatadownload: + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and limitations under the License. \ No newline at end of file
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth/README.chromium b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth/README.chromium index d52dea02..09d7396 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth/README.chromium +++ b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth/README.chromium
@@ -1,7 +1,7 @@ Name: play-services-auth Short Name: play-services-auth URL: https://developers.google.com/android/guides/setup -Version: 21.3.0 +Version: 21.4.0 Update Mechanism: Autoroll License: Android Software Development Kit License License File: LICENSE
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth/com_google_android_gms_play_services_auth.info b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth/com_google_android_gms_play_services_auth.info index 1dd164b..c99b355 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth/com_google_android_gms_play_services_auth.info +++ b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth/com_google_android_gms_play_services_auth.info
@@ -5,7 +5,7 @@ assets = [] has_classes_jar = true has_native_libraries = false -has_proguard_flags = false +has_proguard_flags = true has_r_text_file = true is_manifest_empty = false manifest_package = "com.google.android.gms.auth.api"
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth_base/LICENSE b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth_base/LICENSE index c473ef1d..096e57a 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth_base/LICENSE +++ b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth_base/LICENSE
@@ -6308,6 +6308,37 @@ limitations under the License. +Protocol Buffers for Go v2: + +Copyright (c) 2018 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Protocol Buffers for Java: Copyright 2008 Google Inc. All rights reserved. @@ -6550,212 +6581,6 @@ limitations under the License. -Tink: - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - apksig: @@ -7564,4 +7389,413 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and + limitations under the License. + +kotlinx_serialization: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +mobiledatadownload: + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and limitations under the License. \ No newline at end of file
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth_base/README.chromium b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth_base/README.chromium index 0237d54..99f7285 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth_base/README.chromium +++ b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_auth_base/README.chromium
@@ -1,7 +1,7 @@ Name: play-services-auth-base Short Name: play-services-auth-base URL: https://developers.google.com/android/guides/setup -Version: 18.1.0 +Version: 18.3.0 Update Mechanism: Autoroll License: Android Software Development Kit License License File: LICENSE
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_instantapps/LICENSE b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_instantapps/LICENSE index e0f15cf7..faf09be 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_instantapps/LICENSE +++ b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_instantapps/LICENSE
@@ -147,585 +147,6 @@ December 9, 2016 -AndroidX lifecycle common library: - - - Copyright (c) 2005-2011, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - -AndroidX lifecycle livedatacore library: - - - Copyright (c) 2005-2011, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - -AndroidX lifecycle runtime library: - - - Copyright (c) 2005-2011, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Animal Sniffer: The MIT License @@ -1613,6 +1034,1253 @@ See the License for the specific language governing permissions and limitations under the License. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +GNU General Public License + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street Fifth Floor Boston Ma 02110-1301 Usa + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to +most of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software is +covered by the GNU Library General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change +the software or use pieces of it in new free programs; and that you know you +can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny +you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must +make sure that they, too, receive or can get the source code. And you must +show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients to +know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program proprietary. +To prevent this, we have made it clear that any patent must be licensed for +everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms of +this General Public License. The "Program", below, refers to any such program +or work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is included +without limitation in the term "modification".) Each licensee is addressed as +"you". + +Activities other than copying, distribution and modification are not covered by +this License; they are outside its scope. The act of running the Program is +not restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by +running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as +you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this License +and to the absence of any warranty; and give any other recipients of the +Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may +at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus +forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all of +these conditions: + + a) You must cause the modified files to carry prominent notices stating + that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or + in part contains or is derived from the Program or any part thereof, to be + licensed as a whole at no charge to all third parties under the terms of + this License. + + c) If the modified program normally reads commands interactively when run, + you must cause it, when started running for such interactive use in the + most ordinary way, to print or display an announcement including an + appropriate copyright notice and a notice that there is no warranty (or + else, saying that you provide a warranty) and that users may redistribute + the program under these conditions, and telling the user how to view a copy + of this License. (Exception: if the Program itself is interactive but does + not normally print such an announcement, your work based on the Program is + not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, and +its terms, do not apply to those sections when you distribute them as separate +works. But when you distribute the same sections as part of a whole which is a +work based on the Program, the distribution of the whole must be on the terms +of this License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based on +the Program. + +In addition, mere aggregation of another work not based on the Program with the +Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under +Section 2) in object code or executable form under the terms of Sections 1 and +2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source + code, which must be distributed under the terms of Sections 1 and 2 above + on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to + give any third party, for a charge no more than your cost of physically + performing source distribution, a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed only + for noncommercial distribution and only if you received the program in + object code or executable form with such an offer, in accord with + Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all +the source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code +distributed need not include anything that is normally distributed (in either +source or binary form) with the major components (compiler, kernel, and so on) +of the operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the source +code from the same place counts as distribution of the source code, even though +third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, or +rights, from you under this License will not have their licenses terminated so +long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the Program +or its derivative works. These actions are prohibited by law if you do not +accept this License. Therefore, by modifying or distributing the Program (or +any work based on the Program), you indicate your acceptance of this License to +do so, and all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor to +copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of the +rights granted herein. You are not responsible for enforcing compliance by +third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), conditions +are imposed on you (whether by court order, agreement or otherwise) that +contradict the conditions of this License, they do not excuse you from the +conditions of this License. If you cannot distribute so as to satisfy +simultaneously your obligations under this License and any other pertinent +obligations, then as a consequence you may not distribute the Program at all. +For example, if a patent license would not permit royalty-free redistribution +of the Program by all those who receive copies directly or indirectly through +you, then the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many +people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose that +choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original +copyright holder who places the Program under this License may add an explicit +geographical distribution limitation excluding those countries, so that +distribution is permitted only in or among countries not thus excluded. In +such case, this License incorporates the limitation as if written in the body +of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the +General Public License from time to time. Such new versions will be similar in +spirit to the present version, but may differ in detail to address new problems +or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any later +version", you have the option of following the terms and conditions either of +that version or of any later version published by the Free Software Foundation. +If the Program does not specify a version number of this License, you may +choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status of +all derivatives of our free software and of promoting the sharing and reuse of +software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE +PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, +YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL +ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE +PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR +INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA +BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER +OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively convey the exclusion +of warranty; and each file should have at least the "copyright" line and a +pointer to where the full notice is found. + + One line to give the program's name and a brief idea of what it does. + + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it +starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes + with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free + software, and you are welcome to redistribute it under certain conditions; + type 'show c' for details. + +The hypothetical commands 'show w' and 'show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may be +called something other than 'show w' and 'show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the program, if necessary. Here +is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + 'Gnomovision' (which makes passes at compilers) written by James Hacker. + + signature of Ty Coon, 1 April 1989 + + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General Public +License instead of this License. + + +"CLASSPATH" EXCEPTION TO THE GPL + +Certain source files distributed by Oracle America and/or its affiliates are +subject to the following clarification and special exception to the GPL, but +only where Oracle has expressly included in the particular source file's header +the words "Oracle designates this particular file as subject to the "Classpath" +exception as provided by Oracle in the LICENSE file that accompanied this code." + + Linking this library statically or dynamically with other modules is making + a combined work based on this library. Thus, the terms and conditions of + the GNU General Public License cover the whole combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent modules, + and to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent module, + the terms and conditions of the license of that module. An independent + module is a module which is not derived from or based on this library. If + you modify this library, you may extend this exception to your version of + the library, but you are not obligated to do so. If you do not wish to do + so, delete this exception statement from your version. + +APPLE PUBLIC SOURCE LICENSE Version 2.0 - August 6, 2003 + +Please read this License carefully before downloading this software. By +downloading or using this software, you are agreeing to be bound by the terms of +this License. If you do not or cannot agree to the terms of this License, +please do not download or use the software. + +Apple Note: In January 2007, Apple changed its corporate name from "Apple +Computer, Inc." to "Apple Inc." This change has been reflected below and +copyright years updated, but no other changes have been made to the APSL 2.0. + +1. General; Definitions. This License applies to any program or other work +which Apple Inc. ("Apple") makes publicly available and which contains a notice +placed by Apple identifying such program or work as "Original Code" and stating +that it is subject to the terms of this Apple Public Source License version 2.0 +("License"). As used in this License: + +1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is the +grantor of rights, (i) claims of patents that are now or hereafter acquired, +owned by or assigned to Apple and (ii) that cover subject matter contained in +the Original Code, but only to the extent necessary to use, reproduce and/or +distribute the Original Code without infringement; and (b) in the case where You +are the grantor of rights, (i) claims of patents that are now or hereafter +acquired, owned by or assigned to You and (ii) that cover subject matter in Your +Modifications, taken alone or in combination with Original Code. + +1.2 "Contributor" means any person or entity that creates or contributes to the +creation of Modifications. + +1.3 "Covered Code" means the Original Code, Modifications, the combination of +Original Code and any Modifications, and/or any respective portions thereof. + +1.4 "Externally Deploy" means: (a) to sublicense, distribute or otherwise make +Covered Code available, directly or indirectly, to anyone other than You; and/or +(b) to use Covered Code, alone or as part of a Larger Work, in any way to +provide a service, including but not limited to delivery of content, through +electronic communication with a client other than You. + +1.5 "Larger Work" means a work which combines Covered Code or portions thereof +with code not governed by the terms of this License. + +1.6 "Modifications" mean any addition to, deletion from, and/or change to, the +substance and/or structure of the Original Code, any previous Modifications, the +combination of Original Code and any previous Modifications, and/or any +respective portions thereof. When code is released as a series of files, a +Modification is: (a) any addition to or deletion from the contents of a file +containing Covered Code; and/or (b) any new file or other representation of +computer program statements that contains any part of Covered Code. + +1.7 "Original Code" means (a) the Source Code of a program or other work as +originally made available by Apple under this License, including the Source Code +of any updates or upgrades to such programs or works made available by Apple +under this License, and that has been expressly identified by Apple as such in +the header file(s) of such work; and (b) the object code compiled from such +Source Code and originally made available by Apple under this License + +1.8 "Source Code" means the human readable form of a program or other work that +is suitable for making modifications to it, including all modules it contains, +plus any associated interface definition files, scripts used to control +compilation and installation of an executable (object code). + +1.9 "You" or "Your" means an individual or a legal entity exercising rights +under this License. For legal entities, "You" or "Your" includes any entity +which controls, is controlled by, or is under common control with, You, where +"control" means (a) the power, direct or indirect, to cause the direction or +management of such entity, whether by contract or otherwise, or (b) ownership of +fifty percent (50%) or more of the outstanding shares or beneficial ownership of +such entity. + +2. Permitted Uses; Conditions & Restrictions. Subject to the terms and +conditions of this License, Apple hereby grants You, effective on the date You +accept this License and download the Original Code, a world-wide, royalty-free, +non-exclusive license, to the extent of Apple's Applicable Patent Rights and +copyrights covering the Original Code, to do the following: + +2.1 Unmodified Code. You may use, reproduce, display, perform, internally +distribute within Your organization, and Externally Deploy verbatim, unmodified +copies of the Original Code, for commercial or non-commercial purposes, provided +that in each instance: + +(a) You must retain and reproduce in all copies of Original Code the copyright +and other proprietary notices and disclaimers of Apple as they appear in the +Original Code, and keep intact all notices in the Original Code that refer to +this License; and + +(b) You must include a copy of this License with every copy of Source Code of +Covered Code and documentation You distribute or Externally Deploy, and You may +not offer or impose any terms on such Source Code that alter or restrict this +License or the recipients' rights hereunder, except as permitted under Section +6. + +2.2 Modified Code. You may modify Covered Code and use, reproduce, display, +perform, internally distribute within Your organization, and Externally Deploy +Your Modifications and Covered Code, for commercial or non-commercial purposes, +provided that in each instance You also meet all of these conditions: + +(a) You must satisfy all the conditions of Section 2.1 with respect to the +Source Code of the Covered Code; + +(b) You must duplicate, to the extent it does not already exist, the notice in +Exhibit A in each file of the Source Code of all Your Modifications, and cause +the modified files to carry prominent notices stating that You changed the files +and the date of any change; and + +(c) If You Externally Deploy Your Modifications, You must make Source Code of +all Your Externally Deployed Modifications either available to those to whom You +have Externally Deployed Your Modifications, or publicly available. Source Code +of Your Externally Deployed Modifications must be released under the terms set +forth in this License, including the license grants set forth in Section 3 +below, for as long as you Externally Deploy the Covered Code or twelve (12) +months from the date of initial External Deployment, whichever is longer. You +should preferably distribute the Source Code of Your Externally Deployed +Modifications electronically (e.g. download from a web site). + +2.3 Distribution of Executable Versions. In addition, if You Externally Deploy +Covered Code (Original Code and/or Modifications) in object code, executable +form only, You must include a prominent notice, in the code itself as well as in +related documentation, stating that Source Code of the Covered Code is available +under the terms of this License with information on how and where to obtain such +Source Code. + +2.4 Third Party Rights. You expressly acknowledge and agree that although +Apple and each Contributor grants the licenses to their respective portions of +the Covered Code set forth herein, no assurances are provided by Apple or any +Contributor that the Covered Code does not infringe the patent or other +intellectual property rights of any other entity. Apple and each Contributor +disclaim any liability to You for claims brought by any other entity based on +infringement of intellectual property rights or otherwise. As a condition to +exercising the rights and licenses granted hereunder, You hereby assume sole +responsibility to secure any other intellectual property rights needed, if any. +For example, if a third party patent license is required to allow You to +distribute the Covered Code, it is Your responsibility to acquire that license +before distributing the Covered Code. + +3. Your Grants. In consideration of, and as a condition to, the licenses +granted to You under this License, You hereby grant to any person or entity +receiving or distributing Covered Code under this License a non-exclusive, +royalty-free, perpetual, irrevocable license, under Your Applicable Patent +Rights and other intellectual property rights (other than patent) owned or +controlled by You, to use, reproduce, display, perform, modify, sublicense, +distribute and Externally Deploy Your Modifications of the same scope and extent +as Apple's licenses under Sections 2.1 and 2.2 above. + +4. Larger Works. You may create a Larger Work by combining Covered Code with +other code not governed by the terms of this License and distribute the Larger +Work as a single product. In each such instance, You must make sure the +requirements of this License are fulfilled for the Covered Code or any portion +thereof. + +5. Limitations on Patent License. Except as expressly stated in Section 2, no +other patent rights, express or implied, are granted by Apple herein. +Modifications and/or Larger Works may require additional patent licenses from +Apple which Apple may grant in its sole discretion. + +6. Additional Terms. You may choose to offer, and to charge a fee for, +warranty, support, indemnity or liability obligations and/or other rights +consistent with the scope of the license granted herein ("Additional Terms") to +one or more recipients of Covered Code. However, You may do so only on Your own +behalf and as Your sole responsibility, and not on behalf of Apple or any +Contributor. You must obtain the recipient's agreement that any such Additional +Terms are offered by You alone, and You hereby agree to indemnify, defend and +hold Apple and every Contributor harmless for any liability incurred by or +claims asserted against Apple or such Contributor by reason of any such +Additional Terms. + +7. Versions of the License. Apple may publish revised and/or new versions of +this License from time to time. Each version will be given a distinguishing +version number. Once Original Code has been published under a particular +version of this License, You may continue to use it under the terms of that +version. You may also choose to use such Original Code under the terms of any +subsequent version of this License published by Apple. No one other than Apple +has the right to modify the terms applicable to Covered Code created under this +License. + +8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in part +pre-release, untested, or not fully tested works. The Covered Code may contain +errors that could cause failures or loss of data, and may be incomplete or +contain inaccuracies. You expressly acknowledge and agree that use of the +Covered Code, or any portion thereof, is at Your sole and entire risk. THE +COVERED CODE IS PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT OF +ANY KIND AND APPLE AND APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" +FOR THE PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM +ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF MERCHANTABILITY, OF SATISFACTORY +QUALITY, OF FITNESS FOR A PARTICULAR PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, +AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT +WARRANT AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE +FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS, THAT THE +OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT +DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO ORAL OR WRITTEN INFORMATION +OR ADVICE GIVEN BY APPLE, AN APPLE AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR +SHALL CREATE A WARRANTY. You acknowledge that the Covered Code is not intended +for use in the operation of nuclear facilities, aircraft navigation, +communication systems, or air traffic control machines in which case the failure +of the Covered Code could lead to death, personal injury, or severe physical or +environmental damage. + +9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT +SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT +OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO THIS LICENSE OR YOUR USE +OR INABILITY TO USE THE COVERED CODE, OR ANY PORTION THEREOF, WHETHER UNDER A +THEORY OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR +OTHERWISE, EVEN IF APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY +OF SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY +REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF +INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY TO YOU. In +no event shall Apple's total liability to You for all damages (other than as may +be required by applicable law) under this License exceed the amount of fifty +dollars ($50.00). + +10. Trademarks. This License does not grant any rights to use the trademarks +or trade names "Apple", "Mac", "Mac OS", "QuickTime", "QuickTime Streaming +Server" or any other trademarks, service marks, logos or trade names belonging +to Apple (collectively "Apple Marks") or to any trademark, service mark, logo or +trade name belonging to any Contributor. You agree not to use any Apple Marks +in or as part of the name of products derived from the Original Code or to +endorse or promote products derived from the Original Code other than as +expressly permitted by and in strict compliance at all times with Apple's third +party trademark usage guidelines which are posted at +http://www.apple.com/legal/guidelinesfor3rdparties.html. + +11. Ownership. Subject to the licenses granted under this License, each +Contributor retains all rights, title and interest in and to any Modifications +made by such Contributor. Apple retains all rights, title and interest in and +to the Original Code and any Modifications made by or on behalf of Apple ("Apple +Modifications"), and such Apple Modifications will not be automatically subject +to this License. Apple may, at its sole discretion, choose to license such +Apple Modifications under this License, or on different terms from those +contained in this License or may choose not to license them at all. + +12. Termination. + +12.1 Termination. This License and the rights granted hereunder will +terminate: + +(a) automatically without notice from Apple if You fail to comply with any +term(s) of this License and fail to cure such breach within 30 days of becoming +aware of such breach; (b) immediately in the event of the circumstances +described in Section 13.5(b); or (c) automatically without notice from Apple if +You, at any time during the term of this License, commence an action for patent +infringement against Apple; provided that Apple did not first commence an action +for patent infringement against You in that instance. + +12.2 Effect of Termination. Upon termination, You agree to immediately stop +any further use, reproduction, modification, sublicensing and distribution of +the Covered Code. All sublicenses to the Covered Code which have been properly +granted prior to termination shall survive any termination of this License. +Provisions which, by their nature, should remain in effect beyond the +termination of this License shall survive, including but not limited to Sections +3, 5, 8, 9, 10, 11, 12.2 and 13. No party will be liable to any other for +compensation, indemnity or damages of any sort solely as a result of terminating +this License in accordance with its terms, and termination of this License will +be without prejudice to any other right or remedy of any party. + +13. Miscellaneous. + +13.1 Government End Users. The Covered Code is a "commercial item" as defined +in FAR 2.101. Government software and technical data rights in the Covered Code +include only those rights customarily provided to the public as defined in this +License. This customary commercial license in technical data and software is +provided in accordance with FAR 12.211 (Technical Data) and 12.212 (Computer +Software) and, for Department of Defense purchases, DFAR 252.227-7015 (Technical +Data -- Commercial Items) and 227.7202-3 (Rights in Commercial Computer Software +or Computer Software Documentation). Accordingly, all U.S. Government End Users +acquire Covered Code with only those rights set forth herein. + +13.2 Relationship of Parties. This License will not be construed as creating +an agency, partnership, joint venture or any other form of legal association +between or among You, Apple or any Contributor, and You will not represent to +the contrary, whether expressly, by implication, appearance or otherwise. + +13.3 Independent Development. Nothing in this License will impair Apple's +right to acquire, license, develop, have others develop for it, market and/or +distribute technology or products that perform the same or similar functions as, +or otherwise compete with, Modifications, Larger Works, technology or products +that You may develop, produce, market or distribute. + +13.4 Waiver; Construction. Failure by Apple or any Contributor to enforce any +provision of this License will not be deemed a waiver of future enforcement of +that or any other provision. Any law or regulation which provides that the +language of a contract shall be construed against the drafter will not apply to +this License. + +13.5 Severability. (a) If for any reason a court of competent jurisdiction +finds any provision of this License, or portion thereof, to be unenforceable, +that provision of the License will be enforced to the maximum extent permissible +so as to effect the economic benefits and intent of the parties, and the +remainder of this License will continue in full force and effect. (b) +Notwithstanding the foregoing, if applicable law prohibits or restricts You from +fully and/or specifically complying with Sections 2 and/or 3 or prevents the +enforceability of either of those Sections, this License will immediately +terminate and You must immediately discontinue any use of the Covered Code and +destroy all copies of it that are in your possession or control. + +13.6 Dispute Resolution. Any litigation or other dispute resolution between +You and Apple relating to this License shall take place in the Northern District +of California, and You and Apple hereby consent to the personal jurisdiction of, +and venue in, the state and federal courts within that District with respect to +this License. The application of the United Nations Convention on Contracts for +the International Sale of Goods is expressly excluded. + +13.7 Entire Agreement; Governing Law. This License constitutes the entire +agreement between the parties with respect to the subject matter hereof. This +License shall be governed by the laws of the United States and the State of +California, except that body of California law concerning conflicts of law. + +Where You are located in the province of Quebec, Canada, the following clause +applies: The parties hereby confirm that they have requested that this License +and all related documents be drafted in English. Les parties ont exigé que le +présent contrat et tous les documents connexes soient rédigés en anglais. + +EXHIBIT A. + +"Portions Copyright (c) 1999-2007 Apple Inc. All Rights Reserved. + +This file contains Original Code and/or Modifications of Original Code as +defined in and that are subject to the Apple Public Source License Version 2.0 +(the 'License'). You may not use this file except in compliance with the +License. Please obtain a copy of the License at +http://www.opensource.apple.com/apsl/ and read it before using this file. + +The Original Code and all software distributed under the License are distributed +on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, +AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, +ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET +ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the specific language +governing rights and limitations under the License." + +ICU License - ICU 1.8.1 and later + +COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 1995-2016 International Business Machines Corporation and others + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY +SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + + +All trademarks and registered trademarks mentioned herein are the +property of their respective owners. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Unicode data files and any associated documentation +(the "Data Files") or Unicode software and any associated documentation +(the "Software") to deal in the Data Files or Software +without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, and/or sell copies of +the Data Files or Software, and to permit persons to whom the Data Files +or Software are furnished to do so, provided that +(a) this copyright and permission notice appear with all copies +of the Data Files or Software, +(b) this copyright and permission notice appear in associated +documentation, and +(c) there is clear notice in each modified Data File or in the Software +as well as in the documentation associated with the Data File(s) or +Software that the data or software has been modified. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT OF THIRD PARTY RIGHTS. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THE DATA FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in these Data Files or Software without prior +written authorization of the copyright holder. + + # The Google Chrome software developed by Google is licensed under + # the BSD license. Other software included in this distribution is + # provided under other licenses, as set forth below. + # + # The BSD License + # http://opensource.org/licenses/bsd-license.php + # Copyright (C) 2006-2008, Google Inc. + # + # All rights reserved. + + # The word list in cjdict.txt are generated by combining three word lists + # listed below with further processing for compound word breaking. The + # frequency is generated with an iterative training against Google web + # corpora. + # + # * Libtabe (Chinese) + # - https://sourceforge.net/project/?group_id=1519 + # - Its license terms and conditions are shown below. + # + # * IPADIC (Japanese) + # - http://chasen.aist-nara.ac.jp/chasen/distribution.html + # - Its license terms and conditions are shown below. + + # * All rights reserved. + # * + # * Redistribution and use in source and binary forms, with or without + # * modification, are permitted provided that the following conditions + # * are met: + # * + # * . Redistributions of source code must retain the above copyright + # * notice, this list of conditions and the following disclaimer. + # * . Redistributions in binary form must reproduce the above copyright + # * notice, this list of conditions and the following disclaimer in + # * the documentation and/or other materials provided with the + # * distribution. + # * . Neither the name of the TaBE Project nor the names of its + # * contributors may be used to endorse or promote products derived + # * from this software without specific prior written permission. + # * + # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + # * OF THE POSSIBILITY OF SUCH DAMAGE. + + # All rights reserved. + # * + # * Redistribution and use in source and binary forms, with or without + # * modification, are permitted provided that the following conditions + # * are met: + # * + # * . Redistributions of source code must retain the above copyright + # * notice, this list of conditions and the following disclaimer. + # * . Redistributions in binary form must reproduce the above copyright + # * notice, this list of conditions and the following disclaimer in + # * the documentation and/or other materials provided with the + # * distribution. + # * . Neither the name of the Computer Systems and Communication Lab + # * nor the names of its contributors may be used to endorse or + # * promote products derived from this software without specific + # * prior written permission. + # * + # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + # * OF THE POSSIBILITY OF SUCH DAMAGE. + # University of Illinois + # c-tsai4@uiuc.edu http://casper.beckman.uiuc.edu/~c-tsai4 + + # Use, reproduction, and distribution of this software is permitted. + # Any copy of this software, whether in its original form or modified, + # must include both the above copyright notice and the following + # paragraphs. + # + # Nara Institute of Science and Technology (NAIST), + # the copyright holders, disclaims all warranties with regard to this + # software, including all implied warranties of merchantability and + # fitness, in no event shall NAIST be liable for + # any special, indirect or consequential damages or any damages + # whatsoever resulting from loss of use, data or profits, whether in an + # action of contract, negligence or other tortuous action, arising out + # of or in connection with the use or performance of this software. + # + # A large portion of the dictionary entries + # originate from ICOT Free Software. The following conditions for ICOT + # Free Software applies to the current dictionary as well. + # + # Each User may also freely distribute the Program, whether in its + # original form or modified, to any third party or parties, PROVIDED + # that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear + # on, or be attached to, the Program, which is distributed substantially + # in the same form as set out herein and that such intended + # distribution, if actually made, will neither violate or otherwise + # contravene any of the laws and regulations of the countries having + # jurisdiction over the User or the intended distribution itself. + # + # NO WARRANTY + # + # The program was produced on an experimental basis in the course of the + # research and development conducted during the project and is provided + # to users as so produced on an experimental basis. Accordingly, the + # program is provided without any warranty whatsoever, whether express, + # implied, statutory or otherwise. The term "warranty" used herein + # includes, but is not limited to, any warranty of the quality, + # performance, merchantability and fitness for a particular purpose of + # the program and the nonexistence of any infringement or violation of + # any right of any third party. + # + # Each user of the program will agree and understand, and be deemed to + # have agreed and understood, that there is no warranty whatsoever for + # the program and, accordingly, the entire risk arising from or + # otherwise connected with the program is assumed by the user. + # + # Therefore, neither ICOT, the copyright holder, or any other + # organization that participated in or was otherwise related to the + # development of the program and their respective officials, directors, + # officers and other employees shall be held liable for any and all + # damages, including, without limitation, general, special, incidental + # and consequential damages, arising out of or otherwise in connection + # with the use or inability to use the program or any product, material + # or result produced or otherwise obtained by using the program, + # regardless of whether they have been advised of, or otherwise had + # knowledge of, the possibility of such damages at any time during the + # project or thereafter. Each user will be deemed to have agreed to the + # foregoing by his or her commencement of use of the program. The term + # "use" as used herein includes, but is not limited to, the use, + # modification, copying and distribution of the program and the + # production of secondary products from the program. + # + # In the case where the program, whether in its original form or + # modified, was distributed or delivered to or received by a user from + # any person, organization or entity other than ICOT, unless it makes or + # grants independently of ICOT any specific warranty to the user in + # writing, such person, organization or entity, will also be exempted + # from and not be held liable to the user for any such damages as noted + # above as far as the program is concerned. + + # All Rights Reserved. + # + # Project: http://code.google.com/p/lao-dictionary/ + # Dictionary: http://lao-dictionary.googlecode.com/git/Lao-Dictionary.txt + # License: http://lao-dictionary.googlecode.com/git/Lao-Dictionary-LICENSE.txt + # (copied below) + # + # This file is derived from the above dictionary, with slight + # modifications. + + # Redistribution and use in source and binary forms, with or without + # modification, + # are permitted provided that the following conditions are met: + # + # + # Redistributions of source code must retain the above copyright notice, this + # list of conditions and the following disclaimer. Redistributions in + # binary form must reproduce the above copyright notice, this list of + # conditions and the following disclaimer in the documentation and/or + # other materials provided with the distribution. + # + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + # OF THE POSSIBILITY OF SUCH DAMAGE. + + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: Redistributions of source code must retain the above + # copyright notice, this list of conditions and the following + # disclaimer. Redistributions in binary form must reproduce the + # above copyright notice, this list of conditions and the following + # disclaimer in the documentation and/or other materials provided + # with the distribution. + # + # Neither the name Myanmar Karen Word Lists, nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + # SUCH DAMAGE. + + ICU uses the public domain data and code derived from Time Zone +Database for its time zone support. The ownership of the TZ database +is explained in BCP 175: Procedure for Maintaining the Time Zone +Database section 7. + + # 7. Database Ownership + # + # The TZ database itself is not an IETF Contribution or an IETF + # document. Rather it is a pre-existing and regularly updated work + # that is in the public domain, and is intended to remain in the + # public domain. Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do + # not apply to the TZ Database or contributions that individuals make + # to it. Should any claims be made and substantiated against the TZ + # Database, the organization that is providing the IANA + # Considerations defined in this RFC, under the memorandum of + # understanding with the IETF, currently ICANN, may act in accordance + # with all competent court orders. No ownership claims will be made + # by ICANN or the IETF Trust on the database or the code. Any person + # making a contribution to the database or code waives all rights to + # future claims in that contribution or in the TZ Database. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Permission to use, copy, modify, and distribute this +software is freely granted, provided that this notice +is preserved. + +Common Public License - Version 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC +LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM +CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial code and + documentation distributed under this Agreement, and + b) in the case of each subsequent Contributor: + + i) changes to the Program, and + + ii) additions to the Program; + + where such changes and/or additions to the Program originate from and are +distributed by that particular Contributor. A Contribution 'originates' from a +Contributor if it was added to the Program by such Contributor itself or anyone +acting on such Contributor's behalf. Contributions do not include additions to +the Program which: (i) are separate modules of software distributed in +conjunction with the Program under their own license agreement, and (ii) are +not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor which are +necessarily infringed by the use or sale of its Contribution alone or when +combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, +including all Contributors. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free copyright license to +reproduce, prepare derivative works of, publicly display, publicly perform, +distribute and sublicense the Contribution of such Contributor, if any, and +such derivative works, in source code and object code form. + + b) Subject to the terms of this Agreement, each Contributor hereby grants +Recipient a non-exclusive, worldwide, royalty-free patent license under +Licensed Patents to make, use, sell, offer to sell, import and otherwise +transfer the Contribution of such Contributor, if any, in source code and +object code form. This patent license shall apply to the combination of the +Contribution and the Program if, at the time the Contribution is added by the +Contributor, such addition of the Contribution causes such combination to be +covered by the Licensed Patents. The patent license shall not apply to any +other combinations which include the Contribution. No hardware per se is +licensed hereunder. + + c) Recipient understands that although each Contributor grants the +licenses to its Contributions set forth herein, no assurances are provided by +any Contributor that the Program does not infringe the patent or other +intellectual property rights of any other entity. Each Contributor disclaims +any liability to Recipient for claims brought by any other entity based on +infringement of intellectual property rights or otherwise. As a condition to +exercising the rights and licenses granted hereunder, each Recipient hereby +assumes sole responsibility to secure any other intellectual property rights +needed, if any. For example, if a third party patent license is required to +allow Recipient to distribute the Program, it is Recipient's responsibility to +acquire that license before distributing the Program. + + d) Each Contributor represents that to its knowledge it has sufficient +copyright rights in its Contribution, if any, to grant the copyright license +set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under +its own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; and + + b) its license agreement: + + i) effectively disclaims on behalf of all Contributors all warranties and +conditions, express and implied, including warranties or conditions of title +and non-infringement, and implied warranties or conditions of merchantability +and fitness for a particular purpose; + + ii) effectively excludes on behalf of all Contributors all liability for +damages, including direct, indirect, special, incidental and consequential +damages, such as lost profits; + + iii) states that any provisions which differ from this Agreement are +offered by that Contributor alone and not by any other party; and + + iv) states that source code for the Program is available from such +Contributor, and informs licensees how to obtain it in a reasonable manner on +or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + + b) a copy of this Agreement must be included with each copy of the +Program. + +Contributors may not remove or alter any copyright notices contained within the +Program. + +Each Contributor must identify itself as the originator of its Contribution, if +any, in a manner that reasonably allows subsequent Recipients to identify the +originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with +respect to end users, business partners and the like. While this license is +intended to facilitate the commercial use of the Program, the Contributor who +includes the Program in a commercial product offering should do so in a manner +which does not create potential liability for other Contributors. Therefore, if +a Contributor includes the Program in a commercial product offering, such +Contributor ("Commercial Contributor") hereby agrees to defend and indemnify +every other Contributor ("Indemnified Contributor") against any losses, damages +and costs (collectively "Losses") arising from claims, lawsuits and other legal +actions brought by a third party against the Indemnified Contributor to the +extent caused by the acts or omissions of such Commercial Contributor in +connection with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In order +to qualify, an Indemnified Contributor must: a) promptly notify the Commercial +Contributor in writing of such claim, and b) allow the Commercial Contributor +to control, and cooperate with the Commercial Contributor in, the defense and +any related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product +offering, Product X. That Contributor is then a Commercial Contributor. If that +Commercial Contributor then makes performance claims, or offers warranties +related to Product X, those performance claims and warranties are such +Commercial Contributor's responsibility alone. Under this section, the +Commercial Contributor would have to defend claims against the other +Contributors related to those performance claims and warranties, and if a court +requires any other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each +Recipient is solely responsible for determining the appropriateness of using +and distributing the Program and assumes all risks associated with its exercise +of rights under this Agreement, including but not limited to the risks and +costs of program errors, compliance with applicable laws, damage to or loss of +data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY +CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY +WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS +GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable +law, it shall not affect the validity or enforceability of the remainder of the +terms of this Agreement, and without further action by the parties hereto, such +provision shall be reformed to the minimum extent necessary to make such +provision valid and enforceable. + +If Recipient institutes patent litigation against a Contributor with respect to +a patent applicable to software (including a cross-claim or counterclaim in a +lawsuit), then any patent licenses granted by that Contributor to such +Recipient under this Agreement shall terminate as of the date such litigation +is filed. In addition, if Recipient institutes patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software or +hardware) infringes such Recipient's patent(s), then such Recipient's rights +granted under Section 2(b) shall terminate as of the date such litigation is +filed. + +All Recipient's rights under this Agreement shall terminate if it fails to +comply with any of the material terms or conditions of this Agreement and does +not cure such failure in a reasonable period of time after becoming aware of +such noncompliance. If all Recipient's rights under this Agreement terminate, +Recipient agrees to cease use and distribution of the Program as soon as +reasonably practicable. However, Recipient's obligations under this Agreement +and any licenses granted by Recipient relating to the Program shall continue +and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in +order to avoid inconsistency the Agreement is copyrighted and may only be +modified in the following manner. The Agreement Steward reserves the right to +publish new versions (including revisions) of this Agreement from time to time. +No one other than the Agreement Steward has the right to modify this Agreement. +IBM is the initial Agreement Steward. IBM may assign the responsibility to +serve as the Agreement Steward to a suitable separate entity. Each new version +of the Agreement will be given a distinguishing version number. The Program +(including Contributions) may always be distributed subject to the version of +the Agreement under which it was received. In addition, after a new version of +the Agreement is published, Contributor may elect to distribute the Program +(including its Contributions) under the new version. Except as expressly stated +in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to +the intellectual property of any Contributor under this Agreement, whether +expressly, by implication, estoppel or otherwise. All rights in the Program not +expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the +intellectual property laws of the United States of America. No party to this +Agreement will bring a legal action under this Agreement more than one year +after the cause of action arose. Each party waives its rights to a jury trial +in any resulting litigation. + JSR 305: @@ -1646,6 +2314,212 @@ POSSIBILITY OF SUCH DAMAGE. +JSpecify: + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + JsInterop Annotations: Apache License @@ -1850,6 +2724,2390 @@ See the License for the specific language governing permissions and limitations under the License. +Kotlin: + +Files: kotlinc/* + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2000-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +------------------ + +Files: kotlinc/lib/trove4j.jar + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + +------------------ + +Files: + +The version of Rhino used in GWT is licensed under a dual license, +Netscape Public License 1.1 / GNU General Public License. +The text of the Netscape Public License +is provided below (http://website-archive.mozilla.org/www.mozilla.org/mpl/MPL/NPL/1.1/): + +AMENDMENTS + +The Netscape Public License Version 1.1 ("NPL") consists of the +Mozilla Public License Version 1.1 with the following Amendments, +including Exhibit A-Netscape Public License. Files identified with +"Exhibit A-Netscape Public License" are governed by the Netscape +Public License Version 1.1. + +Additional Terms applicable to the Netscape Public License. + + I. Effect. + + These additional terms described in this Netscape Public + License -- Amendments shall apply to the Mozilla Communicator + client code and to all Covered Code under this License. + + II. ''Netscape's Branded Code'' means Covered Code that Netscape + distributes and/or permits others to distribute under one or + more trademark(s) which are controlled by Netscape but which + are not licensed for use under this License. + + III. Netscape and logo. + + This License does not grant any rights to use the trademarks + "Netscape'', the "Netscape N and horizon'' logo or the + "Netscape lighthouse" logo, "Netcenter", "Gecko", "Java" or + "JavaScript", "Smart Browsing" even if such marks are included + in the Original Code or Modifications. + + IV. Inability to Comply Due to Contractual Obligation. + + Prior to licensing the Original Code under this License, + Netscape has licensed third party code for use in Netscape's + Branded Code. To the extent that Netscape is limited + contractually from making such third party code available under + this License, Netscape may choose to reintegrate such code into + Covered Code without being required to distribute such code in + Source Code form, even if such code would otherwise be + considered ''Modifications'' under this License. + + V. Use of Modifications and Covered Code by Initial Developer. + + V.1. In General. + + The obligations of Section 3 apply to Netscape, except to + the extent specified in this Amendment, Section V.2 and + V.3. + + V.2. Other Products. + + Netscape may include Covered Code in products other than + the Netscape's Branded Code which are released by + Netscape during the two (2) years following the release + date of the Original Code, without such additional + products becoming subject to the terms of this License, + and may license such additional products on different + terms from those contained in this License. + + V.3. Alternative Licensing. + + Netscape may license the Source Code of Netscape's + Branded Code, including Modifications incorporated + therein, without such Netscape Branded Code becoming + subject to the terms of this License, and may license + such Netscape Branded Code on different terms from those + contained in this License. + + VI. Litigation. + + Notwithstanding the limitations of Section 11 above, the + provisions regarding litigation in Section 11(a), (b) and (c) + of the License shall apply to all disputes relating to this + License. + + +EXHIBIT A-Netscape Public License. + + + ''The contents of this file are subject to the Netscape Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/NPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The Original Code is Mozilla Communicator client code, released + March 31, 1998. + + The Initial Developer of the Original Code is Netscape + Communications Corporation. Portions created by Netscape are + Copyright (C) 1998-1999 Netscape Communications Corporation. All + Rights Reserved. + + Contributor(s): ______________________________________. + + + Alternatively, the contents of this file may be used under the + terms of the _____ license (the �[___] License�), in which case + the provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to + use your version of this file under the NPL, indicate your + decision by deleting the provisions above and replace them with + the notice and other provisions required by the [___] License. If + you do not delete the provisions above, a recipient may use your + version of this file under either the NPL or the [___] License." + + +---------------------- + +MOZILLA PUBLIC LICENSE +Version 1.1 + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. ''Contributor'' means each entity that creates or contributes + to the creation of Modifications. + + 1.2. ''Contributor Version'' means the combination of the Original + Code, prior Modifications used by a Contributor, and the + Modifications made by that particular Contributor. + + 1.3. ''Covered Code'' means the Original Code or Modifications or + the combination of the Original Code and Modifications, in each + case including portions thereof. + + 1.4. ''Electronic Distribution Mechanism'' means a mechanism + generally accepted in the software development community for the + electronic transfer of data. + + 1.5. ''Executable'' means Covered Code in any form other than Source Code. + + 1.6. ''Initial Developer'' means the individual or entity + identified as the Initial Developer in the Source Code notice + required by Exhibit A. + + 1.7. ''Larger Work'' means a work which combines Covered Code or + portions thereof with code not governed by the terms of this + License. + + 1.8. ''License'' means this document. + + 1.8.1. "Licensable" means having the right to grant, to the + maximum extent possible, whether at the time of the initial grant + or subsequently acquired, any and all of the rights conveyed + herein. + + 1.9. ''Modifications'' means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, + a Modification is: + + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. ''Original Code'' means Source Code of computer software + code which is described in the Source Code notice required by + Exhibit A as Original Code, and which, at the time of its release + under this License is not already Covered Code governed by this + License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. ''Source Code'' means the preferred form of the Covered Code + for making modifications to it, including all modules it contains, + plus any associated interface definition files, scripts used to + control compilation and installation of an Executable, or source + code differential comparisons against either the Original Code or + another well known, available Covered Code of the Contributor's + choice. The Source Code can be in a compressed or archival form, + provided the appropriate decompression or de-archiving software is + widely available for no charge. + + 1.12. "You'' (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, + this License or a future version of this License issued under + Section 6.1. For legal entities, "You'' includes any entity which + controls, is controlled by, or is under common control with + You. For purposes of this definition, "control'' means (a) the + power, direct or indirect, to cause the direction or management of + such entity, whether by contract or otherwise, or (b) ownership of + more than fifty percent (50%) of the outstanding shares or + beneficial ownership of such entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + + The Initial Developer hereby grants You a world-wide, + royalty-free, non-exclusive license, subject to third party + intellectual property claims: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the + Original Code (or portions thereof) with or without + Modifications, and/or as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; + 2) separate from the Original Code; or 3) for infringements + caused by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or + devices. + + 2.2. Contributor Grant. + + Subject to third party intellectual property claims, each + Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, + modify, display, perform, sublicense and distribute the + Modifications created by such Contributor (or portions + thereof) either on an unmodified basis, with other + Modifications, as Covered Code and/or as part of a Larger + Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or + portions of such combination), to make, use, sell, offer for + sale, have made, and/or otherwise dispose of: 1) Modifications + made by that Contributor (or portions thereof); and 2) the + combination of Modifications made by that Contributor with its + Contributor Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use + of the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications + of Contributor Version or ii) the combination of Modifications + made by that Contributor with other software (except as part + of the Contributor Version) or other devices; or 4) under + Patent Claims infringed by Covered Code in the absence of + Modifications made by that Contributor. + + +3. Distribution Obligations. + + 3.1. Application of License. + + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without + limitation Section 2.2. The Source Code version of Covered Code + may be distributed only under the terms of this License or a + future version of this License released under Section 6.1, and You + must include a copy of this License with every copy of the Source + Code You distribute. You may not offer or impose any terms on any + Source Code version that alters or restricts the applicable + version of this License or the recipients' rights + hereunder. However, You may include an additional document + offering the additional rights described in Section 3.5. + + 3.2. Availability of Source Code. + + Any Modification which You create or to which You contribute must + be made available in Source Code form under the terms of this + License either on the same media as an Executable version or via + an accepted Electronic Distribution Mechanism to anyone to whom + you made an Executable version available; and if made available + via Electronic Distribution Mechanism, must remain available for + at least twelve (12) months after the date it initially became + available, or at least six (6) months after a subsequent version + of that particular Modification has been made available to such + recipients. You are responsible for ensuring that the Source Code + version remains available even if the Electronic Distribution + Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + + You must cause all Covered Code to which You contribute to contain + a file documenting the changes You made to create that Covered + Code and the date of any change. You must include a prominent + statement that the Modification is derived, directly or + indirectly, from Original Code provided by the Initial Developer + and including the name of the Initial Developer in (a) the Source + Code, and (b) in any notice in an Executable version or related + documentation in which You describe the origin or ownership of the + Covered Code. + + 3.4. Intellectual Property Matters + + (a) Third Party Claims. + + If Contributor has knowledge that a license under a third + party's intellectual property rights is required to exercise + the rights granted by such Contributor under Sections 2.1 or + 2.2, Contributor must include a text file with the Source Code + distribution titled "LEGAL'' which describes the claim and the + party making the claim in sufficient detail that a recipient + will know whom to contact. If Contributor obtains such + knowledge after the Modification is made available as + described in Section 3.2, Contributor shall promptly modify + the LEGAL file in all copies Contributor makes available + thereafter and shall take other steps (such as notifying + appropriate mailing lists or newsgroups) reasonably calculated + to inform those who received the Covered Code that new + knowledge has been obtained. + + (b) Contributor APIs. + + If Contributor's Modifications include an application + programming interface and Contributor has knowledge of patent + licenses which are reasonably necessary to implement that API, + Contributor must also include this information in the LEGAL + file. + + (c) Representations. + + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed + by this License. + + + 3.5. Required Notices. + + You must duplicate the notice in Exhibit A in each file of the + Source Code. If it is not possible to put such notice in a + particular Source Code file due to its structure, then You must + include such notice in a location (such as a relevant directory) + where a user would be likely to look for such a notice. If You + created one or more Modification(s) You may add your name as a + Contributor to the notice described in Exhibit A. You must also + duplicate this License in any documentation for the Source Code + where You describe recipients' rights or ownership rights relating + to Covered Code. You may choose to offer, and to charge a fee + for, warranty, support, indemnity or liability obligations to one + or more recipients of Covered Code. However, You may do so only on + Your own behalf, and not on behalf of the Initial Developer or any + Contributor. You must make it absolutely clear than any such + warranty, support, indemnity or liability obligation is offered by + You alone, and You hereby agree to indemnify the Initial Developer + and every Contributor for any liability incurred by the Initial + Developer or such Contributor as a result of warranty, support, + indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered + Code, and if You include a notice stating that the Source Code + version of the Covered Code is available under the terms of this + License, including a description of how and where You have + fulfilled the obligations of Section 3.2. The notice must be + conspicuously included in any notice in an Executable version, + related documentation or collateral in which You describe + recipients' rights relating to the Covered Code. You may + distribute the Executable version of Covered Code or ownership + rights under a license of Your choice, which may contain terms + different from this License, provided that You are in compliance + with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the + recipient's rights in the Source Code version from the rights set + forth in this License. If You distribute the Executable version + under a different license You must make it absolutely clear that + any terms which differ from this License are offered by You alone, + not by the Initial Developer or any Contributor. You hereby agree + to indemnify the Initial Developer and every Contributor for any + liability incurred by the Initial Developer or such Contributor as + a result of any such terms You offer. + + 3.7. Larger Works. + + You may create a Larger Work by combining Covered Code with other + code not governed by the terms of this License and distribute the + Larger Work as a single product. In such a case, You must make + sure the requirements of this License are fulfilled for the + Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of + this License with respect to some or all of the Covered Code due + to statute, judicial order, or regulation then You must: (a) + comply with the terms of this License to the maximum extent + possible; and (b) describe the limitations and the code they + affect. Such description must be included in the LEGAL file + described in Section 3.4 and must be included with all + distributions of the Source Code. Except to the extent prohibited + by statute or regulation, such description must be sufficiently + detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + + Netscape Communications Corporation (''Netscape'') may publish + revised and/or new versions of the License from time to time. Each + version will be given a distinguishing version number. + + 6.2. Effect of New Versions. + + Once Covered Code has been published under a particular version of + the License, You may always continue to use it under the terms of + that version. You may also choose to use such Covered Code under + the terms of any subsequent version of the License published by + Netscape. No one other than Netscape has the right to modify the + terms applicable to Covered Code created under this License. + + 6.3. Derivative Works. + + If You create or use a modified version of this License (which you + may only do in order to apply it to code which is not already + Covered Code governed by this License), You must (a) rename Your + license so that the phrases ''Mozilla'', ''MOZILLAPL'', ''MOZPL'', + ''Netscape'', "MPL", ''NPL'' or any confusingly similar phrase do + not appear in your license (except to note that your license + differs from this License) and (b) otherwise make it clear that + Your version of the license contains terms which differ from the + Mozilla Public License and Netscape Public License. (Filling in + the name of the Initial Developer, Original Code or Contributor in + the notice described in Exhibit A shall not of themselves be + deemed to be modifications of this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS'' BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, + INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS + FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR + NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE + OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE + DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY + OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, + REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN + ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS + AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to + cure such breach within 30 days of becoming aware of the + breach. All sublicenses to the Covered Code which are properly + granted shall survive any termination of this License. Provisions + which, by their nature, must remain in effect beyond the + termination of this License shall survive. + + 8.2. If You initiate litigation by asserting a patent + infringement claim (excluding declatory judgment actions) against + Initial Developer or a Contributor (the Initial Developer or + Contributor against whom You file such action is referred to as + "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate + prospectively, unless if within 60 days after receipt of notice + You either: (i) agree in writing to pay Participant a mutually + agreeable reasonable royalty for Your past and future use of + Modifications made by such Participant, or (ii) withdraw Your + litigation claim with respect to the Contributor Version against + such Participant. If within 60 days of notice, a reasonable + royalty and payment arrangement are not mutually agreed upon in + writing by the parties or the litigation claim is not withdrawn, + the rights granted by Participant to You under Sections 2.1 and/or + 2.2 automatically terminate at the expiration of the 60 day notice + period specified above. + + (b) any software, hardware, or device, other than such + Participant's Contributor Version, directly or indirectly + infringes any patent, then any rights granted to You by such + Participant under Sections 2.1(b) and 2.2(b) are revoked effective + as of the date You first made, used, sold, distributed, or had + made, Modifications made by that Participant. + + 8.3. If You assert a patent infringement claim against + Participant alleging that such Participant's Contributor Version + directly or indirectly infringes any patent where such claim is + resolved (such as by license or settlement) prior to the + initiation of patent infringement litigation, then the reasonable + value of the licenses granted by such Participant under Sections + 2.1 or 2.2 shall be taken into account in determining the amount + or value of any payment or license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and + resellers) which have been validly granted by You or any + distributor hereunder prior to termination shall survive + termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE + INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF + COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO + ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL + DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES + FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR + MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, + EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF + SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO + LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S + NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH + LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR + LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS + EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a ''commercial item,'' as that term is defined + in 48 C.F.R. 2.101 (Oct. 1995), consisting of ''commercial + computer software'' and ''commercial computer software + documentation,'' as such terms are used in 48 C.F.R. 12.212 + (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 + C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all + U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed + by California law provisions (except to the extent applicable law, + if any, provides otherwise), excluding its conflict-of-law + provisions. With respect to disputes in which at least one party + is a citizen of, or an entity chartered or registered to do + business in the United States of America, any litigation relating + to this License shall be subject to the jurisdiction of the + Federal Courts of the Northern District of California, with venue + lying in Santa Clara County, California, with the losing party + responsible for costs, including without limitation, court costs + and reasonable attorneys' fees and expenses. The application of + the United Nations Convention on Contracts for the International + Sale of Goods is expressly excluded. Any law or regulation which + provides that the language of a contract shall be construed + against the drafter shall not apply to this License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or + indirectly, out of its utilization of rights under this License + and You agree to work with Initial Developer and Contributors to + distribute such responsibility on an equitable basis. Nothing + herein is intended or shall be deemed to constitute any admission + of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + �Multiple-Licensed�. �Multiple-Licensed� means that the Initial + Developer permits you to utilize portions of the Covered Code + under Your choice of the NPL or the alternative licenses, if any, + specified by the Initial Developer in the file described in + Exhibit A. + + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is + ________________________. Portions created by + ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the + terms of the _____ license (the �[___] License�), in which case + the provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to + use your version of this file under the MPL, indicate your + decision by deleting the provisions above and replace them with + the notice and other provisions required by the [___] License. If + you do not delete the provisions above, a recipient may use your + version of this file under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the + text of the notices in the Source Code files of the Original + Code. You should use the text of this Exhibit A rather than the + text found in the Original Code Source Code for Your + Modifications.] +============================================================================ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your + freedom to share and change it. By contrast, the GNU General Public + License is intended to guarantee your freedom to share and change free + software--to make sure the software is free for all its users. This + General Public License applies to most of the Free Software + Foundation's software and to any other program whose authors commit to + using it. (Some other Free Software Foundation software is covered by + the GNU Lesser General Public License instead.) You can apply it to + your programs, too. + + When we speak of free software, we are referring to freedom, not + price. Our General Public Licenses are designed to make sure that you + have the freedom to distribute copies of free software (and charge for + this service if you wish), that you receive source code or can get it + if you want it, that you can change the software or use pieces of it + in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid + anyone to deny you these rights or to ask you to surrender the rights. + These restrictions translate to certain responsibilities for you if you + distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether + gratis or for a fee, you must give the recipients all the rights that + you have. You must make sure that they, too, receive or can get the + source code. And you must show them these terms so they know their + rights. + + We protect your rights with two steps: (1) copyright the software, and + (2) offer you this license which gives you legal permission to copy, + distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain + that everyone understands that there is no warranty for this free + software. If the software is modified by someone else and passed on, we + want its recipients to know that what they have is not the original, so + that any problems introduced by others will not reflect on the original + authors' reputations. + + Finally, any free program is threatened constantly by software + patents. We wish to avoid the danger that redistributors of a free + program will individually obtain patent licenses, in effect making the + program proprietary. To prevent this, we have made it clear that any + patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and + modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains + a notice placed by the copyright holder saying it may be distributed + under the terms of this General Public License. The "Program", below, + refers to any such program or work, and a "work based on the Program" + means either the Program or any derivative work under copyright law: + that is to say, a work containing the Program or a portion of it, + either verbatim or with modifications and/or translated into another + language. (Hereinafter, translation is included without limitation in + the term "modification".) Each licensee is addressed as "you". + + Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of + running the Program is not restricted, and the output from the Program + is covered only if its contents constitute a work based on the + Program (independent of having been made by running the Program). + Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's + source code as you receive it, in any medium, provided that you + conspicuously and appropriately publish on each copy an appropriate + copyright notice and disclaimer of warranty; keep intact all the + notices that refer to this License and to the absence of any warranty; + and give any other recipients of the Program a copy of this License + along with the Program. + + You may charge a fee for the physical act of transferring a copy, and + you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion + of it, thus forming a work based on the Program, and copy and + distribute such modifications or work under the terms of Section 1 + above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Program, + and can be reasonably considered independent and separate works in + themselves, then this License, and its terms, do not apply to those + sections when you distribute them as separate works. But when you + distribute the same sections as part of a whole which is a work based + on the Program, the distribution of the whole must be on the terms of + this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote it. + + Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Program. + + In addition, mere aggregation of another work not based on the Program + with the Program (or with a work based on the Program) on a volume of + a storage or distribution medium does not bring the other work under + the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, + under Section 2) in object code or executable form under the terms of + Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + + The source code for a work means the preferred form of the work for + making modifications to it. For an executable work, complete source + code means all the source code for all modules it contains, plus any + associated interface definition files, plus the scripts used to + control compilation and installation of the executable. However, as a + special exception, the source code distributed need not include + anything that is normally distributed (in either source or binary + form) with the major components (compiler, kernel, and so on) of the + operating system on which the executable runs, unless that component + itself accompanies the executable. + + If distribution of executable or object code is made by offering + access to copy from a designated place, then offering equivalent + access to copy the source code from the same place counts as + distribution of the source code, even though third parties are not + compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program + except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense or distribute the Program is + void, and will automatically terminate your rights under this License. + However, parties who have received copies, or rights, from you under + this License will not have their licenses terminated so long as such + parties remain in full compliance. + + 5. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify or + distribute the Program or its derivative works. These actions are + prohibited by law if you do not accept this License. Therefore, by + modifying or distributing the Program (or any work based on the + Program), you indicate your acceptance of this License to do so, and + all its terms and conditions for copying, distributing or modifying + the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the + Program), the recipient automatically receives a license from the + original licensor to copy, distribute or modify the Program subject to + these terms and conditions. You may not impose any further + restrictions on the recipients' exercise of the rights granted herein. + You are not responsible for enforcing compliance by third parties to + this License. + + 7. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent issues), + conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot + distribute so as to satisfy simultaneously your obligations under this + License and any other pertinent obligations, then as a consequence you + may not distribute the Program at all. For example, if a patent + license would not permit royalty-free redistribution of the Program by + all those who receive copies directly or indirectly through you, then + the only way you could satisfy both it and this License would be to + refrain entirely from distribution of the Program. + + If any portion of this section is held invalid or unenforceable under + any particular circumstance, the balance of the section is intended to + apply and the section as a whole is intended to apply in other + circumstances. + + It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system, which is + implemented by public license practices. Many people have made + generous contributions to the wide range of software distributed + through that system in reliance on consistent application of that + system; it is up to the author/donor to decide if he or she is willing + to distribute software through any other system and a licensee cannot + impose that choice. + + This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in + certain countries either by patents or by copyrighted interfaces, the + original copyright holder who places the Program under this License + may add an explicit geographical distribution limitation excluding + those countries, so that distribution is permitted only in or among + countries not thus excluded. In such case, this License incorporates + the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions + of the General Public License from time to time. Such new versions will + be similar in spirit to the present version, but may differ in detail to + address new problems or concerns. + + Each version is given a distinguishing version number. If the Program + specifies a version number of this License which applies to it and "any + later version", you have the option of following the terms and conditions + either of that version or of any later version published by the Free + Software Foundation. If the Program does not specify a version number of + this License, you may choose any version ever published by the Free Software + Foundation. + + 10. If you wish to incorporate parts of the Program into other free + programs whose distribution conditions are different, write to the author + to ask for permission. For software which is copyrighted by the Free + Software Foundation, write to the Free Software Foundation; we sometimes + make exceptions for this. Our decision will be guided by the two goals + of preserving the free status of all derivatives of our free software and + of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED + OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS + TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE + PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, + REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING + WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR + REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, + INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING + OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED + TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY + YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER + PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest + possible use to the public, the best way to achieve this is to make it + free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest + to attach them to the start of each source file to most effectively + convey the exclusion of warranty; and each file should have at least + the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + Also add information on how to contact you by electronic and paper mail. + + If the program is interactive, make it output a short notice like this + when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + + The hypothetical commands `show w' and `show c' should show the appropriate + parts of the General Public License. Of course, the commands you use may + be called something other than `show w' and `show c'; they could even be + mouse-clicks or menu items--whatever suits your program. + + You should also get your employer (if you work as a programmer) or your + school, if any, to sign a "copyright disclaimer" for the program, if + necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + + This General Public License does not permit incorporating your program into + proprietary programs. If your program is a subroutine library, you may + consider it more useful to permit linking proprietary applications with the + library. If this is what you want to do, use the GNU Lesser General + Public License instead of this License. +============================================================================ + +------------------ + +Files: + +Copyright (c) 2005-2010 Sam Stephenson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------ + +Files: kotlinc/lib/kotlin-compiler.jar + +The MIT License + +Copyright (c) 2003, Kohsuke Kawaguchi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +------------------ + +Files: + + + ASM: a very small and fast Java bytecode manipulation framework + Copyright (c) 2000-2005 INRIA, France Telecom + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. + +------------------ + +Files: + +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +------------------ + +Files: + +Eclipse Public License, Version 1.0 (EPL-1.0) + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC +LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM +CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial code and + documentation distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + +where such changes and/or additions to the Program originate from and are +distributed by that particular Contributor. A Contribution 'originates' +from a Contributor if it was added to the Program by such Contributor itself +or anyone acting on such Contributor's behalf. Contributions do not include +additions to the Program which: (i) are separate modules of software +distributed in conjunction with the Program under their own license agreement, +and (ii) are not derivative works of the Program. + +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents " mean patent claims licensable by a Contributor which are +necessarily infringed by the use or sale of its Contribution alone or +when combined with the Program. + +"Program" means the Contributions distributed in accordance with +this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, +including all Contributors. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby grants + Recipient a non-exclusive, worldwide, royalty-free copyright license to + reproduce, prepare derivative works of, publicly display, publicly + perform, distribute and sublicense the Contribution of such + Contributor, if any, and such derivative works, + in source code and object code form. + + b) Subject to the terms of this Agreement, each Contributor hereby grants + Recipient a non-exclusive, worldwide, royalty-free patent license under + Licensed Patents to make, use, sell, offer to sell, import and + otherwise transfer the Contribution of such Contributor, if any, + in source code and object code form. This patent license shall apply + to the combination of the Contribution and the Program if, at the time + the Contribution is added by the Contributor, such addition of the + Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. + No hardware per se is licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby assumes + sole responsibility to secure any other intellectual property rights + needed, if any. For example, if a third party patent license is + required to allow Recipient to distribute the Program, it is + Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has sufficient + copyright rights in its Contribution, if any, to grant the copyright + license set forth in this Agreement. + +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under +its own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; and + + b) its license agreement: + + i) effectively disclaims on behalf of all Contributors all warranties + and conditions, express and implied, including warranties or + conditions of title and non-infringement, and implied warranties or + conditions of merchantability and fitness for a particular purpose; + + ii) effectively excludes on behalf of all Contributors all liability + for damages, including direct, indirect, special, incidental and + consequential damages, such as lost profits; + + iii) states that any provisions which differ from this Agreement are + offered by that Contributor alone and not by any other party; and + + iv) states that source code for the Program is available from such + Contributor, and informs licensees how to obtain it in a reasonable + manner on or through a medium customarily used for software exchange. + +When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + b) a copy of this Agreement must be included with each copy of the Program. + +Contributors may not remove or alter any copyright notices contained +within the Program. + +Each Contributor must identify itself as the originator of its Contribution, +if any, in a manner that reasonably allows subsequent Recipients to +identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with +respect to end users, business partners and the like. While this license is +intended to facilitate the commercial use of the Program, the Contributor who +includes the Program in a commercial product offering should do so in a manner +which does not create potential liability for other Contributors. Therefore, +if a Contributor includes the Program in a commercial product offering, +such Contributor ("Commercial Contributor") hereby agrees to defend and +indemnify every other Contributor ("Indemnified Contributor") against any +losses, damages and costs (collectively "Losses") arising from claims, +lawsuits and other legal actions brought by a third party against the +Indemnified Contributor to the extent caused by the acts or omissions of +such Commercial Contributor in connection with its distribution of the Program +in a commercial product offering. The obligations in this section do not apply +to any claims or Losses relating to any actual or alleged intellectual +property infringement. In order to qualify, an Indemnified Contributor must: +a) promptly notify the Commercial Contributor in writing of such claim, +and b) allow the Commercial Contributor to control, and cooperate with the +Commercial Contributor in, the defense and any related settlement +negotiations. The Indemnified Contributor may participate in any such +claim at its own expense. + +For example, a Contributor might include the Program in a commercial product +offering, Product X. That Contributor is then a Commercial Contributor. +If that Commercial Contributor then makes performance claims, or offers +warranties related to Product X, those performance claims and warranties +are such Commercial Contributor's responsibility alone. Under this section, +the Commercial Contributor would have to defend claims against the other +Contributors related to those performance claims and warranties, and if a +court requires any other Contributor to pay any damages as a result, +the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +Each Recipient is solely responsible for determining the appropriateness of +using and distributing the Program and assumes all risks associated with its +exercise of rights under this Agreement , including but not limited to the +risks and costs of program errors, compliance with applicable laws, damage to +or loss of data, programs or equipment, and unavailability +or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY +CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION +LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE +EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of the +remainder of the terms of this Agreement, and without further action by +the parties hereto, such provision shall be reformed to the minimum extent +necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Program itself +(excluding combinations of the Program with other software or hardware) +infringes such Recipient's patent(s), then such Recipient's rights granted +under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to +comply with any of the material terms or conditions of this Agreement and +does not cure such failure in a reasonable period of time after becoming +aware of such noncompliance. If all Recipient's rights under this +Agreement terminate, Recipient agrees to cease use and distribution of the +Program as soon as reasonably practicable. However, Recipient's obligations +under this Agreement and any licenses granted by Recipient relating to the +Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and may +only be modified in the following manner. The Agreement Steward reserves +the right to publish new versions (including revisions) of this Agreement +from time to time. No one other than the Agreement Steward has the right to +modify this Agreement. The Eclipse Foundation is the initial +Agreement Steward. The Eclipse Foundation may assign the responsibility to +serve as the Agreement Steward to a suitable separate entity. Each new version +of the Agreement will be given a distinguishing version number. The Program +(including Contributions) may always be distributed subject to the version +of the Agreement under which it was received. In addition, after a new version +of the Agreement is published, Contributor may elect to distribute the Program +(including its Contributions) under the new version. Except as expressly +stated in Sections 2(a) and 2(b) above, Recipient receives no rights or +licenses to the intellectual property of any Contributor under this Agreement, +whether expressly, by implication, estoppel or otherwise. All rights in the +Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the +intellectual property laws of the United States of America. No party to +this Agreement will bring a legal action under this Agreement more than one +year after the cause of action arose. Each party waives its rights to a +jury trial in any resulting litigation. + +------------------ + +Files: + +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + +Developed at SunSoft, a Sun Microsystems, Inc. business. +Permission to use, copy, modify, and distribute this +software is freely granted, provided that this notice +is preserved. + +------------------ + +MIT License + +Copyright (c) 2018 Chad Retz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------ + +Creative Commons CC0 1.0 Universal + +CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL +SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT +RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. +CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE +INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES +RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED +HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific +works ("Commons") that the public can reliably and without fear of later +claims of infringement build upon, modify, incorporate in other works, reuse +and redistribute as freely as possible in any form whatsoever and for any +purposes, including without limitation commercial purposes. These owners may +contribute to the Commons to promote the ideal of a free culture and the +further production of creative, cultural and scientific works, or to gain +reputation or greater distribution for their Work in part through the use and +efforts of others. + +For these and/or other purposes and motivations, and without any expectation +of additional consideration or compensation, the person associating CC0 with a +Work (the "Affirmer"), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work +and publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: + +i. the right to reproduce, adapt, distribute, perform, display, communicate, +and translate a Work; + +ii. moral rights retained by the original author(s) and/or performer(s); + +iii. publicity and privacy rights pertaining to a person's image or +likeness depicted in a Work; + +iv. rights protecting against unfair competition in regards to a Work, subject +to the limitations in paragraph 4(a), below; + +v. rights protecting the extraction, dissemination, use and reuse of data in a +Work; + +vi. database rights (such as those arising under Directive 96/9/EC of the +European Parliament and of the Council of 11 March 1996 on the legal +protection of databases, and under any national implementation thereof, +including any amended or successor version of such directive); and + +vii. other similar, equivalent or corresponding rights throughout the world +based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. + +4. Limitations and Disclaimers. + +a. No trademark or patent rights held by Affirmer are waived, abandoned, +surrendered, licensed or otherwise affected by this document. + +b. Affirmer offers the Work as-is and makes no representations or warranties +of any kind concerning the Work, express, implied, statutory or otherwise, +including without limitation warranties of title, merchantability, fitness for +a particular purpose, non infringement, or the absence of latent or other +defects, accuracy, or the present or absence of errors, whether or not +discoverable, all to the greatest extent permissible under applicable law. + +c. Affirmer disclaims responsibility for clearing rights of other persons that +may apply to the Work or any use thereof, including without limitation any +person's Copyright and Related Rights in the Work. Further, Affirmer +disclaims responsibility for obtaining any necessary consents, permissions or +other rights required for any use of the Work. + +d. Affirmer understands and acknowledges that Creative Commons is not a party +to this document and has no duty or obligation with respect to this CC0 or use +of the Work. + + +Kotlin coroutines: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +Protocol Buffers for Java: + +Copyright 2008 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Code generated by the Protocol Buffer compiler is owned by the owner +of the input file used when generating it. This code is not +standalone and requires a support library to be linked with it. This +support library is itself covered by the above license. + + SafeParcelable library: @@ -2250,7 +5508,7 @@ -JSpecify: +gsfclient: Apache License @@ -2454,3 +5712,582 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + +java_annotations: + + +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + + +kotlinx_atomicfu: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +kotlinx_serialization: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_instantapps/README.chromium b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_instantapps/README.chromium index 9ba95aec..f558faf4 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_instantapps/README.chromium +++ b/third_party/android_deps/autorolled/committed/libs/com_google_android_gms_play_services_instantapps/README.chromium
@@ -1,7 +1,7 @@ Name: play-services-instantapps Short Name: play-services-instantapps URL: https://developers.google.com/android/guides/setup -Version: 18.1.0 +Version: 18.2.0 Update Mechanism: Autoroll License: Android Software Development Kit License License File: LICENSE
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_android_material_material/README.chromium b/third_party/android_deps/autorolled/committed/libs/com_google_android_material_material/README.chromium index 2bae377b..2fb22a50 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_android_material_material/README.chromium +++ b/third_party/android_deps/autorolled/committed/libs/com_google_android_material_material/README.chromium
@@ -1,7 +1,7 @@ Name: Material Components for Android Short Name: material URL: https://github.com/material-components/material-components-android -Version: 1.14.0-alpha02 +Version: 1.14.0-alpha03 Update Mechanism: Autoroll License: Android Software Development Kit License License File: LICENSE
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_android_material_material/com_google_android_material_material.info b/third_party/android_deps/autorolled/committed/libs/com_google_android_material_material/com_google_android_material_material.info index 18816bd..2b1ef386 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_android_material_material/com_google_android_material_material.info +++ b/third_party/android_deps/autorolled/committed/libs/com_google_android_material_material/com_google_android_material_material.info
@@ -307,12 +307,12 @@ "res/drawable/ic_m3_chip_check.xml", "res/drawable/ic_m3_chip_checked_circle.xml", "res/drawable/ic_m3_chip_close.xml", + "res/drawable/ic_mtrl_arrow_circle.xml", "res/drawable/ic_mtrl_checked_circle.xml", "res/drawable/ic_mtrl_chip_checked_black.xml", "res/drawable/ic_mtrl_chip_checked_circle.xml", "res/drawable/ic_mtrl_chip_close_circle.xml", "res/drawable/ic_search_black_24.xml", - "res/drawable/indeterminate_static.xml", "res/drawable/m3_avd_hide_password.xml", "res/drawable/m3_avd_show_password.xml", "res/drawable/m3_bottom_sheet_drag_handle.xml", @@ -456,6 +456,7 @@ "res/values-gl/values-gl.xml", "res/values-gu/values-gu.xml", "res/values-h320dp-port-v13/values-h320dp-port-v13.xml", + "res/values-h320dp-v13/values-h320dp-v13.xml", "res/values-h360dp-land-v13/values-h360dp-land-v13.xml", "res/values-h480dp-land-v13/values-h480dp-land-v13.xml", "res/values-h480dp-v13/values-h480dp-v13.xml",
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_annotations/README.chromium b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_annotations/README.chromium index de21a292..cc0140e 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_annotations/README.chromium +++ b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_annotations/README.chromium
@@ -1,7 +1,7 @@ Name: firebase-annotations Short Name: firebase-annotations URL: https://firebase.google.com -Version: 16.2.0 +Version: 17.0.0 Update Mechanism: Autoroll License: Apache-2.0 License File: LICENSE
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common/README.chromium b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common/README.chromium index 5408005..1fdee05 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common/README.chromium +++ b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common/README.chromium
@@ -1,7 +1,7 @@ Name: firebase-common Short Name: firebase-common URL: https://firebase.google.com -Version: 21.0.0 +Version: 22.0.0 Update Mechanism: Autoroll License: Apache-2.0 License File: LICENSE
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common_ktx/LICENSE b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common_ktx/LICENSE deleted file mode 100644 index d645695..0000000 --- a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common_ktx/LICENSE +++ /dev/null
@@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License.
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common_ktx/README.chromium b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common_ktx/README.chromium deleted file mode 100644 index 7f1306db..0000000 --- a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common_ktx/README.chromium +++ /dev/null
@@ -1,16 +0,0 @@ -Name: firebase-common-ktx -Short Name: firebase-common-ktx -URL: https://firebase.google.com -Version: 21.0.0 -Update Mechanism: Autoroll -License: Apache-2.0 -License File: LICENSE -CPEPrefix: unknown -Security Critical: yes -Shipped: yes - -Description: -Firebase firebase common ktx pulled in via gradle. - -Local Modifications: -No modifications.
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common_ktx/com_google_firebase_firebase_common_ktx.info b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common_ktx/com_google_firebase_firebase_common_ktx.info deleted file mode 100644 index 78dfd57..0000000 --- a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_common_ktx/com_google_firebase_firebase_common_ktx.info +++ /dev/null
@@ -1,14 +0,0 @@ -# Generated by //build/android/gyp/aar.py -# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". - -aidl = [] -assets = [] -has_classes_jar = true -has_native_libraries = false -has_proguard_flags = false -has_r_text_file = false -is_manifest_empty = false -manifest_package = "com.google.firebase.ktx" -resources = [] -subjar_tuples = [] -subjars = []
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_components/README.chromium b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_components/README.chromium index 2193e96..e51e837 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_components/README.chromium +++ b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_components/README.chromium
@@ -1,7 +1,7 @@ Name: firebase-components Short Name: firebase-components URL: https://firebase.google.com -Version: 18.0.0 +Version: 19.0.0 Update Mechanism: Autoroll License: Apache-2.0 License File: LICENSE
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_installations/README.chromium b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_installations/README.chromium index cc71516..0ae869b 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_installations/README.chromium +++ b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_installations/README.chromium
@@ -1,7 +1,7 @@ Name: firebase-installations Short Name: firebase-installations URL: https://firebase.google.com -Version: 17.2.0 +Version: 18.0.0 Update Mechanism: Autoroll License: Apache-2.0 License File: LICENSE
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_installations/com_google_firebase_firebase_installations.info b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_installations/com_google_firebase_firebase_installations.info index 1285da8..7d7b8a4a 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_installations/com_google_firebase_firebase_installations.info +++ b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_installations/com_google_firebase_firebase_installations.info
@@ -6,7 +6,7 @@ has_classes_jar = true has_native_libraries = false has_proguard_flags = false -has_r_text_file = true +has_r_text_file = false is_manifest_empty = false manifest_package = "com.google.firebase.installations" resources = []
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_messaging/README.chromium b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_messaging/README.chromium index a1d854ec..824682e4 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_messaging/README.chromium +++ b/third_party/android_deps/autorolled/committed/libs/com_google_firebase_firebase_messaging/README.chromium
@@ -1,7 +1,7 @@ Name: firebase-messaging Short Name: firebase-messaging URL: https://firebase.google.com -Version: 24.1.2 +Version: 25.0.0 Update Mechanism: Autoroll License: Apache-2.0 License File: LICENSE
diff --git a/third_party/android_deps/autorolled/committed/libs/com_google_protobuf_protobuf_javalite/README.chromium b/third_party/android_deps/autorolled/committed/libs/com_google_protobuf_protobuf_javalite/README.chromium index 93a8b12c..4f37c33 100644 --- a/third_party/android_deps/autorolled/committed/libs/com_google_protobuf_protobuf_javalite/README.chromium +++ b/third_party/android_deps/autorolled/committed/libs/com_google_protobuf_protobuf_javalite/README.chromium
@@ -1,7 +1,7 @@ Name: Protocol Buffers [Lite] Short Name: protobuf-javalite URL: https://github.com/protocolbuffers/protobuf/blob/master/java/lite.md -Version: 4.31.1 +Version: 4.32.0-RC1 Update Mechanism: Autoroll License: BSD-3-Clause License File: LICENSE
diff --git a/third_party/android_deps/autorolled/committed/libs/org_jetbrains_kotlinx_kotlinx_coroutines_play_services/README.chromium b/third_party/android_deps/autorolled/committed/libs/org_jetbrains_kotlinx_kotlinx_coroutines_play_services/README.chromium index cb56dc6b..337ea74 100644 --- a/third_party/android_deps/autorolled/committed/libs/org_jetbrains_kotlinx_kotlinx_coroutines_play_services/README.chromium +++ b/third_party/android_deps/autorolled/committed/libs/org_jetbrains_kotlinx_kotlinx_coroutines_play_services/README.chromium
@@ -1,7 +1,7 @@ Name: kotlinx-coroutines-play-services Short Name: kotlinx-coroutines-play-services URL: https://github.com/Kotlin/kotlinx.coroutines -Version: 1.6.4 +Version: 1.9.0 Update Mechanism: Autoroll License: Apache-2.0 License File: LICENSE
diff --git a/third_party/angle b/third_party/angle index dd6a1a2..bc9ff5e6 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit dd6a1a2c2346cabb0a8ce54140c3471c3f1ca18e +Subproject commit bc9ff5e6c934f04e060ea9754a9156f1bf3ad107
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index adc8d96d..e8e2413 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -316,7 +316,6 @@ "//third_party/blink/public/mojom/gpu", "//third_party/blink/public/mojom/origin_trials:origin_trial_feature", "//third_party/blink/public/mojom/origin_trials:origin_trial_state", - "//third_party/blink/public/mojom/private_network_device", "//third_party/blink/public/mojom/quota", "//third_party/blink/public/mojom/service_worker:storage", "//third_party/blink/public/mojom/storage_key",
diff --git a/third_party/blink/public/mojom/private_network_device/BUILD.gn b/third_party/blink/public/mojom/private_network_device/BUILD.gn deleted file mode 100644 index 4e00292..0000000 --- a/third_party/blink/public/mojom/private_network_device/BUILD.gn +++ /dev/null
@@ -1,27 +0,0 @@ -# Copyright 2023 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//mojo/public/tools/bindings/mojom.gni") - -mojom("private_network_device") { - generate_java = true - - sources = [ "private_network_device.mojom" ] - - deps = [ - "//mojo/public/mojom/base", - "//services/network/public/mojom", - "//services/network/public/mojom:mojom_ip_address", - ] - - scramble_message_ids = false - - export_class_attribute = "BLINK_COMMON_EXPORT" - export_define = "BLINK_COMMON_IMPLEMENTATION=1" - export_header = "third_party/blink/public/common/common_export.h" - - export_class_attribute_blink = "PLATFORM_EXPORT" - export_define_blink = "BLINK_PLATFORM_IMPLEMENTATION=1" - export_header_blink = "third_party/blink/renderer/platform/platform_export.h" -}
diff --git a/third_party/blink/public/mojom/private_network_device/DIR_METADATA b/third_party/blink/public/mojom/private_network_device/DIR_METADATA deleted file mode 100644 index 552f886f..0000000 --- a/third_party/blink/public/mojom/private_network_device/DIR_METADATA +++ /dev/null
@@ -1 +0,0 @@ -mixins: "//chrome/browser/private_network_access/COMMON_METADATA"
diff --git a/third_party/blink/public/mojom/private_network_device/OWNERS b/third_party/blink/public/mojom/private_network_device/OWNERS deleted file mode 100644 index 008d711..0000000 --- a/third_party/blink/public/mojom/private_network_device/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -per-file *.mojom=set noparent -per-file *.mojom=file://ipc/SECURITY_OWNERS - -file://chrome/browser/private_network_access/OWNERS
diff --git a/third_party/blink/public/mojom/private_network_device/private_network_device.mojom b/third_party/blink/public/mojom/private_network_device/private_network_device.mojom deleted file mode 100644 index 590a5a8..0000000 --- a/third_party/blink/public/mojom/private_network_device/private_network_device.mojom +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module blink.mojom; - -import "services/network/public/mojom/ip_address.mojom"; - -// PrivateNetworkDevice represents a server on private/local network responding -// to requests from public websites. ID and name will defined by HTTP response -// header `Private-Network-Access-ID` and `Private-Network-Access-Name` for -// private network preflight requests. -struct PrivateNetworkDevice { - // Device ID defined in the HTTP response header `Private-Network-Access-ID` - // by the device itself. - string? id; - - // Device name defined in the HTTP response header `Private-Network-Access-Name` - // by the device itself. - string? name; - - // The IP address of the device. - network.mojom.IPAddress ip_address; -};
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom index d5d1f85a..67f6671 100644 --- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom +++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -3561,7 +3561,7 @@ kDeviceOrientationUsedWithoutPermissionRequest = 4290, kDeviceMotionPermissionRequested = 4291, kDeviceMotionUsedWithoutPermissionRequest = 4292, - kPrivateNetworkAccessPermissionPrompt = 4293, + kOBSOLETE_PrivateNetworkAccessPermissionPrompt = 4293, kPseudoBeforeAfterForDateTimeInputElement = 4294, kOBSOLETE_kV8PendingBeacon_IsPending_AttributeGetter = 4295, kParentOfDisabledFormControlRespondsToMouseEvents = 4296,
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 9e1c5ce..f940b640 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -4051,6 +4051,7 @@ } AttachSucceedingPseudoElements(children_context); + AttachTransitionPseudo(); if (!IsPseudoElement() && layout_object) { context.counters_context.LeaveObject(*layout_object); @@ -4112,6 +4113,9 @@ // https://crbug.com/939769 if (ChildNeedsReattachLayoutTree() || GetComputedStyle() || (!performing_reattach && IsUserActionElement())) { + if (performing_reattach) { + DetachTransitionPseudo(); + } if (ShadowRoot* shadow_root = GetShadowRoot()) { shadow_root->DetachLayoutTree(performing_reattach); Node::DetachLayoutTree(performing_reattach); @@ -4145,6 +4149,52 @@ } } +void Element::DetachTransitionPseudo() { + if (!RuntimeEnabledFeatures::ScopedViewTransitionsEnabled()) { + return; + } + + auto* transition_pseudo = GetPseudoElement(kPseudoIdViewTransition); + if (!transition_pseudo || IsDocumentElement()) { + return; + } + + auto* scope_layout_object = GetLayoutObject(); + auto* pseudo_layout_object = transition_pseudo->GetLayoutObject(); + if (!scope_layout_object || !pseudo_layout_object) { + return; + } + + // Disconnect the pseudo's layout object from the scope's layout object. + // This is done so that when the scope runs LayoutObject::Destroy, it does + // not recurse into the pseudo tree. Instead the pseudo holds on to its + // layout tree until it is reattached in AttachTransitionPseudo. + scope_layout_object->RemoveChild(pseudo_layout_object); +} + +void Element::AttachTransitionPseudo() { + if (!RuntimeEnabledFeatures::ScopedViewTransitionsEnabled()) { + return; + } + + auto* transition_pseudo = GetPseudoElement(kPseudoIdViewTransition); + if (!transition_pseudo || IsDocumentElement()) { + return; + } + + auto* scope_layout_object = GetLayoutObject(); + auto* pseudo_layout_object = transition_pseudo->GetLayoutObject(); + if (!scope_layout_object || !pseudo_layout_object) { + return; + } + + // Reconnect the existing pseudo layout object to the scope parent. + // Note: this method only handles the scenario of the scope being reattached + // after acquiring transition pseudos. Construction of the transition pseudo + // layout objects is handled in RebuildTransitionPseudoLayoutTree. + scope_layout_object->AddChild(pseudo_layout_object); +} + void Element::ReattachLayoutTreeChildren(base::PassKey<StyleEngine>) { DCHECK(NeedsReattachLayoutTree()); DCHECK(ChildNeedsReattachLayoutTree());
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index d0ce214..131739e 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -1894,6 +1894,8 @@ PseudoId, const AtomicString& view_transition_name = g_null_atom); void ClearTransitionPseudoTreeIfNeeded(const StyleRecalcChange); + void DetachTransitionPseudo(); + void AttachTransitionPseudo(); bool IsElementNode() const = delete; // This will catch anyone doing an unnecessary check.
diff --git a/third_party/blink/renderer/core/loader/mixed_content_checker.cc b/third_party/blink/renderer/core/loader/mixed_content_checker.cc index 3e7e4cf..65e6f72 100644 --- a/third_party/blink/renderer/core/loader/mixed_content_checker.cc +++ b/third_party/blink/renderer/core/loader/mixed_content_checker.cc
@@ -619,31 +619,6 @@ } } - // Skip mixed content check for private and local targets. - // `target_address_space` here is private/local only when resource request - // has explicitly set `targetAddressSpace` fetch option. - // TODO(lyf): check the IP address space for initiator, only skip when the - // initiator is more public. - if (base::FeatureList::IsEnabled( - network::features::kPrivateNetworkAccessPermissionPrompt) && - RuntimeEnabledFeatures::PrivateNetworkAccessPermissionPromptEnabled( - frame->DomWindow())) { - // TODO(crbug.com/323583084): Re-enable PNA permission prompt for documents - // fetched via service worker. - if (!frame->Loader() - .GetDocumentLoader() - ->GetResponse() - .WasFetchedViaServiceWorker() && - (target_address_space == - network::mojom::blink::IPAddressSpace::kLocal || - target_address_space == - network::mojom::blink::IPAddressSpace::kLoopback)) { - UseCounter::Count(frame->GetDocument(), - WebFeature::kPrivateNetworkAccessPermissionPrompt); - allowed = true; - } - } - if (reporting_disposition == ReportingDisposition::kReport) { frame->GetDocument()->AddConsoleMessage( CreateConsoleMessageAboutFetch(MainResourceUrlForFrame(mixed_frame),
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_2d_recorder_context.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_2d_recorder_context.h index 5f3bb61..aa2026ed 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_2d_recorder_context.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_2d_recorder_context.h
@@ -48,6 +48,7 @@ #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/core/SkM44.h" +#include "third_party/skia/include/core/SkPathTypes.h" #include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "ui/gfx/geometry/rect_f.h" @@ -55,7 +56,6 @@ // IWYU pragma: no_include "third_party/blink/renderer/platform/heap/visitor.h" -enum class SkPathFillType; struct SkSamplingOptions; namespace ui {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index e5a53a4..cac89bc 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -3728,14 +3728,6 @@ base_feature: "none", }, { - name: "PrivateNetworkAccessPermissionPrompt", - origin_trial_feature_name: "PrivateNetworkAccessPermissionPrompt", - origin_trial_os: ["win", "mac", "linux", "fuchsia", "chromeos"], - status: "stable", - public: true, - base_feature: "none", - }, - { name: "PrivateStateTokens", status: "stable", base_feature: "none", @@ -5266,7 +5258,7 @@ }, { // When enabled, makes links `:visited` even when the visit results in an - // HTTP error response code (4XX-5XX). + // HTTP error response code of 404. name: "VisitedLinksOnErrorNavigation", }, {
diff --git a/third_party/blink/renderer/platform/text/locale_mac_test.mm b/third_party/blink/renderer/platform/text/locale_mac_test.mm index 14dfb50..5a51842 100644 --- a/third_party/blink/renderer/platform/text/locale_mac_test.mm +++ b/third_party/blink/renderer/platform/text/locale_mac_test.mm
@@ -220,17 +220,11 @@ } TEST_F(LocaleMacTest, formatTime) { -#if BUILDFLAG(IS_MAC) - if (base::mac::MacOSMajorVersion() == 15) { - GTEST_SKIP() << "Disabled on macOS Sequoia."; - } -#endif - EXPECT_EQ("1:23 PM", FormatTime("en_US", 13, 23, 00, 000, true)); EXPECT_EQ("13:23", FormatTime("fr_FR", 13, 23, 00, 000, true)); EXPECT_EQ("13:23", FormatTime("ja_JP", 13, 23, 00, 000, true)); EXPECT_EQ("\xD9\xA1:\xD9\xA2\xD9\xA3\xC2\xA0\xD9\x85", - FormatTime("ar", 13, 23, 00, 000, true).Utf8()); + FormatTime("ar_SA", 13, 23, 00, 000, true).Utf8()); EXPECT_EQ("\xDB\xB1\xDB\xB3:\xDB\xB2\xDB\xB3", FormatTime("fa", 13, 23, 00, 000, true).Utf8()); @@ -238,7 +232,7 @@ EXPECT_EQ("00:00", FormatTime("fr_FR", 00, 00, 00, 000, true)); EXPECT_EQ("0:00", FormatTime("ja_JP", 00, 00, 00, 000, true)); EXPECT_EQ("\xD9\xA1\xD9\xA2:\xD9\xA0\xD9\xA0\xC2\xA0\xD8\xB5", - FormatTime("ar", 00, 00, 00, 000, true).Utf8()); + FormatTime("ar_SA", 00, 00, 00, 000, true).Utf8()); EXPECT_EQ("\xDB\xB0:\xDB\xB0\xDB\xB0", FormatTime("fa", 00, 00, 00, 000, true).Utf8()); @@ -247,7 +241,7 @@ EXPECT_EQ("7:07:07.007", FormatTime("ja_JP", 07, 07, 07, 007, false)); EXPECT_EQ("\xD9\xA7:\xD9\xA0\xD9\xA7:" "\xD9\xA0\xD9\xA7\xD9\xAB\xD9\xA0\xD9\xA0\xD9\xA7\xC2\xA0\xD8\xB5", - FormatTime("ar", 07, 07, 07, 007, false).Utf8()); + FormatTime("ar_SA", 07, 07, 07, 007, false).Utf8()); EXPECT_EQ("\xDB\xB7:\xDB\xB0\xDB\xB7:" "\xDB\xB0\xDB\xB7\xD9\xAB\xDB\xB0\xDB\xB0\xDB\xB7", FormatTime("fa", 07, 07, 07, 007, false).Utf8());
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 75583067..933be31 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -2526,6 +2526,7 @@ "Win" ], "bases": [ + "external/wpt/cookies/origin-bound-cookies/port-bound-cookies.html", "http/tests/inspector-protocol/issues/port-mismatch-exclusion.js", "http/tests/inspector-protocol/network/blocked-cookie-port-mismatch.js" ], @@ -2979,6 +2980,7 @@ "Win" ], "bases": [ + "external/wpt/cookies/origin-bound-cookies/scheme-bound-cookies.https.html", "http/tests/inspector-protocol/issues/scheme-mismatch-exclusion.js", "http/tests/inspector-protocol/network/blocked-cookie-scheme-mismatch.js" ],
diff --git a/third_party/blink/web_tests/external/wpt/cookies/origin-bound-cookies/port-bound-cookies.html b/third_party/blink/web_tests/external/wpt/cookies/origin-bound-cookies/port-bound-cookies.html new file mode 100644 index 0000000..696e538 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/cookies/origin-bound-cookies/port-bound-cookies.html
@@ -0,0 +1,76 @@ +<!DOCTYPE html> +<title>Port-Bound Cookies Test</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> + +<body> +<script> +if (location.protocol === 'https:') { + // This test needs to run from an insecure origin to be able to set + // cookies on an insecure origin. + location.href.replace("https://", "http://"); +} else { + const httpOriginUrl = new URL(get_host_info().HTTP_ORIGIN); + const httpOriginUrlDifferentPort = new URL(get_host_info().HTTP_ORIGIN_WITH_DIFFERENT_PORT); + + const httpOrigin = httpOriginUrl.origin; + // A second HTTP origin on the same host but with a different port. + const httpOriginDifferentPort = httpOriginUrlDifferentPort.origin; + + const cookieName = "pbc-test-cookie"; + const cookieValue = "1"; + const cookieValueDifferentPort = "2"; + + async function setCookie(origin, name, value) { + const cookieString = `${name}=${value};path=/`; + const url = `${origin}/cookies/resources/set.py?${cookieString}`; + await credFetch(url); + } + + async function getCookie(origin, name) { + const url = `${origin}/cookies/resources/list.py`; + const response = await credFetch(url); + const cookies = await response.json(); + return cookies[name] || null; + } + + async function deleteCookie(origin, name) { + // To delete a cookie, we set it with an expiry date in the past. + const cookieString = `${name}=;path=/;Max-Age=0`; + const url = `${origin}/cookies/resources/set.py?${cookieString}`; + await credFetch(url); + } + + promise_test(async t => { + // Clean up any existing cookies on both origins to ensure a clean slate. + await deleteCookie(httpOrigin, cookieName); + await deleteCookie(httpOriginDifferentPort, cookieName); + + // Add a cleanup function to run after the test finishes. + t.add_cleanup(async () => { + await deleteCookie(httpOrigin, cookieName); + await deleteCookie(httpOriginDifferentPort, cookieName); + }); + + // Set a cookie on the first HTTP origin. + await setCookie(httpOrigin, cookieName, cookieValue); + assert_equals(await getCookie(httpOrigin, cookieName), cookieValue, "Cookie must be set on the first HTTP origin successfully."); + + // Verify the cookie is not present on the second HTTP origin. + assert_equals(await getCookie(httpOriginDifferentPort, cookieName), null, "Cookie set on first port should not be visible to second port."); + + // Attempt to set a cookie on the second HTTP origin. + await setCookie(httpOriginDifferentPort, cookieName, cookieValueDifferentPort); + + // Since port-bound behavior is active the cookie will be set in a seperate jar on this other port, it will not overwrite the original cookie. + assert_equals(await getCookie(httpOriginDifferentPort, cookieName), cookieValueDifferentPort, "The cookie on the second port should have been created."); + + // Verify that the original cookie on the HTTP origin is unchanged. + assert_equals(await getCookie(httpOrigin, cookieName), cookieValue, "Cookie 1 should remain unchanged."); + + }, "Cookies should be bound to their origin's port."); +} +</script> +</body> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/cookies/origin-bound-cookies/resources/scheme-bound-cookies-window.html b/third_party/blink/web_tests/external/wpt/cookies/origin-bound-cookies/resources/scheme-bound-cookies-window.html new file mode 100644 index 0000000..0ad1d0b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/cookies/origin-bound-cookies/resources/scheme-bound-cookies-window.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<title>Scheme-bound Cookies Window</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> + +<body> +<script> + async function getCookie(origin, name) { + const url = `${origin}/cookies/resources/list.py`; + const response = await credFetch(url); + const cookies = await response.json(); + return cookies[name] || null; + } + + const cookieName = "scheme-bound-cookie"; + const cookieValue1 = "1"; + const cookieValue2 = "2"; + const httpsOrigin = get_host_info().HTTPS_ORIGIN; + + promise_test(async () => { + assert_equals(await getCookie(self.origin, cookieName), null, "Cookie should not be sent to an insecure origin"); + // Set a cookie on the insecure origin. + await credFetch( + `${self.origin}/cookies/resources/set.py?${cookieName}=${cookieValue2};Path=/`); + // Verify the cookie was set. + assert_equals(await getCookie(self.origin, cookieName), cookieValue2, "Cookie should be set on the insecure origin"); + // Ensure the original secure cookie is still intact, this is due to scheme bounding being enabled, we will not overwrite. + assert_equals(await getCookie(httpsOrigin, cookieName), cookieValue1, "Cookie should be set on the secure origin"); + }, "Check scheme bounding behavior is working."); +</script> +</body> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/cookies/origin-bound-cookies/scheme-bound-cookies.https-expected.txt b/third_party/blink/web_tests/external/wpt/cookies/origin-bound-cookies/scheme-bound-cookies.https-expected.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/cookies/origin-bound-cookies/scheme-bound-cookies.https-expected.txt
@@ -0,0 +1 @@ +
diff --git a/third_party/blink/web_tests/external/wpt/cookies/origin-bound-cookies/scheme-bound-cookies.https.html b/third_party/blink/web_tests/external/wpt/cookies/origin-bound-cookies/scheme-bound-cookies.https.html new file mode 100644 index 0000000..e7f1158 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/cookies/origin-bound-cookies/scheme-bound-cookies.https.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<title>Scheme-bound Cookies</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> + +<body> +<script> + async function getCookie(origin, name) { + const url = `${origin}/cookies/resources/list.py`; + const response = await credFetch(url); + const cookies = await response.json(); + return cookies[name] || null; + } + + const cookieName = "scheme-bound-cookie"; + const cookieValue = "1"; + const httpOrigin = get_host_info().HTTP_ORIGIN; + const httpsOrigin = get_host_info().HTTPS_ORIGIN; + + promise_test(async t => { + // Set a cookie on the secure origin. + await credFetch( + `${httpsOrigin}/cookies/resources/set.py?${cookieName}=${cookieValue};Secure;Path=/`); + + // Verify the cookie was set. + assert_equals(await getCookie(httpsOrigin, cookieName), cookieValue, "Cookie should be set on the secure origin"); + + // Open a window to the insecure version of this origin and run tests there. + // We cannot just use an insecure subresource due to mixed content rules. + const url = new URL("/cookies/origin-bound-cookies/resources/scheme-bound-cookies-window.html", httpOrigin); + const popup = window.open(url); + await fetch_tests_from_window(popup); + }, "Set a cookie on a secure origin and test it's not sent to an insecure origin."); +</script> +</body> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-view-transitions/scoped/display-change.html b/third_party/blink/web_tests/external/wpt/css/css-view-transitions/scoped/display-change.html new file mode 100644 index 0000000..74428fa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-view-transitions/scoped/display-change.html
@@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<head> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="match" href="content-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script src="/web-animations/testcommon.js"></script> +<style> + +body { margin: 20px } +#scope { + position: relative; z-index: 0; background: pink; + border: 5px dashed purple; padding: 5px; + width: 180px; height: 120px; +} +#part { + position: relative; z-index: 0; background: lightgrey; + border: 5px solid blue; padding: 5px; + width: 120px; height: 60px; + left: 20px; top: 20px; + view-transition-name: foo; +} + +#scope::view-transition { background: yellow; } +#scope::view-transition-group(foo) { animation-play-state: paused; } +#scope::view-transition-new(foo) { animation: unset; opacity: 1; } +#scope::view-transition-old(foo) { animation: unset; opacity: 0; } + +</style> +</head> +<body> +<div id=scope> + <div id=part> + PARTICIPANT + </div> +</div> +<script> + +const scope = document.querySelector("#scope"); +failIfNot(scope.startViewTransition, "Missing element.startViewTransition"); + +async function runTest() { + await waitForCompositorReady(); + scope.startViewTransition(() => { + scope.style.display = "flex"; + requestAnimationFrame(takeScreenshot) + }); +} +onload = () => runTest(); + +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/digital-credentials/DIR_METADATA b/third_party/blink/web_tests/external/wpt/digital-credentials/DIR_METADATA new file mode 100644 index 0000000..4781593 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/digital-credentials/DIR_METADATA
@@ -0,0 +1,9 @@ +monorail: { + component: "Blink>Identity>DigitalCredentials" +} +wpt: { + notify: YES +} +buganizer_public: { + component_id: 1518527 +}
diff --git a/third_party/breakpad/breakpad b/third_party/breakpad/breakpad index 7c56a01..ff252ff 160000 --- a/third_party/breakpad/breakpad +++ b/third_party/breakpad/breakpad
@@ -1 +1 @@ -Subproject commit 7c56a01c1437ecdbe1d02c724573ca378947f82b +Subproject commit ff252ff6faf5e3a52dc4955aab0d84831697dc94
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 26ab7701..a9fee9c 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 26ab7701c3537b32486490fb6dcb26eab6e149ef +Subproject commit a9fee9cd133c82bb62a79f27e037f67526dbfdfb
diff --git a/third_party/flatbuffers/README.chromium b/third_party/flatbuffers/README.chromium index 3862495..ca22a23 100644 --- a/third_party/flatbuffers/README.chromium +++ b/third_party/flatbuffers/README.chromium
@@ -7,6 +7,7 @@ License File: LICENSE Security Critical: yes Shipped: yes +CPEPrefix: cpe:/a:google:flatbuffers Description: FlatBuffers is an efficient cross platform serialization library for games and
diff --git a/third_party/fontconfig/BUILD.gn b/third_party/fontconfig/BUILD.gn index acb6c6a0..84520bb 100644 --- a/third_party/fontconfig/BUILD.gn +++ b/third_party/fontconfig/BUILD.gn
@@ -64,9 +64,6 @@ "//third_party/rust/read_fonts/v0_30:lib", "//third_party/rust/skrifa/v0_32:lib", ] - - # TODO(https://crbug.com/429255379): Stop suppressing this warning. - rustflags = [ "-Amismatched_lifetime_syntaxes" ] } config("fontconfig_config") {
diff --git a/third_party/libaom/README.chromium b/third_party/libaom/README.chromium index 7824d30d..a168f6434 100644 --- a/third_party/libaom/README.chromium +++ b/third_party/libaom/README.chromium
@@ -2,7 +2,7 @@ Short Name: libaom URL: https://aomedia.googlesource.com/aom/ Version: N/A -Revision: a48eee7fd280967ce00308a48285f11fb03be464 +Revision: f6055d0dc007d24e39e8d6a4a268216d67608b56 CPEPrefix: cpe:/a:aomedia:aomedia:3.12.1 License: BSD-2-Clause, Patent License Android Compatible: yes
diff --git a/third_party/libaom/source/config/config/aom_version.h b/third_party/libaom/source/config/config/aom_version.h index b8cfcd2..dea3cae 100644 --- a/third_party/libaom/source/config/config/aom_version.h +++ b/third_party/libaom/source/config/config/aom_version.h
@@ -14,9 +14,9 @@ #define VERSION_MAJOR 3 #define VERSION_MINOR 12 #define VERSION_PATCH 1 -#define VERSION_EXTRA "221-ga48eee7fd2" +#define VERSION_EXTRA "229-gf6055d0dc0" #define VERSION_PACKED \ ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH)) -#define VERSION_STRING_NOSP "3.12.1-221-ga48eee7fd2" -#define VERSION_STRING " 3.12.1-221-ga48eee7fd2" +#define VERSION_STRING_NOSP "3.12.1-229-gf6055d0dc0" +#define VERSION_STRING " 3.12.1-229-gf6055d0dc0" #endif // AOM_VERSION_H_
diff --git a/third_party/libaom/source/libaom b/third_party/libaom/source/libaom index a48eee7..f6055d0 160000 --- a/third_party/libaom/source/libaom +++ b/third_party/libaom/source/libaom
@@ -1 +1 @@ -Subproject commit a48eee7fd280967ce00308a48285f11fb03be464 +Subproject commit f6055d0dc007d24e39e8d6a4a268216d67608b56
diff --git a/third_party/libc++/src b/third_party/libc++/src index ac9e486..ed0f32e 160000 --- a/third_party/libc++/src +++ b/third_party/libc++/src
@@ -1 +1 @@ -Subproject commit ac9e4860cadb33ec5185084ed7c6345eca5fa50c +Subproject commit ed0f32ee7a8d9481bfd26cfa6f5940b9f296f371
diff --git a/third_party/libx11/README.chromium b/third_party/libx11/README.chromium index 2ef1ce0..db6e2e9 100644 --- a/third_party/libx11/README.chromium +++ b/third_party/libx11/README.chromium
@@ -8,6 +8,7 @@ License File: LICENSE Security Critical: no Shipped: yes +CPEPrefix: cpe:/a:x.org:libx11 Description: Core X11 protocol client library
diff --git a/third_party/perfetto b/third_party/perfetto index 40f166c..c26b918 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit 40f166cc9df71dd893f0b589b69b3e6d53171855 +Subproject commit c26b918af62b7375d8089dd7c7ca7f5fbe9c111b
diff --git a/tools/clang/scripts/OWNERS b/tools/clang/scripts/OWNERS index 6141cf6..cec7358f 100644 --- a/tools/clang/scripts/OWNERS +++ b/tools/clang/scripts/OWNERS
@@ -1,6 +1,5 @@ # This is the list of Chromium committers responsible for updating clang. aeubanks@google.com -akhuang@google.com ayzhao@google.com dloehr@google.com hans@chromium.org
diff --git a/tools/clang/scripts/compiler_inputs_size.py b/tools/clang/scripts/compiler_inputs_size.py index aabe29a..1b9038b 100755 --- a/tools/clang/scripts/compiler_inputs_size.py +++ b/tools/clang/scripts/compiler_inputs_size.py
@@ -23,7 +23,7 @@ Example usage: (Remove use_remoteexec=true if you don't have reclient access.) -$ gn gen out/Debug --args="system_headers_in_deps=true enable_nacl=false +$ gn gen out/Debug --args="system_headers_in_deps=true \ symbol_level=0 use_remoteexec=true" $ autoninja -C out/Debug chrome $ tools/clang/scripts/compiler_inputs_size.py out/Debug \
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index d4ea3e9c..79d11df 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -24822,6 +24822,14 @@ <description>User pressed 'Help' in the app menu.</description> </action> +<action name="MobileMenuHideReaderMode"> + <owner>wylieb@google.com</owner> + <owner>evanluo@google.com</owner> + <description> + User pressed/clicked the "Hide Reading Mode" item in the app menu. + </description> +</action> + <action name="MobileMenuHistory"> <owner>aurimas@chromium.org</owner> <description>User pressed 'History' in the app menu.</description> @@ -24968,14 +24976,6 @@ <description>User pressed 'Listen to this page' in the app menu.</description> </action> -<action name="MobileMenuReaderMode"> - <owner>jinsukkim@chromium.org</owner> - <owner>wylieb@chromium.org</owner> - <description> - User pressed/clicked the "Show Reading Mode" item in the app menu. - </description> -</action> - <action name="MobileMenuReadingList"> <owner>gambard@chromium.org</owner> <description>User pressed 'Reading List' in the app menu.</description> @@ -25084,6 +25084,14 @@ <description>User opened the app menu in the empty tablet mode.</description> </action> +<action name="MobileMenuShowReaderMode"> + <owner>jinsukkim@chromium.org</owner> + <owner>wylieb@google.com</owner> + <description> + User pressed/clicked the "Show Reading Mode" item in the app menu. + </description> +</action> + <action name="MobileMenuSiteInformation"> <owner>gambard@chromium.org</owner> <description>User pressed 'Site Information' in the app menu.</description> @@ -26270,6 +26278,12 @@ <description>Recorded when reader mode gets activated.</description> </action> +<action name="MobileReaderModeHidden"> + <owner>wylieb@google.com</owner> + <owner>evanluo@google.com</owner> + <description>Recorded when reader mode gets hidden.</description> +</action> + <action name="MobileReadingListAccessibilityClose"> <owner>myuu@google.com</owner> <owner>chrome-signin-mobile-team@google.com</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 896b002..bd93e6f 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -2553,8 +2553,8 @@ <int value="86" label="Notification interactions"/> <int value="87" label="Reduce accept language"/> <int value="88" label="Notification permission review"/> - <int value="89" label="Private network guard"/> - <int value="90" label="Private network chooser data"/> + <int value="89" label="(Obsolete) Private network guard"/> + <int value="90" label="(Obsolete) Private network chooser data"/> <int value="91" label="Federated identity identity-provider-sign-in-status API"/> <int value="92" label="Unused site permissions"/> @@ -15891,6 +15891,7 @@ <int value="666871156" label="KaleidoscopeModule:enabled"/> <int value="667262414" label="IOSPromoBookmarkBubble:disabled"/> <int value="667643314" label="LitePageServerPreviews:enabled"/> + <int value="668342684" label="TabModelInitFixes:disabled"/> <int value="669097106" label="NtpRealboxMatchOmniboxTheme:disabled"/> <int value="669958310" label="EnableSuggestedLocalFiles:disabled"/> <int value="670404276" label="ImeUsEnglishModelUpdate:disabled"/> @@ -16214,6 +16215,7 @@ <int value="773952982" label="ReduceIPAddressChangeNotification:disabled"/> <int value="775075949" label="ImeInputLogicHmm:enabled"/> <int value="775148009" label="OsSettingsDeepLinking:disabled"/> + <int value="775373286" label="TabModelInitFixes:enabled"/> <int value="777569794" label="FeedWebUi:enabled"/> <int value="777667507" label="DesktopPWAsLinkCapturing:enabled"/> <int value="778000757" label="EnableInputEventLogging:disabled"/>
diff --git a/tools/metrics/histograms/metadata/accessibility/enums.xml b/tools/metrics/histograms/metadata/accessibility/enums.xml index a14a8b44..6dcc717 100644 --- a/tools/metrics/histograms/metadata/accessibility/enums.xml +++ b/tools/metrics/histograms/metadata/accessibility/enums.xml
@@ -1600,6 +1600,17 @@ <!-- LINT.ThenChange(//chrome/renderer/accessibility/phrase_segmentation/dependency_parser_model.h:DependencyParserModelState) --> +<!-- LINT.IfChange(DistillationParseResult)--> + +<enum name="DistillationParseResult"> + <summary>Describes the result of a disillation parsing attempt</summary> + <int value="0" label="Success"/> + <int value="1" label="Parse Failure"/> + <int value="2" label="No Data"/> +</enum> + +<!-- LINT.ThenChange(//components/dom_distiller/core/distiller_page.cc:DistillationParseResult) --> + <!-- LINT.IfChange(DistillationResult)--> <enum name="DistillationResult">
diff --git a/tools/metrics/histograms/metadata/accessibility/histograms.xml b/tools/metrics/histograms/metadata/accessibility/histograms.xml index 97be9f2..fc91fed 100644 --- a/tools/metrics/histograms/metadata/accessibility/histograms.xml +++ b/tools/metrics/histograms/metadata/accessibility/histograms.xml
@@ -3958,6 +3958,16 @@ </summary> </histogram> +<histogram name="DomDistiller.Distillation.Result" + enum="DistillationParseResult" expires_after="2026-06-01"> + <owner>gusmartin@google.com</owner> + <owner>chrome-reader-mode-team@google.com</owner> + <summary> + Records whether distilling the page resulted in sucess, parse failure, or no + Data to distill + </summary> +</histogram> + <histogram name="DomDistiller.IsDistillable" enum="Boolean" expires_after="2026-06-01"> <owner>wylieb@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/blink/enums.xml b/tools/metrics/histograms/metadata/blink/enums.xml index eb5dfcf..04bfd6d 100644 --- a/tools/metrics/histograms/metadata/blink/enums.xml +++ b/tools/metrics/histograms/metadata/blink/enums.xml
@@ -4771,7 +4771,7 @@ <int value="4290" label="DeviceOrientationUsedWithoutPermissionRequest"/> <int value="4291" label="DeviceMotionPermissionRequested"/> <int value="4292" label="DeviceMotionUsedWithoutPermissionRequest"/> - <int value="4293" label="PrivateNetworkAccessPermissionPrompt"/> + <int value="4293" label="OBSOLETE_PrivateNetworkAccessPermissionPrompt"/> <int value="4294" label="PseudoBeforeAfterForDateTimeInputElement"/> <int value="4295" label="OBSOLETE_kV8PendingBeacon_IsPending_AttributeGetter"/>
diff --git a/tools/metrics/histograms/metadata/facilitated_payments/enums.xml b/tools/metrics/histograms/metadata/facilitated_payments/enums.xml index 9db1608..97e4607d 100644 --- a/tools/metrics/histograms/metadata/facilitated_payments/enums.xml +++ b/tools/metrics/histograms/metadata/facilitated_payments/enums.xml
@@ -82,6 +82,15 @@ <int value="1" label="Screen was closed not by the user"/> <int value="2" label="Screen was closed by the user"/> <int value="3" label="User clicked the No Thanks button"/> + <int value="4" label="Wallet is not installed"/> + <int value="5" label="Wallet version is not supported"/> + <int value="6" + label="User opted out of the flow using the Settings page pref"/> + <int value="7" label="No screen lock or biometric setup"/> + <int value="8" + label="User's account was determined to be ineligible by the server"/> + <int value="9" label="User switched to a different tab"/> + <int value="10" label="User navigated to a different website"/> </enum> <!-- LINT.ThenChange(/components/facilitated_payments/core/metrics/facilitated_payments_metrics.h:PixAccountLinkingFlowExitedReason) -->
diff --git a/tools/metrics/histograms/metadata/glic/histograms.xml b/tools/metrics/histograms/metadata/glic/histograms.xml index 45156b3..05e853a 100644 --- a/tools/metrics/histograms/metadata/glic/histograms.xml +++ b/tools/metrics/histograms/metadata/glic/histograms.xml
@@ -97,6 +97,7 @@ <variant name="OnResponseStarted"/> <variant name="OnResponseStopped"/> <variant name="OnSessionTerminated"/> + <variant name="OnTurnCompleted"/> <variant name="OnUserInputSubmitted"/> <variant name="OpenGlicSettingsPage"/> <variant name="OpenOsPermissionSettingsMenu"/> @@ -836,6 +837,20 @@ </summary> </histogram> +<histogram name="Glic.Response.TurnDuration.{Mode}" units="ms" + expires_after="2026-01-15"> + <owner>dtapuska@chromium.org</owner> + <owner>erikchen@chromium.org</owner> + <summary> + Recorded at the end of a turn response from the server indicating the time + the entire request/response sequence took. + </summary> + <token key="Mode"> + <variant name="Actor" summary="Recorded when the actor model is used."/> + <variant name="Default" summary="Recorded when the default model is used."/> + </token> +</histogram> + <histogram name="Glic.ScrollTo.ErrorReason" enum="GlicScrollToErrorReason" expires_after="2026-01-15"> <owner>liuwilliam@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/permissions/histograms.xml b/tools/metrics/histograms/metadata/permissions/histograms.xml index 60eb64e..0e21601 100644 --- a/tools/metrics/histograms/metadata/permissions/histograms.xml +++ b/tools/metrics/histograms/metadata/permissions/histograms.xml
@@ -484,6 +484,17 @@ </summary> </histogram> +<histogram name="Permissions.AIv3.ModelExecutionAlreadyInProgress" + enum="BooleanSuccess" expires_after="2025-12-02"> + <owner>elklm@chromium.org</owner> + <owner>hempjudith@google.com</owner> + <owner>src/components/permissions/PERMISSIONS_OWNERS</owner> + <summary> + Records whether the AIv3 model execution is already in progress when + ExecuteModel is called. This should not happen, but we want to verify this. + </summary> +</histogram> + <histogram name="Permissions.AIv3.ModelHandlerProviderExists" enum="BooleanSuccess" expires_after="2025-12-02"> <owner>elklm@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/session/histograms.xml b/tools/metrics/histograms/metadata/session/histograms.xml index 1754732..6d5d8b4 100644 --- a/tools/metrics/histograms/metadata/session/histograms.xml +++ b/tools/metrics/histograms/metadata/session/histograms.xml
@@ -443,6 +443,24 @@ </summary> </histogram> +<histogram name="Session.TotalDuration.TimeInTabletMode" units="times" + expires_after="2026-07-08"> + <owner>robliao@chromium.org</owner> + <owner>arakeri@microsoft.com</owner> + <owner>gerchiko@microsoft.com</owner> + <owner>wangsongjin@microsoft.com</owner> + <owner>input-dev@chromium.org</owner> + <summary> + Time spent in tablet mode in each session (as defined by + DesktopSessionDurationTracker). Samples correspond one-to-one with + Session.TotalDuration samples. + + This histogram should be analyzed with Session.TotalDuration. For example, + the sum of this histogram divided by the sum of Session.TotalDuration is the + total proportion of active browsing time spent in tablet mode. + </summary> +</histogram> + <histogram name="Session.TotalDuration.TouchMode" units="times" expires_after="2024-01-14"> <owner>collinbaker@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index b9b7de5..7de2166 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@ "full_remote_path": "perfetto-luci-artifacts/361808c959b026d558c9948602ea38bf25d8981e/linux-arm64/trace_processor_shell" }, "win": { - "hash": "1d5779d7e9aa8f9908bc6872a897268e44b08ed5", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/4c466cce8f57be636e994ac7181e3411d2627459/trace_processor_shell.exe" + "hash": "0fee34f2fc6fb3a792f1a678d07ad6599d75fcad", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/40f166cc9df71dd893f0b589b69b3e6d53171855/trace_processor_shell.exe" }, "linux_arm": { "hash": "ab1a0d9236a63649044414663b6ace711253648f", @@ -21,8 +21,8 @@ "full_remote_path": "perfetto-luci-artifacts/v51.2/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "b172933c198e8b0b25c6bdcb1df13978f42d0afb", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/c5d96ec25c43d648c008a2e7de8288a223eb217d/trace_processor_shell" + "hash": "42a878ace9bc6771ce4ed010f4621a29b9b34e15", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/a5564ee5b7c510f90835346b380826df972ab393/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/perry.py b/tools/perry.py index 4eb7f39..496f1f1 100755 --- a/tools/perry.py +++ b/tools/perry.py
@@ -8,7 +8,7 @@ Example invocation: -gn gen out/asan --args='is_asan=true enable_nacl=false is_debug=false' +gn gen out/asan --args='is_asan=true is_debug=false' ninja -C out/asan base_unittests tools/perry.py out/asan/base_unittests > perry.log & tail -f perry.log
diff --git a/tools/rust/build_rust.py b/tools/rust/build_rust.py index dbad3c5..257f472 100755 --- a/tools/rust/build_rust.py +++ b/tools/rust/build_rust.py
@@ -596,6 +596,9 @@ # with `GitMoveSubmoduleBranch()`. ############################# + # TODO(crbug.com/433513424): Remove once we roll past this revision. + GitCherryPick(RUST_SRC_DIR, 'https://github.com/rust-lang/rust.git', + '23fda6084b5e9a618b74a9c417f5353783b72ae9') print('Finished applying cherry-picks.')
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc index 2bf46355..cff2e70 100644 --- a/ui/accessibility/ax_node.cc +++ b/ui/accessibility/ax_node.cc
@@ -2297,6 +2297,14 @@ if (!ui::IsLikelyActiveDescendantRole(GetRole())) return false; + // False if no explicit ARIA role -- not a perfect rule, but a reasonable + // heuristic. Don't apply this rule for table cells or headers that get their + // role from their HTML semantics (e.g., <td>, <th>, etc.). + if (!HasStringAttribute(ax::mojom::StringAttribute::kRole) && + !ui::IsCellOrTableHeader(GetRole())) { + return false; + } + // False if invisible, ignored or disabled. if (IsInvisibleOrIgnored() || GetIntAttribute(ax::mojom::IntAttribute::kRestriction) == @@ -2304,10 +2312,6 @@ return false; } - // False if no ARIA role -- not a perfect rule, but a reasonable heuristic. - if (!HasStringAttribute(ax::mojom::StringAttribute::kRole)) - return false; - // False if no id attribute -- nothing to point to. // This requirement may need to be removed if ARIA element reflection is // implemented. HTML attribute serialization must currently be turned on in
diff --git a/ui/accessibility/ax_node_position_unittest.cc b/ui/accessibility/ax_node_position_unittest.cc index 648183e..b83d614 100644 --- a/ui/accessibility/ax_node_position_unittest.cc +++ b/ui/accessibility/ax_node_position_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/accessibility/ax_node_position.h" #include <stdint.h>
diff --git a/ui/accessibility/ax_node_unittest.cc b/ui/accessibility/ax_node_unittest.cc index 573eb13..fd98e01 100644 --- a/ui/accessibility/ax_node_unittest.cc +++ b/ui/accessibility/ax_node_unittest.cc
@@ -1031,6 +1031,39 @@ EXPECT_EQ(tree.GetFromId(8)->GetSetSize(), 6); } +TEST(AXNodeTest, GridCellsFocusableViaARIAActiveDescendant) { + TestAXTreeUpdate update(std::string(R"HTML( + ++1 kRootWebArea + ++++2 kGrid stringAttribute=kHtmlTag,"table" intAttribute=kActivedescendantId,4 + ++++++3 kRow stringAttribute=kHtmlTag,"tr" + ++++++++4 kColumnHeader stringAttribute=kHtmlId,"row1-cell1" stringAttribute=kHtmlTag,"th" + ++++++5 kRow stringAttribute=kHtmlTag,"tr" + ++++++++6 kGridCell stringAttribute=kHtmlId,"row2-cell1" stringAttribute=kHtmlTag,"td" + ++++7 kGrid stringAttribute=kHtmlTag,"table" + ++++++8 kRow stringAttribute=kHtmlTag,"tr" + ++++++++9 kColumnHeader stringAttribute=kHtmlId,"row1-cell1" stringAttribute=kHtmlTag,"th" + ++++++10 kRow stringAttribute=kHtmlTag,"tr" + ++++++++11 kGridCell stringAttribute=kHtmlId,"row2-cell1" stringAttribute=kHtmlTag,"td" + )HTML")); + + AXTree tree(update); + + // Grid with aria-activedescendant should have focusable cells because they + // have HTML ids. Rows shouldn't. None of the cells in the grid without + // aria-activedescendant should be focusable. + for (int id : {4, 6}) { + const AXNode* n = tree.GetFromId(id); + ASSERT_NE(n, nullptr) << "Node " << id << " missing"; + EXPECT_TRUE(n->IsFocusable()) << "cell with " << id << " not focusable"; + } + + for (int id : {2, 3, 5, 7, 8, 9, 10, 11}) { + const AXNode* n = tree.GetFromId(id); + ASSERT_NE(n, nullptr) << "Node " << id << " missing"; + EXPECT_FALSE(n->IsFocusable()) << "Node " << id << " is focusable"; + } +} + #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) TEST(AXNodeTest, ExtraAnnouncementNodesNotCreated) { AXNodeData root;
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc index 03b92c58..a5da158 100644 --- a/ui/accessibility/ax_role_properties.cc +++ b/ui/accessibility/ax_role_properties.cc
@@ -419,6 +419,7 @@ case ax::mojom::Role::kButton: case ax::mojom::Role::kCell: case ax::mojom::Role::kCheckBox: + case ax::mojom::Role::kColumnHeader: case ax::mojom::Role::kComment: case ax::mojom::Role::kGridCell: case ax::mojom::Role::kListBoxOption: @@ -428,6 +429,7 @@ case ax::mojom::Role::kMenuListOption: case ax::mojom::Role::kRadioButton: case ax::mojom::Role::kRow: + case ax::mojom::Role::kRowHeader: case ax::mojom::Role::kTab: case ax::mojom::Role::kToggleButton: case ax::mojom::Role::kTreeItem:
diff --git a/ui/accessibility/platform/inspect/ax_call_statement_invoker_auralinux.cc b/ui/accessibility/platform/inspect/ax_call_statement_invoker_auralinux.cc index f997646d..e8b7a0d 100644 --- a/ui/accessibility/platform/inspect/ax_call_statement_invoker_auralinux.cc +++ b/ui/accessibility/platform/inspect/ax_call_statement_invoker_auralinux.cc
@@ -2,15 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/accessibility/platform/inspect/ax_call_statement_invoker_auralinux.h" #include <variant> +#include "base/compiler_specific.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "base/strings/sys_string_conversions.h" @@ -207,7 +203,8 @@ GArray* state_array = atspi_state_set_get_states(atspi_states); for (unsigned i = 0; i < state_array->len; i++) { - AtspiStateType state_type = g_array_index(state_array, AtspiStateType, i); + AtspiStateType state_type = + UNSAFE_TODO(g_array_index(state_array, AtspiStateType, i)); const char* state_str = ATSPIStateToString(state_type); if (state.compare(state_str) == 0) { return AXOptionalObject(Target(true)); @@ -227,7 +224,7 @@ if (!error) { for (guint idx = 0; idx < relations->len; idx++) { AtspiRelation* atspi_relation = - g_array_index(relations, AtspiRelation*, idx); + UNSAFE_TODO(g_array_index(relations, AtspiRelation*, idx)); std::string relation_str = ATSPIRelationToString( atspi_relation_get_relation_type(atspi_relation)); if (relation_str.compare(relation) == 0) { @@ -256,7 +253,7 @@ atspi_accessible_get_interfaces(const_cast<AtspiAccessible*>(target)); for (unsigned i = 0; i < interfaces->len; i++) { - char* iface = g_array_index(interfaces, char*, i); + char* iface = UNSAFE_TODO(g_array_index(interfaces, char*, i)); if (interface.compare(std::string(iface)) == 0) { return AXOptionalObject(Target(true)); }
diff --git a/ui/accessibility/platform/inspect/ax_event_recorder_auralinux.cc b/ui/accessibility/platform/inspect/ax_event_recorder_auralinux.cc index 7fd5c19..60096413 100644 --- a/ui/accessibility/platform/inspect/ax_event_recorder_auralinux.cc +++ b/ui/accessibility/platform/inspect/ax_event_recorder_auralinux.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/accessibility/platform/inspect/ax_event_recorder_auralinux.h" #include <atk/atk.h> @@ -15,6 +10,7 @@ #include <array> +#include "base/compiler_specific.h" #include "base/no_destructor.h" #include "base/process/process_handle.h" #include "base/strings/string_number_conversions.h" @@ -152,8 +148,8 @@ std::string log; if (event_name.find("property-change") != std::string::npos) { DCHECK_GE(n_params, 2u); - AtkPropertyValues* property_values = - static_cast<AtkPropertyValues*>(g_value_get_pointer(¶ms[1])); + AtkPropertyValues* property_values = static_cast<AtkPropertyValues*>( + g_value_get_pointer(&UNSAFE_TODO(params[1]))); if (g_strcmp0(property_values->property_name, "accessible-value") == 0) { log += "VALUE-CHANGED:"; @@ -183,34 +179,36 @@ log_name = false; log += base::ToUpperASCII(event); // Despite this actually being a signed integer, it's defined as a uint. - int index = static_cast<int>(g_value_get_uint(¶ms[1])); + int index = static_cast<int>(g_value_get_uint(&UNSAFE_TODO(params[1]))); log += base::StringPrintf(" index:%d", index); - AtkObject* child = static_cast<AtkObject*>(g_value_get_pointer(¶ms[2])); + AtkObject* child = + static_cast<AtkObject*>(g_value_get_pointer(&UNSAFE_TODO(params[2]))); if (child) log += " CHILD:(" + AtkObjectToString(child, log_name) + ")"; else log += " CHILD:(NULL)"; } else if (event_name.find("focus-event") != std::string::npos) { log += base::ToUpperASCII(event); - gchar* parameter = g_strdup_value_contents(¶ms[1]); + gchar* parameter = g_strdup_value_contents(&UNSAFE_TODO(params[1])); log += base::StringPrintf(":%s", parameter); g_free(parameter); } else { log += base::ToUpperASCII(event); if (event_name.find("state-change") != std::string::npos) { - std::string state_type = g_value_get_string(¶ms[1]); + std::string state_type = g_value_get_string(&UNSAFE_TODO(params[1])); log += ":" + base::ToUpperASCII(state_type); - gchar* parameter = g_strdup_value_contents(¶ms[2]); + gchar* parameter = g_strdup_value_contents(&UNSAFE_TODO(params[2])); log += base::StringPrintf(":%s", parameter); g_free(parameter); } else if (event_name.find("text-insert") != std::string::npos || event_name.find("text-remove") != std::string::npos) { DCHECK_GE(n_params, 4u); - log += base::StringPrintf( - " (start=%i length=%i '%s')", g_value_get_int(¶ms[1]), - g_value_get_int(¶ms[2]), g_value_get_string(¶ms[3])); + log += base::StringPrintf(" (start=%i length=%i '%s')", + g_value_get_int(&UNSAFE_TODO(params[1])), + g_value_get_int(&UNSAFE_TODO(params[2])), + g_value_get_string(&UNSAFE_TODO(params[3]))); } } @@ -388,7 +386,8 @@ GArray* state_array = atspi_state_set_get_states(atspi_states); std::vector<std::string> states; for (unsigned i = 0; i < state_array->len; i++) { - AtspiStateType state_type = g_array_index(state_array, AtspiStateType, i); + AtspiStateType state_type = + UNSAFE_TODO(g_array_index(state_array, AtspiStateType, i)); states.push_back(ATSPIStateToString(state_type)); } g_array_free(state_array, TRUE);
diff --git a/ui/android/java/src/org/chromium/ui/util/XrUtils.java b/ui/android/java/src/org/chromium/ui/util/XrUtils.java index af80e8e..57cc52e 100644 --- a/ui/android/java/src/org/chromium/ui/util/XrUtils.java +++ b/ui/android/java/src/org/chromium/ui/util/XrUtils.java
@@ -28,6 +28,8 @@ } private static boolean isXrDeviceInternal() { + // TODO(crbug.com/422134376): To detect "Android XR" query OS instead of device's + // properties. return PackageManagerUtils.hasSystemFeature(PackageManagerUtils.XR_OPENXR_FEATURE_NAME); } }
diff --git a/ui/android/java/src/org/chromium/ui/xr/scenecore/XrSceneCoreSessionManager.java b/ui/android/java/src/org/chromium/ui/xr/scenecore/XrSceneCoreSessionManager.java index 4f41dfd..6e557cd 100644 --- a/ui/android/java/src/org/chromium/ui/xr/scenecore/XrSceneCoreSessionManager.java +++ b/ui/android/java/src/org/chromium/ui/xr/scenecore/XrSceneCoreSessionManager.java
@@ -13,58 +13,44 @@ * (https://developer.android.com/reference/androidx/xr/scenecore/package-summary.html). It's used * by activities to control XR space modes transitions. See implementation in {@link * org.chromium.chrome.browser.xr.scenecore.XrSceneCoreSessionManagerImpl}. - * - * <p>Usage: There are two ways to switch between XR space modes. - * - * <p>1. Visibility of an activity is controlled internally. Call {@link - * XrSceneCoreSessionManager#requestSpaceModeChange}. - * - * <p>2. Visibility of an activity has to be controlled manually by a caller. This 3-steps flow is - * necessary to adjust the background of the activity, hide some UI elements and avoid UI flicker. - * Flow: - * - * <p>2.1. Call {@link XrSceneCoreSessionManager#startSpaceModeChange} and provide a callback. It - * will start the XR mode transition flow and will make the activity invisible for up to 1 second. - * - * <p>2.2. After XR space mode transition is completed, the callback from (2.1) will be called on - * the main thread. - * - * <p>2.3. The activity will still be invisible at this moment. To make it visible, finish the - * transition by calling {@link XrSceneCoreSessionManager#finishSpaceModeChange}. All XR space mode - * transitions requests must be called on the main thread. */ @NullMarked public interface XrSceneCoreSessionManager extends Destroyable { /** - * @param fsmModeRequested Requested XR space mode (true for XR full space mode). - * @param completedCallback Callback function, signaling that XR space mode transition is - * completed. Caller still need to call 'finishSpaceModeChange' to make the activity - * visible. - * @return Success status. True: if the activity has focus and it's not in the middle of - * transition between XR space modes. False: the 'completedCallback' will not be called. + * Request to change XR space mode. + * + * @param requestFullSpaceMode True: to request Full Space mode, false to exit Full Space mode. + * @return Success status. True: if request is handled and transition has started (the activity + * has focus and it's not in the middle of transition between XR space modes), false + * otherwise. */ - boolean startSpaceModeChange(boolean fsmModeRequested, Runnable completedCallback); + boolean requestSpaceModeChange(boolean requestFullSpaceMode); + + /** + * Request to change XR space mode. + * + * @param requestFullSpaceMode True: to request Full Space mode, false to exit Full Space mode. + * @param completedCallback Callback function, signaling that XR space mode transition is + * complete. + * @return Success status. True: if request is handled and transition has started (the activity + * has focus and it's not in the middle of transition between XR space modes), false + * otherwise (the 'completedCallback' will not be called). + */ + boolean requestSpaceModeChange(boolean requestFullSpaceMode, Runnable completedCallback); /** * Get XR space mode observable supplier. The supplier provides boolean value: true for XR Full - * space mode. + * Space mode. */ ObservableSupplier<Boolean> getXrSpaceModeObservableSupplier(); /** - * Call to complete XR space mode transition initiated in {@link - * XrSceneCoreSessionManager#startSpaceModeChange}. + * Is the activity in the Full Space mode. It will report the previous mode until the current + * transition is complete. */ - void finishSpaceModeChange(); + boolean isXrFullSpaceMode(); - /** - * Request to change XR space mode synchronously. Visibility of the activity is controlled - * internally. - * - * @param fsmModeRequested Requested XR space mode (true for XR full space mode). - * @return success status. True: if the activity has focus and it's not in the middle of - * transition between XR space modes. - */ - boolean requestSpaceModeChange(boolean fsmModeRequested); + /** Update visibility of main panel in the Full Space mode. */ + void setMainPanelVisibility(boolean visible); }
diff --git a/ui/base/clipboard/clipboard_ozone.cc b/ui/base/clipboard/clipboard_ozone.cc index efedcb48..793f214b 100644 --- a/ui/base/clipboard/clipboard_ozone.cc +++ b/ui/base/clipboard/clipboard_ozone.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/clipboard/clipboard_ozone.h" #include <algorithm> @@ -18,6 +13,7 @@ #include <vector> #include "base/check.h" +#include "base/compiler_specific.h" #include "base/containers/contains.h" #include "base/containers/flat_map.h" #include "base/containers/map_util.h" @@ -717,9 +713,9 @@ std::u16string bookmark = base::StrCat({base::UTF8ToUTF16(url) + u"\n" + base::UTF8ToUTF16(title)}); - std::vector<uint8_t> data( - reinterpret_cast<const uint8_t*>(bookmark.data()), - reinterpret_cast<const uint8_t*>(bookmark.data() + bookmark.size())); + std::vector<uint8_t> data(reinterpret_cast<const uint8_t*>(bookmark.data()), + reinterpret_cast<const uint8_t*>(UNSAFE_TODO( + bookmark.data() + bookmark.size()))); async_clipboard_ozone_->InsertData(std::move(data), {kMimeTypeMozillaUrl}); }
diff --git a/ui/base/clipboard/scoped_clipboard_writer.cc b/ui/base/clipboard/scoped_clipboard_writer.cc index 8064a2c..4aa6a6c 100644 --- a/ui/base/clipboard/scoped_clipboard_writer.cc +++ b/ui/base/clipboard/scoped_clipboard_writer.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/clipboard/scoped_clipboard_writer.h" #include <memory> @@ -15,6 +10,7 @@ #include <utility> #include <variant> +#include "base/compiler_specific.h" #include "base/json/json_writer.h" #include "base/pickle.h" #include "base/strings/escape.h" @@ -205,7 +201,8 @@ raw_data.format = format; raw_data.data = std::vector<uint8_t>( reinterpret_cast<const uint8_t*>(pickle.data()), - reinterpret_cast<const uint8_t*>(pickle.data()) + pickle.size()); + UNSAFE_TODO(reinterpret_cast<const uint8_t*>(pickle.data()) + + pickle.size())); raw_objects_.insert({format, std::move(raw_data)}); }
diff --git a/ui/base/glib/scoped_gsignal_unittest.cc b/ui/base/glib/scoped_gsignal_unittest.cc index e820f21..44c126d 100644 --- a/ui/base/glib/scoped_gsignal_unittest.cc +++ b/ui/base/glib/scoped_gsignal_unittest.cc
@@ -2,13 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/glib/scoped_gsignal.h" +#include "base/compiler_specific.h" #include "base/functional/bind.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/glib/scoped_gobject.h" @@ -24,7 +20,7 @@ GObject parent_instance; }; -G_DEFINE_TYPE(TestObject, test_object, G_TYPE_OBJECT) +UNSAFE_TODO(G_DEFINE_TYPE(TestObject, test_object, G_TYPE_OBJECT)) // Used by G_DEFINE_TYPE above. void test_object_class_init(TestObjectClass*) {
diff --git a/ui/base/ime/character_composer.cc b/ui/base/ime/character_composer.cc index a3cb540..b4fd964f 100644 --- a/ui/base/ime/character_composer.cc +++ b/ui/base/ime/character_composer.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/ime/character_composer.h" #include <algorithm> @@ -15,6 +10,7 @@ #include <string> #include "base/check.h" +#include "base/compiler_specific.h" #include "base/logging.h" #include "base/notreached.h" #include "base/strings/string_util.h" @@ -50,7 +46,7 @@ if (character) { output->resize(CBU16_LENGTH(character)); size_t i = 0; - CBU16_APPEND_UNSAFE(&(*output)[0], i, character); + UNSAFE_TODO(CBU16_APPEND_UNSAFE(&(*output)[0], i, character)); } return true; } @@ -311,8 +307,10 @@ // character tables. int32_t character = -1; if (keystroke.IsDeadKey() || keystroke.IsComposeKey()) { - tree_index += 2 * data_->tree[tree_index] + 1; // internal unicode table - tree_index += 2 * data_->tree[tree_index] + 1; // leaf unicode table + tree_index += 2 * UNSAFE_TODO(data_->tree[tree_index]) + + 1; // internal unicode table + tree_index += + 2 * UNSAFE_TODO(data_->tree[tree_index]) + 1; // leaf unicode table // The generate_character_composer_data.py script assigns 0 to the Compose // key. character = keystroke.IsComposeKey() @@ -326,7 +324,7 @@ // Check the internal subtree table. uint16_t result = 0; - uint16_t entries = data_->tree[tree_index++]; + uint16_t entries = UNSAFE_TODO(data_->tree[tree_index++]); if (entries && Find(tree_index, entries, static_cast<uint16_t>(character), &result)) { tree_index = result; @@ -335,7 +333,7 @@ // Skip over the internal subtree table and check the leaf table. tree_index += 2 * entries; - entries = data_->tree[tree_index++]; + entries = UNSAFE_TODO(data_->tree[tree_index++]); if (entries && Find(tree_index, entries, static_cast<uint16_t>(character), &result)) { *composed_character = result; @@ -358,8 +356,8 @@ } }; const TableEntry* a = - reinterpret_cast<const TableEntry*>(&data_->tree[index]); - const TableEntry* z = a + size; + reinterpret_cast<const TableEntry*>(&UNSAFE_TODO(data_->tree[index])); + const TableEntry* z = UNSAFE_TODO(a + size); const TableEntry target = {key, 0}; const TableEntry* it = std::lower_bound(a, z, target); if ((it != z) && (it->key == key)) {
diff --git a/ui/base/ime/character_composer_unittest.cc b/ui/base/ime/character_composer_unittest.cc index 00f55ff..949b91f 100644 --- a/ui/base/ime/character_composer_unittest.cc +++ b/ui/base/ime/character_composer_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/ime/character_composer.h" #include <stdint.h> @@ -14,6 +9,7 @@ #include <memory> #include <string> +#include "base/compiler_specific.h" #include "base/containers/contains.h" #include "base/strings/utf_string_conversions.h" #include "testing/gtest/include/gtest/gtest.h" @@ -389,11 +385,11 @@ subtrees.push_back(index); for (int t = 0; t < kTypes; ++t) { // Skip the internal table and verify the next index is within the data. - index += 1 + 2 * kCompositions.tree[index]; + index += 1 + 2 * UNSAFE_TODO(kCompositions.tree[index]); EXPECT_GT(kCompositions.tree_entries, index); // Skip the leaf table and verify that the next index is not past the // end of the data. - index += 1 + 2 * kCompositions.tree[index]; + index += 1 + 2 * UNSAFE_TODO(kCompositions.tree[index]); EXPECT_GE(kCompositions.tree_entries, index); } } @@ -407,11 +403,11 @@ for (int t = 0; t < kTypes; ++t) { // Check the internal subtable. uint16_t previous_key = 0; - uint16_t size = kCompositions.tree[index++]; + uint16_t size = UNSAFE_TODO(kCompositions.tree[index++]); for (uint16_t i = 0; i < size; ++i) { // Verify that the subtable is sorted. - uint16_t key = kCompositions.tree[index]; - uint16_t value = kCompositions.tree[index + 1]; + uint16_t key = UNSAFE_TODO(kCompositions.tree[index]); + uint16_t value = UNSAFE_TODO(kCompositions.tree[index + 1]); if (i) EXPECT_LT(previous_key, key) << index; previous_key = key; @@ -421,10 +417,10 @@ } // Check the leaf subtable. previous_key = 0; - size = kCompositions.tree[index++]; + size = UNSAFE_TODO(kCompositions.tree[index++]); for (uint16_t i = 0; i < size; ++i) { // Verify that the subtable is sorted. - uint16_t key = kCompositions.tree[index]; + uint16_t key = UNSAFE_TODO(kCompositions.tree[index]); if (i) EXPECT_LT(previous_key, key) << index; previous_key = key;
diff --git a/ui/base/ime/linux/composition_text_util_pango.cc b/ui/base/ime/linux/composition_text_util_pango.cc index c114981..db2efe3 100644 --- a/ui/base/ime/linux/composition_text_util_pango.cc +++ b/ui/base/ime/linux/composition_text_util_pango.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/ime/linux/composition_text_util_pango.h" #include <pango/pango-attributes.h> @@ -15,6 +10,7 @@ #include <algorithm> #include <string> +#include "base/compiler_specific.h" #include "base/i18n/char_iterator.h" #include "base/strings/utf_string_conversions.h" #include "ui/base/ime/composition_text.h" @@ -66,8 +62,9 @@ if (start >= end) continue; - start = g_utf8_pointer_to_offset(utf8_text, utf8_text + start); - end = g_utf8_pointer_to_offset(utf8_text, utf8_text + end); + start = + g_utf8_pointer_to_offset(utf8_text, UNSAFE_TODO(utf8_text + start)); + end = g_utf8_pointer_to_offset(utf8_text, UNSAFE_TODO(utf8_text + end)); // Double check, in case |utf8_text| is not a valid utf-8 string. start = std::min(start, char_length);
diff --git a/ui/base/ime/linux/composition_text_util_pango_unittest.cc b/ui/base/ime/linux/composition_text_util_pango_unittest.cc index 73db53e..6c16af1 100644 --- a/ui/base/ime/linux/composition_text_util_pango_unittest.cc +++ b/ui/base/ime/linux/composition_text_util_pango_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/ime/linux/composition_text_util_pango.h" #include <pango/pango-attributes.h> @@ -17,6 +12,7 @@ #include <string> #include <utility> +#include "base/compiler_specific.h" #include "base/notreached.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/composition_text.h" @@ -130,12 +126,12 @@ << " text:" << text); PangoAttrList* pango_attrs = pango_attr_list_new(); - for (size_t a = 0; attrs[a].type; ++a) { + for (size_t a = 0; UNSAFE_TODO(attrs[a]).type; ++a) { PangoAttribute* pango_attr = NULL; - switch (attrs[a].type) { + switch (UNSAFE_TODO(attrs[a]).type) { case PANGO_ATTR_UNDERLINE: pango_attr = pango_attr_underline_new( - static_cast<PangoUnderline>(attrs[a].value)); + static_cast<PangoUnderline>(UNSAFE_TODO(attrs[a]).value)); break; case PANGO_ATTR_BACKGROUND: pango_attr = pango_attr_background_new(0, 0, 0); @@ -144,9 +140,11 @@ NOTREACHED(); } pango_attr->start_index = - g_utf8_offset_to_pointer(text, attrs[a].start_offset) - text; + g_utf8_offset_to_pointer(text, UNSAFE_TODO(attrs[a]).start_offset) - + text; pango_attr->end_index = - g_utf8_offset_to_pointer(text, attrs[a].end_offset) - text; + g_utf8_offset_to_pointer(text, UNSAFE_TODO(attrs[a]).end_offset) - + text; pango_attr_list_insert(pango_attrs, pango_attr); } @@ -154,11 +152,12 @@ ui::ExtractCompositionTextFromGtkPreedit(text, pango_attrs, 0, &result); const ImeTextSpan* ime_text_spans = kTestData[i].ime_text_spans; - for (size_t u = 0; - ime_text_spans[u].underline_color && u < result.ime_text_spans.size(); + for (size_t u = 0; UNSAFE_TODO(ime_text_spans[u]).underline_color && + u < result.ime_text_spans.size(); ++u) { SCOPED_TRACE(testing::Message() << "ImeTextSpan:" << u); - CompareImeTextSpan(ime_text_spans[u], result.ime_text_spans[u]); + CompareImeTextSpan(UNSAFE_TODO(ime_text_spans[u]), + result.ime_text_spans[u]); } pango_attr_list_unref(pango_attrs);
diff --git a/ui/base/nine_image_painter_factory.cc b/ui/base/nine_image_painter_factory.cc index 7bf28719..f1962a7 100644 --- a/ui/base/nine_image_painter_factory.cc +++ b/ui/base/nine_image_painter_factory.cc
@@ -2,15 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/nine_image_painter_factory.h" #include <stddef.h> +#include "base/compiler_specific.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/nine_image_painter.h" @@ -23,8 +19,9 @@ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); std::vector<gfx::ImageSkia> images(9); for (size_t i = 0; i < 9; ++i) { - if (image_ids[i] != 0) - images[i] = *rb.GetImageSkiaNamed(image_ids[i]); + if (UNSAFE_TODO(image_ids[i]) != 0) { + images[i] = *rb.GetImageSkiaNamed(UNSAFE_TODO(image_ids[i])); + } } return images; }
diff --git a/ui/base/pointer/touch_ui_controller.cc b/ui/base/pointer/touch_ui_controller.cc index 85e98c6..31fc04a 100644 --- a/ui/base/pointer/touch_ui_controller.cc +++ b/ui/base/pointer/touch_ui_controller.cc
@@ -80,14 +80,14 @@ #if BUILDFLAG(IS_WIN) -void RecordDevicePostureModeOnStartup(bool tablet_mode) { +void RecordPostureModeOnStartup(bool tablet_mode) { base::UmaHistogramEnumeration("Touch.DevicePosture.Startup", tablet_mode ? TouchUiController::PostureMode::kTablet : TouchUiController::PostureMode::kDesktop); } -void RecordDevicePostureModeOnSwitch(bool tablet_mode) { +void RecordPostureModeOnSwitch(bool tablet_mode) { base::UmaHistogramEnumeration("Touch.DevicePosture.Switch", tablet_mode ? TouchUiController::PostureMode::kTablet @@ -149,14 +149,17 @@ } // namespace TouchUiController::TouchUiScoperForTesting::TouchUiScoperForTesting( - bool enabled, + bool touch_ui_enabled, + bool tablet_mode_enabled, TouchUiController* controller) : controller_(controller), - old_state_(controller_->SetTouchUiState( - enabled ? TouchUiState::kEnabled : TouchUiState::kDisabled)) {} + old_ui_state_(controller_->SetTouchUiState( + touch_ui_enabled ? TouchUiState::kEnabled : TouchUiState::kDisabled)), + old_tablet_mode_(controller_->SetTabletMode(tablet_mode_enabled)) {} TouchUiController::TouchUiScoperForTesting::~TouchUiScoperForTesting() { - controller_->SetTouchUiState(old_state_); + controller_->SetTouchUiState(old_ui_state_); + controller_->SetTabletMode(old_tablet_mode_); } void TouchUiController::TouchUiScoperForTesting::UpdateState(bool enabled) { @@ -164,6 +167,11 @@ : TouchUiState::kDisabled); } +void TouchUiController::TouchUiScoperForTesting::UpdateTabletMode( + bool enabled) { + controller_->SetTabletMode(enabled); +} + // static TouchUiController* TouchUiController::Get() { static base::NoDestructor<TouchUiController> instance([] { @@ -216,14 +224,18 @@ void TouchUiController::OnTabletModeToggled(bool enabled) { #if BUILDFLAG(IS_WIN) - if (tablet_mode_ != enabled) { - RecordDevicePostureModeOnSwitch(enabled); - } + const bool was_tablet_mode = tablet_mode_; #endif // BUILDFLAG(IS_WIN) const bool was_touch_ui = touch_ui(); tablet_mode_ = enabled; - if (touch_ui() != was_touch_ui) + if (touch_ui() != was_touch_ui) { TouchUiChanged(); + } +#if BUILDFLAG(IS_WIN) + if (tablet_mode_ != was_tablet_mode) { + TabletModeChanged(); + } +#endif // BUILDFLAG(IS_WIN) } #if BUILDFLAG(IS_WIN) @@ -235,6 +247,7 @@ } void TouchUiController::SetInitialTabletMode(bool enabled) { + const bool was_tablet_mode = tablet_mode_; const bool was_touch_ui = touch_ui(); tablet_mode_ = enabled; // Unconditionally record the histogram following discovery of the initial @@ -247,22 +260,33 @@ // Notify observers only if the mode has changed. if (touch_ui() != was_touch_ui) { TRACE_EVENT0("ui", "TouchUiController.NotifyListeners"); - callback_list_.Notify(); + touch_mode_callback_list_.Notify(); } const auto& convertibility_enabled = base::win::GetConvertibilityEnabledOverride(); if (!convertibility_enabled || *convertibility_enabled) { - RecordDevicePostureModeOnStartup(enabled); + RecordPostureModeOnStartup(enabled); + // Notify observers only if the posture mode has changed. + if (tablet_mode_ != was_tablet_mode) { + tablet_mode_callback_list_.Notify(); + } } } #endif // BUILDFLAG(IS_WIN) base::CallbackListSubscription TouchUiController::RegisterCallback( const base::RepeatingClosure& closure) { - return callback_list_.Add(closure); + return touch_mode_callback_list_.Add(closure); } +#if BUILDFLAG(IS_WIN) +base::CallbackListSubscription TouchUiController::RegisterTabletModeCallback( + const base::RepeatingClosure& closure) { + return tablet_mode_callback_list_.Add(closure); +} +#endif // BUILDFLAG(IS_WIN) + TouchUiController::TouchUiState TouchUiController::SetTouchUiState( TouchUiState touch_ui_state) { const bool was_touch_ui = touch_ui(); @@ -272,6 +296,17 @@ return old_state; } +bool TouchUiController::SetTabletMode(bool tablet_mode_enabled) { + const bool was_tablet_mode = tablet_mode_; + tablet_mode_ = tablet_mode_enabled; +#if BUILDFLAG(IS_WIN) + if (tablet_mode_ != was_tablet_mode) { + TabletModeChanged(); + } +#endif // BUILDFLAG(IS_WIN) + return was_tablet_mode; +} + void TouchUiController::TouchUiChanged() { if (touch_ui()) RecordEnteredTouchMode(); @@ -279,9 +314,16 @@ RecordEnteredNonTouchMode(); TRACE_EVENT0("ui", "TouchUiController.NotifyListeners"); - callback_list_.Notify(); + touch_mode_callback_list_.Notify(); } +#if BUILDFLAG(IS_WIN) +void TouchUiController::TabletModeChanged() { + RecordPostureModeOnSwitch(tablet_mode()); + tablet_mode_callback_list_.Notify(); +} +#endif // BUILDFLAG(IS_WIN) + #if BUILDFLAG(USE_BLINK) void TouchUiController::OnPointerDeviceConnected(PointerDevice::Key key) { if (const std::optional<PointerDevice> device = GetPointerDevice(key)) {
diff --git a/ui/base/pointer/touch_ui_controller.h b/ui/base/pointer/touch_ui_controller.h index 2fe30e9..43f7727c 100644 --- a/ui/base/pointer/touch_ui_controller.h +++ b/ui/base/pointer/touch_ui_controller.h
@@ -29,7 +29,10 @@ // Central controller to handle touch UI modes. class COMPONENT_EXPORT(UI_BASE) TouchUiController { public: - using CallbackList = base::RepeatingClosureList; + using TouchModeCallbackList = base::RepeatingClosureList; +#if BUILDFLAG(IS_WIN) + using TabletModeCallbackList = base::RepeatingClosureList; +#endif // BUILDFLAG(IS_WIN) enum class TouchUiState { kDisabled, @@ -48,7 +51,8 @@ class COMPONENT_EXPORT(UI_BASE) TouchUiScoperForTesting { public: - explicit TouchUiScoperForTesting(bool enabled, + explicit TouchUiScoperForTesting(bool touch_ui_enabled, + bool tablet_mode_enabled = false, TouchUiController* controller = Get()); TouchUiScoperForTesting(const TouchUiScoperForTesting&) = delete; TouchUiScoperForTesting& operator=(const TouchUiScoperForTesting&) = delete; @@ -58,10 +62,12 @@ // original state at destruction. Allows a test to change the mode // multiple times without creating multiple instances. void UpdateState(bool enabled); + void UpdateTabletMode(bool enabled); private: const raw_ptr<TouchUiController> controller_; - const TouchUiState old_state_; + const TouchUiState old_ui_state_; + const bool old_tablet_mode_; }; static TouchUiController* Get(); @@ -78,9 +84,18 @@ ((touch_ui_state_ == TouchUiState::kAuto) && tablet_mode_); } +#if BUILDFLAG(IS_WIN) + bool tablet_mode() const { return tablet_mode_; } +#endif // BUILDFLAG(IS_WIN) + base::CallbackListSubscription RegisterCallback( const base::RepeatingClosure& closure); +#if BUILDFLAG(IS_WIN) + base::CallbackListSubscription RegisterTabletModeCallback( + const base::RepeatingClosure& closure); +#endif // BUILDFLAG(IS_WIN) + void OnTabletModeToggled(bool enabled); #if BUILDFLAG(IS_WIN) // Check whether a device is in tablet or desktop mode in a threadpool thread, @@ -95,6 +110,7 @@ protected: TouchUiState SetTouchUiState(TouchUiState touch_ui_state); + bool SetTabletMode(bool enable_tablet_mode); #if BUILDFLAG(USE_BLINK) virtual int MaxTouchPoints() const; @@ -107,12 +123,14 @@ private: void TouchUiChanged(); +#if BUILDFLAG(IS_WIN) + void TabletModeChanged(); // Records whether the user has entered touch mode and runs callbacks // if touch mode has initially been detected. void SetInitialTabletMode(bool enabled); - - bool tablet_mode_ = false; +#endif // BUILDFLAG(IS_WIN) TouchUiState touch_ui_state_; + bool tablet_mode_ = false; #if BUILDFLAG(USE_BLINK) void OnInitializePointerDevices(); @@ -121,9 +139,10 @@ #if BUILDFLAG(IS_WIN) std::unique_ptr<gfx::SingletonHwndObserver> singleton_hwnd_observer_; + TabletModeCallbackList tablet_mode_callback_list_; #endif - CallbackList callback_list_; + TouchModeCallbackList touch_mode_callback_list_; base::WeakPtrFactory<TouchUiController> weak_factory_{this}; };
diff --git a/ui/base/pointer/touch_ui_controller_unittest.cc b/ui/base/pointer/touch_ui_controller_unittest.cc index 45a44ac43..d3f21cd 100644 --- a/ui/base/pointer/touch_ui_controller_unittest.cc +++ b/ui/base/pointer/touch_ui_controller_unittest.cc
@@ -131,14 +131,14 @@ histogram_tester.ExpectBucketCount(kStartup, PostureMode::kDesktop, 1); histogram_tester.ExpectBucketCount(kStartup, PostureMode::kTablet, 0); - // Verify the tablet switch happens when the device posture mode - // changes from desktop to tablet. + // Verify the tablet switch histogram happens when the device posture + // mode changes from desktop to tablet. controller.OnTabletModeToggled(true); histogram_tester.ExpectBucketCount(kSwitch, PostureMode::kTablet, 1); histogram_tester.ExpectBucketCount(kSwitch, PostureMode::kDesktop, 0); - // Verify the desktop switch happens when the device posture mode - // changes from tablet to desktop. + // Verify the desktop switch histogram happens when the device posture + // mode changes from tablet to desktop. controller.OnTabletModeToggled(false); histogram_tester.ExpectBucketCount(kSwitch, PostureMode::kDesktop, 1); histogram_tester.ExpectBucketCount(kSwitch, PostureMode::kTablet, 1);
diff --git a/ui/base/resource/scoped_file_writer.cc b/ui/base/resource/scoped_file_writer.cc index 3cca5f0..45097d8 100644 --- a/ui/base/resource/scoped_file_writer.cc +++ b/ui/base/resource/scoped_file_writer.cc
@@ -2,13 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/base/resource/scoped_file_writer.h" +#include "base/compiler_specific.h" #include "base/files/file_util.h" #include "base/logging.h" @@ -31,7 +27,7 @@ if (!data_size) return; - if (valid_ && fwrite(data, data_size, 1, file_) != 1) { + if (valid_ && UNSAFE_TODO(fwrite(data, data_size, 1, file_)) != 1) { PLOG(ERROR) << "Could not write to pak file"; valid_ = false; }
diff --git a/ui/base/text/bytes_formatting.cc b/ui/base/text/bytes_formatting.cc index f1a16d67..8361484 100644 --- a/ui/base/text/bytes_formatting.cc +++ b/ui/base/text/bytes_formatting.cc
@@ -2,16 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/text/bytes_formatting.h" #include <ostream> #include "base/check.h" +#include "base/compiler_specific.h" #include "base/i18n/number_formatting.h" #include "base/notreached.h" #include "base/strings/string_util.h" @@ -61,7 +57,7 @@ std::u16string result = base::FormatDouble(unit_amount, fractional_digits); if (show_units) - result = l10n_util::GetStringFUTF16(suffix[units], result); + result = l10n_util::GetStringFUTF16(UNSAFE_TODO(suffix[units]), result); return result; } @@ -85,8 +81,9 @@ int unit_index = std::size(kUnitThresholds); while (--unit_index > 0) { - if (bytes >= kUnitThresholds[unit_index]) + if (bytes >= UNSAFE_TODO(kUnitThresholds[unit_index])) { break; + } } DCHECK(unit_index >= DATA_UNITS_BYTE && unit_index <= DATA_UNITS_PEBIBYTE);
diff --git a/ui/base/x/selection_owner.cc b/ui/base/x/selection_owner.cc index d106cb0..7ae2ba1b 100644 --- a/ui/base/x/selection_owner.cc +++ b/ui/base/x/selection_owner.cc
@@ -2,15 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/x/selection_owner.h" #include <algorithm> +#include "base/compiler_specific.h" #include "base/logging.h" #include "base/memory/ref_counted_memory.h" #include "ui/base/x/selection_utils.h" @@ -259,7 +255,8 @@ } } else { auto& mem = it->second; - std::vector<uint8_t> data(mem->data(), mem->data() + mem->size()); + std::vector<uint8_t> data(mem->data(), + UNSAFE_TODO(mem->data() + mem->size())); connection_->SetArrayProperty(requestor, property, target, data); } return true; @@ -273,8 +270,8 @@ void SelectionOwner::ProcessIncrementalTransfer(IncrementalTransfer* transfer) { size_t remaining = transfer->data->size() - transfer->offset; size_t chunk_length = std::min(remaining, GetMaxIncrementalTransferSize()); - const uint8_t* data = transfer->data->data() + transfer->offset; - std::vector<uint8_t> buf(data, data + chunk_length); + const uint8_t* data = UNSAFE_TODO(transfer->data->data() + transfer->offset); + std::vector<uint8_t> buf(data, UNSAFE_TODO(data + chunk_length)); connection_->SetArrayProperty(transfer->window, transfer->property, transfer->target, buf); transfer->offset += chunk_length;
diff --git a/ui/base/x/selection_requestor.cc b/ui/base/x/selection_requestor.cc index 601203b..dc2ef3a5 100644 --- a/ui/base/x/selection_requestor.cc +++ b/ui/base/x/selection_requestor.cc
@@ -2,15 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/x/selection_requestor.h" #include <algorithm> +#include "base/compiler_specific.h" #include "base/memory/ref_counted_memory.h" #include "ui/base/x/selection_owner.h" #include "ui/base/x/selection_utils.h" @@ -38,7 +34,7 @@ std::vector<uint8_t> combined; combined.reserve(bytes); for (const auto& datum : data) { - std::copy(datum->data(), datum->data() + datum->size(), + std::copy(datum->data(), UNSAFE_TODO(datum->data() + datum->size()), std::back_inserter(combined)); } return combined;
diff --git a/ui/base/x/x11_clipboard_helper.cc b/ui/base/x/x11_clipboard_helper.cc index 8e531b0c..6d83ea9d 100644 --- a/ui/base/x/x11_clipboard_helper.cc +++ b/ui/base/x/x11_clipboard_helper.cc
@@ -2,16 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/x/x11_clipboard_helper.h" #include <string> #include <vector> +#include "base/compiler_specific.h" #include "base/containers/contains.h" #include "base/feature_list.h" #include "base/memory/ref_counted_memory.h" @@ -335,9 +331,9 @@ // Some apps return an |out_type| of "TARGETS". (crbug.com/377893) if (out_type == x11::Atom::ATOM || out_type == x11::GetAtom(kTargets)) { const x11::Atom* atom_array = - reinterpret_cast<const x11::Atom*>(data.data()); + UNSAFE_TODO(reinterpret_cast<const x11::Atom*>(data.data())); for (size_t i = 0; i < data.size() / sizeof(x11::Atom); ++i) { - out.push_back(atom_array[i]); + out.push_back(UNSAFE_TODO(atom_array[i])); } } } else {
diff --git a/ui/base/x/x11_display_util.cc b/ui/base/x/x11_display_util.cc index 3576e11..c8eff585 100644 --- a/ui/base/x/x11_display_util.cc +++ b/ui/base/x/x11_display_util.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/x/x11_display_util.h" #include <dlfcn.h> @@ -20,6 +15,7 @@ #include "base/bits.h" #include "base/command_line.h" +#include "base/compiler_specific.h" #include "base/containers/flat_map.h" #include "base/logging.h" #include "base/notimplemented.h" @@ -79,7 +75,8 @@ return gfx::Rect(); } const uint32_t* value = response->value->cast_to<uint32_t>(); - return gfx::Rect(value[0], value[1], value[2], value[3]); + return gfx::Rect(value[0], UNSAFE_TODO(value[1]), UNSAFE_TODO(value[2]), + UNSAFE_TODO(value[3])); } x11::Future<x11::GetPropertyReply> GetIccProfileFuture(
diff --git a/ui/base/x/x11_software_bitmap_presenter.cc b/ui/base/x/x11_software_bitmap_presenter.cc index dbd19e5..2b4b600 100644 --- a/ui/base/x/x11_software_bitmap_presenter.cc +++ b/ui/base/x/x11_software_bitmap_presenter.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/base/x/x11_software_bitmap_presenter.h" #include <stddef.h> @@ -17,6 +12,7 @@ #include <memory> #include <utility> +#include "base/compiler_specific.h" #include "base/functional/bind.h" #include "base/logging.h" #include "base/memory/raw_ptr.h" @@ -124,9 +120,10 @@ } canvas.drawImage(fg_bitmap.asImage(), 0, 0); - connection->PutImage( - {x11::ImageFormat::ZPixmap, widget, gc, w_u16, h_u16, x_i16, y_i16, 0, - d_u8, x11::SizedRefCountedMemory::From(bg, size_t{w_u16} * h_u16)}); + connection->PutImage({x11::ImageFormat::ZPixmap, widget, gc, w_u16, h_u16, + x_i16, y_i16, 0, d_u8, + UNSAFE_TODO(x11::SizedRefCountedMemory::From( + bg, size_t{w_u16} * h_u16))}); return true; }
diff --git a/ui/base/x/x11_workspace_handler.cc b/ui/base/x/x11_workspace_handler.cc index 5853e3d..bb48796 100644 --- a/ui/base/x/x11_workspace_handler.cc +++ b/ui/base/x/x11_workspace_handler.cc
@@ -2,13 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/base/x/x11_workspace_handler.h" +#include "base/compiler_specific.h" #include "base/strings/string_number_conversions.h" #include "ui/base/x/x11_util.h" #include "ui/gfx/x/atom_cache.h" @@ -70,7 +66,7 @@ DCHECK_EQ(response->type, static_cast<x11::Atom>(x11::Atom::CARDINAL)); uint32_t workspace; - memcpy(&workspace, response->value->bytes(), 4); + UNSAFE_TODO(memcpy(&workspace, response->value->bytes(), 4)); workspace_ = base::NumberToString(workspace); delegate_->OnCurrentWorkspaceChanged(workspace_); }
diff --git a/ui/color/sys_color_mixer_unittest.cc b/ui/color/sys_color_mixer_unittest.cc index c9b711a..82fcb7c 100644 --- a/ui/color/sys_color_mixer_unittest.cc +++ b/ui/color/sys_color_mixer_unittest.cc
@@ -2,15 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/color/sys_color_mixer.h" #include <tuple> +#include "base/compiler_specific.h" #include "base/strings/stringprintf.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/color/color_mixer.h" @@ -66,11 +62,11 @@ }; for (const ColorId* ids : minimum_visible_contrasting_ids) { - check_sufficient_contrast(ids[0], ids[1], + check_sufficient_contrast(ids[0], UNSAFE_TODO(ids[1]), color_utils::kMinimumVisibleContrastRatio); } for (const ColorId* ids : minimum_readable_contrasting_ids) { - check_sufficient_contrast(ids[0], ids[1], + check_sufficient_contrast(ids[0], UNSAFE_TODO(ids[1]), color_utils::kMinimumReadableContrastRatio); } }
diff --git a/ui/display/mojom/display_mojom_traits_unittest.cc b/ui/display/mojom/display_mojom_traits_unittest.cc index 8811c474..6a39614 100644 --- a/ui/display/mojom/display_mojom_traits_unittest.cc +++ b/ui/display/mojom/display_mojom_traits_unittest.cc
@@ -2,16 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif +#include "ui/display/mojom/display_mojom_traits.h" #include <memory> #include <string> #include <utility> #include <vector> +#include "base/compiler_specific.h" #include "mojo/public/cpp/base/file_path_mojom_traits.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/display.h" @@ -21,7 +19,6 @@ #include "ui/display/mojom/display_color_management_mojom_traits.h" #include "ui/display/mojom/display_layout_mojom_traits.h" #include "ui/display/mojom/display_mode_mojom_traits.h" -#include "ui/display/mojom/display_mojom_traits.h" #include "ui/display/mojom/display_snapshot.mojom.h" #include "ui/display/mojom/display_snapshot_mojom_traits.h" #include "ui/display/mojom/gamma_ramp_rgb_entry.mojom.h" @@ -299,8 +296,9 @@ SerializeAndDeserialize<mojom::ColorCalibration>(input, &output); // Validate `srgb_to_device_matrix`. - EXPECT_EQ(0, memcmp(&input.srgb_to_device_matrix, - &output.srgb_to_device_matrix, sizeof(skcms_Matrix3x3))); + UNSAFE_TODO(EXPECT_EQ( + 0, memcmp(&input.srgb_to_device_matrix, &output.srgb_to_device_matrix, + sizeof(skcms_Matrix3x3)))); // Validate `srgb_to_linear`. input.srgb_to_linear.Evaluate(0.5f, in_r, in_g, in_b); @@ -324,8 +322,8 @@ ColorTemperatureAdjustment output; SerializeAndDeserialize<mojom::ColorTemperatureAdjustment>(input, &output); - EXPECT_EQ(0, memcmp(&input.srgb_matrix, &output.srgb_matrix, - sizeof(skcms_Matrix3x3))); + UNSAFE_TODO(EXPECT_EQ(0, memcmp(&input.srgb_matrix, &output.srgb_matrix, + sizeof(skcms_Matrix3x3)))); } TEST(DisplayStructTraitsTest, GammaAdjustmentRoundtrip) {
diff --git a/ui/display/types/display_color_management.cc b/ui/display/types/display_color_management.cc index 3493aa6..5548e06 100644 --- a/ui/display/types/display_color_management.cc +++ b/ui/display/types/display_color_management.cc
@@ -2,19 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/display/types/display_color_management.h" +#include <cmath> + #include "base/check.h" +#include "base/compiler_specific.h" #include "base/notreached.h" #include "base/strings/stringprintf.h" -#include <cmath> - namespace display { namespace { @@ -149,7 +145,7 @@ void GammaCurve::Evaluate(float rgb[3]) const { for (size_t c = 0; c < 3; ++c) { - rgb[c] = Evaluate(rgb[c], c); + UNSAFE_TODO(rgb[c]) = Evaluate(UNSAFE_TODO(rgb[c]), c); } }
diff --git a/ui/display/util/edid_parser_unittest.cc b/ui/display/util/edid_parser_unittest.cc index 7feb6ea..fb02786 100644 --- a/ui/display/util/edid_parser_unittest.cc +++ b/ui/display/util/edid_parser_unittest.cc
@@ -2,17 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/display/util/edid_parser.h" #include <stdint.h> #include <memory> +#include "base/compiler_specific.h" #include "base/containers/flat_set.h" #include "base/hash/md5.h" #include "base/numerics/ranges.h" @@ -884,7 +880,7 @@ EDIDParserTest() : parser_(std::vector<uint8_t>( GetParam().edid_blob, - GetParam().edid_blob + GetParam().edid_blob_length)) {} + UNSAFE_TODO(GetParam().edid_blob + GetParam().edid_blob_length))) {} EDIDParserTest(const EDIDParserTest&) = delete; EDIDParserTest& operator=(const EDIDParserTest&) = delete; @@ -894,7 +890,8 @@ TEST_P(EDIDParserTest, ParseEdids) { std::vector<uint8_t> expected_edid( - GetParam().edid_blob, GetParam().edid_blob + GetParam().edid_blob_length); + GetParam().edid_blob, + UNSAFE_TODO(GetParam().edid_blob + GetParam().edid_blob_length)); EXPECT_EQ(parser_.edid_blob(), expected_edid); EXPECT_EQ(parser_.manufacturer_id(), GetParam().manufacturer_id);
diff --git a/ui/events/event_dispatcher_unittest.cc b/ui/events/event_dispatcher_unittest.cc index 74a15de..6de964b 100644 --- a/ui/events/event_dispatcher_unittest.cc +++ b/ui/events/event_dispatcher_unittest.cc
@@ -2,17 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/events/event_dispatcher.h" #include <memory> #include <utility> #include "base/check.h" +#include "base/compiler_specific.h" #include "base/memory/raw_ptr.h" #include "base/notreached.h" #include "testing/gtest/include/gtest/gtest.h" @@ -260,9 +256,9 @@ { int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; - EXPECT_EQ( + UNSAFE_TODO(EXPECT_EQ( std::vector<int>(expected, expected + sizeof(expected) / sizeof(int)), - child.handler_list()); + child.handler_list())); } child.Reset(); @@ -278,9 +274,9 @@ // |h1| marks the event as handled. So only the pre-target handlers should // receive the event. int expected[] = { 1, 2, 3, 4 }; - EXPECT_EQ( + UNSAFE_TODO(EXPECT_EQ( std::vector<int>(expected, expected + sizeof(expected) / sizeof(int)), - child.handler_list()); + child.handler_list())); } child.Reset(); @@ -294,9 +290,9 @@ EXPECT_EQ(EP_POSTDISPATCH, mouse.phase()); EXPECT_TRUE(mouse.stopped_propagation()); EXPECT_TRUE(mouse.handled()); - EXPECT_EQ( + UNSAFE_TODO(EXPECT_EQ( std::vector<int>(nexpected, nexpected + sizeof(nexpected) / sizeof(int)), - child.handler_list()); + child.handler_list())); child.Reset(); event_mod.set_phase(EP_PREDISPATCH); @@ -308,9 +304,8 @@ EXPECT_EQ(EP_POSTDISPATCH, mouse.phase()); EXPECT_TRUE(mouse.stopped_propagation()); EXPECT_TRUE(mouse.handled()); - EXPECT_EQ( - std::vector<int>(exp, exp + sizeof(exp) / sizeof(int)), - child.handler_list()); + UNSAFE_TODO(EXPECT_EQ(std::vector<int>(exp, exp + sizeof(exp) / sizeof(int)), + child.handler_list())); parent.RemovePreTargetHandler(&h1); parent.RemovePreTargetHandler(&h2); @@ -338,9 +333,9 @@ EXPECT_EQ(ER_UNHANDLED, mouse.result()); int handlers[] = { 11, 11 }; - EXPECT_EQ( + UNSAFE_TODO(EXPECT_EQ( std::vector<int>(handlers, handlers + sizeof(handlers) / sizeof(int)), - target.handler_list()); + target.handler_list())); target.RemovePreTargetHandler(&handler); }
diff --git a/ui/events/event_modifiers.cc b/ui/events/event_modifiers.cc index 1c8dfbe..3699e47 100644 --- a/ui/events/event_modifiers.cc +++ b/ui/events/event_modifiers.cc
@@ -2,15 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/events/event_modifiers.h" #include <array> +#include "base/compiler_specific.h" #include "ui/events/event.h" #include "ui/events/event_constants.h" @@ -38,9 +34,9 @@ } // namespace EventModifiers::EventModifiers() { - memset( - modifiers_down_.data(), 0, - (modifiers_down_.size() * sizeof(decltype(modifiers_down_)::value_type))); + UNSAFE_TODO(memset(modifiers_down_.data(), 0, + (modifiers_down_.size() * + sizeof(decltype(modifiers_down_)::value_type)))); } EventModifiers::~EventModifiers() {}
diff --git a/ui/events/gesture_event_details.cc b/ui/events/gesture_event_details.cc index 99d9320c..704286dc 100644 --- a/ui/events/gesture_event_details.cc +++ b/ui/events/gesture_event_details.cc
@@ -2,16 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/events/gesture_event_details.h" #include <ostream> #include "base/check_op.h" +#include "base/compiler_specific.h" #include "base/notreached.h" #include "base/types/cxx23_to_underlying.h" @@ -108,7 +104,7 @@ } GestureEventDetails::Details::Details() { - memset(this, 0, sizeof(Details)); + UNSAFE_TODO(memset(this, 0, sizeof(Details))); } } // namespace ui
diff --git a/ui/events/keycodes/dom/keycode_converter_unittest.cc b/ui/events/keycodes/dom/keycode_converter_unittest.cc index 1fe219ff..c32cb3fd 100644 --- a/ui/events/keycodes/dom/keycode_converter_unittest.cc +++ b/ui/events/keycodes/dom/keycode_converter_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/events/keycodes/dom/keycode_converter.h" #include <stddef.h> @@ -17,6 +12,7 @@ #include <map> #include <set> +#include "base/compiler_specific.h" #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/events/keycodes/dom/dom_code.h" @@ -128,7 +124,7 @@ size_t numEntries = ui::KeycodeConverter::NumKeycodeMapEntriesForTest(); for (size_t i = 0; i < numEntries; ++i) { - const ui::KeycodeMapEntry* entry = &keycode_map[i]; + const ui::KeycodeMapEntry* entry = &UNSAFE_TODO(keycode_map[i]); // Don't test keys with no native keycode mapping on this platform. if (entry->native_keycode == ui::KeycodeConverter::InvalidNativeKeycode()) continue; @@ -172,7 +168,7 @@ size_t numEntries = ui::KeycodeConverter::NumKeycodeMapEntriesForTest(); for (size_t i = 0; i < numEntries; ++i) { SCOPED_TRACE(i); - const ui::KeycodeMapEntry* entry = &keycode_map[i]; + const ui::KeycodeMapEntry* entry = &UNSAFE_TODO(keycode_map[i]); if (entry->code) { ui::DomCode code = ui::KeycodeConverter::CodeStringToDomCode(entry->code); EXPECT_STREQ(entry->code,
diff --git a/ui/events/ozone/device/udev/device_manager_udev.cc b/ui/events/ozone/device/udev/device_manager_udev.cc index 6748f42..1d2cef7 100644 --- a/ui/events/ozone/device/udev/device_manager_udev.cc +++ b/ui/events/ozone/device/udev/device_manager_udev.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/events/ozone/device/udev/device_manager_udev.h" #include <stddef.h> @@ -15,6 +10,7 @@ #include <memory> #include <string> +#include "base/compiler_specific.h" #include "base/logging.h" #include "base/observer_list.h" #include "base/strings/stringprintf.h" @@ -139,9 +135,11 @@ std::string_view path(path_cstr); DeviceEvent::DeviceType device_type; - if (!strcmp(subsystem, "input") && path.starts_with("/dev/input/event")) { + if (!UNSAFE_TODO(strcmp(subsystem, "input")) && + path.starts_with("/dev/input/event")) { device_type = DeviceEvent::INPUT; - } else if (!strcmp(subsystem, "drm") && path.starts_with("/dev/dri/card")) { + } else if (!UNSAFE_TODO(strcmp(subsystem, "drm")) && + path.starts_with("/dev/dri/card")) { device_type = DeviceEvent::DISPLAY; } else { return nullptr; @@ -149,14 +147,15 @@ const char* action = device::udev_device_get_action(device); DeviceEvent::ActionType action_type; - if (!action || !strcmp(action, "add")) + if (!action || !UNSAFE_TODO(strcmp(action, "add"))) { action_type = DeviceEvent::ADD; - else if (!strcmp(action, "remove")) + } else if (!UNSAFE_TODO(strcmp(action, "remove"))) { action_type = DeviceEvent::REMOVE; - else if (!strcmp(action, "change")) + } else if (!UNSAFE_TODO(strcmp(action, "change"))) { action_type = DeviceEvent::CHANGE; - else + } else { return nullptr; + } PropertyMap property_map; udev_list_entry* property_list =
diff --git a/ui/events/ozone/evdev/event_device_test_util.cc b/ui/events/ozone/evdev/event_device_test_util.cc index 8d54fe7..aa6dfa7 100644 --- a/ui/events/ozone/evdev/event_device_test_util.cc +++ b/ui/events/ozone/evdev/event_device_test_util.cc
@@ -2,15 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/events/ozone/evdev/event_device_test_util.h" #include <stdint.h> +#include "base/compiler_specific.h" #include "base/format_macros.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" @@ -33,8 +29,8 @@ std::string ret; for (int i = EVDEV_BITS_TO_GROUPS(max) - 1; i >= 0; i--) { - if (bitmap[i] || ret.size()) { - base::StringAppendF(&ret, "%lx", bitmap[i]); + if (UNSAFE_TODO(bitmap[i]) || ret.size()) { + base::StringAppendF(&ret, "%lx", UNSAFE_TODO(bitmap[i])); if (i > 0) ret += " "; @@ -1620,7 +1616,7 @@ devinfo->SetProps(&prop_bits[0], prop_bits.size()); for (size_t i = 0; i < capabilities.abs_axis_count; ++i) { - const DeviceAbsoluteAxis& axis = capabilities.abs_axis[i]; + const DeviceAbsoluteAxis& axis = UNSAFE_TODO(capabilities.abs_axis[i]); devinfo->SetAbsInfo(axis.code, axis.absinfo); } @@ -1637,10 +1633,10 @@ } input_id id = {}; - sscanf(capabilities.vendor, "%" SCNx16, &id.vendor); - sscanf(capabilities.product, "%" SCNx16, &id.product); - sscanf(capabilities.bustype, "%" SCNx16, &id.bustype); - sscanf(capabilities.version, "%" SCNx16, &id.version); + UNSAFE_TODO(sscanf(capabilities.vendor, "%" SCNx16, &id.vendor)); + UNSAFE_TODO(sscanf(capabilities.product, "%" SCNx16, &id.product)); + UNSAFE_TODO(sscanf(capabilities.bustype, "%" SCNx16, &id.bustype)); + UNSAFE_TODO(sscanf(capabilities.version, "%" SCNx16, &id.version)); devinfo->SetId(id); devinfo->SetDeviceType(EventDeviceInfo::GetInputDeviceTypeFromId(id)); devinfo->SetName(capabilities.name);
diff --git a/ui/events/ozone/evdev/gamepad_event_converter_evdev.cc b/ui/events/ozone/evdev/gamepad_event_converter_evdev.cc index c0d08f14..9c4ff9c 100644 --- a/ui/events/ozone/evdev/gamepad_event_converter_evdev.cc +++ b/ui/events/ozone/evdev/gamepad_event_converter_evdev.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/events/ozone/evdev/gamepad_event_converter_evdev.h" #include <errno.h> @@ -15,6 +10,7 @@ #include <stdint.h> #include <sys/ioctl.h> +#include "base/compiler_specific.h" #include "base/logging.h" #include "base/posix/eintr_wrapper.h" #include "base/trace_event/trace_event.h" @@ -126,7 +122,7 @@ uint16_t strong_magnitude, uint16_t weak_magnitude) { struct ff_effect effect; - memset(&effect, 0, sizeof(effect)); + UNSAFE_TODO(memset(&effect, 0, sizeof(effect))); effect.type = FF_RUMBLE; effect.id = effect_id; effect.replay.length = duration; @@ -141,7 +137,7 @@ int effect_id, bool do_start) { struct input_event start_stop; - memset(&start_stop, 0, sizeof(start_stop)); + UNSAFE_TODO(memset(&start_stop, 0, sizeof(start_stop))); start_stop.type = EV_FF; start_stop.code = effect_id; start_stop.value = do_start ? 1 : 0;
diff --git a/ui/events/ozone/evdev/mouse_button_property.cc b/ui/events/ozone/evdev/mouse_button_property.cc index 3be69d6..99a8197 100644 --- a/ui/events/ozone/evdev/mouse_button_property.cc +++ b/ui/events/ozone/evdev/mouse_button_property.cc
@@ -2,17 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/events/ozone/evdev/mouse_button_property.h" #include <cstdint> #include <cstring> #include <optional> +#include "base/compiler_specific.h" #include "ui/events/event.h" namespace ui { @@ -32,14 +28,14 @@ CHECK_LE(iter->second.size(), sizeof(uint32_t)); uint32_t result = 0; - std::memcpy(&result, iter->second.data(), iter->second.size()); + UNSAFE_TODO(std::memcpy(&result, iter->second.data(), iter->second.size())); return result; } void SetForwardBackMouseButtonProperty(Event& event, uint32_t button) { std::vector<uint8_t> buffer; buffer.resize(sizeof(uint32_t)); - std::memcpy(buffer.data(), &button, buffer.size()); + UNSAFE_TODO(std::memcpy(buffer.data(), &button, buffer.size())); Event::Properties properties = event.properties() ? *event.properties() : Event::Properties(); properties.emplace(kForwardBackMouseButtonPropertyName, std::move(buffer));
diff --git a/ui/events/ozone/evdev/stylus_button_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/stylus_button_event_converter_evdev_unittest.cc index cf32685..cf3b899 100644 --- a/ui/events/ozone/evdev/stylus_button_event_converter_evdev_unittest.cc +++ b/ui/events/ozone/evdev/stylus_button_event_converter_evdev_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/events/ozone/evdev/stylus_button_event_converter_evdev.h" #include <errno.h> @@ -19,6 +14,7 @@ #include <utility> #include <vector> +#include "base/compiler_specific.h" #include "base/files/file_util.h" #include "base/files/scoped_file.h" #include "base/functional/bind.h" @@ -120,8 +116,9 @@ struct input_event* queue, long read_this_many, long queue_index) { - int nwrite = HANDLE_EINTR(write(write_pipe_, queue + queue_index, - sizeof(struct input_event) * read_this_many)); + int nwrite = UNSAFE_TODO( + HANDLE_EINTR(write(write_pipe_, queue + queue_index, + sizeof(struct input_event) * read_this_many))); DPCHECK(nwrite == static_cast<int>(sizeof(struct input_event) * read_this_many)) << "write() failed";
diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc index fce291a..0730bf62 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc +++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/events/ozone/evdev/touch_event_converter_evdev.h" #include <errno.h> @@ -19,6 +14,7 @@ #include "ash/constants/ash_features.h" #include "base/command_line.h" +#include "base/compiler_specific.h" #include "base/feature_list.h" #include "base/files/file_util.h" #include "base/files/scoped_file.h" @@ -378,9 +374,9 @@ void MockTouchEventConverterEvdev::ConfigureReadMock(struct input_event* queue, long read_this_many, long queue_index) { - int nwrite = HANDLE_EINTR(write(write_pipe_, - queue + queue_index, - sizeof(struct input_event) * read_this_many)); + int nwrite = UNSAFE_TODO( + HANDLE_EINTR(write(write_pipe_, queue + queue_index, + sizeof(struct input_event) * read_this_many))); DPCHECK(nwrite == static_cast<int>(sizeof(struct input_event) * read_this_many)) << "write() failed"; @@ -440,7 +436,7 @@ void UpdateTime(struct input_event* queue, long count, timeval time) const { for (int i = 0; i < count; ++i) { - queue[i].time = time; + UNSAFE_TODO(queue[i]).time = time; } }
diff --git a/ui/events/ozone/evdev/touch_filter/false_touch_finder_unittest.cc b/ui/events/ozone/evdev/touch_filter/false_touch_finder_unittest.cc index 7d7f708..cbdee72 100644 --- a/ui/events/ozone/evdev/touch_filter/false_touch_finder_unittest.cc +++ b/ui/events/ozone/evdev/touch_filter/false_touch_finder_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/events/ozone/evdev/touch_filter/false_touch_finder.h" #include <stddef.h> @@ -15,6 +10,7 @@ #include <memory> #include "base/command_line.h" +#include "base/compiler_specific.h" #include "base/logging.h" #include "base/strings/stringprintf.h" #include "testing/gtest/include/gtest/gtest.h" @@ -50,7 +46,7 @@ size_t start_index = 0u; std::bitset<kNumTouchEvdevSlots> was_touching; for (size_t i = 0; i < count; ++i) { - const TouchEntry& entry = entries[i]; + const TouchEntry& entry = UNSAFE_TODO(entries[i]); InProgressTouchEvdev touch; touch.x = entry.location.x(); @@ -62,12 +58,14 @@ touch.touching = entry.touching; touches.push_back(touch); - if (i == count - 1 || entry.time_ms != entries[i + 1].time_ms) { + if (i == count - 1 || + entry.time_ms != UNSAFE_TODO(entries[i + 1]).time_ms) { false_touch_finder_->HandleTouches( touches, base::TimeTicks() + base::Milliseconds(entry.time_ms)); for (size_t j = 0; j < touches.size(); ++j) { - bool expect_delay = entries[j + start_index].expect_delay; + bool expect_delay = + UNSAFE_TODO(entries[j + start_index]).expect_delay; size_t slot = touches[j].slot; if (false_touch_finder_->SlotShouldDelay(slot) != expect_delay) { LOG(ERROR) << base::StringPrintf(
diff --git a/ui/events/ozone/layout/keyboard_layout_engine_unittest.cc b/ui/events/ozone/layout/keyboard_layout_engine_unittest.cc index 17d867530..95a73a27 100644 --- a/ui/events/ozone/layout/keyboard_layout_engine_unittest.cc +++ b/ui/events/ozone/layout/keyboard_layout_engine_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ui/events/velocity_tracker/motion_event_generic.cc b/ui/events/velocity_tracker/motion_event_generic.cc index 33f5a0c..716be69 100644 --- a/ui/events/velocity_tracker/motion_event_generic.cc +++ b/ui/events/velocity_tracker/motion_event_generic.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/events/velocity_tracker/motion_event_generic.h" #include <numbers> @@ -14,6 +9,7 @@ #include <utility> #include "base/check_op.h" +#include "base/compiler_specific.h" #include "base/memory/ptr_util.h" #include "base/numerics/angle_conversions.h" #include "ui/events/base_event_utils.h" @@ -286,7 +282,7 @@ void MotionEventGeneric::RemovePointerAt(size_t index) { DCHECK_LT(index, pointers_.size()); - pointers_.erase(pointers_.begin() + index); + pointers_.erase(UNSAFE_TODO(pointers_.begin() + index)); } void MotionEventGeneric::PushHistoricalEvent(
diff --git a/ui/events/velocity_tracker/velocity_tracker.cc b/ui/events/velocity_tracker/velocity_tracker.cc index 3d32ed69..11e51bc 100644 --- a/ui/events/velocity_tracker/velocity_tracker.cc +++ b/ui/events/velocity_tracker/velocity_tracker.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/events/velocity_tracker/velocity_tracker.h" #include <stddef.h> @@ -16,6 +11,7 @@ #include <ostream> #include "base/check_op.h" +#include "base/compiler_specific.h" #include "base/containers/span.h" #include "base/notreached.h" #include "build/build_config.h" @@ -83,8 +79,8 @@ degree = 0; confidence = 0; for (size_t i = 0; i <= kMaxDegree; i++) { - xcoeff[i] = 0; - ycoeff[i] = 0; + UNSAFE_TODO(xcoeff[i]) = 0; + UNSAFE_TODO(ycoeff[i]) = 0; } } }; @@ -92,7 +88,7 @@ float VectorDot(const float* a, const float* b, uint32_t m) { float r = 0; while (m--) { - r += *(a++) * *(b++); + r += *(UNSAFE_TODO(a++)) * *(UNSAFE_TODO(b++)); } return r; } @@ -100,7 +96,7 @@ float VectorNorm(const float* a, uint32_t m) { float r = 0; while (m--) { - float t = *(a++); + float t = *(UNSAFE_TODO(a++)); r += t * t; } return sqrtf(r); @@ -548,14 +544,14 @@ // We just work from bottom-right to top-left calculating B's coefficients. float wy[M_ARRAY_LENGTH]; for (uint32_t h = 0; h < m; h++) { - wy[h] = y[h] * w[h]; + UNSAFE_TODO(wy[h]) = y[h] * w[h]; } for (uint32_t i = n; i-- != 0;) { - out_b[i] = VectorDot(&q[i][0], wy, m); + UNSAFE_TODO(out_b[i]) = VectorDot(&q[i][0], wy, m); for (uint32_t j = n - 1; j > i; j--) { - out_b[i] -= r[i][j] * out_b[j]; + UNSAFE_TODO(out_b[i]) -= r[i][j] * UNSAFE_TODO(out_b[j]); } - out_b[i] /= r[i][i]; + UNSAFE_TODO(out_b[i]) /= r[i][i]; } // Calculate the coefficient of determination as 1 - (SSerr / SStot) where @@ -575,7 +571,7 @@ float term = 1; for (uint32_t i = 1; i < n; i++) { term *= x[h]; - err -= term * out_b[i]; + err -= term * UNSAFE_TODO(out_b[i]); } sserr += w[h] * w[h] * err * err; float var = y[h] - ymean;
diff --git a/ui/gfx/codec/png_codec_unittest.cc b/ui/gfx/codec/png_codec_unittest.cc index 5a4e3882..04debd3 100644 --- a/ui/gfx/codec/png_codec_unittest.cc +++ b/ui/gfx/codec/png_codec_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/gfx/codec/png_codec.h" #include <stddef.h> @@ -19,6 +14,7 @@ #include "base/base_paths.h" #include "base/check.h" +#include "base/compiler_specific.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/logging.h" @@ -143,7 +139,7 @@ std::vector<uint8_t>& v = *static_cast<std::vector<uint8_t>*>(png_get_io_ptr(png_ptr)); v.resize(v.size() + length); - memcpy(&v[v.size() - length], data, length); + UNSAFE_TODO(memcpy(&v[v.size() - length], data, length)); } // User flush function; goes with WriteImageData, above.
diff --git a/ui/gfx/color_space.cc b/ui/gfx/color_space.cc index e5997185..02892e604 100644 --- a/ui/gfx/color_space.cc +++ b/ui/gfx/color_space.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/color_space.h" #include <iomanip> @@ -15,6 +10,7 @@ #include <sstream> #include "base/atomic_sequence_num.h" +#include "base/compiler_specific.h" #include "base/lazy_instance.h" #include "base/logging.h" #include "base/notreached.h" @@ -40,7 +36,7 @@ int n, float tol) { for (int i = 0; i < n; ++i) { - if (std::abs(a[i] - b[i]) > tol) { + if (std::abs(UNSAFE_TODO(a[i]) - UNSAFE_TODO(b[i])) > tol) { return false; } } @@ -194,7 +190,7 @@ } } - memcpy(custom_primary_matrix_, &to_XYZD50, 9 * sizeof(float)); + UNSAFE_TODO(memcpy(custom_primary_matrix_, &to_XYZD50, 9 * sizeof(float))); primaries_ = PrimaryID::CUSTOM; } @@ -273,14 +269,14 @@ return false; } if (primaries_ == PrimaryID::CUSTOM) { - if (memcmp(custom_primary_matrix_, other.custom_primary_matrix_, - sizeof(custom_primary_matrix_))) { + if (UNSAFE_TODO(memcmp(custom_primary_matrix_, other.custom_primary_matrix_, + sizeof(custom_primary_matrix_)))) { return false; } } if (size_t param_count = TransferParamCount(transfer_)) { - if (memcmp(transfer_params_, other.transfer_params_, - param_count * sizeof(float))) { + if (UNSAFE_TODO(memcmp(transfer_params_, other.transfer_params_, + param_count * sizeof(float)))) { return false; } } @@ -363,16 +359,16 @@ return false; if (primaries_ == PrimaryID::CUSTOM) { int primary_result = - memcmp(custom_primary_matrix_, other.custom_primary_matrix_, - sizeof(custom_primary_matrix_)); + UNSAFE_TODO(memcmp(custom_primary_matrix_, other.custom_primary_matrix_, + sizeof(custom_primary_matrix_))); if (primary_result < 0) return true; if (primary_result > 0) return false; } if (size_t param_count = TransferParamCount(transfer_)) { - int transfer_result = memcmp(transfer_params_, other.transfer_params_, - param_count * sizeof(float)); + int transfer_result = UNSAFE_TODO(memcmp( + transfer_params_, other.transfer_params_, param_count * sizeof(float))); if (transfer_result < 0) return true; if (transfer_result > 0) @@ -390,15 +386,15 @@ const uint32_t* params = reinterpret_cast<const uint32_t*>(custom_primary_matrix_); result ^= params[0]; - result ^= params[4]; - result ^= params[8]; + result ^= UNSAFE_TODO(params[4]); + result ^= UNSAFE_TODO(params[8]); } { // Note that |transfer_params_| must be zero when they are unused. const uint32_t* params = reinterpret_cast<const uint32_t*>(transfer_params_); - result ^= params[3]; - result ^= params[6]; + result ^= UNSAFE_TODO(params[3]); + result ^= UNSAFE_TODO(params[6]); } return result; } @@ -552,7 +548,7 @@ GetPrimaryMatrix(&to_XYZD50); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { - to_XYZD50.vals[row][col] *= factor; + UNSAFE_TODO(to_XYZD50.vals[row][col]) *= factor; } } result.SetCustomPrimaries(to_XYZD50); @@ -751,8 +747,10 @@ constexpr float epsilon = 0.001f; for (int r = 0; r < 3; r++) { for (int c = 0; c < 3; c++) { - if (matrix.vals[r][c] < -epsilon || matrix.vals[r][c] > 1 + epsilon) + if (UNSAFE_TODO(matrix.vals[r][c]) < -epsilon || + UNSAFE_TODO(matrix.vals[r][c]) > 1 + epsilon) { return false; + } } } return true; @@ -826,7 +824,7 @@ SkColorSpacePrimaries ColorSpace::GetPrimaries() const { skcms_Matrix3x3 matrix; - memcpy(&matrix, custom_primary_matrix_, 9 * sizeof(float)); + UNSAFE_TODO(memcpy(&matrix, custom_primary_matrix_, 9 * sizeof(float))); return GetColorSpacePrimaries(primaries_, &matrix); } @@ -844,7 +842,7 @@ void ColorSpace::GetPrimaryMatrix(skcms_Matrix3x3* to_XYZD50) const { if (primaries_ == PrimaryID::CUSTOM) { - memcpy(to_XYZD50, custom_primary_matrix_, 9 * sizeof(float)); + UNSAFE_TODO(memcpy(to_XYZD50, custom_primary_matrix_, 9 * sizeof(float))); } else { GetPrimaryMatrix(primaries_, to_XYZD50); }
diff --git a/ui/gfx/color_space_unittest.cc b/ui/gfx/color_space_unittest.cc index 6123257f..daaf53a 100644 --- a/ui/gfx/color_space_unittest.cc +++ b/ui/gfx/color_space_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/color_space.h" #include <algorithm> @@ -14,6 +9,7 @@ #include <cmath> #include <tuple> +#include "base/compiler_specific.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/skia_color_space_util.h" @@ -80,7 +76,7 @@ for (size_t j = 0; j < kNumTestRGBs; ++j) { SkV4 yuv = range_adjust_inv * transfer * test_rgbs[j]; - EXPECT_LT(Diff(yuv, expected_yuvs[i][j]), kEpsilon); + UNSAFE_TODO(EXPECT_LT(Diff(yuv, expected_yuvs[i][j]), kEpsilon)); } } } @@ -171,7 +167,7 @@ for (size_t k = 0; k < kNumTestYUVs; ++k) { SkV4 yuv = range_adjust_inv * test_yuvs[k]; - EXPECT_LT(Diff(yuv, expected_yuvs[i][j][k]), kEpsilon); + UNSAFE_TODO(EXPECT_LT(Diff(yuv, expected_yuvs[i][j][k]), kEpsilon)); } } } @@ -349,7 +345,7 @@ skcms_Matrix3x3 in_m33 = SkNamedGamut::kSRGB; SkM44 m44 = SkM44FromSkcmsMatrix3x3(in_m33); skcms_Matrix3x3 out_m33 = SkcmsMatrix3x3FromSkM44(m44); - EXPECT_EQ(memcmp(&in_m33, &out_m33, sizeof(in_m33)), 0); + UNSAFE_TODO(EXPECT_EQ(memcmp(&in_m33, &out_m33, sizeof(in_m33)), 0)); } } // namespace
diff --git a/ui/gfx/color_transform.cc b/ui/gfx/color_transform.cc index 55168e0..f518975 100644 --- a/ui/gfx/color_transform.cc +++ b/ui/gfx/color_transform.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/color_transform.h" #include <algorithm> @@ -16,6 +11,7 @@ #include <sstream> #include <utility> +#include "base/compiler_specific.h" #include "base/logging.h" #include "base/notreached.h" #include "base/strings/string_number_conversions.h" @@ -246,7 +242,7 @@ size_t num, const ColorTransform::RuntimeOptions& options) const override { for (size_t i = 0; i < num; i++) { - auto& color = colors[i]; + auto& color = UNSAFE_TODO(colors[i]); SkV4 mapped = matrix_.map(color.x(), color.y(), color.z(), 1); color.SetPoint(mapped.x, mapped.y, mapped.z); } @@ -265,7 +261,7 @@ size_t num, const ColorTransform::RuntimeOptions& options) const override { for (size_t i = 0; i < num; i++) { - ColorTransform::TriStim& c = colors[i]; + ColorTransform::TriStim& c = UNSAFE_TODO(colors[i]); if (extended_) { c.set_x(copysign(Evaluate(abs(c.x())), c.x())); c.set_y(copysign(Evaluate(abs(c.y())), c.y())); @@ -454,11 +450,13 @@ ComputeHLGToneMapConstants(options, gamma_minus_one); for (size_t i = 0; i < num; i++) { - float L = kLr * color[i].x() + kLg * color[i].y() + kLb * color[i].z(); + float L = kLr * UNSAFE_TODO(color[i]).x() + + kLg * UNSAFE_TODO(color[i]).y() + + kLb * UNSAFE_TODO(color[i]).z(); if (L > 0.f) { - color[i].Scale(powf(L, gamma_minus_one)); + UNSAFE_TODO(color[i]).Scale(powf(L, gamma_minus_one)); // Scale the result to the full HDR range. - color[i].Scale(dst_max_luminance_relative); + UNSAFE_TODO(color[i]).Scale(dst_max_luminance_relative); } } } @@ -488,9 +486,11 @@ size_t num, const ColorTransform::RuntimeOptions& options) const override { for (size_t i = 0; i < num; i++) { - float L = kLr * color[i].x() + kLg * color[i].y() + kLb * color[i].z(); + float L = kLr * UNSAFE_TODO(color[i]).x() + + kLg * UNSAFE_TODO(color[i]).y() + + kLb * UNSAFE_TODO(color[i]).z(); if (L > 0.f) { - color[i].Scale(powf(L, kGammaMinusOne)); + UNSAFE_TODO(color[i]).Scale(powf(L, kGammaMinusOne)); } } } @@ -513,9 +513,11 @@ ComputeToneMapConstants(options, a, b); for (size_t i = 0; i < num; i++) { - float maximum = std::max({color[i].x(), color[i].y(), color[i].z()}); + float maximum = + std::max({UNSAFE_TODO(color[i]).x(), UNSAFE_TODO(color[i]).y(), + UNSAFE_TODO(color[i]).z()}); if (maximum > 0.f) { - color[i].Scale((1.f + a * maximum) / (1.f + b * maximum)); + UNSAFE_TODO(color[i]).Scale((1.f + a * maximum) / (1.f + b * maximum)); } } } @@ -574,7 +576,7 @@ const ColorTransform::RuntimeOptions& options) const override { const float factor = ComputeNitsToSdrRelativeFactor(options); for (size_t i = 0; i < num; i++) { - color[i].Scale(factor); + UNSAFE_TODO(color[i]).Scale(factor); } } @@ -609,7 +611,7 @@ const ColorTransform::RuntimeOptions& options) const override { const float factor = ComputeSdrRelativeToNitsFactor(options); for (size_t i = 0; i < num; i++) { - color[i].Scale(factor); + UNSAFE_TODO(color[i]).Scale(factor); } }
diff --git a/ui/gfx/font_fallback_linux.cc b/ui/gfx/font_fallback_linux.cc index b83703cd..8a16b16 100644 --- a/ui/gfx/font_fallback_linux.cc +++ b/ui/gfx/font_fallback_linux.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/font_fallback_linux.h" #include <fontconfig/fontconfig.h> @@ -17,6 +12,7 @@ #include <string> #include <string_view> +#include "base/compiler_specific.h" #include "base/containers/lru_cache.h" #include "base/files/file_path.h" #include "base/memory/ptr_util.h" @@ -273,7 +269,7 @@ // Add each potential fallback font returned by font-config to the // set of fallback fonts and keep track of their codepoints coverage. for (int i = 0; i < fonts->nfont; ++i) { - FcPattern* current_font = fonts->fonts[i]; + FcPattern* current_font = UNSAFE_TODO(fonts->fonts[i]); if (!IsValidFontFromPattern(current_font)) continue; @@ -311,7 +307,7 @@ size_t i = 0; while (i < text.length()) { UChar32 c = 0; - U16_NEXT(text.data(), i, text.length(), c); + UNSAFE_TODO(U16_NEXT(text.data(), i, text.length(), c)); if (entry.HasGlyphForCharacter(c)) { ++matching_glyphs; } else { @@ -374,7 +370,7 @@ if (fonts) { std::set<std::string> fallback_names; for (int i = 0; i < fonts->nfont; ++i) { - std::string name_str = GetFontName(fonts->fonts[i]); + std::string name_str = GetFontName(UNSAFE_TODO(fonts->fonts[i])); if (name_str.empty()) continue; @@ -494,7 +490,7 @@ return; for (int i = 0; i < font_set_->nfont; ++i) { - FcPattern* pattern = font_set_->fonts[i]; + FcPattern* pattern = UNSAFE_TODO(font_set_->fonts[i]); if (!IsValidFontFromPattern(pattern)) continue;
diff --git a/ui/gfx/geometry/axis_transform2d_unittest.cc b/ui/gfx/geometry/axis_transform2d_unittest.cc index 4c46d38b..5e73300d 100644 --- a/ui/gfx/geometry/axis_transform2d_unittest.cc +++ b/ui/gfx/geometry/axis_transform2d_unittest.cc
@@ -2,13 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/geometry/axis_transform2d.h" +#include "base/compiler_specific.h" #include "base/strings/stringprintf.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/decomposed_transform.h" @@ -116,7 +112,7 @@ for (double* entry : entries) { const float mv = entry[0]; - const float factor = entry[1]; + const float factor = UNSAFE_TODO(entry[1]); auto is_valid_point = [&](const PointF& p) -> bool { return std::isfinite(p.x()) && std::isfinite(p.y());
diff --git a/ui/gfx/geometry/matrix3_f.cc b/ui/gfx/geometry/matrix3_f.cc index d3fcd88b..8738ef6 100644 --- a/ui/gfx/geometry/matrix3_f.cc +++ b/ui/gfx/geometry/matrix3_f.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/geometry/matrix3_f.h" #include <string.h> @@ -15,6 +10,7 @@ #include <cmath> #include <limits> +#include "base/compiler_specific.h" #include "base/strings/stringprintf.h" namespace { @@ -38,16 +34,21 @@ // This routine is separated from the Matrix3F::Determinant because in // computing inverse we do want higher precision afforded by the explicit // use of 'double'. - return - static_cast<double>(data[M00]) * ( - static_cast<double>(data[M11]) * data[M22] - - static_cast<double>(data[M12]) * data[M21]) + - static_cast<double>(data[M01]) * ( - static_cast<double>(data[M12]) * data[M20] - - static_cast<double>(data[M10]) * data[M22]) + - static_cast<double>(data[M02]) * ( - static_cast<double>(data[M10]) * data[M21] - - static_cast<double>(data[M11]) * data[M20]); + return static_cast<double>(UNSAFE_TODO(data[M00])) * + (static_cast<double>(UNSAFE_TODO(data[M11])) * + UNSAFE_TODO(data[M22]) - + static_cast<double>(UNSAFE_TODO(data[M12])) * + UNSAFE_TODO(data[M21])) + + static_cast<double>(UNSAFE_TODO(data[M01])) * + (static_cast<double>(UNSAFE_TODO(data[M12])) * + UNSAFE_TODO(data[M20]) - + static_cast<double>(UNSAFE_TODO(data[M10])) * + UNSAFE_TODO(data[M22])) + + static_cast<double>(UNSAFE_TODO(data[M02])) * + (static_cast<double>(UNSAFE_TODO(data[M10])) * + UNSAFE_TODO(data[M21]) - + static_cast<double>(UNSAFE_TODO(data[M11])) * + UNSAFE_TODO(data[M20])); } } // namespace @@ -91,8 +92,9 @@ } bool Matrix3F::IsEqual(const Matrix3F& rhs) const { - return 0 == memcmp(data_.data(), rhs.data_.data(), - (data_.size() * sizeof(decltype(data_)::value_type))); + return 0 == UNSAFE_TODO( + memcmp(data_.data(), rhs.data_.data(), + (data_.size() * sizeof(decltype(data_)::value_type)))); } bool Matrix3F::IsNear(const Matrix3F& rhs, float precision) const {
diff --git a/ui/gfx/geometry/matrix44.cc b/ui/gfx/geometry/matrix44.cc index b9ffe42aa..18ced76 100644 --- a/ui/gfx/geometry/matrix44.cc +++ b/ui/gfx/geometry/matrix44.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/geometry/matrix44.h" #include <algorithm> @@ -14,6 +9,7 @@ #include <type_traits> #include <utility> +#include "base/compiler_specific.h" #include "base/containers/span.h" #include "ui/gfx/geometry/decomposed_transform.h" @@ -109,12 +105,12 @@ void Matrix44::GetColMajor(double dst[16]) const { const double* src = &matrix_[0][0]; - std::copy(src, src + 16, dst); + std::copy(src, UNSAFE_TODO(src + 16), dst); } void Matrix44::GetColMajorF(float dst[16]) const { const double* src = &matrix_[0][0]; - std::copy(src, src + 16, dst); + std::copy(src, UNSAFE_TODO(src + 16), dst); } void Matrix44::PreTranslate(double dx, double dy) { @@ -157,7 +153,7 @@ SetCol(3, Col(3) + t); } else { for (int i = 0; i < 4; ++i) - SetCol(i, Col(i) + t * matrix_[i][3]); + SetCol(i, Col(i) + t * UNSAFE_TODO(matrix_[i])[3]); } }
diff --git a/ui/gfx/geometry/rrect_f.cc b/ui/gfx/geometry/rrect_f.cc index de93533..fd9ecc4 100644 --- a/ui/gfx/geometry/rrect_f.cc +++ b/ui/gfx/geometry/rrect_f.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/geometry/rrect_f.h" #include <array>
diff --git a/ui/gfx/geometry/skia_conversions.cc b/ui/gfx/geometry/skia_conversions.cc index eddda9a..9b611f9 100644 --- a/ui/gfx/geometry/skia_conversions.cc +++ b/ui/gfx/geometry/skia_conversions.cc
@@ -2,16 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/geometry/skia_conversions.h" #include <stddef.h> #include <stdint.h> +#include "base/compiler_specific.h" #include "base/numerics/safe_conversions.h" #include "base/numerics/safe_math.h" #include "ui/gfx/geometry/axis_transform2d.h" @@ -89,9 +85,9 @@ void QuadFToSkPoints(const QuadF& quad, SkPoint points[4]) { points[0] = PointFToSkPoint(quad.p1()); - points[1] = PointFToSkPoint(quad.p2()); - points[2] = PointFToSkPoint(quad.p3()); - points[3] = PointFToSkPoint(quad.p4()); + UNSAFE_TODO(points[1]) = PointFToSkPoint(quad.p2()); + UNSAFE_TODO(points[2]) = PointFToSkPoint(quad.p3()); + UNSAFE_TODO(points[3]) = PointFToSkPoint(quad.p4()); } SkMatrix AxisTransform2dToSkMatrix(const AxisTransform2d& transform) {
diff --git a/ui/gfx/geometry/transform.cc b/ui/gfx/geometry/transform.cc index b4ab4fd..cae45ba 100644 --- a/ui/gfx/geometry/transform.cc +++ b/ui/gfx/geometry/transform.cc
@@ -2,17 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/geometry/transform.h" #include <array> #include <ostream> #include "base/check_op.h" +#include "base/compiler_specific.h" #include "base/containers/span.h" #include "base/notreached.h" #include "base/numerics/angle_conversions.h" @@ -60,11 +56,14 @@ template <typename T> void AxisTransform2dToColMajor(const AxisTransform2d& axis_2d, T a[16]) { a[0] = axis_2d.scale().x(); - a[5] = axis_2d.scale().y(); - a[12] = axis_2d.translation().x(); - a[13] = axis_2d.translation().y(); - a[1] = a[2] = a[3] = a[4] = a[6] = a[7] = a[8] = a[9] = a[11] = a[14] = 0; - a[10] = a[15] = 1; + UNSAFE_TODO(a[5]) = axis_2d.scale().y(); + UNSAFE_TODO(a[12]) = axis_2d.translation().x(); + UNSAFE_TODO(a[13]) = axis_2d.translation().y(); + UNSAFE_TODO(a[1]) = UNSAFE_TODO(a[2]) = UNSAFE_TODO(a[3]) = + UNSAFE_TODO(a[4]) = UNSAFE_TODO(a[6]) = UNSAFE_TODO(a[7]) = + UNSAFE_TODO(a[8]) = UNSAFE_TODO(a[9]) = UNSAFE_TODO(a[11]) = + UNSAFE_TODO(a[14]) = 0; + UNSAFE_TODO(a[10]) = UNSAFE_TODO(a[15]) = 1; } } // namespace @@ -114,13 +113,21 @@ // static Transform Transform::ColMajorF(const float a[16]) { - if (AllTrue(Float4{a[1], a[2], a[3], a[4]} == Float4{0, 0, 0, 0} & - Float4{a[6], a[7], a[8], a[9]} == Float4{0, 0, 0, 0} & - Float4{a[10], a[11], a[14], a[15]} == Float4{1, 0, 0, 1})) { - return Transform(a[0], a[5], a[12], a[13]); + if (AllTrue(Float4{UNSAFE_TODO(a[1]), UNSAFE_TODO(a[2]), UNSAFE_TODO(a[3]), + UNSAFE_TODO(a[4])} == Float4{0, 0, 0, 0} & + Float4{UNSAFE_TODO(a[6]), UNSAFE_TODO(a[7]), UNSAFE_TODO(a[8]), + UNSAFE_TODO(a[9])} == Float4{0, 0, 0, 0} & + Float4{UNSAFE_TODO(a[10]), UNSAFE_TODO(a[11]), UNSAFE_TODO(a[14]), + UNSAFE_TODO(a[15])} == Float4{1, 0, 0, 1})) { + return Transform(a[0], UNSAFE_TODO(a[5]), UNSAFE_TODO(a[12]), + UNSAFE_TODO(a[13])); } - return Transform(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], - a[10], a[11], a[12], a[13], a[14], a[15]); + return Transform(a[0], UNSAFE_TODO(a[1]), UNSAFE_TODO(a[2]), + UNSAFE_TODO(a[3]), UNSAFE_TODO(a[4]), UNSAFE_TODO(a[5]), + UNSAFE_TODO(a[6]), UNSAFE_TODO(a[7]), UNSAFE_TODO(a[8]), + UNSAFE_TODO(a[9]), UNSAFE_TODO(a[10]), UNSAFE_TODO(a[11]), + UNSAFE_TODO(a[12]), UNSAFE_TODO(a[13]), UNSAFE_TODO(a[14]), + UNSAFE_TODO(a[15])); } void Transform::GetColMajor(double a[16]) const {
diff --git a/ui/gfx/geometry/transform_unittest.cc b/ui/gfx/geometry/transform_unittest.cc index 9df58f4..642e358 100644 --- a/ui/gfx/geometry/transform_unittest.cc +++ b/ui/gfx/geometry/transform_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/geometry/transform.h" #include <stddef.h> @@ -18,6 +13,7 @@ #include <optional> #include <ostream> +#include "base/compiler_specific.h" #include "base/containers/span.h" #include "base/numerics/angle_conversions.h" #include "base/strings/stringprintf.h" @@ -1642,7 +1638,7 @@ composed.GetColMajorF(actual); double sse = 0; for (int i = 0; i < 16; i++) { - double diff = expected[i] - actual[i]; + double diff = UNSAFE_TODO(expected[i]) - UNSAFE_TODO(actual[i]); sse += diff * diff; } return sse; @@ -2037,7 +2033,7 @@ float data1[16]; transform.GetColMajorF(data1); for (int i = 0; i < 16; i++) - EXPECT_EQ(data1[i], data[i]); + UNSAFE_TODO(EXPECT_EQ(data1[i], data[i])); EXPECT_EQ(transform, Transform::ColMajorF(data1)); } @@ -3926,7 +3922,7 @@ for (double* entry : entries) { const float mv = entry[0]; - const float factor = entry[1]; + const float factor = UNSAFE_TODO(entry[1]); auto is_valid_point = [&](const PointF& p) -> bool { return std::isfinite(p.x()) && std::isfinite(p.y());
diff --git a/ui/gfx/half_float.cc b/ui/gfx/half_float.cc index fad7661..e32e5cf 100644 --- a/ui/gfx/half_float.cc +++ b/ui/gfx/half_float.cc
@@ -2,15 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/half_float.h" #include <cstring> +#include "base/compiler_specific.h" #include "base/containers/span.h" namespace gfx { @@ -25,7 +21,7 @@ for (size_t i = 0; i < spanification_suspected_redundant_num; i++) { float tmp = input[i] * 1.9259299444e-34f; uint32_t tmp2; - std::memcpy(&tmp2, &tmp, 4); + UNSAFE_TODO(std::memcpy(&tmp2, &tmp, 4)); tmp2 += (1 << 12); output[i] = (tmp2 & 0x80000000UL) >> 16 | (tmp2 >> 13); }
diff --git a/ui/gfx/icc_profile.cc b/ui/gfx/icc_profile.cc index 5c1b3c0..01f69bd 100644 --- a/ui/gfx/icc_profile.cc +++ b/ui/gfx/icc_profile.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/icc_profile.h" #include <array> @@ -14,6 +9,7 @@ #include <set> #include "base/command_line.h" +#include "base/compiler_specific.h" #include "base/containers/lru_cache.h" #include "base/logging.h" #include "base/no_destructor.h" @@ -153,7 +149,7 @@ // static ICCProfile ICCProfile::FromData(const void* data_as_void, size_t size) { const char* data_as_byte = reinterpret_cast<const char*>(data_as_void); - std::vector<char> data(data_as_byte, data_as_byte + size); + std::vector<char> data(data_as_byte, UNSAFE_TODO(data_as_byte + size)); base::AutoLock lock(GetIccProfileLock());
diff --git a/ui/gfx/icc_profile_unittest.cc b/ui/gfx/icc_profile_unittest.cc index 597bec202..d920623 100644 --- a/ui/gfx/icc_profile_unittest.cc +++ b/ui/gfx/icc_profile_unittest.cc
@@ -2,12 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/icc_profile.h" + +#include "base/compiler_specific.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/color_space.h" #include "ui/gfx/skia_color_space_util.h" @@ -112,7 +109,7 @@ std::vector<char> bad_data(10 * 1024); const char* bad_data_string = "deadbeef"; for (size_t i = 0; i < bad_data.size(); ++i) - bad_data[i] = bad_data_string[i % 8]; + bad_data[i] = UNSAFE_TODO(bad_data_string[i % 8]); ICCProfile garbage_profile = ICCProfile::FromData(bad_data.data(), bad_data.size()); EXPECT_FALSE(garbage_profile.IsValid());
diff --git a/ui/gfx/image/buffer_w_stream.cc b/ui/gfx/image/buffer_w_stream.cc index 40804d3..62db9b7 100644 --- a/ui/gfx/image/buffer_w_stream.cc +++ b/ui/gfx/image/buffer_w_stream.cc
@@ -2,15 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/image/buffer_w_stream.h" #include <utility> +#include "base/compiler_specific.h" + namespace gfx { BufferWStream::BufferWStream() = default; @@ -23,7 +20,7 @@ bool BufferWStream::write(const void* buffer, size_t size) { const uint8_t* bytes = reinterpret_cast<const uint8_t*>(buffer); - result_.insert(result_.end(), bytes, bytes + size); + result_.insert(result_.end(), bytes, UNSAFE_TODO(bytes + size)); return true; }
diff --git a/ui/gfx/ipc/geometry/gfx_param_traits.cc b/ui/gfx/ipc/geometry/gfx_param_traits.cc index c8bcb760..aadd7c0 100644 --- a/ui/gfx/ipc/geometry/gfx_param_traits.cc +++ b/ui/gfx/ipc/geometry/gfx_param_traits.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/ipc/geometry/gfx_param_traits.h" #include <stddef.h> @@ -14,6 +9,7 @@ #include <string> +#include "base/compiler_specific.h" #include "base/strings/stringprintf.h" #include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/rect.h" @@ -99,10 +95,11 @@ if (!iter->ReadBytes(&char_values, sizeof(int) * 2)) return false; const int* values = reinterpret_cast<const int*>(char_values); - if (values[0] < 0 || values[1] < 0) + if (values[0] < 0 || UNSAFE_TODO(values[1]) < 0) { return false; + } r->set_width(values[0]); - r->set_height(values[1]); + r->set_height(UNSAFE_TODO(values[1])); return true; } @@ -123,7 +120,7 @@ return false; const float* values = reinterpret_cast<const float*>(char_values); r->set_width(values[0]); - r->set_height(values[1]); + r->set_height(UNSAFE_TODO(values[1])); return true; } @@ -145,7 +142,7 @@ return false; const int* values = reinterpret_cast<const int*>(char_values); r->set_x(values[0]); - r->set_y(values[1]); + r->set_y(UNSAFE_TODO(values[1])); return true; } @@ -167,7 +164,7 @@ return false; const float* values = reinterpret_cast<const float*>(char_values); r->set_x(values[0]); - r->set_y(values[1]); + r->set_y(UNSAFE_TODO(values[1])); return true; } @@ -187,9 +184,11 @@ if (!iter->ReadBytes(&char_values, sizeof(int) * 4)) return false; const int* values = reinterpret_cast<const int*>(char_values); - if (values[2] < 0 || values[3] < 0) + if (UNSAFE_TODO(values[2]) < 0 || UNSAFE_TODO(values[3]) < 0) { return false; - r->SetRect(values[0], values[1], values[2], values[3]); + } + r->SetRect(values[0], UNSAFE_TODO(values[1]), UNSAFE_TODO(values[2]), + UNSAFE_TODO(values[3])); return true; } @@ -210,7 +209,8 @@ if (!iter->ReadBytes(&char_values, sizeof(float) * 4)) return false; const float* values = reinterpret_cast<const float*>(char_values); - r->SetRect(values[0], values[1], values[2], values[3]); + r->SetRect(values[0], UNSAFE_TODO(values[1]), UNSAFE_TODO(values[2]), + UNSAFE_TODO(values[3])); return true; }
diff --git a/ui/gfx/ipc/skia/gfx_skia_param_traits.cc b/ui/gfx/ipc/skia/gfx_skia_param_traits.cc index c2f50a16..f1fc154b 100644 --- a/ui/gfx/ipc/skia/gfx_skia_param_traits.cc +++ b/ui/gfx/ipc/skia/gfx_skia_param_traits.cc
@@ -2,23 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/gfx/ipc/skia/gfx_skia_param_traits.h" #include <string> +#include "base/compiler_specific.h" #include "base/pickle.h" #include "ipc/ipc_message_utils.h" +// Generate param traits write methods. +#include "ipc/param_traits_write_macros.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "ui/gfx/geometry/transform.h" - -// Generate param traits write methods. -#include "ipc/param_traits_write_macros.h" namespace IPC { #undef UI_GFX_IPC_SKIA_GFX_SKIA_PARAM_TRAITS_MACROS_H_ #include "ui/gfx/ipc/skia/gfx_skia_param_traits_macros.h" @@ -90,7 +85,7 @@ if (bitmap_data_size != r->computeByteSize()) return false; - memcpy(r->getPixels(), bitmap_data, bitmap_data_size); + UNSAFE_TODO(memcpy(r->getPixels(), bitmap_data, bitmap_data_size)); return true; }
diff --git a/ui/gfx/nine_image_painter.cc b/ui/gfx/nine_image_painter.cc index 35f9b94..d6d0fabc 100644 --- a/ui/gfx/nine_image_painter.cc +++ b/ui/gfx/nine_image_painter.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/nine_image_painter.h" #include <stddef.h> @@ -14,6 +9,7 @@ #include <array> #include <limits> +#include "base/compiler_specific.h" #include "base/numerics/safe_conversions.h" #include "cc/paint/paint_flags.h" #include "third_party/skia/include/core/SkRect.h" @@ -60,7 +56,7 @@ NineImagePainter::NineImagePainter(const std::vector<ImageSkia>& images) { DCHECK_EQ(std::size(images_), images.size()); for (size_t i = 0; i < std::size(images_); ++i) - images_[i] = images[i]; + UNSAFE_TODO(images_[i]) = images[i]; } NineImagePainter::NineImagePainter(const ImageSkia& image, @@ -70,7 +66,8 @@ DCHECK_EQ(9u, regions.size()); for (size_t i = 0; i < 9; ++i) - images_[i] = ImageSkiaOperations::ExtractSubset(image, regions[i]); + UNSAFE_TODO(images_[i]) = + ImageSkiaOperations::ExtractSubset(image, regions[i]); } NineImagePainter::~NineImagePainter() { @@ -120,7 +117,7 @@ std::array<ImageSkiaRep, 9> image_reps; static_assert(std::size(image_reps) == std::extent<decltype(images_)>(), ""); for (size_t i = 0; i < std::size(image_reps); ++i) { - image_reps[i] = images_[i].GetRepresentation(scale); + image_reps[i] = UNSAFE_TODO(images_[i]).GetRepresentation(scale); DCHECK(image_reps[i].is_null() || image_reps[i].scale() == scale); }
diff --git a/ui/gfx/shadow_value_unittest.cc b/ui/gfx/shadow_value_unittest.cc index 9282a92..0d516275 100644 --- a/ui/gfx/shadow_value_unittest.cc +++ b/ui/gfx/shadow_value_unittest.cc
@@ -2,17 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/shadow_value.h" #include <stddef.h> #include <array> +#include "base/compiler_specific.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/vector2d.h" @@ -71,9 +67,9 @@ }); for (size_t i = 0; i < std::size(kTestCases); ++i) { - Insets margin = ShadowValue::GetMargin( - ShadowValues(kTestCases[i].shadows, - kTestCases[i].shadows + kTestCases[i].shadow_count)); + Insets margin = ShadowValue::GetMargin(ShadowValues( + kTestCases[i].shadows, + UNSAFE_TODO(kTestCases[i].shadows + kTestCases[i].shadow_count))); EXPECT_EQ(kTestCases[i].expected_margin, margin) << " i=" << i; }
diff --git a/ui/gfx/skbitmap_operations.cc b/ui/gfx/skbitmap_operations.cc index a3f1839..3e15462d8 100644 --- a/ui/gfx/skbitmap_operations.cc +++ b/ui/gfx/skbitmap_operations.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/skbitmap_operations.h" #include <stddef.h> @@ -16,6 +11,7 @@ #include <algorithm> #include "base/check_op.h" +#include "base/compiler_specific.h" #include "base/containers/auto_spanification_helper.h" #include "base/containers/span.h" #include "skia/ext/pmcolor_utils.h" @@ -238,8 +234,8 @@ SkPMColor* out, int width) { for (int x = 0; x < width; x++) { - out[x] = SkPreMultiplyColor(color_utils::HSLShift( - SkUnPreMultiply::PMColorToColor(in[x]), hsl_shift)); + UNSAFE_TODO(out[x]) = SkPreMultiplyColor(color_utils::HSLShift( + SkUnPreMultiply::PMColorToColor(UNSAFE_TODO(in[x])), hsl_shift)); } } @@ -251,7 +247,7 @@ DCHECK(hsl_shift.h < 0); DCHECK(hsl_shift.s < 0 || fabs(hsl_shift.s - 0.5) < HSLShift::epsilon); DCHECK(hsl_shift.l < 0 || fabs(hsl_shift.l - 0.5) < HSLShift::epsilon); - memcpy(out, in, static_cast<size_t>(width) * sizeof(out[0])); + UNSAFE_TODO(memcpy(out, in, static_cast<size_t>(width) * sizeof(out[0]))); } // Line processor: H no-op, S no-op, L decrease. @@ -267,14 +263,14 @@ uint32_t ldec_num = static_cast<uint32_t>(hsl_shift.l * 2 * den); for (int x = 0; x < width; x++) { - uint32_t a = SkPMColorGetA(in[x]); - uint32_t r = SkPMColorGetR(in[x]); - uint32_t g = SkPMColorGetG(in[x]); - uint32_t b = SkPMColorGetB(in[x]); + uint32_t a = SkPMColorGetA(UNSAFE_TODO(in[x])); + uint32_t r = SkPMColorGetR(UNSAFE_TODO(in[x])); + uint32_t g = SkPMColorGetG(UNSAFE_TODO(in[x])); + uint32_t b = SkPMColorGetB(UNSAFE_TODO(in[x])); r = r * ldec_num / den; g = g * ldec_num / den; b = b * ldec_num / den; - out[x] = SkPMColorSetARGB(a, r, g, b); + UNSAFE_TODO(out[x]) = SkPMColorSetARGB(a, r, g, b); } } @@ -291,14 +287,14 @@ uint32_t linc_num = static_cast<uint32_t>((hsl_shift.l - 0.5) * 2 * den); for (int x = 0; x < width; x++) { - uint32_t a = SkPMColorGetA(in[x]); - uint32_t r = SkPMColorGetR(in[x]); - uint32_t g = SkPMColorGetG(in[x]); - uint32_t b = SkPMColorGetB(in[x]); + uint32_t a = SkPMColorGetA(UNSAFE_TODO(in[x])); + uint32_t r = SkPMColorGetR(UNSAFE_TODO(in[x])); + uint32_t g = SkPMColorGetG(UNSAFE_TODO(in[x])); + uint32_t b = SkPMColorGetB(UNSAFE_TODO(in[x])); r += (a - r) * linc_num / den; g += (a - g) * linc_num / den; b += (a - b) * linc_num / den; - out[x] = SkPMColorSetARGB(a, r, g, b); + UNSAFE_TODO(out[x]) = SkPMColorSetARGB(a, r, g, b); } } @@ -337,10 +333,10 @@ const int32_t denom = 65536; int32_t s_numer = static_cast<int32_t>(hsl_shift.s * 2 * denom); for (int x = 0; x < width; x++) { - int32_t a = static_cast<int32_t>(SkPMColorGetA(in[x])); - int32_t r = static_cast<int32_t>(SkPMColorGetR(in[x])); - int32_t g = static_cast<int32_t>(SkPMColorGetG(in[x])); - int32_t b = static_cast<int32_t>(SkPMColorGetB(in[x])); + int32_t a = static_cast<int32_t>(SkPMColorGetA(UNSAFE_TODO(in[x]))); + int32_t r = static_cast<int32_t>(SkPMColorGetR(UNSAFE_TODO(in[x]))); + int32_t g = static_cast<int32_t>(SkPMColorGetG(UNSAFE_TODO(in[x]))); + int32_t b = static_cast<int32_t>(SkPMColorGetB(UNSAFE_TODO(in[x]))); int32_t vmax, vmin; if (r > g) { // This uses 3 compares rather than 4. @@ -358,7 +354,7 @@ r = (denom_l + r * s_numer - s_numer_l) / denom; g = (denom_l + g * s_numer - s_numer_l) / denom; b = (denom_l + b * s_numer - s_numer_l) / denom; - out[x] = SkPMColorSetARGB(a, r, g, b); + UNSAFE_TODO(out[x]) = SkPMColorSetARGB(a, r, g, b); } } @@ -376,10 +372,10 @@ int32_t l_numer = static_cast<int32_t>(hsl_shift.l * 2 * denom); int32_t s_numer = static_cast<int32_t>(hsl_shift.s * 2 * denom); for (int x = 0; x < width; x++) { - int32_t a = static_cast<int32_t>(SkPMColorGetA(in[x])); - int32_t r = static_cast<int32_t>(SkPMColorGetR(in[x])); - int32_t g = static_cast<int32_t>(SkPMColorGetG(in[x])); - int32_t b = static_cast<int32_t>(SkPMColorGetB(in[x])); + int32_t a = static_cast<int32_t>(SkPMColorGetA(UNSAFE_TODO(in[x]))); + int32_t r = static_cast<int32_t>(SkPMColorGetR(UNSAFE_TODO(in[x]))); + int32_t g = static_cast<int32_t>(SkPMColorGetG(UNSAFE_TODO(in[x]))); + int32_t b = static_cast<int32_t>(SkPMColorGetB(UNSAFE_TODO(in[x]))); int32_t vmax, vmin; if (r > g) { // This uses 3 compares rather than 4. @@ -397,7 +393,7 @@ r = (denom_l + r * s_numer - s_numer_l) * l_numer / (denom * denom); g = (denom_l + g * s_numer - s_numer_l) * l_numer / (denom * denom); b = (denom_l + b * s_numer - s_numer_l) * l_numer / (denom * denom); - out[x] = SkPMColorSetARGB(a, r, g, b); + UNSAFE_TODO(out[x]) = SkPMColorSetARGB(a, r, g, b); } } @@ -415,10 +411,10 @@ int32_t l_numer = static_cast<int32_t>((hsl_shift.l - 0.5) * 2 * denom); int32_t s_numer = static_cast<int32_t>(hsl_shift.s * 2 * denom); for (int x = 0; x < width; x++) { - int32_t a = static_cast<int32_t>(SkPMColorGetA(in[x])); - int32_t r = static_cast<int32_t>(SkPMColorGetR(in[x])); - int32_t g = static_cast<int32_t>(SkPMColorGetG(in[x])); - int32_t b = static_cast<int32_t>(SkPMColorGetB(in[x])); + int32_t a = static_cast<int32_t>(SkPMColorGetA(UNSAFE_TODO(in[x]))); + int32_t r = static_cast<int32_t>(SkPMColorGetR(UNSAFE_TODO(in[x]))); + int32_t g = static_cast<int32_t>(SkPMColorGetG(UNSAFE_TODO(in[x]))); + int32_t b = static_cast<int32_t>(SkPMColorGetB(UNSAFE_TODO(in[x]))); int32_t vmax, vmin; if (r > g) { // This uses 3 compares rather than 4. @@ -440,7 +436,7 @@ r = (r * denom + (a * denom - r) * l_numer) / (denom * denom); g = (g * denom + (a * denom - g) * l_numer) / (denom * denom); b = (b * denom + (a * denom - b) * l_numer) / (denom * denom); - out[x] = SkPMColorSetARGB(a, r, g, b); + UNSAFE_TODO(out[x]) = SkPMColorSetARGB(a, r, g, b); } } @@ -513,7 +509,7 @@ L_op = HSLShift::kOpLInc; HSLShift::LineProcessor line_proc = - HSLShift::kLineProcessors[H_op][S_op][L_op]; + UNSAFE_TODO(HSLShift::kLineProcessors[H_op][S_op][L_op]); DCHECK(bitmap.empty() == false); DCHECK(bitmap.colorType() == kN32_SkColorType);
diff --git a/ui/gfx/skbitmap_operations_unittest.cc b/ui/gfx/skbitmap_operations_unittest.cc index f1a73b2a..f168b17 100644 --- a/ui/gfx/skbitmap_operations_unittest.cc +++ b/ui/gfx/skbitmap_operations_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/skbitmap_operations.h" #include <stdint.h>
diff --git a/ui/gfx/skia_color_space_util.cc b/ui/gfx/skia_color_space_util.cc index c03ec64..84e85e2 100644 --- a/ui/gfx/skia_color_space_util.cc +++ b/ui/gfx/skia_color_space_util.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/skia_color_space_util.h" #include <algorithm> @@ -14,6 +9,7 @@ #include <vector> #include "base/check.h" +#include "base/compiler_specific.h" namespace gfx { @@ -103,10 +99,11 @@ SkM44 SkM44FromRowMajor3x3(const float* data) { DCHECK(data); // clang-format off - return SkM44(data[0], data[1], data[2], 0, - data[3], data[4], data[5], 0, - data[6], data[7], data[8], 0, - 0, 0, 0, 1); + return SkM44( + data[0], UNSAFE_TODO(data[1]), UNSAFE_TODO(data[2]), 0, + UNSAFE_TODO(data[3]), UNSAFE_TODO(data[4]), UNSAFE_TODO(data[5]), 0, + UNSAFE_TODO(data[6]), UNSAFE_TODO(data[7]), UNSAFE_TODO(data[8]), 0, + 0, 0, 0, 1); // clang-format on }
diff --git a/ui/gfx/skia_util.cc b/ui/gfx/skia_util.cc index d02390b..18a2a537 100644 --- a/ui/gfx/skia_util.cc +++ b/ui/gfx/skia_util.cc
@@ -2,14 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/gfx/skia_util.h" #include "base/check.h" +#include "base/compiler_specific.h" #include "base/numerics/safe_conversions.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -34,7 +30,7 @@ size_t size1 = bitmap1.computeByteSize(); size_t size2 = bitmap2.computeByteSize(); - return (size1 == size2) && (0 == memcmp(addr1, addr2, size1)); + return (size1 == size2) && (0 == UNSAFE_TODO(memcmp(addr1, addr2, size1))); } // We treat HarfBuzz ints as 16.16 fixed-point.
diff --git a/ui/gfx/x/xproto_internal.cc b/ui/gfx/x/xproto_internal.cc index 5310306..4cbc5ff0 100644 --- a/ui/gfx/x/xproto_internal.cc +++ b/ui/gfx/x/xproto_internal.cc
@@ -2,17 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/x/xproto_internal.h" #include <stdint.h> #include <xcb/xcb.h> #include <xcb/xcbext.h> +#include "base/compiler_specific.h" + namespace x11 { MallocedRefCountedMemory::MallocedRefCountedMemory(void* data) @@ -37,11 +34,11 @@ OffsetRefCountedMemory::~OffsetRefCountedMemory() = default; void* OffsetRefCountedMemory::data() { - return memory_->bytes() + offset_; + return UNSAFE_TODO(memory_->bytes() + offset_); } const void* OffsetRefCountedMemory::data() const { - return memory_->bytes() + offset_; + return UNSAFE_TODO(memory_->bytes() + offset_); } UnretainedRefCountedMemory::UnretainedRefCountedMemory(void* data)
diff --git a/ui/gfx/x/xproto_types.cc b/ui/gfx/x/xproto_types.cc index dd8da58..a7495e0 100644 --- a/ui/gfx/x/xproto_types.cc +++ b/ui/gfx/x/xproto_types.cc
@@ -2,15 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/354829279): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gfx/x/xproto_types.h" #include <xcb/xcbext.h> +#include "base/compiler_specific.h" #include "base/memory/scoped_refptr.h" #include "ui/gfx/x/connection.h" #include "ui/gfx/x/xproto_internal.h" @@ -75,7 +71,8 @@ size_t reply_length = 32 + 4 * reply_header->length; // libxcb stores the fds after the reply data. - fds = reinterpret_cast<const int*>(data->bytes() + reply_length); + fds = + reinterpret_cast<const int*>(UNSAFE_TODO(data->bytes() + reply_length)); } }
diff --git a/ui/gl/angle_platform_impl.cc b/ui/gl/angle_platform_impl.cc index 3017fdf..18b191c 100644 --- a/ui/gl/angle_platform_impl.cc +++ b/ui/gl/angle_platform_impl.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/gl/angle_platform_impl.h" #include "base/base64.h"
diff --git a/ui/gtk/gtk_util.cc b/ui/gtk/gtk_util.cc index cef31f8..22eafc1 100644 --- a/ui/gtk/gtk_util.cc +++ b/ui/gtk/gtk_util.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gtk/gtk_util.h" #include <locale.h> @@ -200,7 +195,7 @@ // Callers should have already called setlocale(LC_ALL, "") and // setlocale(LC_NUMERIC, "C") by now. Chrome does this in // service_manager::Main. - DCHECK_EQ(strcmp(setlocale(LC_NUMERIC, nullptr), "C"), 0); + UNSAFE_TODO(DCHECK_EQ(strcmp(setlocale(LC_NUMERIC, nullptr), "C"), 0)); // This prevents GTK from calling setlocale(LC_ALL, ""), which potentially // overwrites the LC_NUMERIC locale to something other than "C". gtk_disable_setlocale(); @@ -327,7 +322,7 @@ long a = 0, r = 0, g = 0, b = 0; unsigned int max_alpha = 0; for (int i = 0; i < width * height; i++) { - SkColor color = data[i]; + SkColor color = UNSAFE_TODO(data[i]); max_alpha = std::max(SkColorGetA(color), max_alpha); a += SkColorGetA(color); r += SkColorGetR(color); @@ -468,7 +463,8 @@ case CSS_PSEUDOCLASS: { GtkStateFlags state_flag = GTK_STATE_FLAG_NORMAL; for (const auto& pseudo_class_entry : pseudo_classes) { - if (strcmp(pseudo_class_entry.name, t.token().c_str()) == 0) { + if (UNSAFE_TODO( + strcmp(pseudo_class_entry.name, t.token().c_str())) == 0) { state_flag = pseudo_class_entry.state_flag; break; }
diff --git a/ui/gtk/nav_button_provider_gtk.cc b/ui/gtk/nav_button_provider_gtk.cc index 243d2b5..527b9a0 100644 --- a/ui/gtk/nav_button_provider_gtk.cc +++ b/ui/gtk/nav_button_provider_gtk.cc
@@ -2,13 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/gtk/nav_button_provider_gtk.h" +#include "base/compiler_specific.h" #include "base/notreached.h" #include "ui/base/glib/glib_cast.h" #include "ui/base/glib/scoped_gobject.h" @@ -118,14 +114,15 @@ auto* node = gtk_snapshot_free_to_node(snapshot); size_t nbytes = width * height * sizeof(SkColor); SkColor* pixels = reinterpret_cast<SkColor*>(g_malloc(nbytes)); - memset(pixels, 0, nbytes); + UNSAFE_TODO(memset(pixels, 0, nbytes)); size_t stride = sizeof(SkColor) * width; if (GdkTexture* texture = GetTextureFromRenderNode(node)) { gdk_texture_download(texture, reinterpret_cast<guchar*>(pixels), stride); } SkColor fg = GtkStyleContextGetColor(button_context); for (int i = 0; i < width * height; ++i) { - pixels[i] = SkColorSetA(fg, SkColorGetA(pixels[i])); + UNSAFE_TODO(pixels[i]) = + SkColorSetA(fg, UNSAFE_TODO(SkColorGetA(pixels[i]))); } icon->texture = TakeGObject( gdk_memory_texture_new(width, height, GDK_MEMORY_B8G8R8A8,
diff --git a/ui/gtk/x/gtk_event_loop_x11.cc b/ui/gtk/x/gtk_event_loop_x11.cc index 1151829..beff418 100644 --- a/ui/gtk/x/gtk_event_loop_x11.cc +++ b/ui/gtk/x/gtk_event_loop_x11.cc
@@ -2,20 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/gtk/gtk_util.h" -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif +#include "ui/gtk/x/gtk_event_loop_x11.h" #include <xcb/xcb.h> #include <xcb/xproto.h> +#include "base/compiler_specific.h" #include "base/functional/bind.h" #include "ui/base/x/x11_util.h" #include "ui/gfx/x/event.h" #include "ui/gtk/gtk_compat.h" -#include "ui/gtk/x/gtk_event_loop_x11.h" +#include "ui/gtk/gtk_util.h" namespace gtk { @@ -58,8 +55,8 @@ GdkKeymapKey keymap_key{0, 0, 0}; if (keys) { for (gint i = 0; i < n_entries; i++) { - if (keyvals[i] == keyval) { - keymap_key = keys[i]; + if (UNSAFE_TODO(keyvals[i]) == keyval) { + keymap_key = UNSAFE_TODO(keys[i]); break; } }
diff --git a/ui/linux/display_server_utils.cc b/ui/linux/display_server_utils.cc index 8895083..4ddbf96 100644 --- a/ui/linux/display_server_utils.cc +++ b/ui/linux/display_server_utils.cc
@@ -125,7 +125,7 @@ MaybeOverrideDefaultAsAuto(command_line); const auto ozone_platform_hint = command_line.GetSwitchValueASCII(switches::kOzonePlatformHint); - if (!ozone_platform_hint.empty()) { + if (!ozone_platform_hint.empty() && ozone_platform_hint != "auto") { command_line.AppendSwitchASCII(switches::kOzonePlatform, MaybeFixPlatformName(ozone_platform_hint)); }
diff --git a/ui/linux/linux_ui.cc b/ui/linux/linux_ui.cc index 3ab395e..d41d350 100644 --- a/ui/linux/linux_ui.cc +++ b/ui/linux/linux_ui.cc
@@ -2,17 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/linux/linux_ui.h" #include <cstdio> #include <utility> #include "base/command_line.h" +#include "base/compiler_specific.h" #include "base/no_destructor.h" #include "build/build_config.h" #include "ui/linux/cursor_theme_manager_observer.h" @@ -95,8 +91,9 @@ char* dst = cmd_line.args.data(); for (const auto& arg : argv) { cmd_line.argv.push_back(dst); - snprintf(dst, &cmd_line.args.back() + 1 - dst, "%s", arg.c_str()); - dst += arg.size() + 1; + UNSAFE_TODO( + snprintf(dst, &cmd_line.args.back() + 1 - dst, "%s", arg.c_str())); + UNSAFE_TODO(dst += arg.size() + 1); } cmd_line.argc = cmd_line.argv.size();
diff --git a/ui/lottie/animation_unittest.cc b/ui/lottie/animation_unittest.cc index 204ed9f4..990285c 100644 --- a/ui/lottie/animation_unittest.cc +++ b/ui/lottie/animation_unittest.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/lottie/animation.h" #include <map> @@ -15,6 +10,7 @@ #include <string_view> #include "base/check.h" +#include "base/compiler_specific.h" #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted_memory.h" #include "base/memory/scoped_refptr.h" @@ -316,7 +312,7 @@ const SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); const int num_pixels = bitmap.width() * bitmap.height(); for (int i = 0; i < num_pixels; i++) - EXPECT_EQ(pixels[i], color); + UNSAFE_TODO(EXPECT_EQ(pixels[i], color)); } else { for (int x = 0; x < bitmap.width(); x++) for (int y = 0; y < bitmap.height(); y++)
diff --git a/ui/ozone/common/gl_surface_egl_readback.cc b/ui/ozone/common/gl_surface_egl_readback.cc index f4926dd9..c8d661c2 100644 --- a/ui/ozone/common/gl_surface_egl_readback.cc +++ b/ui/ozone/common/gl_surface_egl_readback.cc
@@ -2,15 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40285824): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/ozone/common/gl_surface_egl_readback.h" #include <utility> +#include "base/compiler_specific.h" #include "base/functional/bind.h" #include "base/task/single_thread_task_runner.h" #include "ui/gl/gl_bindings.h" @@ -59,7 +55,7 @@ if (!pixels_.empty()) { ReadPixels(pixels_.as_span()); - if (HandlePixels(pixels_.as_span().data())) { + if (UNSAFE_TODO(HandlePixels(pixels_.as_span().data()))) { // Swap is successful, so return SWAP_ACK and provide the current time // with presentation feedback. swap_result = gfx::SwapResult::SWAP_ACK;
diff --git a/ui/ozone/demo/window_manager.cc b/ui/ozone/demo/window_manager.cc index 9aab2239..a4cb84c 100644 --- a/ui/ozone/demo/window_manager.cc +++ b/ui/ozone/demo/window_manager.cc
@@ -2,17 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/ozone/demo/window_manager.h" #include <memory> #include <utility> #include "base/command_line.h" +#include "base/compiler_specific.h" #include "base/functional/bind.h" #include "base/logging.h" #include "base/task/single_thread_task_runner.h" @@ -49,10 +45,10 @@ LOG(WARNING) << "No display delegate; falling back to test window"; int width = kTestWindowWidth; int height = kTestWindowHeight; - sscanf(base::CommandLine::ForCurrentProcess() - ->GetSwitchValueASCII(kWindowSize) - .c_str(), - "%dx%d", &width, &height); + UNSAFE_TODO(sscanf(base::CommandLine::ForCurrentProcess() + ->GetSwitchValueASCII(kWindowSize) + .c_str(), + "%dx%d", &width, &height)); DemoWindow* window = new DemoWindow(this, renderer_factory_.get(), gfx::Rect(gfx::Size(width, height)));
diff --git a/ui/ozone/platform/wayland/common/drm_render_node_path_finder.cc b/ui/ozone/platform/wayland/common/drm_render_node_path_finder.cc index 1a76ad1..f4a732ab 100644 --- a/ui/ozone/platform/wayland/common/drm_render_node_path_finder.cc +++ b/ui/ozone/platform/wayland/common/drm_render_node_path_finder.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/ozone/platform/wayland/common/drm_render_node_path_finder.h" #include <fcntl.h> @@ -17,6 +12,7 @@ #include <vector> #include "base/command_line.h" +#include "base/compiler_specific.h" #include "base/files/scoped_file.h" #include "base/logging.h" #include "base/trace_event/trace_event.h" @@ -64,7 +60,8 @@ } CHECK(device->nodes); - const std::string dri_render_node(device->nodes[DRM_NODE_RENDER]); + const std::string dri_render_node( + UNSAFE_TODO(device->nodes[DRM_NODE_RENDER])); base::ScopedFD drm_fd(open(dri_render_node.c_str(), O_RDWR)); if (drm_fd.get() < 0) { continue;
diff --git a/ui/ozone/platform_selection.cc b/ui/ozone/platform_selection.cc index 7087f69..3b2d828 100644 --- a/ui/ozone/platform_selection.cc +++ b/ui/ozone/platform_selection.cc
@@ -2,14 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/ozone/platform_selection.h" #include "base/command_line.h" +#include "base/compiler_specific.h" #include "base/logging.h" #include "ui/ozone/platform_list.h" #include "ui/ozone/public/ozone_switches.h" @@ -41,7 +37,7 @@ // Search for a matching platform in the list. for (int platform_id = 0; platform_id < kPlatformCount; ++platform_id) { - if (platform_name == kPlatformNames[platform_id]) { + if (platform_name == UNSAFE_TODO(kPlatformNames[platform_id])) { g_selected_platform = platform_id; return g_selected_platform; } @@ -54,7 +50,7 @@ } const char* GetOzonePlatformName() { - return kPlatformNames[GetOzonePlatformId()]; + return UNSAFE_TODO(kPlatformNames[GetOzonePlatformId()]); } } // namespace ui
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.cc b/ui/shell_dialogs/select_file_dialog_linux_portal.cc index 9853bac..54cefe5b 100644 --- a/ui/shell_dialogs/select_file_dialog_linux_portal.cc +++ b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/shell_dialogs/select_file_dialog_linux_portal.h" #include <string_view>
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index 6163e47..78207bda 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -550,6 +550,18 @@ content_window_->SetFillsBoundsCompletely(true); } +Widget::Widgets DesktopNativeWidgetAura::GetOwnedDesktopWidgets() { + Widget::Widgets widgets; + // Adds any Widgets owned by this NativeWidget's tree host. + DesktopWindowTreeHost::WindowTreeHosts owned_tree_hosts = + desktop_window_tree_host_->GetOwnedWindowTreeHosts(); + for (aura::WindowTreeHost* owned_tree_host : owned_tree_hosts) { + widgets.merge( + NativeWidgetPrivate::GetAllOwnedWidgets(owned_tree_host->window())); + } + return widgets; +} + //////////////////////////////////////////////////////////////////////////////// // DesktopNativeWidgetAura, internal::NativeWidgetPrivate implementation: void DesktopNativeWidgetAura::InitNativeWidget(Widget::InitParams params) {
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h index 8d0240e..f739d373 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -117,6 +117,10 @@ // DesktopWindowTreeHost's transparency. void UpdateWindowTransparency(); + // Gets child Widgets with an ownership relationship established at the + // platform window level. Does not include the views::Widget for this. + Widget::Widgets GetOwnedDesktopWidgets(); + base::WeakPtr<internal::NativeWidgetPrivate> GetWeakPtr() override; protected:
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host.cc index 02f6ca0..6cd0402 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host.cc
@@ -13,6 +13,11 @@ namespace views { +DesktopWindowTreeHost::WindowTreeHosts +DesktopWindowTreeHost::GetOwnedWindowTreeHosts() { + return WindowTreeHosts(); +} + bool DesktopWindowTreeHost::IsMoveLoopSupported() const { return true; }
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host.h b/ui/views/widget/desktop_aura/desktop_window_tree_host.h index 9be7cf9..fcc4bc4 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host.h +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host.h
@@ -6,6 +6,7 @@ #define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_H_ #include <memory> +#include <set> #include <string> #include "ui/aura/window_event_dispatcher.h" @@ -48,6 +49,9 @@ class VIEWS_EXPORT DesktopWindowTreeHost { public: + using WindowTreeHosts = + std::set<raw_ptr<aura::WindowTreeHost, SetExperimental>>; + virtual ~DesktopWindowTreeHost() = default; static DesktopWindowTreeHost* Create( @@ -94,6 +98,9 @@ virtual aura::WindowTreeHost* AsWindowTreeHost() = 0; + // Gets all the owned WindowTreeHosts of this host. + virtual WindowTreeHosts GetOwnedWindowTreeHosts(); + // There are two distinct ways for DesktopWindowTreeHosts's to be shown: // 1. This function is called. As this function is specific to // DesktopWindowTreeHost, it is only called from DesktopNativeWidgetAura.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc index da7c545..671960f 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -288,6 +288,19 @@ return this; } +DesktopWindowTreeHost::WindowTreeHosts +DesktopWindowTreeHostWin::GetOwnedWindowTreeHosts() { + WindowTreeHosts window_tree_hosts; + std::vector<HWND> owned_hwns = message_handler_->GetOwnedWindows(); + for (HWND hwnd : owned_hwns) { + if (aura::WindowTreeHost* host = + aura::WindowTreeHost::GetForAcceleratedWidget(hwnd)) { + window_tree_hosts.insert(host); + } + } + return window_tree_hosts; +} + void DesktopWindowTreeHostWin::Show(ui::mojom::WindowShowState show_state, const gfx::Rect& restore_bounds) { OnAcceleratedWidgetMadeVisible(true);
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h index ed45fcb..dcda976 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -106,6 +106,7 @@ void Close() override; void CloseNow() override; aura::WindowTreeHost* AsWindowTreeHost() override; + DesktopWindowTreeHost::WindowTreeHosts GetOwnedWindowTreeHosts() override; void Show(ui::mojom::WindowShowState show_state, const gfx::Rect& restore_bounds) override; bool IsVisible() const override;
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index 0dd1b665..5c15ee47 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc
@@ -1555,6 +1555,17 @@ owned.merge(GetAllOwnedWidgets(transient_child)); } +#if BUILDFLAG(ENABLE_DESKTOP_AURA) + // If the aura::Window is a desktop widget, fetch any additional widgets + // with an ownership relationship established at the platform-window level. + NativeWidgetPrivate* native_widget = + GetNativeWidgetForNativeView(native_view); + if (native_widget && native_widget->IsDesktopNativeWidget()) { + owned.merge(static_cast<DesktopNativeWidgetAura*>(native_widget) + ->GetOwnedDesktopWidgets()); + } +#endif // BUILDFLAG(ENABLE_DESKTOP_AURA) + // Add all child windows. for (aura::Window* child : native_view->children()) { owned.merge(GetAllChildWidgets(child));
diff --git a/ui/wm/core/cursor_util.cc b/ui/wm/core/cursor_util.cc index ed6a458..01ba23b 100644 --- a/ui/wm/core/cursor_util.cc +++ b/ui/wm/core/cursor_util.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/390223051): Remove C-library calls to fix the errors. -#pragma allow_unsafe_libc_calls -#endif - #include "ui/wm/core/cursor_util.h" #include <algorithm> @@ -16,6 +11,7 @@ #include <optional> #include "base/check_op.h" +#include "base/compiler_specific.h" #include "base/containers/contains.h" #include "base/containers/flat_map.h" #include "base/no_destructor.h" @@ -73,7 +69,7 @@ bitmap->reset(); bitmap->allocPixels(image_info); // this memcpy call assumes bitmap->rowBytes() == info_row_bytes - memcpy(bitmap->getPixels(), &buffer[0], buffer.size()); + UNSAFE_TODO(memcpy(bitmap->getPixels(), &buffer[0], buffer.size())); return true; }
diff --git a/ui/wm/core/cursor_util_unittest.cc b/ui/wm/core/cursor_util_unittest.cc index 0cc73c39..81e93a4 100644 --- a/ui/wm/core/cursor_util_unittest.cc +++ b/ui/wm/core/cursor_util_unittest.cc
@@ -2,16 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "ui/wm/core/cursor_util.h" #include <array> #include <optional> +#include "base/compiler_specific.h" #include "base/numerics/safe_conversions.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -121,11 +117,12 @@ test.size[base::checked_cast<int>(size)], scale)); const float resource_scale = ui::GetScaleForResourceScaleFactor( ui::GetSupportedResourceScaleFactorForRescale(scale)); - EXPECT_EQ(pointer_data->hotspot, - gfx::ScaleToFlooredPoint( - test.hotspot[base::checked_cast<int>(size)] - [base::checked_cast<int>(resource_scale) - 1], - scale / resource_scale)); + UNSAFE_TODO(EXPECT_EQ( + pointer_data->hotspot, + gfx::ScaleToFlooredPoint( + test.hotspot[base::checked_cast<int>(size)] + [base::checked_cast<int>(resource_scale) - 1], + scale / resource_scale))); } } }
diff --git a/url/android/test/java/src/org/chromium/url/JUnitTestGURLs.java b/url/android/test/java/src/org/chromium/url/JUnitTestGURLs.java index a153649a..0479f6335 100644 --- a/url/android/test/java/src/org/chromium/url/JUnitTestGURLs.java +++ b/url/android/test/java/src/org/chromium/url/JUnitTestGURLs.java
@@ -34,4 +34,6 @@ public static final GURL GOOGLE_URL_CAT = new GURL("http://www.google.com/cat"); public static final GURL ABOUT_BLANK = new GURL("about:blank"); public static final GURL CHROME_ABOUT = new GURL("chrome://about"); + public static final GURL CHROME_DISTILLER_EXAMPLE_URL = + new GURL("chrome-distiller://abc123/?url=https://www.example.com"); }