diff --git a/DEPS b/DEPS index 7ddfc748677a8c..34e98db2b10a7b 100644 --- a/DEPS +++ b/DEPS @@ -209,7 +209,7 @@ vars = { # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '9d11cbdef8547d33fa4d1dd8bd4a623df9475ecc', + 'skia_revision': 'd8c2750cf607df6b765b1efe51dcb6d90e294cbf', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -280,7 +280,7 @@ vars = { # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'eb5af39fe4ebfa192ad1c4821c6de2bb998de2df', + 'catapult_revision': '09248fe4327ccc493cd70a49f741d044bf33e1be', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -504,7 +504,7 @@ deps = { 'packages': [ { 'package': 'chromium/chrome/test/data/autofill/captured_sites', - 'version': '-vI5CMccdvrghkWJqjvLu9QWqnAvidTWtzK46qs_rdcC', + 'version': 'OokRFv9eH5WdCbodw09oxOP9JdN6GijYpkNbOZRr85UC', } ], 'condition': 'checkout_chromium_autofill_test_dependencies', @@ -1411,7 +1411,7 @@ deps = { 'packages': [ { 'package': 'fuchsia/third_party/aemu/linux-amd64', - 'version': 'cgsZ4Tlh31ekQv6m8-zELPLTF0s9SqAalvHGlmWrlQkC' + 'version': 'I7MELvwpxgQpRokYTSnS20jdXqx9-i_4TFD9QFLyCbEC' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', diff --git a/WATCHLISTS b/WATCHLISTS index 85ec201d9b269e..89fe2d576c896d 100644 --- a/WATCHLISTS +++ b/WATCHLISTS @@ -645,9 +645,7 @@ '|components/test/data/cast_certificate/', }, 'cast_channel': { - 'filepath': 'chrome/test/data/extensions/api_test/cast_channel/' \ - '|components/cast_channel/' \ - '|extensions/browser/api/cast_channel' + 'filepath': 'components/cast_channel/' }, 'cast_streaming': { 'filepath': 'media/cast/' \ diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index e8f1115d2100b8..2383ef42315277 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp @@ -1593,6 +1593,9 @@ Invalid client certificate + + Failed to fetch the SAML redirect URL from the server + diff --git a/chrome/app/chromeos_strings_grdp/IDS_FAILED_TO_FETCH_SAML_REDIRECT.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_FAILED_TO_FETCH_SAML_REDIRECT.png.sha1 new file mode 100644 index 00000000000000..7d77ac00e89433 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_FAILED_TO_FETCH_SAML_REDIRECT.png.sha1 @@ -0,0 +1 @@ +77b71aa7942261bb0f87f6a8a88b5c3c7844437c \ No newline at end of file diff --git a/chrome/browser/ash/login/active_directory_login_browsertest.cc b/chrome/browser/ash/login/active_directory_login_browsertest.cc index 523f56a2970275..2d1bcc70ad172a 100644 --- a/chrome/browser/ash/login/active_directory_login_browsertest.cc +++ b/chrome/browser/ash/login/active_directory_login_browsertest.cc @@ -13,9 +13,11 @@ #include "chrome/browser/ash/login/test/active_directory_login_mixin.h" #include "chrome/browser/ash/login/test/device_state_mixin.h" #include "chrome/browser/ash/login/test/oobe_base_test.h" +#include "chrome/browser/ash/login/test/oobe_screen_waiter.h" #include "chrome/browser/ash/login/test/oobe_screens_utils.h" #include "chrome/browser/ash/login/test/session_manager_state_waiter.h" #include "chrome/browser/ash/login/wizard_controller.h" +#include "chrome/browser/ui/webui/chromeos/login/signin_fatal_error_screen_handler.h" #include "chromeos/dbus/authpolicy/fake_authpolicy_client.h" #include "components/user_manager/user_names.h" #include "content/public/browser/network_service_instance.h" @@ -163,6 +165,10 @@ IN_PROC_BROWSER_TEST_F(ActiveDirectoryLoginTest, LoginErrors) { fake_authpolicy_client()->set_auth_error(authpolicy::ERROR_UNKNOWN); ad_login_.SubmitActiveDirectoryCredentials(test_user_, kPassword); ad_login_.WaitForAuthError(); + + OobeScreenWaiter(SignInFatalErrorView::kScreenId).Wait(); + test::ClickSignInFatalScreenActionButton(); + // Inputs are not invalidated for the unknown error. ad_login_.TestNoError(); ad_login_.TestDomainHidden(); diff --git a/chrome/browser/ash/login/login_browsertest.cc b/chrome/browser/ash/login/login_browsertest.cc index 4c0d857c192085..e3b76a904af301 100644 --- a/chrome/browser/ash/login/login_browsertest.cc +++ b/chrome/browser/ash/login/login_browsertest.cc @@ -25,6 +25,7 @@ #include "chrome/browser/ash/login/test/offline_login_test_mixin.h" #include "chrome/browser/ash/login/test/oobe_base_test.h" #include "chrome/browser/ash/login/test/oobe_screen_waiter.h" +#include "chrome/browser/ash/login/test/oobe_screens_utils.h" #include "chrome/browser/ash/login/test/session_manager_state_waiter.h" #include "chrome/browser/ash/login/test/test_predicate_waiter.h" #include "chrome/browser/ash/login/test/user_adding_screen_utils.h" @@ -142,6 +143,8 @@ IN_PROC_BROWSER_TEST_F(LoginOnlineCryptohomeError, FatalScreenShown) { FakeGaiaMixin::kFakeUserPassword, FakeGaiaMixin::kEmptyUserServices); OobeScreenWaiter(SignInFatalErrorView::kScreenId).Wait(); + test::ClickSignInFatalScreenActionButton(); + OobeScreenWaiter(GaiaView::kScreenId).Wait(); } class LoginOfflineManagedTest : public LoginManagerTest { diff --git a/chrome/browser/ash/login/screens/active_directory_login_screen.cc b/chrome/browser/ash/login/screens/active_directory_login_screen.cc index bafc9d02f15d88..b98ae20d4d5e86 100644 --- a/chrome/browser/ash/login/screens/active_directory_login_screen.cc +++ b/chrome/browser/ash/login/screens/active_directory_login_screen.cc @@ -4,7 +4,9 @@ #include "chrome/browser/ash/login/screens/active_directory_login_screen.h" +#include "chrome/browser/ash/login/screens/signin_fatal_error_screen.h" #include "chrome/browser/ash/login/ui/login_display_host.h" +#include "chrome/browser/ash/login/ui/signin_ui.h" #include "chrome/browser/ash/login/wizard_controller.h" #include "chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h" @@ -21,15 +23,15 @@ namespace { constexpr char kUserActionCancel[] = "cancel"; -std::string GetErrorMessage(authpolicy::ErrorType error) { +chromeos::SigninError GetSigninError(authpolicy::ErrorType error) { switch (error) { case authpolicy::ERROR_NETWORK_PROBLEM: - return l10n_util::GetStringUTF8(IDS_AD_AUTH_NETWORK_ERROR); + return chromeos::SigninError::kActiveDirectoryNetworkProblem; case authpolicy::ERROR_KDC_DOES_NOT_SUPPORT_ENCRYPTION_TYPE: - return l10n_util::GetStringUTF8(IDS_AD_AUTH_NOT_SUPPORTED_ENCRYPTION); + return chromeos::SigninError::kActiveDirectoryNotSupportedEncryption; default: DLOG(WARNING) << "Unhandled error code: " << error; - return l10n_util::GetStringUTF8(IDS_AD_AUTH_UNKNOWN_ERROR); + return chromeos::SigninError::kActiveDirectoryUnknownError; } } @@ -165,7 +167,9 @@ void ActiveDirectoryLoginScreen::OnAdAuthResult( default: view_->SetErrorState(username, static_cast(ActiveDirectoryErrorState::NONE)); - view_->ShowSignInError(GetErrorMessage(error)); + LoginDisplayHost::default_host()->GetSigninUI()->ShowSigninError( + GetSigninError(error), /*details=*/std::string(), + /*login_attempts=*/1); } } diff --git a/chrome/browser/ash/login/test/oobe_screens_utils.cc b/chrome/browser/ash/login/test/oobe_screens_utils.cc index 8ac716d659da0c..1408fcb3faf6c7 100644 --- a/chrome/browser/ash/login/test/oobe_screens_utils.cc +++ b/chrome/browser/ash/login/test/oobe_screens_utils.cc @@ -176,6 +176,10 @@ void ExitScreenSyncConsent() { WaitForExit(SyncConsentScreenView::kScreenId); } +void ClickSignInFatalScreenActionButton() { + test::OobeJS().ClickOnPath({"signin-fatal-error", "actionButton"}); +} + bool IsScanningRequestedOnNetworkScreen() { return test::OobeJS().GetAttributeBool( "enableWifiScans", diff --git a/chrome/browser/ash/login/test/oobe_screens_utils.h b/chrome/browser/ash/login/test/oobe_screens_utils.h index 69df80445562fd..4426fa76d6d8a9 100644 --- a/chrome/browser/ash/login/test/oobe_screens_utils.h +++ b/chrome/browser/ash/login/test/oobe_screens_utils.h @@ -32,6 +32,8 @@ void TapEulaAccept(); void WaitForSyncConsentScreen(); void ExitScreenSyncConsent(); +void ClickSignInFatalScreenActionButton(); + bool IsScanningRequestedOnNetworkScreen(); bool IsScanningRequestedOnErrorScreen(); diff --git a/chrome/browser/ash/login/ui/login_display_host_common.cc b/chrome/browser/ash/login/ui/login_display_host_common.cc index 68a189c932b303..798840c257db03 100644 --- a/chrome/browser/ash/login/ui/login_display_host_common.cc +++ b/chrome/browser/ash/login/ui/login_display_host_common.cc @@ -138,14 +138,29 @@ int ErrorToMessageId(SigninError error) { return IDS_LOGIN_ERROR_AUTHENTICATING; case SigninError::kOwnerKeyLost: return IDS_LOGIN_ERROR_OWNER_KEY_LOST; + case SigninError::kChallengeResponseAuthMultipleClientCerts: + return IDS_CHALLENGE_RESPONSE_AUTH_MULTIPLE_CLIENT_CERTS_ERROR; + case SigninError::kChallengeResponseAuthInvalidClientCert: + return IDS_CHALLENGE_RESPONSE_AUTH_INVALID_CLIENT_CERT_ERROR; + case SigninError::kCookieWaitTimeout: + return IDS_LOGIN_FATAL_ERROR_NO_AUTH_TOKEN; + case SigninError::kFailedToFetchSamlRedirect: + return IDS_FAILED_TO_FETCH_SAML_REDIRECT; + case SigninError::kActiveDirectoryNetworkProblem: + return IDS_AD_AUTH_NETWORK_ERROR; + case SigninError::kActiveDirectoryNotSupportedEncryption: + return IDS_AD_AUTH_NOT_SUPPORTED_ENCRYPTION; + case SigninError::kActiveDirectoryUnknownError: + return IDS_AD_AUTH_UNKNOWN_ERROR; } } bool IsAuthError(SigninError error) { - return error != SigninError::kOwnerKeyLost && - error != SigninError::kOwnerRequired && - error != SigninError::kGoogleAccountNotAllowed && - error != SigninError::kTpmUpdateRequired; + return error == SigninError::kCaptivePortalError || + error == SigninError::kAuthenticationError || + error == SigninError::kOfflineFailedNetworkNotConnected || + error == SigninError::kAuthenticatingNew || + error == SigninError::kAuthenticating; } } // namespace diff --git a/chrome/browser/ash/login/ui/signin_ui.h b/chrome/browser/ash/login/ui/signin_ui.h index 5a5a98252be94f..e20bff606b06f8 100644 --- a/chrome/browser/ash/login/ui/signin_ui.h +++ b/chrome/browser/ash/login/ui/signin_ui.h @@ -21,6 +21,13 @@ enum class SigninError { kAuthenticatingNew, kAuthenticating, kOwnerKeyLost, + kChallengeResponseAuthMultipleClientCerts, + kChallengeResponseAuthInvalidClientCert, + kCookieWaitTimeout, + kFailedToFetchSamlRedirect, + kActiveDirectoryNetworkProblem, + kActiveDirectoryNotSupportedEncryption, + kActiveDirectoryUnknownError, }; // This class represents an interface between code that performs sign-in diff --git a/chrome/browser/extensions/extension_sync_service.cc b/chrome/browser/extensions/extension_sync_service.cc index ef9fa2c994a981..c4e2e5fe73e079 100644 --- a/chrome/browser/extensions/extension_sync_service.cc +++ b/chrome/browser/extensions/extension_sync_service.cc @@ -4,7 +4,6 @@ #include "chrome/browser/extensions/extension_sync_service.h" -#include #include #include "base/auto_reset.h" @@ -19,11 +18,7 @@ #include "chrome/browser/extensions/launch_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/glue/sync_start_util.h" -#include "chrome/browser/web_applications/components/install_manager.h" -#include "chrome/browser/web_applications/components/web_app_provider_base.h" -#include "chrome/browser/web_applications/components/web_application_info.h" #include "chrome/common/buildflags.h" -#include "chrome/common/chrome_features.h" #include "chrome/common/extensions/extension_constants.h" #include "components/sync/model/sync_change.h" #include "components/sync/model/sync_error_factory.h" @@ -33,7 +28,6 @@ #include "extensions/browser/uninstall_reason.h" #include "extensions/common/extension.h" #include "extensions/common/extension_set.h" -#include "extensions/common/image_util.h" #include "extensions/common/permissions/permission_message_provider.h" #include "extensions/common/permissions/permissions_data.h" @@ -475,11 +469,8 @@ void ExtensionSyncService::ApplySyncData( } if (!extension_sync_data.bookmark_app_url().empty()) { - // Handles creating and updating the bookmark app only if - // kSyncBookmarkApps is enabled. Bookmark apps have been migrated to web - // apps and are now handled by WebAppSyncBridge. - if (base::FeatureList::IsEnabled(features::kSyncBookmarkApps)) - ApplyBookmarkAppSyncData(extension_sync_data); + // Bookmark apps have been migrated to web apps and are now handled by + // WebAppSyncBridge. return; } } @@ -513,50 +504,6 @@ void ExtensionSyncService::ApplySyncData( extension_service()->CheckForUpdatesSoon(); } -void ExtensionSyncService::ApplyBookmarkAppSyncData( - const ExtensionSyncData& extension_sync_data) { - DCHECK(extension_sync_data.is_app()); - - // Process bookmark app sync if necessary. - GURL bookmark_app_url(extension_sync_data.bookmark_app_url()); - if (!bookmark_app_url.is_valid() || - extension_sync_data.uninstalled()) { - return; - } - - auto web_app_info = std::make_unique(); - web_app_info->start_url = bookmark_app_url; - web_app_info->title = base::UTF8ToUTF16(extension_sync_data.name()); - web_app_info->description = - base::UTF8ToUTF16(extension_sync_data.bookmark_app_description()); - web_app_info->scope = GURL(extension_sync_data.bookmark_app_scope()); - web_app_info->theme_color = extension_sync_data.bookmark_app_theme_color(); - web_app_info->open_as_window = - extension_sync_data.launch_type() == extensions::LAUNCH_TYPE_WINDOW; - - if (!extension_sync_data.bookmark_app_icon_color().empty()) { - extensions::image_util::ParseHexColorString( - extension_sync_data.bookmark_app_icon_color(), - &web_app_info->generated_icon_color); - } - for (const auto& icon : extension_sync_data.linked_icons()) { - WebApplicationIconInfo icon_info; - icon_info.url = icon.url; - icon_info.square_size_px = icon.size; - // Web apps in Extensions system supports Purpose::ANY icons only. - icon_info.purpose = blink::mojom::ManifestImageResource_Purpose::ANY; - web_app_info->icon_infos.push_back(icon_info); - } - - auto* provider = web_app::WebAppProviderBase::GetProviderBase(profile_); - // Legacy profiles containing server-side bookmark apps data must be excluded - // from sync if the web apps system is disabled for such a profile. - if (provider) { - provider->install_manager().InstallBookmarkAppFromSync( - extension_sync_data.id(), std::move(web_app_info), base::DoNothing()); - } -} - void ExtensionSyncService::SetSyncStartFlareForTesting( const syncer::SyncableService::StartSyncFlare& flare) { flare_ = flare; diff --git a/chrome/browser/extensions/extension_sync_service.h b/chrome/browser/extensions/extension_sync_service.h index 8c07009dd4079c..0cc32bfa78943f 100644 --- a/chrome/browser/extensions/extension_sync_service.h +++ b/chrome/browser/extensions/extension_sync_service.h @@ -106,10 +106,6 @@ class ExtensionSyncService : public syncer::SyncableService, // Applies the given change coming in from the server to the local state. void ApplySyncData(const extensions::ExtensionSyncData& extension_sync_data); - // Applies the bookmark app specific parts of |extension_sync_data|. - void ApplyBookmarkAppSyncData( - const extensions::ExtensionSyncData& extension_sync_data); - // Collects the ExtensionSyncData for all installed apps or extensions. std::vector GetLocalSyncDataList( syncer::ModelType type) const; diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html index 9671adc77e332f..63981606041d06 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.html @@ -186,7 +186,9 @@
Emoji Groups
-
+
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js index b313b25476fb47..78041c6cb9c72b 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.js @@ -211,6 +211,10 @@ export class EmojiPicker extends PolymerElement { this.$.listContainer.style.display = newValue ? 'none' : ''; } + onBarTransitionStart() { + this.highlightBarMoving = true; + } + onBarTransitionEnd() { this.highlightBarMoving = false; } @@ -262,7 +266,6 @@ export class EmojiPicker extends PolymerElement { onRightChevronClick() { this.shadowRoot.getElementById('tabs').scrollLeft = GROUP_ICON_SIZE * 6; this.scrollToGroup(GROUP_TABS[GROUP_PER_ROW - 3].groupId); - this.highlightBarMoving = true; this.groupTabsMoving = true; this.shadowRoot.getElementById('bar').style.left = EMOJI_GROUP_SIZE_PX; } @@ -270,7 +273,6 @@ export class EmojiPicker extends PolymerElement { onLeftChevronClick() { this.shadowRoot.getElementById('tabs').scrollLeft = 0; this.scrollToGroup(GROUP_TABS[0].groupId); - this.highlightBarMoving = true; this.groupTabsMoving = true; if (this.history.emoji.length > 0) { this.shadowRoot.getElementById('bar').style.left = '0'; diff --git a/chrome/browser/resources/chromeos/login/md_login.js b/chrome/browser/resources/chromeos/login/md_login.js index ca9e66590ebddf..7afa40c2709022 100644 --- a/chrome/browser/resources/chromeos/login/md_login.js +++ b/chrome/browser/resources/chromeos/login/md_login.js @@ -45,9 +45,6 @@ HTMLImports.whenReady(() => { chrome.send('screenStateInitialize'); }, - // Dummy Oobe functions not present with stripped login UI. - refreshA11yInfo(data) {}, - /** * Reloads content of the page. * @param {!Object} data New dictionary with i18n values. diff --git a/chrome/browser/sync/test/integration/single_client_web_apps_sync_test.cc b/chrome/browser/sync/test/integration/single_client_web_apps_sync_test.cc index ea053764781022..65ba35fcd75ab7 100644 --- a/chrome/browser/sync/test/integration/single_client_web_apps_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_web_apps_sync_test.cc @@ -130,17 +130,6 @@ class SingleClientWebAppsSyncTest : public SyncTest { } }; -class SingleClientWebAppsSyncBookmarkAppTest - : public SingleClientWebAppsSyncTest { - public: - SingleClientWebAppsSyncBookmarkAppTest() { - feature_list_.InitAndEnableFeature(features::kSyncBookmarkApps); - } - - private: - base::test::ScopedFeatureList feature_list_; -}; - IN_PROC_BROWSER_TEST_F(SingleClientWebAppsSyncTest, DisablingSelectedTypeDisablesModelType) { ASSERT_TRUE(SetupSync()); @@ -291,42 +280,4 @@ IN_PROC_BROWSER_TEST_F(SingleClientWebAppsSyncTest, web_app::GenerateAppIdFromURL(GURL("https://example.com/")); EXPECT_EQ(expected_app_id, installed_app_id); } - -// bookmark app should be sync installed when kSyncBookmarkApps is -// enabled. -IN_PROC_BROWSER_TEST_F(SingleClientWebAppsSyncBookmarkAppTest, - BookmarkAppSyncInstalled) { - std::string url = "https://example.com/"; - const std::string app_id = web_app::GenerateAppIdFromURL(GURL(url)); - InjectBookmarkAppEntityToFakeServer(app_id, url); - ASSERT_TRUE(SetupSync()); - AwaitWebAppQuiescence(); - - auto* web_app_registrar = web_app::WebAppProvider::Get(GetProfile(0)) - ->registrar() - .AsWebAppRegistrar(); - - EXPECT_TRUE(web_app_registrar->IsInstalled(app_id)); -} - -// Web app install should commit APPS sync entity when kSyncBookmarkApps is -// enabled. -IN_PROC_BROWSER_TEST_F(SingleClientWebAppsSyncBookmarkAppTest, - AppInstallSyncBookmarkApp) { - ASSERT_TRUE(SetupSync()); - WebApplicationInfo info; - std::string name = "Test name"; - info.title = base::UTF8ToUTF16(name); - info.description = u"Test description"; - info.start_url = GURL("http://www.chromium.org/path"); - info.scope = GURL("http://www.chromium.org/"); - web_app::AppId app_id = apps_helper::InstallWebApp(GetProfile(0), info); - ASSERT_TRUE(SetupSync()); - - fake_server::FakeServerVerifier fake_server_verifier(fake_server_.get()); - EXPECT_TRUE(fake_server_verifier.VerifyEntityCountByTypeAndName( - 1, syncer::WEB_APPS, name)); - EXPECT_TRUE(fake_server_verifier.VerifyEntityCountByTypeAndName( - 1, syncer::APPS, name)); -} } // namespace diff --git a/chrome/browser/sync/test/integration/two_client_web_apps_sync_test.cc b/chrome/browser/sync/test/integration/two_client_web_apps_sync_test.cc index 7b3ea4d19f50f4..960122222d94c0 100644 --- a/chrome/browser/sync/test/integration/two_client_web_apps_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_web_apps_sync_test.cc @@ -15,7 +15,6 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" #include "chrome/browser/web_applications/components/app_icon_manager.h" -#include "chrome/browser/web_applications/components/install_manager.h" #include "chrome/browser/web_applications/components/os_integration_manager.h" #include "chrome/browser/web_applications/components/web_application_info.h" #include "chrome/browser/web_applications/test/web_app_install_observer.h" @@ -317,12 +316,6 @@ IN_PROC_BROWSER_TEST_F(TwoClientWebAppsSyncTest, SyncUsingIconUrlFallback) { Profile* source_profile = GetProfile(0); Profile* dest_profile = GetProfile(1); - // Both bookmark app sync and web app sync happen at the same time. Disable - // one of them to simulate the other winning the "race". - InstallManager& install_manager = - WebAppProvider::Get(dest_profile)->install_manager(); - install_manager.DisableBookmarkAppSyncInstallForTesting(); - WebAppInstallObserver dest_install_observer(dest_profile); // Install app with name. diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc index d0a0cc9d892b3a..662bbb3fa3b5ca 100644 --- a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc +++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc @@ -198,7 +198,6 @@ void LockScreenReauthHandler::HandleCompleteAuthentication( base::BindOnce(&LockScreenReauthHandler::CheckCredentials, weak_factory_.GetWeakPtr())); - std::string error_message; pending_user_context_ = std::make_unique(); if (!login::BuildUserContextForGaiaSignIn( login::GetUsertypeFromServicesString(services), @@ -208,7 +207,7 @@ void LockScreenReauthHandler::HandleCompleteAuthentication( SamlPasswordAttributes::FromJs(*password_attributes), /*sync_trusted_vault_keys=*/base::nullopt, *extension_provided_client_cert_usage_observer_, - pending_user_context_.get(), &error_message)) { + pending_user_context_.get(), nullptr)) { pending_user_context_.reset(); NOTREACHED(); return; diff --git a/chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.cc index cae66a330012c9..f1864acfa9c657 100644 --- a/chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.cc @@ -20,10 +20,8 @@ namespace chromeos { constexpr StaticOobeScreenId ActiveDirectoryLoginView::kScreenId; ActiveDirectoryLoginScreenHandler::ActiveDirectoryLoginScreenHandler( - JSCallsContainer* js_calls_container, - CoreOobeView* core_oobe_view) - : BaseScreenHandler(kScreenId, js_calls_container), - core_oobe_view_(core_oobe_view) { + JSCallsContainer* js_calls_container) + : BaseScreenHandler(kScreenId, js_calls_container) { set_user_acted_method_path("login.ActiveDirectoryLoginScreen.userActed"); } @@ -96,13 +94,6 @@ void ActiveDirectoryLoginScreenHandler::SetErrorState( errorState); } -void ActiveDirectoryLoginScreenHandler::ShowSignInError( - const std::string& error_text) { - core_oobe_view_->ShowSignInError(error_text, - std::string() /* help_link_text */, - HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT); -} - void ActiveDirectoryLoginScreenHandler::HandleCompleteAuth( const std::string& username, const std::string& password) { diff --git a/chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.h index a5ee8cfe5adea5..62609f74b21111 100644 --- a/chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/active_directory_login_screen_handler.h @@ -12,7 +12,6 @@ namespace chromeos { class ActiveDirectoryLoginScreen; -class CoreOobeView; // Interface for dependency injection between ActiveDirectoryLoginScreen and its // WebUI representation. @@ -36,9 +35,6 @@ class ActiveDirectoryLoginView { // Set error state. virtual void SetErrorState(const std::string& username, int errorState) = 0; - - // Shows sign-in error bubble. - virtual void ShowSignInError(const std::string& error_text) = 0; }; class ActiveDirectoryLoginScreenHandler : public ActiveDirectoryLoginView, @@ -47,8 +43,7 @@ class ActiveDirectoryLoginScreenHandler : public ActiveDirectoryLoginView, using TView = ActiveDirectoryLoginView; explicit ActiveDirectoryLoginScreenHandler( - JSCallsContainer* js_calls_container, - CoreOobeView* core_oobe_view); + JSCallsContainer* js_calls_container); ~ActiveDirectoryLoginScreenHandler() override; @@ -67,7 +62,6 @@ class ActiveDirectoryLoginScreenHandler : public ActiveDirectoryLoginView, void Unbind() override; void Reset() override; void SetErrorState(const std::string& username, int errorState) override; - void ShowSignInError(const std::string& error_text) override; // BaseScreenHandler: void RegisterMessages() override; @@ -79,9 +73,6 @@ class ActiveDirectoryLoginScreenHandler : public ActiveDirectoryLoginView, // Whether the screen should be shown right after initialization. bool show_on_init_ = false; - - // Non-owned. Used to display signin error. - CoreOobeView* core_oobe_view_ = nullptr; }; } // namespace chromeos diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc index 204de97c8a58ae..7ba974c3a22d25 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc @@ -147,15 +147,6 @@ void CoreOobeHandler::RegisterMessages() { AddCallback("enableShelfButtons", &CoreOobeHandler::HandleEnableShelfButtons); } -void CoreOobeHandler::ShowSignInError( - const std::string& error_text, - const std::string& help_link_text, - HelpAppLauncher::HelpTopic help_topic_id) { - LOG(ERROR) << "CoreOobeHandler::ShowSignInError: error_text=" << error_text; - CallJS("cr.ui.Oobe.showSignInError", error_text, help_link_text, - static_cast(help_topic_id)); -} - void CoreOobeHandler::ShowDeviceResetScreen() { LaunchResetScreen(); } diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h index 6543337fe39b17..e362320ac3c626 100644 --- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h @@ -50,9 +50,6 @@ class CoreOobeView { virtual ~CoreOobeView() = default; - virtual void ShowSignInError(const std::string& error_text, - const std::string& help_link_text, - HelpAppLauncher::HelpTopic help_topic_id) = 0; virtual void ResetSignInUI(bool force_online) = 0; virtual void ClearErrors() = 0; virtual void ReloadContent(const base::DictionaryValue& dictionary) = 0; @@ -121,9 +118,6 @@ class CoreOobeHandler : public BaseWebUIHandler, private: // CoreOobeView implementation: - void ShowSignInError(const std::string& error_text, - const std::string& help_link_text, - HelpAppLauncher::HelpTopic help_topic_id) override; void ResetSignInUI(bool force_online) override; void ClearErrors() override; void ReloadContent(const base::DictionaryValue& dictionary) override; diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index 5e77dbae1fdc00..76c3654b4f7f0a 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc @@ -45,6 +45,7 @@ #include "chrome/browser/ash/login/signin_partition_manager.h" #include "chrome/browser/ash/login/ui/login_display_host.h" #include "chrome/browser/ash/login/ui/login_display_host_webui.h" +#include "chrome/browser/ash/login/ui/signin_ui.h" #include "chrome/browser/ash/login/ui/user_adding_screen.h" #include "chrome/browser/ash/login/users/chrome_user_manager.h" #include "chrome/browser/ash/login/users/chrome_user_manager_util.h" @@ -519,10 +520,9 @@ void GaiaScreenHandler::LoadGaiaWithPartitionAndVersionAndConsent( if (public_saml_url_fetcher_->FetchSucceeded()) { params.SetString("frameUrl", public_saml_url_fetcher_->GetRedirectUrl()); } else { - // TODO: make the string localized. - std::string msg = "Failed to fetch the SAML redirect URL from the server"; - core_oobe_view_->ShowSignInError( - msg, std::string(), HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT); + LoginDisplayHost::default_host()->GetSigninUI()->ShowSigninError( + SigninError::kFailedToFetchSamlRedirect, /*details=*/std::string(), + /*login_attempts=*/1); return; } } @@ -783,7 +783,7 @@ void GaiaScreenHandler::HandleCompleteAuthentication( base::Unretained(LoginDisplayHost::default_host()))); pending_user_context_ = std::make_unique(); - std::string error_message; + SigninError error; if (!login::BuildUserContextForGaiaSignIn( login::GetUsertypeFromServicesString(services), GetAccountId(email, gaia_id, AccountType::GOOGLE), using_saml, @@ -794,9 +794,9 @@ void GaiaScreenHandler::HandleCompleteAuthentication( SyncTrustedVaultKeys::FromJs(*sync_trusted_vault_keys)) : base::nullopt, *extension_provided_client_cert_usage_observer_, - pending_user_context_.get(), &error_message)) { - core_oobe_view_->ShowSignInError(error_message, std::string(), - HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT); + pending_user_context_.get(), &error)) { + LoginDisplayHost::default_host()->GetSigninUI()->ShowSigninError( + error, /*details=*/std::string(), /*login_attempts=*/1); pending_user_context_.reset(); return; } @@ -816,9 +816,9 @@ void GaiaScreenHandler::HandleCompleteAuthentication( void GaiaScreenHandler::OnCookieWaitTimeout() { LoadAuthExtension(true /* force */); - core_oobe_view_->ShowSignInError( - l10n_util::GetStringUTF8(IDS_LOGIN_FATAL_ERROR_NO_AUTH_TOKEN), - std::string(), HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT); + LoginDisplayHost::default_host()->GetSigninUI()->ShowSigninError( + SigninError::kCookieWaitTimeout, /*details=*/std::string(), + /*login_attempts=*/1); } void GaiaScreenHandler::HandleCompleteLogin(const std::string& gaia_id, @@ -1003,16 +1003,16 @@ void GaiaScreenHandler::DoCompleteLogin(const std::string& gaia_id, user_manager::UserManager::Get()->FindUser(account_id); UserContext user_context; - std::string error_message; + SigninError error; if (!login::BuildUserContextForGaiaSignIn( user ? user->GetType() : CalculateUserType(account_id), GetAccountId(typed_email, gaia_id, AccountType::GOOGLE), using_saml, using_saml_api_, password, SamlPasswordAttributes(), /*sync_trusted_vault_keys=*/base::nullopt, *extension_provided_client_cert_usage_observer_, &user_context, - &error_message)) { - core_oobe_view_->ShowSignInError(error_message, std::string(), - HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT); + &error)) { + LoginDisplayHost::default_host()->GetSigninUI()->ShowSigninError( + error, /*details=*/std::string(), /*login_attempts=*/1); return; } diff --git a/chrome/browser/ui/webui/chromeos/login/online_login_helper.cc b/chrome/browser/ui/webui/chromeos/login/online_login_helper.cc index 032344632d77b5..36faf0db21330e 100644 --- a/chrome/browser/ui/webui/chromeos/login/online_login_helper.cc +++ b/chrome/browser/ui/webui/chromeos/login/online_login_helper.cc @@ -6,6 +6,7 @@ #include "chrome/browser/ash/login/signin_partition_manager.h" #include "chrome/browser/ash/login/ui/login_display_host_webui.h" +#include "chrome/browser/ash/login/ui/signin_ui.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" @@ -114,7 +115,7 @@ bool BuildUserContextForGaiaSignIn( const LoginClientCertUsageObserver& extension_provided_client_cert_usage_observer, UserContext* user_context, - std::string* error_message) { + SigninError* error) { *user_context = UserContext(user_type, account_id); if (using_saml && extension_provided_client_cert_usage_observer.ClientCertsWereUsed()) { @@ -123,15 +124,15 @@ bool BuildUserContextForGaiaSignIn( std::string extension_id; if (!extension_provided_client_cert_usage_observer.GetOnlyUsedClientCert( &saml_client_cert, &signature_algorithms, &extension_id)) { - *error_message = l10n_util::GetStringUTF8( - IDS_CHALLENGE_RESPONSE_AUTH_MULTIPLE_CLIENT_CERTS_ERROR); + if (error) + *error = SigninError::kChallengeResponseAuthMultipleClientCerts; return false; } ChallengeResponseKey challenge_response_key; if (!ExtractChallengeResponseKeyFromCert( *saml_client_cert, signature_algorithms, &challenge_response_key)) { - *error_message = l10n_util::GetStringUTF8( - IDS_CHALLENGE_RESPONSE_AUTH_INVALID_CLIENT_CERT_ERROR); + if (error) + *error = SigninError::kChallengeResponseAuthInvalidClientCert; return false; } challenge_response_key.set_extension_id(extension_id); diff --git a/chrome/browser/ui/webui/chromeos/login/online_login_helper.h b/chrome/browser/ui/webui/chromeos/login/online_login_helper.h index f62f6139423f97..0c18f032e279d8 100644 --- a/chrome/browser/ui/webui/chromeos/login/online_login_helper.h +++ b/chrome/browser/ui/webui/chromeos/login/online_login_helper.h @@ -11,6 +11,7 @@ #include "chrome/browser/ash/login/login_client_cert_usage_observer.h" #include "chrome/browser/ash/login/signin_partition_manager.h" #include "chrome/browser/ash/login/ui/login_display_host.h" +#include "chrome/browser/ash/login/ui/signin_ui.h" #include "chrome/browser/extensions/api/cookies/cookies_api.h" #include "chromeos/login/auth/cryptohome_authenticator.h" #include "components/login/base_screen_handler_utils.h" @@ -79,7 +80,7 @@ bool BuildUserContextForGaiaSignIn( const LoginClientCertUsageObserver& extension_provided_client_cert_usage_observer, UserContext* user_context, - std::string* error_message); + SigninError* error); } // namespace login diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc index afd12200d5ead8..e14489048deb66 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc @@ -499,7 +499,7 @@ void OobeUI::ConfigureOobeDisplay() { js_calls_container_.get())); AddScreenHandler(std::make_unique( - js_calls_container_.get(), core_handler_)); + js_calls_container_.get())); auto password_change_handler = std::make_unique( diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index 40b8dc65c0ab9b..fb9696946b89fb 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc @@ -624,12 +624,6 @@ void SigninScreenHandler::OnPreferencesChanged() { } } -void SigninScreenHandler::ShowError(const std::string& error_text, - const std::string& help_link_text, - HelpAppLauncher::HelpTopic help_topic_id) { - core_oobe_view_->ShowSignInError(error_text, help_link_text, help_topic_id); -} - void SigninScreenHandler::ShowAllowlistCheckFailedError() { gaia_screen_handler_->ShowAllowlistCheckFailedError(); } diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h index 1ef0ea6f8a363c..c4dfd725d52f09 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h @@ -55,9 +55,6 @@ class LoginDisplayWebUIHandler { public: virtual void ClearAndEnablePassword() = 0; virtual void OnPreferencesChanged() = 0; - virtual void ShowError(const std::string& error_text, - const std::string& help_link_text, - HelpAppLauncher::HelpTopic help_topic_id) = 0; virtual void ShowAllowlistCheckFailedError() = 0; protected: @@ -185,9 +182,6 @@ class SigninScreenHandler // LoginDisplayWebUIHandler implementation: void ClearAndEnablePassword() override; void OnPreferencesChanged() override; - void ShowError(const std::string& error_text, - const std::string& help_link_text, - HelpAppLauncher::HelpTopic help_topic_id) override; void ShowAllowlistCheckFailedError() override; // content::NotificationObserver implementation: diff --git a/chrome/browser/web_applications/components/install_manager.h b/chrome/browser/web_applications/components/install_manager.h index d49d2d962f3c82..100caf8ddcb909 100644 --- a/chrome/browser/web_applications/components/install_manager.h +++ b/chrome/browser/web_applications/components/install_manager.h @@ -162,15 +162,6 @@ class InstallManager { webapps::WebappInstallSource install_source, OnceInstallCallback callback) = 0; - // For backward compatibility with ExtensionSyncService-based system: - // Starts background installation or an update of a bookmark app from the sync - // system. |web_application_info| contains received sync data. Icons will be - // downloaded from the icon URLs provided in |web_application_info|. - virtual void InstallBookmarkAppFromSync( - const AppId& app_id, - std::unique_ptr web_application_info, - OnceInstallCallback callback) = 0; - // Reinstall an existing web app. If |redownload_app_icons| is true, will // redownload app icons and update them on disk. Otherwise, the icons in // |web_application_info.bitmap_icons| will be used and saved to disk. @@ -194,9 +185,6 @@ class InstallManager { webapps::WebappInstallSource install_source, WebAppManifestCheckCallback callback) = 0; - void DisableBookmarkAppSyncInstallForTesting() { - disable_bookmark_app_sync_install_for_testing_ = true; - } void DisableWebAppSyncInstallForTesting() { disable_web_app_sync_install_for_testing_ = true; } @@ -210,9 +198,6 @@ class InstallManager { } InstallFinalizer* finalizer() { return finalizer_; } - bool disable_bookmark_app_sync_install_for_testing() const { - return disable_bookmark_app_sync_install_for_testing_; - } bool disable_web_app_sync_install_for_testing() const { return disable_web_app_sync_install_for_testing_; } @@ -225,7 +210,6 @@ class InstallManager { OsIntegrationManager* os_integration_manager_ = nullptr; InstallFinalizer* finalizer_ = nullptr; - bool disable_bookmark_app_sync_install_for_testing_ = false; bool disable_web_app_sync_install_for_testing_ = false; }; diff --git a/chrome/browser/web_applications/web_app_install_finalizer.cc b/chrome/browser/web_applications/web_app_install_finalizer.cc index e015e2b19ec4f3..e03a6a98ccecfa 100644 --- a/chrome/browser/web_applications/web_app_install_finalizer.cc +++ b/chrome/browser/web_applications/web_app_install_finalizer.cc @@ -35,7 +35,6 @@ #include "chrome/browser/web_applications/web_app_installation_utils.h" #include "chrome/browser/web_applications/web_app_registry_update.h" #include "chrome/browser/web_applications/web_app_sync_bridge.h" -#include "chrome/common/chrome_features.h" #include "components/content_settings/core/common/content_settings.h" #include "components/permissions/permission_manager.h" #include "components/permissions/permission_result.h" @@ -192,7 +191,6 @@ void WebAppInstallFinalizer::FinalizeInstall( web_app->SetAdditionalSearchTerms(web_app_info.additional_search_terms); web_app->AddSource(source); web_app->SetIsInSyncInstall(false); - const bool is_synced = web_app->IsSynced(); UpdateIntWebAppPref(profile_->GetPrefs(), app_id, kLatestWebAppInstallSource, static_cast(options.install_source)); @@ -209,20 +207,6 @@ void WebAppInstallFinalizer::FinalizeInstall( SetWebAppManifestFieldsAndWriteData(web_app_info, std::move(web_app), std::move(commit_callback)); - - // Backward compatibility: If a legacy finalizer was provided then install a - // duplicate bookmark app in the extensions registry. No callback, this is - // fire-and-forget install. If a user gets switched back to legacy mode they - // still able to use the duplicate. - // - // We should install shadow bookmark app only for kSync source (we sync only - // user-installed apps). System, Policy, WebAppStore, Default apps should not - // get a shadow bookmark app. - if (legacy_finalizer_ && is_synced && - base::FeatureList::IsEnabled(features::kSyncBookmarkApps)) { - legacy_finalizer_->FinalizeInstall(web_app_info, options, - base::DoNothing()); - } } void WebAppInstallFinalizer::FinalizeUninstallAfterSync( @@ -483,7 +467,6 @@ void WebAppInstallFinalizer::FinalizeUpdateWithShortcutInfo( // Prepare copy-on-write to update existing app. const WebApp* existing_web_app = GetWebAppRegistrar().GetAppById(app_id); auto web_app = std::make_unique(*existing_web_app); - const bool is_synced = web_app->IsSynced(); CommitCallback commit_callback = base::BindOnce( &WebAppInstallFinalizer::OnDatabaseCommitCompletedForUpdate, weak_ptr_factory_.GetWeakPtr(), std::move(callback), app_id, @@ -492,12 +475,6 @@ void WebAppInstallFinalizer::FinalizeUpdateWithShortcutInfo( SetWebAppManifestFieldsAndWriteData(web_app_info, std::move(web_app), std::move(commit_callback)); - - if (legacy_finalizer_ && is_synced && - base::FeatureList::IsEnabled(features::kSyncBookmarkApps)) { - // Passing an empty web_contents because BookmarkApps should not need this. - legacy_finalizer_->FinalizeUpdate(web_app_info, nullptr, base::DoNothing()); - } } bool WebAppInstallFinalizer::DoFileHandlersNeedOsUpdate( diff --git a/chrome/browser/web_applications/web_app_install_manager.cc b/chrome/browser/web_applications/web_app_install_manager.cc index b50a4c491a5f80..faac0e229764b2 100644 --- a/chrome/browser/web_applications/web_app_install_manager.cc +++ b/chrome/browser/web_applications/web_app_install_manager.cc @@ -204,29 +204,6 @@ void WebAppInstallManager::InstallWebAppWithParams( tasks_.insert(std::move(task)); } -void WebAppInstallManager::InstallBookmarkAppFromSync( - const AppId& bookmark_app_id, - std::unique_ptr web_application_info, - OnceInstallCallback callback) { - if (disable_bookmark_app_sync_install_for_testing()) - return; - - // This method can be called by - // ExtensionSyncService::ApplyBookmarkAppSyncData() while |this| is not - // |started_|. - if (started_) { - EnqueueInstallAppFromSync(bookmark_app_id, std::move(web_application_info), - std::move(callback)); - } else { - AppSyncInstallRequest request; - request.sync_app_id = bookmark_app_id; - request.web_application_info = std::move(web_application_info); - request.callback = std::move(callback); - - externally_managed_app_sync_installs_.push_back(std::move(request)); - } -} - void WebAppInstallManager::EnqueueInstallAppFromSync( const AppId& sync_app_id, std::unique_ptr web_application_info, diff --git a/chrome/browser/web_applications/web_app_install_manager.h b/chrome/browser/web_applications/web_app_install_manager.h index 9c846c8cc3fab8..3106a96a35ae78 100644 --- a/chrome/browser/web_applications/web_app_install_manager.h +++ b/chrome/browser/web_applications/web_app_install_manager.h @@ -74,10 +74,6 @@ class WebAppInstallManager final : public InstallManager, const InstallParams& install_params, webapps::WebappInstallSource install_source, OnceInstallCallback callback) override; - void InstallBookmarkAppFromSync( - const AppId& bookmark_app_id, - std::unique_ptr web_application_info, - OnceInstallCallback callback) override; void UpdateWebAppFromInfo( const AppId& app_id, std::unique_ptr web_application_info, diff --git a/chrome/browser/web_applications/web_app_install_manager_unittest.cc b/chrome/browser/web_applications/web_app_install_manager_unittest.cc index 7ac6b3bfe7f609..56d93e43c53fc8 100644 --- a/chrome/browser/web_applications/web_app_install_manager_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_manager_unittest.cc @@ -311,23 +311,6 @@ class WebAppInstallManagerTest : public WebAppTest { return result; } - InstallResult InstallBookmarkAppFromSync( - const AppId& bookmark_app_id, - std::unique_ptr server_web_application_info) { - InstallResult result; - base::RunLoop run_loop; - install_manager().InstallBookmarkAppFromSync( - bookmark_app_id, std::move(server_web_application_info), - base::BindLambdaForTesting( - [&](const AppId& installed_app_id, InstallResultCode code) { - result.app_id = installed_app_id; - result.code = code; - run_loop.Quit(); - })); - run_loop.Run(); - return result; - } - InstallResult InstallWebAppFromInfo( std::unique_ptr web_application_info) { InstallResult result; @@ -345,21 +328,6 @@ class WebAppInstallManagerTest : public WebAppTest { return result; } - AppId InstallBookmarkAppFromSync(const GURL& url, - bool server_open_as_window) { - const AppId bookmark_app_id = GenerateAppIdFromURL(url); - - auto server_web_application_info = std::make_unique(); - server_web_application_info->start_url = url; - server_web_application_info->open_as_window = server_open_as_window; - server_web_application_info->title = u"Server Name"; - InstallResult result = InstallBookmarkAppFromSync( - bookmark_app_id, std::move(server_web_application_info)); - - EXPECT_EQ(InstallResultCode::kSuccessNewInstall, result.code); - return result.app_id; - } - std::map ReadIcons(const AppId& app_id, IconPurpose purpose, SortedSizesPx sizes_px) { @@ -942,323 +910,6 @@ TEST_F(WebAppInstallManagerTest, DefaultAndUser_UninstallExternalAppByUser) { EXPECT_TRUE(finalizer().WasExternalAppUninstalledByUser(app_id)); } -TEST_F(WebAppInstallManagerTest, InstallBookmarkAppFromSync_LoadSuccess) { - InitEmptyRegistrar(); - - const auto url1 = GURL("https://example.com/"); - const auto url2 = GURL("https://example.org/"); - - url_loader().AddPrepareForLoadResults({WebAppUrlLoader::Result::kUrlLoaded, - WebAppUrlLoader::Result::kUrlLoaded}); - url_loader().SetNextLoadUrlResult(url1, WebAppUrlLoader::Result::kUrlLoaded); - - install_manager().SetDataRetrieverFactoryForTesting( - base::BindLambdaForTesting([&]() { - auto data_retriever = std::make_unique(); - data_retriever->SetEmptyRendererWebApplicationInfo(); - - auto manifest = std::make_unique(); - manifest->start_url = url1; - manifest->scope = url1; - manifest->display = DisplayMode::kBrowser; - data_retriever->SetManifest(std::move(manifest), - /*is_installable=*/true); - - return std::unique_ptr(std::move(data_retriever)); - })); - const AppId app_id1 = - InstallBookmarkAppFromSync(url1, /*server_open_as_window=*/true); - - url_loader().SetNextLoadUrlResult(url2, WebAppUrlLoader::Result::kUrlLoaded); - - install_manager().SetDataRetrieverFactoryForTesting( - base::BindLambdaForTesting([&]() { - auto data_retriever = std::make_unique(); - data_retriever->SetEmptyRendererWebApplicationInfo(); - - auto manifest = std::make_unique(); - manifest->start_url = url2; - manifest->scope = url2; - manifest->display = DisplayMode::kStandalone; - data_retriever->SetManifest(std::move(manifest), - /*is_installable=*/true); - - return std::unique_ptr(std::move(data_retriever)); - })); - const AppId app_id2 = - InstallBookmarkAppFromSync(url2, /*server_open_as_window=*/false); - -#if BUILDFLAG(IS_CHROMEOS_ASH) - EXPECT_TRUE(registrar().GetAppById(app_id1)->is_locally_installed()); -#else // !BUILDFLAG(IS_CHROMEOS_ASH) - EXPECT_FALSE(registrar().GetAppById(app_id1)->is_locally_installed()); -#endif - - EXPECT_EQ(registrar().GetAppDisplayMode(app_id1), DisplayMode::kBrowser); - EXPECT_EQ(registrar().GetAppDisplayMode(app_id2), DisplayMode::kStandalone); - - EXPECT_EQ(registrar().GetAppUserDisplayMode(app_id1), - DisplayMode::kStandalone); - EXPECT_EQ(registrar().GetAppUserDisplayMode(app_id2), DisplayMode::kBrowser); -} - -TEST_F(WebAppInstallManagerTest, InstallBookmarkAppFromSync_LoadFailed) { - InitEmptyRegistrar(); - - const auto url1 = GURL("https://example.com/"); - const auto url2 = GURL("https://example.org/"); - - url_loader().AddPrepareForLoadResults({WebAppUrlLoader::Result::kUrlLoaded, - WebAppUrlLoader::Result::kUrlLoaded, - WebAppUrlLoader::Result::kUrlLoaded, - WebAppUrlLoader::Result::kUrlLoaded}); - - // Induce a load failure: - url_loader().SetNextLoadUrlResult( - url1, WebAppUrlLoader::Result::kRedirectedUrlLoaded); - url_loader().SetNextLoadUrlResult( - url2, WebAppUrlLoader::Result::kRedirectedUrlLoaded); - - auto app_id1 = - InstallBookmarkAppFromSync(url1, /*server_open_as_window=*/false); - - auto app_id2 = - InstallBookmarkAppFromSync(url2, /*server_open_as_window=*/true); - -#if BUILDFLAG(IS_CHROMEOS_ASH) - EXPECT_TRUE(registrar().GetAppById(app_id1)->is_locally_installed()); -#else // !BUILDFLAG(IS_CHROMEOS_ASH) - EXPECT_FALSE(registrar().GetAppById(app_id1)->is_locally_installed()); -#endif - - EXPECT_EQ(registrar().GetAppDisplayMode(app_id1), DisplayMode::kBrowser); - EXPECT_EQ(registrar().GetAppDisplayMode(app_id2), DisplayMode::kBrowser); - - EXPECT_EQ(registrar().GetAppUserDisplayMode(app_id1), DisplayMode::kBrowser); - EXPECT_EQ(registrar().GetAppUserDisplayMode(app_id2), - DisplayMode::kStandalone); -} - -TEST_F(WebAppInstallManagerTest, InstallBookmarkAppFromSync_TwoIcons_Success) { - InitEmptyRegistrar(); - - const GURL url{"https://example.com/path"}; - const GURL icon1_url{"https://example.com/path/icon1.png"}; - const GURL icon2_url{"https://example.com/path/icon2.png"}; - - url_loader().AddPrepareForLoadResults({WebAppUrlLoader::Result::kUrlLoaded}); - url_loader().SetNextLoadUrlResult(url, WebAppUrlLoader::Result::kUrlLoaded); - - const AppId app_id = GenerateAppIdFromURL(url); - - auto server_web_app_info = std::make_unique(); - server_web_app_info->start_url = url; - server_web_app_info->title = u"Server Name"; - { - WebApplicationIconInfo server_icon1_info; - server_icon1_info.url = icon1_url; - server_icon1_info.square_size_px = icon_size::k128; - server_web_app_info->icon_infos.push_back(std::move(server_icon1_info)); - - WebApplicationIconInfo server_icon2_info; - server_icon2_info.url = icon2_url; - server_icon2_info.square_size_px = icon_size::k256; - server_web_app_info->icon_infos.push_back(std::move(server_icon2_info)); - } - - install_manager().SetDataRetrieverFactoryForTesting( - base::BindLambdaForTesting([&]() { - auto data_retriever = std::make_unique(); - data_retriever->BuildDefaultDataToRetrieve(url, url); - // Set the website manifest to be a copy of WebApplicationInfo from - // sync, as if they are the same. - std::unique_ptr site_web_app_info = - std::make_unique(*server_web_app_info); - data_retriever->SetRendererWebApplicationInfo( - std::move(site_web_app_info)); - - IconsMap site_icons_map; - AddIconToIconsMap(icon1_url, icon_size::k128, SK_ColorBLUE, - &site_icons_map); - AddIconToIconsMap(icon2_url, icon_size::k256, SK_ColorRED, - &site_icons_map); - - data_retriever->SetIcons(std::move(site_icons_map)); - return std::unique_ptr(std::move(data_retriever)); - })); - - InstallResult result = InstallBookmarkAppFromSync( - app_id, std::make_unique(*server_web_app_info)); - EXPECT_EQ(InstallResultCode::kSuccessNewInstall, result.code); - EXPECT_EQ(app_id, result.app_id); - - const WebApp* web_app = registrar().GetAppById(app_id); - - EXPECT_EQ(2U, web_app->icon_infos().size()); - EXPECT_EQ(SizesToGenerate().size(), - web_app->downloaded_icon_sizes(IconPurpose::ANY).size()); - EXPECT_EQ(0u, web_app->downloaded_icon_sizes(IconPurpose::MASKABLE).size()); - - EXPECT_EQ(icon1_url, web_app->icon_infos().at(0).url); - EXPECT_EQ(icon2_url, web_app->icon_infos().at(1).url); - - // Read icons from disk to check pixel contents. - std::map icon_bitmaps = - ReadIcons(app_id, IconPurpose::ANY, {icon_size::k128, icon_size::k256}); - EXPECT_EQ(2u, icon_bitmaps.size()); - - const auto& icon1 = icon_bitmaps[icon_size::k128]; - EXPECT_FALSE(icon1.drawsNothing()); - EXPECT_EQ(SK_ColorBLUE, icon1.getColor(0, 0)); - - const auto& icon2 = icon_bitmaps[icon_size::k256]; - EXPECT_FALSE(icon2.drawsNothing()); - EXPECT_EQ(SK_ColorRED, icon2.getColor(0, 0)); -} - -TEST_F(WebAppInstallManagerTest, InstallBookmarkAppFromSync_TwoIcons_Fallback) { - InitEmptyRegistrar(); - - const GURL url{"https://example.com/path"}; - const GURL icon1_url{"https://example.com/path/icon1.png"}; - const GURL icon2_url{"https://example.com/path/icon2.png"}; - - // about:blank will be loaded twice, one for the initial attempt and one for - // the fallback attempt. - url_loader().AddPrepareForLoadResults({WebAppUrlLoader::Result::kUrlLoaded, - WebAppUrlLoader::Result::kUrlLoaded}); - // Induce a load failure: - url_loader().SetNextLoadUrlResult( - url, WebAppUrlLoader::Result::kRedirectedUrlLoaded); - install_manager().SetDataRetrieverFactoryForTesting( - base::BindLambdaForTesting([&]() { - return std::unique_ptr( - std::make_unique()); - })); - - const AppId app_id = GenerateAppIdFromURL(url); - - auto server_web_app_info = std::make_unique(); - server_web_app_info->start_url = url; - server_web_app_info->title = u"Server Name"; - server_web_app_info->generated_icon_color = SK_ColorBLUE; - { - WebApplicationIconInfo server_icon1_info; - server_icon1_info.url = icon1_url; - server_icon1_info.square_size_px = icon_size::k128; - server_web_app_info->icon_infos.push_back(std::move(server_icon1_info)); - - WebApplicationIconInfo server_icon2_info; - server_icon2_info.url = icon2_url; - server_icon2_info.square_size_px = icon_size::k256; - server_web_app_info->icon_infos.push_back(std::move(server_icon2_info)); - } - - InstallResult result = - InstallBookmarkAppFromSync(app_id, std::move(server_web_app_info)); - EXPECT_EQ(InstallResultCode::kSuccessNewInstall, result.code); - EXPECT_EQ(app_id, result.app_id); - - const WebApp* web_app = registrar().GetAppById(app_id); - - EXPECT_EQ(2U, web_app->icon_infos().size()); - EXPECT_EQ(SizesToGenerate().size(), - web_app->downloaded_icon_sizes(IconPurpose::ANY).size()); - EXPECT_EQ(0u, web_app->downloaded_icon_sizes(IconPurpose::MASKABLE).size()); - - EXPECT_EQ(icon1_url, web_app->icon_infos().at(0).url); - EXPECT_EQ(icon2_url, web_app->icon_infos().at(1).url); - - // Read icons from disk. All icons get the E letter drawn into a rounded - // blue background. - std::map icon_bitmaps = - ReadIcons(app_id, IconPurpose::ANY, {icon_size::k128, icon_size::k256}); - EXPECT_EQ(2u, icon_bitmaps.size()); - - const auto& icon1 = icon_bitmaps[icon_size::k128]; - EXPECT_FALSE(icon1.drawsNothing()); - - const auto& icon2 = icon_bitmaps[icon_size::k256]; - EXPECT_FALSE(icon2.drawsNothing()); -} - -TEST_F(WebAppInstallManagerTest, InstallBookmarkAppFromSync_NoIcons) { - InitEmptyRegistrar(); - - const GURL url{"https://example.com/path"}; - - // about:blank will be loaded twice, one for the initial attempt and one for - // the fallback attempt. - url_loader().AddPrepareForLoadResults({WebAppUrlLoader::Result::kUrlLoaded, - WebAppUrlLoader::Result::kUrlLoaded}); - // Induce a load failure: - url_loader().SetNextLoadUrlResult( - url, WebAppUrlLoader::Result::kRedirectedUrlLoaded); - UseDefaultDataRetriever(url); - const AppId app_id = GenerateAppIdFromURL(url); - - auto web_app_info = std::make_unique(); - web_app_info->start_url = url; - web_app_info->title = u"Server Name"; - // All icons will get the E letter drawn into a rounded yellow background. - web_app_info->generated_icon_color = SK_ColorYELLOW; - - InstallResult result = - InstallBookmarkAppFromSync(app_id, std::move(web_app_info)); - EXPECT_EQ(InstallResultCode::kSuccessNewInstall, result.code); - EXPECT_EQ(app_id, result.app_id); - - const WebApp* web_app = registrar().GetAppById(app_id); - - std::map icon_bitmaps = - ReadIcons(app_id, IconPurpose::ANY, - web_app->downloaded_icon_sizes(IconPurpose::ANY)); - - // Make sure that icons have been generated for all sub sizes. - EXPECT_TRUE(ContainsOneIconOfEachSize(icon_bitmaps)); - - for (const std::pair& icon : icon_bitmaps) - EXPECT_FALSE(icon.second.drawsNothing()); -} - -TEST_F(WebAppInstallManagerTest, InstallBookmarkAppFromSync_ExpectAppIdFailed) { - InitEmptyRegistrar(); - - const GURL old_url{"https://example.com/path"}; - - url_loader().AddPrepareForLoadResults({WebAppUrlLoader::Result::kUrlLoaded, - WebAppUrlLoader::Result::kUrlLoaded}); - url_loader().SetNextLoadUrlResult(old_url, - WebAppUrlLoader::Result::kUrlLoaded); - - // The web site has changed app url: - UseDefaultDataRetriever(GURL{"https://example.org"}); - - const AppId expected_app_id = GenerateAppIdFromURL(old_url); - - auto server_web_app_info = std::make_unique(); - server_web_app_info->start_url = old_url; - server_web_app_info->title = u"Server Name"; - - // WebAppInstallTask finishes with kExpectedAppIdCheckFailed but - // WebAppInstallManager falls back to web application info, received from the - // server. - InstallResult result = InstallBookmarkAppFromSync( - expected_app_id, std::move(server_web_app_info)); - EXPECT_EQ(InstallResultCode::kSuccessNewInstall, result.code); - EXPECT_EQ(expected_app_id, result.app_id); - - const WebApp* web_app = registrar().GetAppById(expected_app_id); - ASSERT_TRUE(web_app); - - std::map icon_bitmaps = - ReadIcons(expected_app_id, IconPurpose::ANY, - web_app->downloaded_icon_sizes(IconPurpose::ANY)); - - // Make sure that icons have been generated for all sub sizes. - EXPECT_TRUE(ContainsOneIconOfEachSize(icon_bitmaps)); -} - TEST_F(WebAppInstallManagerTest, InstallWebAppFromInfo) { InitEmptyRegistrar(); @@ -1285,287 +936,6 @@ TEST_F(WebAppInstallManagerTest, InstallWebAppFromInfo) { EXPECT_TRUE(ContainsOneIconOfEachSize(icon_bitmaps)); } -TEST_F(WebAppInstallManagerTest, InstallBookmarkAppFromSync_QueueNewInstall) { - // The registrar is not yet started (initialized) at the beginning of this - // test. - EXPECT_FALSE(install_manager().has_web_contents_for_testing()); - EXPECT_EQ(0u, install_manager().tasks_size_for_testing()); - - const GURL url{"https://example.com/path"}; - - url_loader().AddPrepareForLoadResults({WebAppUrlLoader::Result::kUrlLoaded}); - url_loader().SetNextLoadUrlResult(url, WebAppUrlLoader::Result::kUrlLoaded); - - UseDefaultDataRetriever(url); - const AppId bookmark_app_id = GenerateAppIdFromURL(url); - - auto server_web_application_info = std::make_unique(); - server_web_application_info->start_url = url; - server_web_application_info->title = u"Server Name"; - - // Call InstallBookmarkAppFromSync while WebAppInstallManager is not yet - // started. - base::RunLoop run_loop; - install_manager().InstallBookmarkAppFromSync( - bookmark_app_id, std::move(server_web_application_info), - base::BindLambdaForTesting( - [&](const AppId& installed_app_id, InstallResultCode code) { - EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code); - EXPECT_EQ(bookmark_app_id, installed_app_id); - - EXPECT_TRUE(install_manager().has_web_contents_for_testing()); - EXPECT_EQ(0u, install_manager().tasks_size_for_testing()); - - run_loop.Quit(); - })); - - EXPECT_FALSE(install_manager().has_web_contents_for_testing()); - EXPECT_EQ(0u, install_manager().tasks_size_for_testing()); - - InitEmptyRegistrar(); - run_loop.Run(); - - EXPECT_FALSE(install_manager().has_web_contents_for_testing()); - EXPECT_EQ(0u, install_manager().tasks_size_for_testing()); - - EXPECT_TRUE(registrar().GetAppById(bookmark_app_id)); -} - -TEST_F(WebAppInstallManagerTest, - InstallBookmarkAppFromSync_QueueAlreadyInstalled) { - // The registrar is not yet started (initialized) at the beginning of this - // test. - const GURL url{"https://example.com/path"}; - const AppId bookmark_app_id = GenerateAppIdFromURL(url); - - auto server_web_application_info = std::make_unique(); - server_web_application_info->start_url = url; - - // Call InstallBookmarkAppFromSync while WebAppInstallManager is not yet - // started. - base::RunLoop run_loop; - install_manager().InstallBookmarkAppFromSync( - bookmark_app_id, std::move(server_web_application_info), - base::BindLambdaForTesting( - [&](const AppId& installed_app_id, InstallResultCode code) { - EXPECT_EQ(InstallResultCode::kSuccessAlreadyInstalled, code); - EXPECT_EQ(bookmark_app_id, installed_app_id); - - EXPECT_FALSE(install_manager().has_web_contents_for_testing()); - EXPECT_EQ(0u, install_manager().tasks_size_for_testing()); - - run_loop.Quit(); - })); - - EXPECT_FALSE(install_manager().has_web_contents_for_testing()); - EXPECT_EQ(0u, install_manager().tasks_size_for_testing()); - - // The bookmark app shouldn't overwrite the existing web app which is already - // installed. - std::unique_ptr app = - CreateWebApp(url, Source::kSync, - /*user_display_mode=*/DisplayMode::kStandalone); - - EXPECT_EQ(bookmark_app_id, app->app_id()); - InitRegistrarWithApp(std::move(app)); - - run_loop.Run(); - - EXPECT_FALSE(install_manager().has_web_contents_for_testing()); - EXPECT_EQ(0u, install_manager().tasks_size_for_testing()); - - EXPECT_TRUE(registrar().GetAppById(bookmark_app_id)); -} - -TEST_F(WebAppInstallManagerTest, SyncRace_InstallWebAppFull_ThenBookmarkApp) { - InitEmptyRegistrar(); - - const GURL url{"https://example.com/path"}; - const AppId app_id = GenerateAppIdFromURL(url); - - // The web site url must be loaded only once. - url_loader().AddPrepareForLoadResults({WebAppUrlLoader::Result::kUrlLoaded}); - url_loader().AddNextLoadUrlResults(url, - {WebAppUrlLoader::Result::kUrlLoaded}); - - // Prepare web site data for next enqueued full install (the web app). - UseDefaultDataRetriever(url); - - bool bookmark_app_already_installed = false; - - base::RunLoop run_loop; - - controller().SetInstallWebAppsAfterSyncDelegate(base::BindLambdaForTesting( - [&](std::vector web_apps_installed, - SyncInstallDelegate::RepeatingInstallCallback callback) { - EXPECT_EQ(1u, web_apps_installed.size()); - EXPECT_EQ(app_id, web_apps_installed[0]->app_id()); - EXPECT_EQ(url, web_apps_installed[0]->start_url()); - - install_manager().InstallWebAppsAfterSync( - std::move(web_apps_installed), - base::BindLambdaForTesting( - [&](const AppId& installed_app_id, InstallResultCode code) { - EXPECT_EQ(app_id, installed_app_id); - EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code); - EXPECT_TRUE(bookmark_app_already_installed); - run_loop.Quit(); - })); - })); - - // The web app object arrives first from the server. It creates a registry - // entry immediately (with is_in_sync_install() flag set to true). - controller().ApplySyncChanges_AddApps({url}); - - auto server_bookmark_app_info = std::make_unique(); - server_bookmark_app_info->start_url = url; - - // The bookmark app object arrives second from the server. The install request - // gets declined. - install_manager().InstallBookmarkAppFromSync( - app_id, std::move(server_bookmark_app_info), - base::BindLambdaForTesting( - [&](const AppId& installed_app_id, InstallResultCode code) { - EXPECT_EQ(app_id, installed_app_id); - EXPECT_EQ(InstallResultCode::kSuccessAlreadyInstalled, code); - bookmark_app_already_installed = true; - })); - - run_loop.Run(); - - EXPECT_TRUE(bookmark_app_already_installed); -} - -TEST_F(WebAppInstallManagerTest, SyncRace_InstallBookmarkAppFull_ThenWebApp) { - InitEmptyRegistrar(); - - const GURL url{"https://example.com/path"}; - const AppId app_id = GenerateAppIdFromURL(url); - - url_loader().AddPrepareForLoadResults({WebAppUrlLoader::Result::kUrlLoaded, - WebAppUrlLoader::Result::kUrlLoaded}); - // The web site url must be loaded only once. - url_loader().AddNextLoadUrlResults(url, - {WebAppUrlLoader::Result::kUrlLoaded}); - - // Prepare web site data for next enqueued full install (the bookmark app). - UseDefaultDataRetriever(url); - - auto server_bookmark_app_info = std::make_unique(); - server_bookmark_app_info->start_url = url; - server_bookmark_app_info->title = u"Server Name"; - - bool bookmark_app_installed = false; - bool web_app_install_returns_early = false; - - base::RunLoop run_loop; - - // The bookmark app object arrives first from the server, enqueue full - // install. - install_manager().InstallBookmarkAppFromSync( - app_id, std::move(server_bookmark_app_info), - base::BindLambdaForTesting( - [&](const AppId& installed_app_id, InstallResultCode code) { - EXPECT_EQ(app_id, installed_app_id); - EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code); - bookmark_app_installed = true; - run_loop.Quit(); - })); - - controller().SetInstallWebAppsAfterSyncDelegate(base::BindLambdaForTesting( - [&](std::vector web_apps_installed, - SyncInstallDelegate::RepeatingInstallCallback callback) { - EXPECT_EQ(1u, web_apps_installed.size()); - EXPECT_EQ(app_id, web_apps_installed[0]->app_id()); - EXPECT_EQ(url, web_apps_installed[0]->start_url()); - - install_manager().InstallWebAppsAfterSync( - std::move(web_apps_installed), - base::BindLambdaForTesting( - [&](const AppId& installed_app_id, InstallResultCode code) { - EXPECT_EQ(app_id, installed_app_id); - EXPECT_EQ(InstallResultCode::kSuccessAlreadyInstalled, code); - EXPECT_FALSE(bookmark_app_installed); - web_app_install_returns_early = true; - })); - })); - - // The web app object arrives second from the server but it creates a registry - // entry immediately (with is_in_sync_install() flag set to true). - controller().ApplySyncChanges_AddApps({url}); - run_loop.Run(); - - EXPECT_TRUE(web_app_install_returns_early); - EXPECT_TRUE(bookmark_app_installed); -} - -TEST_F(WebAppInstallManagerTest, - SyncRace_InstallBookmarkAppFallback_ThenWebApp) { - InitEmptyRegistrar(); - - const GURL url{"https://example.com/path"}; - const AppId app_id = GenerateAppIdFromURL(url); - - url_loader().AddPrepareForLoadResults({WebAppUrlLoader::Result::kUrlLoaded, - WebAppUrlLoader::Result::kUrlLoaded}); - // We will try to load the web site url only once. - // The web site url will fail. - url_loader().AddNextLoadUrlResults( - url, {WebAppUrlLoader::Result::kFailedPageTookTooLong}); - - // Prepare web site data for next enqueued full install (the bookmark app). - UseDefaultDataRetriever(url); - - auto server_bookmark_app_info = std::make_unique(); - server_bookmark_app_info->start_url = url; - server_bookmark_app_info->title = u"Server Name"; - - bool bookmark_app_installed = false; - bool web_app_install_returns_early = false; - - base::RunLoop run_loop; - - // The bookmark app object arrives first from the server, enqueue full - // install. - install_manager().InstallBookmarkAppFromSync( - app_id, std::move(server_bookmark_app_info), - base::BindLambdaForTesting( - [&](const AppId& installed_app_id, InstallResultCode code) { - EXPECT_EQ(app_id, installed_app_id); - // Full web app install fails, fallback install succeeds. - EXPECT_EQ(InstallResultCode::kSuccessNewInstall, code); - bookmark_app_installed = true; - run_loop.Quit(); - })); - - controller().SetInstallWebAppsAfterSyncDelegate(base::BindLambdaForTesting( - [&](std::vector web_apps_installed, - SyncInstallDelegate::RepeatingInstallCallback callback) { - EXPECT_EQ(1u, web_apps_installed.size()); - EXPECT_EQ(app_id, web_apps_installed[0]->app_id()); - EXPECT_EQ(url, web_apps_installed[0]->start_url()); - - install_manager().InstallWebAppsAfterSync( - std::move(web_apps_installed), - base::BindLambdaForTesting( - [&](const AppId& installed_app_id, InstallResultCode code) { - EXPECT_EQ(app_id, installed_app_id); - // The web app fallback install returns early. - EXPECT_EQ(InstallResultCode::kSuccessAlreadyInstalled, code); - EXPECT_FALSE(bookmark_app_installed); - web_app_install_returns_early = true; - })); - })); - - // The web app object arrives second from the server but it creates a registry - // entry immediately (with is_in_sync_install() flag set to true). - controller().ApplySyncChanges_AddApps({url}); - run_loop.Run(); - - EXPECT_TRUE(web_app_install_returns_early); - EXPECT_TRUE(bookmark_app_installed); -} - TEST_F(WebAppInstallManagerTest, TaskQueueWebContentsReadyRace) { InitEmptyRegistrar(); diff --git a/chrome/browser/web_applications/web_app_migration_manager_browsertest.cc b/chrome/browser/web_applications/web_app_migration_manager_browsertest.cc index 0ba329ab0a007f..e0f01e1f9454a5 100644 --- a/chrome/browser/web_applications/web_app_migration_manager_browsertest.cc +++ b/chrome/browser/web_applications/web_app_migration_manager_browsertest.cc @@ -81,14 +81,11 @@ class WebAppMigrationManagerBrowserTest : public InProcessBrowserTest { public: WebAppMigrationManagerBrowserTest() { if (content::IsPreTest()) { - scoped_feature_list_.InitWithFeatures( - {features::kSyncBookmarkApps}, - {features::kDesktopPWAsWithoutExtensions}); + scoped_feature_list_.InitAndDisableFeature( + features::kDesktopPWAsWithoutExtensions); } else { - scoped_feature_list_.InitWithFeatures( - {features::kDesktopPWAsWithoutExtensions, - features::kSyncBookmarkApps}, - {}); + scoped_feature_list_.InitAndEnableFeature( + features::kDesktopPWAsWithoutExtensions); } } @@ -253,64 +250,6 @@ IN_PROC_BROWSER_TEST_F(WebAppMigrationManagerBrowserTest, run_loop.Run(); } -IN_PROC_BROWSER_TEST_F(WebAppMigrationManagerBrowserTest, - InstallShadowBookmarkApp) { - EXPECT_FALSE(provider().registrar().AsBookmarkAppRegistrar()); - AwaitRegistryReady(); - - auto* extensions_registry = - extensions::ExtensionRegistry::Get(browser()->profile()); - extensions::TestExtensionRegistryObserver extensions_registry_observer( - extensions_registry); - - ui_test_utils::NavigateToURL(browser(), GURL{kSimpleManifestStartUrl}); - AppId app_id = InstallWebAppAsUserViaOmnibox(); - - EXPECT_TRUE(provider().registrar().IsInstalled(app_id)); - - scoped_refptr extension = - extensions_registry_observer.WaitForExtensionInstalled(); - EXPECT_EQ(extension->id(), app_id); - EXPECT_EQ("Manifest test app", extension->short_name()); -} - -IN_PROC_BROWSER_TEST_F(WebAppMigrationManagerBrowserTest, - PRE_UninstallShadowBookmarkApp) { - EXPECT_TRUE(provider().registrar().AsBookmarkAppRegistrar()); - AwaitRegistryReady(); - - // Install shadow bookmark app. - ui_test_utils::NavigateToURL(browser(), GURL{kSimpleManifestStartUrl}); - AppId app_id = InstallWebAppAsUserViaOmnibox(); - - EXPECT_TRUE(provider().registrar().IsInstalled(app_id)); - EXPECT_TRUE(ui_manager().dialog_manager().CanUninstallWebApp(app_id)); -} - -IN_PROC_BROWSER_TEST_F(WebAppMigrationManagerBrowserTest, - UninstallShadowBookmarkApp) { - EXPECT_FALSE(provider().registrar().AsBookmarkAppRegistrar()); - AwaitRegistryReady(); - - AppId app_id = GenerateAppIdFromURL(GURL{kSimpleManifestStartUrl}); - - EXPECT_TRUE(provider().registrar().IsInstalled(app_id)); - EXPECT_TRUE(ui_manager().dialog_manager().CanUninstallWebApp(app_id)); - - auto* extensions_registry = - extensions::ExtensionRegistry::Get(browser()->profile()); - extensions::TestExtensionRegistryObserver extensions_registry_observer( - extensions_registry); - - UninstallWebAppAsUserViaMenu(app_id); - EXPECT_FALSE(provider().registrar().IsInstalled(app_id)); - - scoped_refptr extension = - extensions_registry_observer.WaitForExtensionUninstalled(); - EXPECT_EQ(extension->id(), app_id); - EXPECT_EQ("Manifest test app", extension->short_name()); -} - // TODO(crbug.com/1020037): Test policy installed bookmark apps with an external // install source to cover // WebAppMigrationManager::MigrateBookmarkAppInstallSource() logic. diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index c5b39930245493..4a70b657a20c9d 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc @@ -862,11 +862,6 @@ const base::Feature kSmbFs{"SmbFs", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kSoundContentSetting{"SoundContentSetting", base::FEATURE_ENABLED_BY_DEFAULT}; -// Enables or disables receiving and sending bookmark apps creation through APPS -// sync. Will be removed in M92 https://crbug.com/1185374. -const base::Feature kSyncBookmarkApps{"SyncBookmarkApps", - base::FEATURE_DISABLED_BY_DEFAULT}; - #if BUILDFLAG(IS_CHROMEOS_ASH) // Enables or disables chrome://sys-internals. const base::Feature kSysInternals{"SysInternals", diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 2cec4166c5b6fc..8d9ee711db93c3 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h @@ -579,9 +579,6 @@ COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kSmbFs; COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kSoundContentSetting; -COMPONENT_EXPORT(CHROME_FEATURES) -extern const base::Feature kSyncBookmarkApps; - #if BUILDFLAG(IS_CHROMEOS_ASH) COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kSysInternals; diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index 4188ae755d19a7..1192b0b02dadfc 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json @@ -183,10 +183,6 @@ "dependencies": ["permission:browsingData"], "contexts": ["blessed_extension"] }, - "cast.channel": { - "dependencies": ["permission:cast"], - "contexts": ["blessed_extension"] - }, "certificateProvider": { "dependencies": ["permission:certificateProvider"], "contexts": ["blessed_extension"] diff --git a/chrome/test/data/autofill/captured_sites/testcases.json b/chrome/test/data/autofill/captured_sites/testcases.json index a26013b9ff78f8..b9b9ed04348e36 100644 --- a/chrome/test/data/autofill/captured_sites/testcases.json +++ b/chrome/test/data/autofill/captured_sites/testcases.json @@ -6,7 +6,7 @@ { "site_name": "abercrombie", "disabled":true, "bug_number":1172845 }, { "site_name": "academy" }, { "site_name": "accesscorrections" }, - { "site_name": "aeropostale" }, + { "site_name": "aeropostale", "bug_number":1197254 }, { "site_name": "agoda" }, { "site_name": "amazon" }, { "site_name": "apmex" }, @@ -19,7 +19,7 @@ { "site_name": "bed_bath_beyond" }, { "site_name": "belk" }, { "site_name": "bestbuy" }, - { "site_name": "bhphotovideo", "disabled":true, "bug_number":1173033 }, + { "site_name": "bhphotovideo", "bug_number":1173033 }, { "site_name": "bloomingdales" }, { "site_name": "bodybuilding" }, { "site_name": "booking" }, @@ -187,7 +187,7 @@ { "site_name": "tickets" }, { "site_name": "tiger_direct" }, { "site_name": "tillys", "bug_number":1172707 }, - { "site_name": "timberland", "disabled":true, "bug_number":1159947 }, + { "site_name": "timberland", "bug_number":1173038 }, { "site_name": "tirerack" }, { "site_name": "torrid" }, { "site_name": "tractorsupply" }, diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/common.js b/chrome/test/data/extensions/api_test/cast_channel/api/common.js deleted file mode 100644 index 2eda0868a2632b..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/common.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -assertOpenChannel = function(channel) { - chrome.test.assertNoLastError(); - chrome.test.assertTrue(!!channel); - chrome.test.assertTrue(channel.channelId > 0); - chrome.test.assertTrue(channel.connectInfo.ipAddress == '192.168.1.1'); - chrome.test.assertTrue(channel.connectInfo.port == 8009); - chrome.test.assertTrue(channel.connectInfo.auth == 'ssl_verified'); - chrome.test.assertTrue(channel.readyState == 'open'); - chrome.test.assertTrue(channel.errorState == undefined); -}; - -assertClosedChannel = function(channel) { - chrome.test.assertNoLastError(); - assertClosedChannelWithError(channel, undefined); -}; - -assertClosedChannelWithError = function(channel, error) { - chrome.test.assertTrue(!!channel); - chrome.test.assertTrue(channel.channelId > 0); - chrome.test.assertTrue(channel.connectInfo.ipAddress == '192.168.1.1'); - chrome.test.assertTrue(channel.connectInfo.port == 8009); - chrome.test.assertTrue(channel.connectInfo.auth == 'ssl_verified'); - chrome.test.assertTrue(channel.readyState == 'closed'); - chrome.test.assertTrue(channel.errorState == error); -}; diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/manifest.json b/chrome/test/data/extensions/api_test/cast_channel/api/manifest.json deleted file mode 100644 index ced616b26b5614..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/manifest.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8xv6iO+j4kzj1HiBL93+XVJH/CRyAQMUHS/Z0l8nCAzaAFkW/JsNwxJqQhrZspnxLqbQxNncXs6g6bsXAwKHiEs+LSs+bIv0Gc/2ycZdhXJ8GhEsSMakog5dpQd1681c2gLK/8CrAoewE/0GIKhaFcp7a2iZlGh4Am6fgMKy0iQIDAQAB", - "manifest_version": 2, - "name": "Cast Channel Extension", - "version": "1.0", - "description": "Test Cast Channel Extension", - "permissions": ["cast"] -} diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error.html b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error.html deleted file mode 100644 index 1a4c6c4aa67bd2..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error.js b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error.js deleted file mode 100644 index 2df11f6f47b212..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error.js +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -var errorEvent = false; -var openCallback = false; - -var onClose = function(channel) { - chrome.test.assertLastError('Channel socket error = 3'); - assertClosedChannelWithError(channel, 'connect_error'); - chrome.test.succeed(); -} - -var onError = function(channel, error) { - errorEvent = true; - chrome.test.assertTrue(error.errorState == 'connect_error'); - chrome.test.assertTrue(error.eventType == 19); - chrome.test.assertTrue(error.netReturnValue == -2); - maybeClose(channel); -} - -var onOpen = function(channel) { - chrome.test.assertLastError('Channel socket error = 3'); - openCallback = true; - assertClosedChannelWithError(channel, 'connect_error'); - maybeClose(channel); -}; - -var maybeClose = function(channel) { - if (errorEvent && openCallback) { - chrome.cast.channel.close(channel, onClose); - } -}; - -chrome.cast.channel.onError.addListener(onError); -chrome.cast.channel.open({ - ipAddress: '192.168.1.1', - port: 8009, - auth: 'ssl_verified'}, onOpen); diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error_send.html b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error_send.html deleted file mode 100644 index 090ff78f99c853..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error_send.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error_send.js b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error_send.js deleted file mode 100644 index 179ef9882c1d59..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error_send.js +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -var message = { - 'namespace_': 'foo', - 'sourceId': 'src', - 'destinationId': 'dest', - 'data': 'some-string' -}; - -var onClose = function(channel) { - chrome.test.assertLastError('Channel socket error = 3'); - chrome.test.succeed(); -}; - -var onSend = function(channel) { - chrome.test.assertLastError('Channel error = 1'); - chrome.cast.channel.close(channel, onClose); -}; - -var onOpen = function(channel) { - chrome.test.assertLastError('Channel socket error = 3'); - assertClosedChannelWithError(channel, 'connect_error'); - chrome.cast.channel.send(channel, message, onSend); -}; - -chrome.cast.channel.open({ - ipAddress: '192.168.1.1', - port: 8009, - auth: 'ssl_verified'}, onOpen); diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_receive_close.html b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_receive_close.html deleted file mode 100644 index accb390c166256..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_receive_close.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_receive_close.js b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_receive_close.js deleted file mode 100644 index 36c255dcd617fb..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_receive_close.js +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -var message = { - 'namespace_': 'foo', - 'sourceId': 'src', - 'destinationId': 'dest', - 'data': 'some-string' -}; - -var onClose = function(channel) { - assertClosedChannel(channel); - chrome.test.succeed(); -}; - -var numMessages = 0; - -var onMessage = function(channel, message) { - assertOpenChannel(channel); - ++numMessages; - if (numMessages == 2) { // Expect a couple of messages. - chrome.cast.channel.close(channel, onClose); - } -}; - -var onOpen = function(channel) { - assertOpenChannel(channel); - chrome.cast.channel.onMessage.addListener(onMessage); - chrome.test.notifyPass(); -}; - -chrome.cast.channel.open({ - ipAddress: '192.168.1.1', - port: 8009, - auth: 'ssl_verified'}, onOpen); diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_send_close.html b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_send_close.html deleted file mode 100644 index e7e13361156429..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_send_close.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_send_close.js b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_send_close.js deleted file mode 100644 index 6ec4ad50de5192..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_send_close.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -var message = { - 'namespace_': 'foo', - 'sourceId': 'src', - 'destinationId': 'dest', - 'data': 'some-string' -}; - -var onClose = function(channel) { - assertClosedChannel(channel); - chrome.test.succeed(); -}; - -var onSend = function(channel) { - assertOpenChannel(channel); - chrome.cast.channel.close(channel, onClose); -}; - -var onOpen = function(channel) { - assertOpenChannel(channel); - chrome.cast.channel.send(channel, message, onSend); -}; -chrome.cast.channel.open({ - ipAddress: '192.168.1.1', - port: 8009, - auth: 'ssl_verified'}, onOpen); diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout.html b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout.html deleted file mode 100644 index 00c4bcb3d2deb0..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout.js b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout.js deleted file mode 100644 index 2ec299dbfdd41c..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - - -chrome.cast.channel.open({ - ipAddress: '192.168.1.1', - port: 8009, - auth: 'ssl_verified', - livenessTimeout: 5000, - pingInterval: 1000 -}, function(channel) { - assertOpenChannel(channel); - console.log(JSON.stringify(channel)); - chrome.test.assertEq(channel.keepAlive, true); - chrome.cast.channel.onError.addListener( - function(channel, error) { - chrome.test.assertEq(channel.keepAlive, true); - if (channel.readyState == 'closed' && - error.errorState == 'ping_timeout') { - chrome.cast.channel.close(channel, () => { - chrome.test.sendMessage('timeout_ssl'); - }); - } - }); - chrome.test.notifyPass(); - chrome.test.sendMessage('channel_opened_ssl'); -}); - diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout_verified.html b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout_verified.html deleted file mode 100644 index dfea8c330305d8..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout_verified.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout_verified.js b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout_verified.js deleted file mode 100644 index f667b61cff3201..00000000000000 --- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout_verified.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -chrome.cast.channel.open({ - ipAddress: '192.168.1.1', - port: 8009, - auth: 'ssl_verified', - livenessTimeout: 5000, - pingInterval: 1000 -}, function(channel) { - assertOpenChannel(channel); - console.log(JSON.stringify(channel)); - chrome.test.assertEq(channel.keepAlive, true); - chrome.cast.channel.onError.addListener( - function(channel, error) { - chrome.test.assertEq(channel.keepAlive, true); - if (channel.readyState == 'closed' && - error.errorState == 'ping_timeout') { - chrome.cast.channel.close(channel, () => { - chrome.test.sendMessage('timeout_ssl_verified'); - }); - } - }); - chrome.test.notifyPass(); - chrome.test.sendMessage('channel_opened_ssl_verified'); -}); diff --git a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc index c4f0e50cd20f1c..bab9c0d7621da9 100644 --- a/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/configure_bottom_sheet_action_unittest.cc @@ -44,9 +44,9 @@ class ConfigureBottomSheetActionTest : public testing::Test { Invoke([this](ConfigureBottomSheetProto::PeekMode peek_mode) { peek_mode_ = peek_mode; })); - ON_CALL(mock_action_delegate_, OnWaitForWindowHeightChange(_)) + ON_CALL(mock_action_delegate_, WaitForWindowHeightChange(_)) .WillByDefault(Invoke( - [this](base::OnceCallback& callback) { + [this](base::OnceCallback callback) { on_resize_cb_ = std::move(callback); })); } @@ -62,11 +62,10 @@ class ConfigureBottomSheetActionTest : public testing::Test { *action_proto.mutable_configure_bottom_sheet() = proto_; action_ = std::make_unique( &mock_action_delegate_, action_proto); - action_->ProcessAction( - base::BindOnce(base::BindLambdaForTesting( - [&](std::unique_ptr result) { - processed_action_ = *result; - }))); + action_->ProcessAction(base::BindOnce(base::BindLambdaForTesting( + [&](std::unique_ptr result) { + processed_action_ = *result; + }))); } // Runs an action that waits for a resize. diff --git a/components/autofill_assistant/browser/actions/dispatch_js_event_action_unittest.cc b/components/autofill_assistant/browser/actions/dispatch_js_event_action_unittest.cc index dff5ee69a60186..13af1181b8f7b6 100644 --- a/components/autofill_assistant/browser/actions/dispatch_js_event_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/dispatch_js_event_action_unittest.cc @@ -22,7 +22,7 @@ class DispatchJsEventActionTest : public testing::Test { DispatchJsEventActionTest() {} void SetUp() override { - ON_CALL(mock_action_delegate_, OnDispatchJsEvent(_)) + ON_CALL(mock_action_delegate_, DispatchJsEvent(_)) .WillByDefault(RunOnceCallback<0>(OkClientStatus())); } @@ -40,7 +40,7 @@ class DispatchJsEventActionTest : public testing::Test { }; TEST_F(DispatchJsEventActionTest, EmptyProtoSetsMessageDoesNothing) { - EXPECT_CALL(mock_action_delegate_, OnDispatchJsEvent(_)); + EXPECT_CALL(mock_action_delegate_, DispatchJsEvent(_)); EXPECT_CALL( callback_, Run(Pointee(Property(&ProcessedActionProto::status, ACTION_APPLIED)))); diff --git a/components/autofill_assistant/browser/actions/generate_password_for_form_field_action_unittest.cc b/components/autofill_assistant/browser/actions/generate_password_for_form_field_action_unittest.cc index 05d0731357366b..b3b140a3f61430 100644 --- a/components/autofill_assistant/browser/actions/generate_password_for_form_field_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/generate_password_for_form_field_action_unittest.cc @@ -60,7 +60,7 @@ class GeneratePasswordForFormFieldActionTest : public testing::Test { }; TEST_F(GeneratePasswordForFormFieldActionTest, GeneratedPassword) { - ON_CALL(mock_action_delegate_, OnRetrieveElementFormAndFieldData) + ON_CALL(mock_action_delegate_, RetrieveElementFormAndFieldData) .WillByDefault(RunOnceCallback<1>(ClientStatus(ACTION_APPLIED), autofill::FormData(), autofill::FormFieldData())); @@ -82,7 +82,7 @@ TEST_F(GeneratePasswordForFormFieldActionTest, GeneratedPassword) { } TEST_F(GeneratePasswordForFormFieldActionTest, FormDataIsNotRetrieved) { - ON_CALL(mock_action_delegate_, OnRetrieveElementFormAndFieldData) + ON_CALL(mock_action_delegate_, RetrieveElementFormAndFieldData) .WillByDefault(RunOnceCallback<1>(ClientStatus(INVALID_SELECTOR), autofill::FormData(), autofill::FormFieldData())); diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h index 68637c388b818d..aa0b20a9d47eb8 100644 --- a/components/autofill_assistant/browser/actions/mock_action_delegate.h +++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h @@ -42,130 +42,69 @@ class MockActionDelegate : public ActionDelegate { override { OnShortWaitForElement(selector, callback); } - MOCK_METHOD2( - OnShortWaitForElement, - void(const Selector& selector, - base::OnceCallback&)); - void ShortWaitForElementWithSlowWarning( const Selector& selector, - base::OnceCallback callback) - override { + base::OnceCallback callback) { OnShortWaitForElement(selector, callback); } MOCK_METHOD2( - OnShortWaitForElementWithSlowWarning, + OnShortWaitForElement, void(const Selector& selector, base::OnceCallback&)); - void WaitForDom( - base::TimeDelta max_wait_time, - bool allow_interrupt, - WaitForDomObserver* observer, - base::RepeatingCallback< - void(BatchElementChecker*, + MOCK_METHOD5( + WaitForDom, + void(base::TimeDelta max_wait_time, + bool allow_interrupt, + WaitForDomObserver* observer, + base::RepeatingCallback)> check_elements, - base::OnceCallback callback) - override { - OnWaitForDom(max_wait_time, allow_interrupt, check_elements, callback); - } - MOCK_METHOD4( - OnWaitForDom, - void(base::TimeDelta, - bool, - base::RepeatingCallback< - void(BatchElementChecker*, - base::OnceCallback)>&, - base::OnceCallback&)); - - void WaitForDomWithSlowWarning( - base::TimeDelta max_wait_time, - bool allow_interrupt, - WaitForDomObserver* observer, - base::RepeatingCallback< - void(BatchElementChecker*, + base::OnceCallback + callback)); + MOCK_METHOD5( + WaitForDomWithSlowWarning, + void(base::TimeDelta max_wait_time, + bool allow_interrupt, + WaitForDomObserver* observer, + base::RepeatingCallback)> check_elements, - base::OnceCallback callback) - override { - OnWaitForDom(max_wait_time, allow_interrupt, check_elements, callback); - } - MOCK_METHOD4( - OnWaitForDomWithSlowWarning, - void(base::TimeDelta, - bool, - base::RepeatingCallback< - void(BatchElementChecker*, - base::OnceCallback)>&, - base::OnceCallback&)); - + base::OnceCallback + callback)); MOCK_METHOD1(SetStatusMessage, void(const std::string& message)); - MOCK_METHOD0(GetStatusMessage, std::string()); - MOCK_METHOD1(SetBubbleMessage, void(const std::string& message)); - MOCK_METHOD0(GetBubbleMessage, std::string()); - MOCK_CONST_METHOD2(FindElement, void(const Selector& selector, ElementFinder::Callback)); - MOCK_CONST_METHOD2(FindAllElements, void(const Selector& selector, ElementFinder::Callback callback)); - MOCK_METHOD5(Prompt, void(std::unique_ptr> user_actions, bool disable_force_expand_sheet, base::OnceCallback end_on_navigation_callback, bool browse_mode, bool browse_mode_invisible)); - MOCK_METHOD0(CleanUpAfterPrompt, void()); - MOCK_METHOD1(SetBrowseDomainsAllowlist, void(std::vector domains)); - - void FillAddressForm( - const autofill::AutofillProfile* profile, - const Selector& selector, - base::OnceCallback callback) override { - OnFillAddressForm(profile, selector, callback); - } - MOCK_METHOD3(OnFillAddressForm, + MOCK_METHOD3(FillAddressForm, void(const autofill::AutofillProfile* profile, const Selector& selector, - base::OnceCallback& callback)); - - void FillCardForm( - std::unique_ptr card, - const std::u16string& cvc, - const Selector& selector, - base::OnceCallback callback) override { - OnFillCardForm(card.get(), cvc, selector, callback); - } - - void RetrieveElementFormAndFieldData( - const Selector& selector, - base::OnceCallback callback) - override { - OnRetrieveElementFormAndFieldData(selector, callback); - } - + base::OnceCallback callback)); + MOCK_METHOD4(FillCardForm, + void(std::unique_ptr card, + const std::u16string& cvc, + const Selector& selector, + base::OnceCallback callback)); MOCK_METHOD2( - OnRetrieveElementFormAndFieldData, + RetrieveElementFormAndFieldData, void(const Selector& selector, base::OnceCallback& callback)); - - MOCK_METHOD4(OnFillCardForm, - void(const autofill::CreditCard* card, - const std::u16string& cvc, - const Selector& selector, - base::OnceCallback& callback)); - + const autofill::FormFieldData&)> callback)); MOCK_METHOD5(ScrollToElementPosition, void(const Selector& selector, const TopPadding& top_padding, @@ -234,72 +173,38 @@ class MockActionDelegate : public ActionDelegate { base::OnceCallback cancel_callback)); MOCK_METHOD0(GetUserModel, UserModel*()); MOCK_METHOD0(GetEventHandler, EventHandler*()); - - void WaitForWindowHeightChange( - base::OnceCallback callback) override { - OnWaitForWindowHeightChange(callback); - } - - MOCK_METHOD1(OnWaitForWindowHeightChange, - void(base::OnceCallback& callback)); - - MOCK_METHOD3(OnWaitForDocumentReadyState, - void(DocumentReadyState, - const ElementFinder::Result&, + MOCK_METHOD1(WaitForWindowHeightChange, + void(base::OnceCallback callback)); + MOCK_METHOD4(WaitForDocumentReadyState, + void(base::TimeDelta max_wait_time, + DocumentReadyState min_ready_state, + const ElementFinder::Result& optional_frame_element, base::OnceCallback&)); - - void WaitForDocumentReadyState( - base::TimeDelta max_wait_time, - DocumentReadyState min_ready_state, - const ElementFinder::Result& optional_frame_element, - base::OnceCallback callback) override { - OnWaitForDocumentReadyState(min_ready_state, optional_frame_element, - callback); - } - + base::TimeDelta)> callback)); MOCK_METHOD4( WaitUntilDocumentIsInReadyState, void(base::TimeDelta, DocumentReadyState, const ElementFinder::Result&, base::OnceCallback)); - MOCK_METHOD0(RequireUI, void()); MOCK_METHOD0(SetExpandSheetForPromptAction, bool()); - MOCK_METHOD3( - OnSetGenericUi, + SetGenericUi, void(std::unique_ptr generic_ui, - base::OnceCallback& end_action_callback, - base::OnceCallback& + base::OnceCallback end_action_callback, + base::OnceCallback view_inflation_finished_callback)); - - void SetGenericUi( - std::unique_ptr generic_ui, - base::OnceCallback end_action_callback, - base::OnceCallback - view_inflation_finished_callback) override { - OnSetGenericUi(std::move(generic_ui), end_action_callback, - view_inflation_finished_callback); - } MOCK_METHOD0(ClearGenericUi, void()); MOCK_METHOD1(SetOverlayBehavior, void(ConfigureUiStateProto::OverlayBehavior)); - MOCK_METHOD1(MaybeShowSlowWebsiteWarning, void(base::OnceCallback)); MOCK_METHOD0(MaybeShowSlowConnectionWarning, void()); - - MOCK_CONST_METHOD1(OnDispatchJsEvent, - void(base::OnceCallback)); - void DispatchJsEvent( - base::OnceCallback callback) const override { - OnDispatchJsEvent(std::move(callback)); - } + MOCK_CONST_METHOD1( + DispatchJsEvent, + void(base::OnceCallback callback)); base::WeakPtr GetWeakPtr() const override { return weak_ptr_factory_.GetWeakPtr(); diff --git a/components/autofill_assistant/browser/actions/prompt_action_unittest.cc b/components/autofill_assistant/browser/actions/prompt_action_unittest.cc index 27fb21612a478a..a94e00f590e154 100644 --- a/components/autofill_assistant/browser/actions/prompt_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/prompt_action_unittest.cc @@ -15,6 +15,7 @@ #include "base/test/test_simple_task_runner.h" #include "base/timer/timer.h" #include "components/autofill_assistant/browser/actions/mock_action_delegate.h" +#include "components/autofill_assistant/browser/wait_for_dom_observer.h" #include "components/autofill_assistant/browser/web/mock_web_controller.h" #include "testing/gmock/include/gmock/gmock.h" @@ -44,7 +45,7 @@ class PromptActionTest : public testing::Test { ON_CALL(mock_web_controller_, OnFindElement(_, _)) .WillByDefault(RunOnceCallback<1>( ClientStatus(ELEMENT_RESOLUTION_FAILED), nullptr)); - EXPECT_CALL(mock_action_delegate_, OnWaitForDom(_, _, _, _)) + EXPECT_CALL(mock_action_delegate_, WaitForDom(_, _, _, _, _)) .WillRepeatedly(Invoke(this, &PromptActionTest::FakeWaitForDom)); ON_CALL(mock_action_delegate_, Prompt(_, _, _, _, _)) .WillByDefault( @@ -65,10 +66,11 @@ class PromptActionTest : public testing::Test { void FakeWaitForDom( base::TimeDelta max_wait_time, bool allow_interrupt, + WaitForDomObserver* observer, base::RepeatingCallback< void(BatchElementChecker*, - base::OnceCallback)>& check_elements, - base::OnceCallback& + base::OnceCallback)> check_elements, + base::OnceCallback done_waiting_callback) { fake_wait_for_dom_done_ = std::move(done_waiting_callback); RunFakeWaitForDom(check_elements); diff --git a/components/autofill_assistant/browser/actions/show_generic_ui_action_unittest.cc b/components/autofill_assistant/browser/actions/show_generic_ui_action_unittest.cc index 469beb5c5fe6b5..4ada2771d39592 100644 --- a/components/autofill_assistant/browser/actions/show_generic_ui_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/show_generic_ui_action_unittest.cc @@ -43,12 +43,12 @@ class ShowGenericUiActionTest : public content::RenderViewHostTestHarness { void SetUp() override { RenderViewHostTestHarness::SetUp(); - ON_CALL(mock_action_delegate_, OnSetGenericUi(_, _, _)) + ON_CALL(mock_action_delegate_, SetGenericUi(_, _, _)) .WillByDefault( Invoke([&](std::unique_ptr generic_ui, - base::OnceCallback& + base::OnceCallback end_action_callback, - base::OnceCallback& + base::OnceCallback view_inflation_finished_callback) { std::move(view_inflation_finished_callback) .Run(ClientStatus(ACTION_APPLIED)); @@ -95,13 +95,12 @@ class ShowGenericUiActionTest : public content::RenderViewHostTestHarness { }; TEST_F(ShowGenericUiActionTest, FailedViewInflationEndsAction) { - ON_CALL(mock_action_delegate_, OnSetGenericUi(_, _, _)) - .WillByDefault( - Invoke([&](std::unique_ptr generic_ui, - base::OnceCallback& - end_action_callback, - base::OnceCallback& - view_inflation_finished_callback) { + ON_CALL(mock_action_delegate_, SetGenericUi(_, _, _)) + .WillByDefault(Invoke( + [&](std::unique_ptr generic_ui, + base::OnceCallback end_action_callback, + base::OnceCallback + view_inflation_finished_callback) { std::move(view_inflation_finished_callback) .Run(ClientStatus(INVALID_ACTION)); })); @@ -117,7 +116,7 @@ TEST_F(ShowGenericUiActionTest, FailedViewInflationEndsAction) { TEST_F(ShowGenericUiActionTest, GoesIntoPromptState) { InSequence seq; EXPECT_CALL(mock_action_delegate_, Prompt(_, _, _, _, _)).Times(1); - EXPECT_CALL(mock_action_delegate_, OnSetGenericUi(_, _, _)).Times(1); + EXPECT_CALL(mock_action_delegate_, SetGenericUi(_, _, _)).Times(1); EXPECT_CALL(mock_action_delegate_, ClearGenericUi()).Times(1); EXPECT_CALL(mock_action_delegate_, CleanUpAfterPrompt()).Times(1); EXPECT_CALL( @@ -157,13 +156,13 @@ TEST_F(ShowGenericUiActionTest, NonEmptyOutputModel) { proto_.add_output_model_identifiers("value_2"); - ON_CALL(mock_action_delegate_, OnSetGenericUi(_, _, _)) - .WillByDefault( - Invoke([this](std::unique_ptr generic_ui, - base::OnceCallback& - end_action_callback, - base::OnceCallback& - view_inflation_finished_callback) { + ON_CALL(mock_action_delegate_, SetGenericUi(_, _, _)) + .WillByDefault(Invoke( + [this]( + std::unique_ptr generic_ui, + base::OnceCallback end_action_callback, + base::OnceCallback + view_inflation_finished_callback) { std::move(view_inflation_finished_callback) .Run(ClientStatus(ACTION_APPLIED)); user_model_.SetValue("value_2", SimpleValue(std::string("change"))); @@ -200,7 +199,7 @@ TEST_F(ShowGenericUiActionTest, OutputModelNotSubsetOfInputModel) { proto_.add_output_model_identifiers("value_2"); proto_.add_output_model_identifiers("value_3"); - EXPECT_CALL(mock_action_delegate_, OnSetGenericUi(_, _, _)).Times(0); + EXPECT_CALL(mock_action_delegate_, SetGenericUi(_, _, _)).Times(0); EXPECT_CALL(mock_action_delegate_, ClearGenericUi()).Times(1); EXPECT_CALL( callback_, @@ -445,7 +444,7 @@ TEST_F(ShowGenericUiActionTest, ElementPreconditionMissesIdentifier) { ->add_filters() ->set_css_selector("selector"); - EXPECT_CALL(mock_action_delegate_, OnSetGenericUi(_, _, _)).Times(0); + EXPECT_CALL(mock_action_delegate_, SetGenericUi(_, _, _)).Times(0); EXPECT_CALL(mock_action_delegate_, ClearGenericUi()).Times(1); EXPECT_CALL( callback_, @@ -459,13 +458,12 @@ TEST_F(ShowGenericUiActionTest, ElementPreconditionMissesIdentifier) { } TEST_F(ShowGenericUiActionTest, EndActionOnNavigation) { - ON_CALL(mock_action_delegate_, OnSetGenericUi(_, _, _)) - .WillByDefault( - Invoke([&](std::unique_ptr generic_ui, - base::OnceCallback& - end_action_callback, - base::OnceCallback& - view_inflation_finished_callback) { + ON_CALL(mock_action_delegate_, SetGenericUi(_, _, _)) + .WillByDefault(Invoke( + [&](std::unique_ptr generic_ui, + base::OnceCallback end_action_callback, + base::OnceCallback + view_inflation_finished_callback) { std::move(view_inflation_finished_callback) .Run(ClientStatus(ACTION_APPLIED)); })); @@ -498,13 +496,12 @@ TEST_F(ShowGenericUiActionTest, BreakingNavigationBeforeUiIsSet) { bool browse_mode, bool browse_mode_invisible) { std::move(end_navigation_callback).Run(); }); - ON_CALL(mock_action_delegate_, OnSetGenericUi(_, _, _)) - .WillByDefault( - Invoke([&](std::unique_ptr generic_ui, - base::OnceCallback& - end_action_callback, - base::OnceCallback& - view_inflation_finished_callback) { + ON_CALL(mock_action_delegate_, SetGenericUi(_, _, _)) + .WillByDefault(Invoke( + [&](std::unique_ptr generic_ui, + base::OnceCallback end_action_callback, + base::OnceCallback + view_inflation_finished_callback) { std::move(view_inflation_finished_callback) .Run(ClientStatus(ACTION_APPLIED)); // Also end action when UI is set. At this point, the action should diff --git a/components/autofill_assistant/browser/actions/use_address_action_unittest.cc b/components/autofill_assistant/browser/actions/use_address_action_unittest.cc index 894b8e919a166c..d50b55e91859c1 100644 --- a/components/autofill_assistant/browser/actions/use_address_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/use_address_action_unittest.cc @@ -173,7 +173,7 @@ TEST_F(UseAddressActionTest, ResolveProfileByNameSucceeds) { *use_address->mutable_form_field_element() = ToSelectorProto(kFakeSelector); use_address->set_name(kAddressName); EXPECT_CALL(mock_action_delegate_, - OnFillAddressForm(Pointee(Eq(profile_)), _, _)) + FillAddressForm(Pointee(Eq(profile_)), _, _)) .WillOnce(RunOnceCallback<2>(OkClientStatus())); EXPECT_EQ(ProcessedActionStatusProto::ACTION_APPLIED, ProcessAction(action)); } @@ -208,7 +208,7 @@ TEST_F(UseAddressActionTest, ResolveProfileByModelIdentifierSucceeds) { *use_address->mutable_form_field_element() = ToSelectorProto(kFakeSelector); use_address->set_model_identifier(kModelIdentifier); EXPECT_CALL(mock_action_delegate_, - OnFillAddressForm(Pointee(Eq(profile_)), _, _)) + FillAddressForm(Pointee(Eq(profile_)), _, _)) .WillOnce(RunOnceCallback<2>(OkClientStatus())); EXPECT_EQ(ProcessedActionStatusProto::ACTION_APPLIED, ProcessAction(action)); } @@ -244,7 +244,7 @@ TEST_F(UseAddressActionTest, ShortWaitForElementVisible) { ActionProto action_proto = CreateUseAddressAction(); // Autofill succeeds. - EXPECT_CALL(mock_action_delegate_, OnFillAddressForm(NotNull(), _, _)) + EXPECT_CALL(mock_action_delegate_, FillAddressForm(NotNull(), _, _)) .WillOnce(RunOnceCallback<2>(OkClientStatus())); // Validation succeeds. @@ -280,7 +280,7 @@ TEST_F(UseAddressActionTest, ValidationSucceeds) { // Autofill succeeds. EXPECT_CALL(mock_action_delegate_, - OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) + FillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) .WillOnce(RunOnceCallback<2>(OkClientStatus())); // Validation succeeds. @@ -321,7 +321,7 @@ TEST_F(UseAddressActionTest, FallbackFails) { // Autofill succeeds. EXPECT_CALL(mock_action_delegate_, - OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) + FillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) .WillOnce(RunOnceCallback<2>(OkClientStatus())); // Validation fails when getting FIRST_NAME. @@ -401,7 +401,7 @@ TEST_F(UseAddressActionTest, FillAddressWithFallback) { // Autofill succeeds. EXPECT_CALL(mock_action_delegate_, - OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) + FillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) .WillOnce(RunOnceCallback<2>(OkClientStatus())); // First validation fails with an empty value, called once for each field. @@ -443,7 +443,7 @@ TEST_F(UseAddressActionTest, AutofillFailureWithoutRequiredFieldsIsFatal) { ActionProto action_proto = CreateUseAddressAction(); EXPECT_CALL(mock_action_delegate_, - OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) + FillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) .WillOnce(RunOnceCallback<2>(ClientStatus(OTHER_ACTION_STATUS))); ProcessedActionProto processed_action; @@ -475,7 +475,7 @@ TEST_F(UseAddressActionTest, Selector first_name_selector({"#first_name"}); EXPECT_CALL(mock_action_delegate_, - OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) + FillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) .WillOnce(RunOnceCallback<2>(ClientStatus(OTHER_ACTION_STATUS))); // First validation fails. @@ -525,7 +525,7 @@ TEST_F(UseAddressActionTest, FallbackForPhoneSucceeds) { // Autofill succeeds. EXPECT_CALL(mock_action_delegate_, - OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) + FillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) .WillOnce(RunOnceCallback<2>(OkClientStatus())); // Validation fails when getting phone number. @@ -577,7 +577,7 @@ TEST_F(UseAddressActionTest, ForcedFallbackWithKeystrokes) { // Autofill succeeds. EXPECT_CALL(mock_action_delegate_, - OnFillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) + FillAddressForm(NotNull(), Eq(Selector({kFakeSelector})), _)) .WillOnce(RunOnceCallback<2>(OkClientStatus())); // Do not check required field. @@ -639,7 +639,7 @@ TEST_F(UseAddressActionTest, SkippingAutofill) { Selector first_name_selector({"#first_name"}); EXPECT_CALL(mock_action_delegate_, OnShortWaitForElement(_, _)).Times(0); - EXPECT_CALL(mock_action_delegate_, OnFillAddressForm(_, _, _)).Times(0); + EXPECT_CALL(mock_action_delegate_, FillAddressForm(_, _, _)).Times(0); // First validation fails. EXPECT_CALL(mock_web_controller_, diff --git a/components/autofill_assistant/browser/actions/use_credit_card_action_unittest.cc b/components/autofill_assistant/browser/actions/use_credit_card_action_unittest.cc index 8be5eea21fca5f..b12b403f479fc8 100644 --- a/components/autofill_assistant/browser/actions/use_credit_card_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/use_credit_card_action_unittest.cc @@ -168,10 +168,9 @@ TEST_F(UseCreditCardActionTest, CreditCardInUserDataSucceeds) { ActionProto action; auto* use_card = action.mutable_use_card(); *use_card->mutable_form_field_element() = ToSelectorProto(kFakeSelector); - EXPECT_CALL( - mock_action_delegate_, - OnFillCardForm(Pointee(Eq(credit_card_)), base::UTF8ToUTF16(kFakeCvc), - Selector({kFakeSelector}), _)) + EXPECT_CALL(mock_action_delegate_, FillCardForm(Pointee(Eq(credit_card_)), + base::UTF8ToUTF16(kFakeCvc), + Selector({kFakeSelector}), _)) .WillOnce(RunOnceCallback<3>(OkClientStatus())); EXPECT_EQ(ProcessedActionStatusProto::ACTION_APPLIED, ProcessAction(action)); } @@ -205,10 +204,9 @@ TEST_F(UseCreditCardActionTest, CreditCardInUserModelSucceeds) { auto* use_card = action.mutable_use_card(); *use_card->mutable_form_field_element() = ToSelectorProto(kFakeSelector); use_card->set_model_identifier(kModelIdentifier); - EXPECT_CALL( - mock_action_delegate_, - OnFillCardForm(Pointee(Eq(credit_card_)), base::UTF8ToUTF16(kFakeCvc), - Selector({kFakeSelector}), _)) + EXPECT_CALL(mock_action_delegate_, FillCardForm(Pointee(Eq(credit_card_)), + base::UTF8ToUTF16(kFakeCvc), + Selector({kFakeSelector}), _)) .WillOnce(RunOnceCallback<3>(OkClientStatus())); EXPECT_EQ(ProcessedActionStatusProto::ACTION_APPLIED, ProcessAction(action)); } @@ -218,8 +216,8 @@ TEST_F(UseCreditCardActionTest, FillCreditCard) { user_data_.selected_card_ = std::make_unique(); EXPECT_CALL(mock_action_delegate_, - OnFillCardForm(_, base::UTF8ToUTF16(kFakeCvc), - Selector({kFakeSelector}), _)) + FillCardForm(_, base::UTF8ToUTF16(kFakeCvc), + Selector({kFakeSelector}), _)) .WillOnce(RunOnceCallback<3>(OkClientStatus())); EXPECT_EQ(ProcessedActionStatusProto::ACTION_APPLIED, ProcessAction(action)); @@ -242,8 +240,8 @@ TEST_F(UseCreditCardActionTest, FillCreditCardRequiredFieldsFilled) { user_data_.selected_card_ = std::make_unique(); EXPECT_CALL(mock_action_delegate_, - OnFillCardForm(_, base::UTF8ToUTF16(kFakeCvc), - Selector({kFakeSelector}), _)) + FillCardForm(_, base::UTF8ToUTF16(kFakeCvc), + Selector({kFakeSelector}), _)) .WillOnce(RunOnceCallback<3>(OkClientStatus())); EXPECT_EQ(ProcessedActionStatusProto::ACTION_APPLIED, ProcessAction(action)); @@ -308,8 +306,8 @@ TEST_F(UseCreditCardActionTest, FillCreditCardWithFallback) { "#network"); EXPECT_CALL(mock_action_delegate_, - OnFillCardForm(_, base::UTF8ToUTF16(kFakeCvc), - Selector({kFakeSelector}), _)) + FillCardForm(_, base::UTF8ToUTF16(kFakeCvc), + Selector({kFakeSelector}), _)) .WillOnce(RunOnceCallback<3>(OkClientStatus())); Selector cvc_selector({"#cvc"}); @@ -401,8 +399,8 @@ TEST_F(UseCreditCardActionTest, ForcedFallbackWithKeystrokes) { user_data_.selected_card_ = std::make_unique(); EXPECT_CALL(mock_action_delegate_, - OnFillCardForm(_, base::UTF8ToUTF16(kFakeCvc), - Selector({kFakeSelector}), _)) + FillCardForm(_, base::UTF8ToUTF16(kFakeCvc), + Selector({kFakeSelector}), _)) .WillOnce(RunOnceCallback<3>(OkClientStatus())); // Do not check required field. @@ -464,7 +462,7 @@ TEST_F(UseCreditCardActionTest, SkippingAutofill) { Selector cvc_selector({"#cvc"}); EXPECT_CALL(mock_action_delegate_, OnShortWaitForElement(_, _)).Times(0); - EXPECT_CALL(mock_action_delegate_, OnFillCardForm(_, _, _, _)).Times(0); + EXPECT_CALL(mock_action_delegate_, FillCardForm(_, _, _, _)).Times(0); // First validation fails. EXPECT_CALL(mock_web_controller_, @@ -494,8 +492,8 @@ TEST_F(UseCreditCardActionTest, AutofillFailureWithoutRequiredFieldsIsFatal) { user_data_.selected_card_ = std::make_unique(); EXPECT_CALL(mock_action_delegate_, - OnFillCardForm(_, base::UTF8ToUTF16(kFakeCvc), - Selector({kFakeSelector}), _)) + FillCardForm(_, base::UTF8ToUTF16(kFakeCvc), + Selector({kFakeSelector}), _)) .WillOnce(RunOnceCallback<3>(ClientStatus(OTHER_ACTION_STATUS))); ProcessedActionProto processed_action; @@ -529,8 +527,8 @@ TEST_F(UseCreditCardActionTest, user_data_.selected_card_ = std::make_unique(); EXPECT_CALL(mock_action_delegate_, - OnFillCardForm(_, base::UTF8ToUTF16(kFakeCvc), - Selector({kFakeSelector}), _)) + FillCardForm(_, base::UTF8ToUTF16(kFakeCvc), + Selector({kFakeSelector}), _)) .WillOnce(RunOnceCallback<3>(ClientStatus(OTHER_ACTION_STATUS))); // First validation fails. @@ -579,8 +577,8 @@ TEST_F(UseCreditCardActionTest, FallbackForCardExpirationSucceeds) { // Autofill succeeds. EXPECT_CALL(mock_action_delegate_, - OnFillCardForm(_, base::UTF8ToUTF16(kFakeCvc), - Selector({kFakeSelector}), _)) + FillCardForm(_, base::UTF8ToUTF16(kFakeCvc), + Selector({kFakeSelector}), _)) .WillOnce(RunOnceCallback<3>(OkClientStatus())); // Validation fails when getting expiration date. @@ -623,8 +621,8 @@ TEST_F(UseCreditCardActionTest, FallbackFails) { // Autofill succeeds. EXPECT_CALL(mock_action_delegate_, - OnFillCardForm(_, base::UTF8ToUTF16(kFakeCvc), - Selector({kFakeSelector}), _)) + FillCardForm(_, base::UTF8ToUTF16(kFakeCvc), + Selector({kFakeSelector}), _)) .WillOnce(RunOnceCallback<3>(OkClientStatus())); // Validation fails when getting expiration date. diff --git a/components/autofill_assistant/browser/actions/wait_for_document_action_unittest.cc b/components/autofill_assistant/browser/actions/wait_for_document_action_unittest.cc index e7df447b8c43a6..7575d96c383262 100644 --- a/components/autofill_assistant/browser/actions/wait_for_document_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/wait_for_document_action_unittest.cc @@ -41,8 +41,8 @@ class WaitForDocumentActionTest : public testing::Test { void SetUp() override { ON_CALL(mock_action_delegate_, GetWebController) .WillByDefault(Return(&mock_web_controller_)); - ON_CALL(mock_action_delegate_, OnWaitForDocumentReadyState(_, _, _)) - .WillByDefault(RunOnceCallback<2>(OkClientStatus(), DOCUMENT_COMPLETE, + ON_CALL(mock_action_delegate_, WaitForDocumentReadyState(_, _, _, _)) + .WillByDefault(RunOnceCallback<3>(OkClientStatus(), DOCUMENT_COMPLETE, base::TimeDelta::FromSeconds(0))); } @@ -138,8 +138,8 @@ TEST_F(WaitForDocumentActionTest, WaitForDocumentInteractive) { EXPECT_CALL(mock_web_controller_, GetDocumentReadyState(_, _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), DOCUMENT_LOADING)); EXPECT_CALL(mock_action_delegate_, - OnWaitForDocumentReadyState(DOCUMENT_INTERACTIVE, _, _)) - .WillOnce(RunOnceCallback<2>(OkClientStatus(), DOCUMENT_INTERACTIVE, + WaitForDocumentReadyState(_, DOCUMENT_INTERACTIVE, _, _)) + .WillOnce(RunOnceCallback<3>(OkClientStatus(), DOCUMENT_INTERACTIVE, base::TimeDelta::FromSeconds(0))); proto_.set_timeout_ms(1000); Run(); @@ -157,8 +157,8 @@ TEST_F(WaitForDocumentActionTest, WaitForDocumentInteractiveTimesOut) { EXPECT_CALL(mock_web_controller_, GetDocumentReadyState(_, _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), DOCUMENT_LOADING)); EXPECT_CALL(mock_action_delegate_, - OnWaitForDocumentReadyState(DOCUMENT_COMPLETE, _, _)) - .WillOnce(RunOnceCallback<2>(ClientStatus(TIMED_OUT), + WaitForDocumentReadyState(_, DOCUMENT_COMPLETE, _, _)) + .WillOnce(RunOnceCallback<3>(ClientStatus(TIMED_OUT), DOCUMENT_UNKNOWN_READY_STATE, base::TimeDelta::FromSeconds(0))); // The second time the document is reported interactive. diff --git a/components/autofill_assistant/browser/actions/wait_for_dom_action_unittest.cc b/components/autofill_assistant/browser/actions/wait_for_dom_action_unittest.cc index f2ad62cfc70576..c5b4cc45d3782f 100644 --- a/components/autofill_assistant/browser/actions/wait_for_dom_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/wait_for_dom_action_unittest.cc @@ -12,6 +12,7 @@ #include "base/test/mock_callback.h" #include "components/autofill_assistant/browser/actions/action_test_utils.h" #include "components/autofill_assistant/browser/actions/mock_action_delegate.h" +#include "components/autofill_assistant/browser/wait_for_dom_observer.h" #include "components/autofill_assistant/browser/web/element.h" #include "components/autofill_assistant/browser/web/mock_web_controller.h" #include "testing/gmock/include/gmock/gmock.h" @@ -36,7 +37,7 @@ class WaitForDomActionTest : public testing::Test { .WillByDefault(RunOnceCallback<1>( ClientStatus(ELEMENT_RESOLUTION_FAILED), nullptr)); - EXPECT_CALL(mock_action_delegate_, OnWaitForDom(_, _, _, _)) + EXPECT_CALL(mock_action_delegate_, WaitForDomWithSlowWarning(_, _, _, _, _)) .WillRepeatedly(Invoke(this, &WaitForDomActionTest::FakeWaitForDom)); } @@ -45,11 +46,11 @@ class WaitForDomActionTest : public testing::Test { void FakeWaitForDom( base::TimeDelta max_wait_time, bool allow_interrupt, + WaitForDomObserver* observer, base::RepeatingCallback< void(BatchElementChecker*, - base::OnceCallback)>& check_elements, - base::OnceCallback& - callback) { + base::OnceCallback)> check_elements, + base::OnceCallback callback) { checker_ = std::make_unique(); has_check_elements_result_ = false; check_elements.Run( diff --git a/components/autofill_assistant/browser/element_area_unittest.cc b/components/autofill_assistant/browser/element_area_unittest.cc index 30c1cd68e1c699..3b93839bbebf95 100644 --- a/components/autofill_assistant/browser/element_area_unittest.cc +++ b/components/autofill_assistant/browser/element_area_unittest.cc @@ -72,10 +72,10 @@ class ElementAreaTest : public testing::Test { base::TimeDelta::FromMilliseconds(100); test_util::MockFindAnyElement(mock_web_controller_); - ON_CALL(mock_web_controller_, OnGetElementRect(_, _)) + ON_CALL(mock_web_controller_, GetElementRect(_, _)) .WillByDefault( RunOnceCallback<1>(ClientStatus(UNEXPECTED_JS_ERROR), RectF())); - ON_CALL(mock_web_controller_, OnGetVisualViewport(_)) + ON_CALL(mock_web_controller_, GetVisualViewport(_)) .WillByDefault( RunOnceCallback<0>(OkClientStatus(), RectF(0, 0, 200, 400))); @@ -149,9 +149,9 @@ TEST_F(ElementAreaTest, GetVisualViewport) { TEST_F(ElementAreaTest, OneRectangle) { Selector expected_selector({"#found"}); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(25, 25, 75, 75))); SetElement("#found"); @@ -163,9 +163,9 @@ TEST_F(ElementAreaTest, OneRectangle) { TEST_F(ElementAreaTest, CallOnUpdate) { Selector expected_selector({"#found"}); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(25, 25, 75, 75))); SetElement("#found"); @@ -177,9 +177,9 @@ TEST_F(ElementAreaTest, CallOnUpdate) { TEST_F(ElementAreaTest, CallOnUpdateAfterSetFromProto) { Selector expected_selector({"#found"}); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector, 2)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector, 2)), + _)) .Times(2) .WillRepeatedly( RunOnceCallback<1>(OkClientStatus(), RectF(25, 25, 75, 75))); @@ -193,14 +193,13 @@ TEST_F(ElementAreaTest, CallOnUpdateAfterSetFromProto) { TEST_F(ElementAreaTest, DontCallOnUpdateWhenViewportMissing) { Selector expected_selector({"#found"}); - // Swallowing calls to OnGetVisualViewport guarantees that the viewport + // Swallowing calls to GetVisualViewport guarantees that the viewport // position will never be known. - EXPECT_CALL(mock_web_controller_, OnGetVisualViewport(_)) - .WillOnce(DoNothing()); + EXPECT_CALL(mock_web_controller_, GetVisualViewport(_)).WillOnce(DoNothing()); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(25, 25, 75, 75))); SetElement("#found"); @@ -208,7 +207,7 @@ TEST_F(ElementAreaTest, DontCallOnUpdateWhenViewportMissing) { } TEST_F(ElementAreaTest, CallOnUpdateWhenViewportMissingAndEmptyRect) { - EXPECT_CALL(mock_web_controller_, OnGetVisualViewport(_)) + EXPECT_CALL(mock_web_controller_, GetVisualViewport(_)) .WillRepeatedly( RunOnceCallback<0>(ClientStatus(UNEXPECTED_JS_ERROR), RectF())); @@ -229,15 +228,15 @@ TEST_F(ElementAreaTest, TwoRectangles) { EXPECT_CALL( mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_top_left)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_top_left)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(0, 0, 25, 25))); - EXPECT_CALL(mock_web_controller_, - OnGetElementRect( - EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_bottom_right)), - _)) + EXPECT_CALL( + mock_web_controller_, + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_bottom_right)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(25, 25, 100, 100))); ElementAreaProto area_proto; @@ -257,14 +256,14 @@ TEST_F(ElementAreaTest, OneRectangleTwoElements) { Selector expected_selector_2({"#element2"}); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_1)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_1)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(1, 3, 2, 4))); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_2)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_2)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(5, 2, 6, 5))); ElementAreaProto area_proto; @@ -281,18 +280,18 @@ TEST_F(ElementAreaTest, OneRectangleTwoElements) { TEST_F(ElementAreaTest, DoNotReportIncompleteRectangles) { Selector expected_selector_1({"#element1"}); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_1)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_1)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(1, 3, 2, 4))); // Getting the position of #element2 neither succeeds nor fails, simulating an // intermediate state which shouldn't be reported to the callback. Selector expected_selector_2({"#element2"}); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_2)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_2)), + _)) .WillOnce(DoNothing()); // overrides default action ElementAreaProto area_proto; @@ -315,24 +314,24 @@ TEST_F(ElementAreaTest, OneRectangleFourElements) { Selector expected_selector_4({"#element4"}); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_1)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_1)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(0, 0, 1, 1))); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_2)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_2)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(9, 9, 100, 100))); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_3)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_3)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(0, 9, 1, 100))); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_4)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_4)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(9, 0, 100, 1))); ElementAreaProto area_proto; @@ -353,14 +352,14 @@ TEST_F(ElementAreaTest, OneRectangleMissingElementsReported) { Selector expected_selector_2({"#element2"}); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_1)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_1)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(1, 1, 2, 2))); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_2)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_2)), + _)) .WillOnce(RunOnceCallback<1>(ClientStatus(UNEXPECTED_JS_ERROR), RectF())); ElementAreaProto area_proto; @@ -381,16 +380,16 @@ TEST_F(ElementAreaTest, FullWidthRectangle) { Selector expected_selector_2({"#element2"}); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_1)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_1)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(1, 3, 2, 4))); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector_2)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector_2)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(5, 7, 6, 8))); - EXPECT_CALL(mock_web_controller_, OnGetVisualViewport(_)) + EXPECT_CALL(mock_web_controller_, GetVisualViewport(_)) .WillRepeatedly( RunOnceCallback<0>(OkClientStatus(), RectF(100, 0, 200, 400))); @@ -415,14 +414,14 @@ TEST_F(ElementAreaTest, ElementMovesAfterUpdate) { Selector expected_selector({"#element"}); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(0, 25, 100, 50))); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(0, 50, 100, 75))); SetElement("#element"); @@ -449,19 +448,19 @@ TEST_F(ElementAreaTest, ElementMovesWithTime) { Selector expected_selector({"#element"}); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(0, 25, 100, 50))); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(0, 50, 100, 75))); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(0, 50, 100, 75))); SetElement("#element"); @@ -488,9 +487,9 @@ TEST_F(ElementAreaTest, RestrictedElement) { Selector expected_selector({"#restricted_element"}); EXPECT_CALL(mock_web_controller_, - OnGetElementRect(EqualsElement(test_util::MockFindElement( - mock_web_controller_, expected_selector)), - _)) + GetElementRect(EqualsElement(test_util::MockFindElement( + mock_web_controller_, expected_selector)), + _)) .WillOnce(RunOnceCallback<1>(OkClientStatus(), RectF(25, 25, 75, 75))); SetElement("#restricted_element", /* restricted= */ true); diff --git a/components/autofill_assistant/browser/script_executor_unittest.cc b/components/autofill_assistant/browser/script_executor_unittest.cc index bfd71044096a90..780fb4d280e9e2 100644 --- a/components/autofill_assistant/browser/script_executor_unittest.cc +++ b/components/autofill_assistant/browser/script_executor_unittest.cc @@ -75,7 +75,7 @@ class ScriptExecutorTest : public testing::Test, // In this test, "tell" actions always succeed and "click" actions, // always fail. The following makes a click action fail. - ON_CALL(mock_web_controller_, OnWaitForDocumentReadyState(_, _, _)) + ON_CALL(mock_web_controller_, WaitForDocumentReadyState(_, _, _)) .WillByDefault(RunOnceCallback<2>(OkClientStatus(), DOCUMENT_COMPLETE, base::TimeDelta::FromSeconds(0))); ON_CALL(mock_web_controller_, ScrollIntoView(_, _, _)) diff --git a/components/autofill_assistant/browser/wait_for_document_operation_unittest.cc b/components/autofill_assistant/browser/wait_for_document_operation_unittest.cc index 6ebafd82ea0831..86ce41a99bfb19 100644 --- a/components/autofill_assistant/browser/wait_for_document_operation_unittest.cc +++ b/components/autofill_assistant/browser/wait_for_document_operation_unittest.cc @@ -51,7 +51,7 @@ class WaitForDocumentOperationTest : public testing::Test { TEST_F(WaitForDocumentOperationTest, ReportsSuccess) { EXPECT_CALL(mock_web_controller_, - OnWaitForDocumentReadyState(_, DOCUMENT_COMPLETE, _)) + WaitForDocumentReadyState(_, DOCUMENT_COMPLETE, _)) .WillOnce(RunOnceCallback<2>(OkClientStatus(), DOCUMENT_COMPLETE, base::TimeDelta::FromSeconds(0))); EXPECT_CALL(mock_callback_, @@ -62,7 +62,7 @@ TEST_F(WaitForDocumentOperationTest, ReportsSuccess) { TEST_F(WaitForDocumentOperationTest, ReportsFailure) { EXPECT_CALL(mock_web_controller_, - OnWaitForDocumentReadyState(_, DOCUMENT_COMPLETE, _)) + WaitForDocumentReadyState(_, DOCUMENT_COMPLETE, _)) .WillOnce(RunOnceCallback<2>(ClientStatus(TIMED_OUT), DOCUMENT_UNKNOWN_READY_STATE, base::TimeDelta::FromSeconds(0))); @@ -76,11 +76,11 @@ TEST_F(WaitForDocumentOperationTest, TimesOutAfterWaiting) { // Capture the call without answering it. WaitForDocumentOperation::Callback captured_callback; EXPECT_CALL(mock_web_controller_, - OnWaitForDocumentReadyState(_, DOCUMENT_COMPLETE, _)) + WaitForDocumentReadyState(_, DOCUMENT_COMPLETE, _)) .WillOnce(Invoke([&captured_callback]( const ElementFinder::Result& optional_frame_element, DocumentReadyState min_ready_state, - WaitForDocumentOperation::Callback& callback) { + WaitForDocumentOperation::Callback callback) { captured_callback = std::move(callback); })); EXPECT_CALL(mock_callback_, Run(_, _, _)).Times(0); @@ -99,7 +99,7 @@ TEST_F(WaitForDocumentOperationTest, TimesOutAfterWaiting) { TEST_F(WaitForDocumentOperationTest, TimeoutIsIgnoredAfterSuccess) { EXPECT_CALL(mock_web_controller_, - OnWaitForDocumentReadyState(_, DOCUMENT_COMPLETE, _)) + WaitForDocumentReadyState(_, DOCUMENT_COMPLETE, _)) .WillOnce(RunOnceCallback<2>(OkClientStatus(), DOCUMENT_COMPLETE, base::TimeDelta::FromSeconds(0))); EXPECT_CALL(mock_callback_, Run(_, _, _)).Times(0); diff --git a/components/autofill_assistant/browser/web/mock_web_controller.h b/components/autofill_assistant/browser/web/mock_web_controller.h index 8cef6b7553a8e7..1209e3565f1e37 100644 --- a/components/autofill_assistant/browser/web/mock_web_controller.h +++ b/components/autofill_assistant/browser/web/mock_web_controller.h @@ -93,26 +93,10 @@ class MockWebController : public WebController { void(ClickType click_type, const ElementFinder::Result& element, base::OnceCallback callback)); - - void ScrollToElementPosition( - std::unique_ptr scrollable_element, - const ElementFinder::Result& element, - const TopPadding& top_padding, - base::OnceCallback callback) override { - OnScrollToElementPosition(std::move(scrollable_element), element, - top_padding, callback); - } - MOCK_METHOD4(OnScrollToElementPosition, - void(std::unique_ptr scrollable_element, - const ElementFinder::Result& element, - const TopPadding& top_padding, - base::OnceCallback& callback)); - MOCK_METHOD2(GetFieldValue, void(const ElementFinder::Result& element, base::OnceCallback callback)); - MOCK_METHOD3( GetStringAttribute, void(const std::vector&, @@ -127,49 +111,18 @@ class MockWebController : public WebController { const std::string&, const ElementFinder::Result&, base::OnceCallback)); - - void GetVisualViewport( - base::OnceCallback callback) - override { - OnGetVisualViewport(callback); - } - MOCK_METHOD1(OnGetVisualViewport, - void(base::OnceCallback& + MOCK_METHOD1(GetVisualViewport, + void(base::OnceCallback callback)); - - void GetElementRect( - const ElementFinder::Result& element, - ElementRectGetter::ElementRectCallback callback) override { - OnGetElementRect(element, callback); - } - MOCK_METHOD2(OnGetElementRect, + MOCK_METHOD2(GetElementRect, void(const ElementFinder::Result& element, - ElementRectGetter::ElementRectCallback& callback)); - - void WaitForWindowHeightChange( - base::OnceCallback callback) { - OnWaitForWindowHeightChange(callback); - } - - MOCK_METHOD1(OnWaitForWindowHeightChange, - void(base::OnceCallback& callback)); - - MOCK_METHOD3(OnWaitForDocumentReadyState, - void(const ElementFinder::Result&, - DocumentReadyState, + ElementRectGetter::ElementRectCallback callback)); + MOCK_METHOD3(WaitForDocumentReadyState, + void(const ElementFinder::Result& optional_frame_element, + DocumentReadyState min_ready_state, base::OnceCallback&)); - - void WaitForDocumentReadyState( - const ElementFinder::Result& optional_frame_element, - DocumentReadyState min_ready_state, - base::OnceCallback callback) override { - OnWaitForDocumentReadyState(optional_frame_element, min_ready_state, - callback); - } + base::TimeDelta)> callback)); base::WeakPtr GetWeakPtr() const override { return weak_ptr_factory_.GetWeakPtr(); diff --git a/components/policy/core/common/policy_map.cc b/components/policy/core/common/policy_map.cc index 4380166bbe4596..1d12a5bae155f0 100644 --- a/components/policy/core/common/policy_map.cc +++ b/components/policy/core/common/policy_map.cc @@ -400,34 +400,6 @@ void PolicyMap::LoadFrom(const base::DictionaryValue* policies, } } -void PolicyMap::GetDifferingKeys(const PolicyMap& other, - std::set* differing_keys) const { - // Walk over the maps in lockstep, adding everything that is different. - auto iter_this(begin()); - auto iter_other(other.begin()); - while (iter_this != end() && iter_other != other.end()) { - const int diff = iter_this->first.compare(iter_other->first); - if (diff == 0) { - if (!iter_this->second.Equals(iter_other->second)) - differing_keys->insert(iter_this->first); - ++iter_this; - ++iter_other; - } else if (diff < 0) { - differing_keys->insert(iter_this->first); - ++iter_this; - } else { - differing_keys->insert(iter_other->first); - ++iter_other; - } - } - - // Add the remaining entries. - for (; iter_this != end(); ++iter_this) - differing_keys->insert(iter_this->first); - for (; iter_other != other.end(); ++iter_other) - differing_keys->insert(iter_other->first); -} - bool PolicyMap::Equals(const PolicyMap& other) const { return other.size() == size() && std::equal(begin(), end(), other.begin(), MapEntryEquals); diff --git a/components/policy/core/common/policy_map.h b/components/policy/core/common/policy_map.h index bf5bcdd0527471..be50444ae3ebb0 100644 --- a/components/policy/core/common/policy_map.h +++ b/components/policy/core/common/policy_map.h @@ -262,13 +262,6 @@ class POLICY_EXPORT PolicyMap { PolicyScope scope, PolicySource source); - // Compares this value map against |other| and stores all key names that have - // different values or reference different external data in |differing_keys|. - // This includes keys that are present only in one of the maps. - // |differing_keys| is not cleared before the keys are added. - void GetDifferingKeys(const PolicyMap& other, - std::set* differing_keys) const; - bool Equals(const PolicyMap& other) const; bool empty() const; size_t size() const; diff --git a/components/policy/core/common/policy_map_unittest.cc b/components/policy/core/common/policy_map_unittest.cc index 73f62621811241..fa38c586f7f5ea 100644 --- a/components/policy/core/common/policy_map_unittest.cc +++ b/components/policy/core/common/policy_map_unittest.cc @@ -963,64 +963,6 @@ TEST_F(PolicyMapTest, MergeValuesGroup) { EXPECT_TRUE(group_merged.Equals(expected_group_merged)); } -TEST_F(PolicyMapTest, GetDifferingKeys) { - PolicyMap a; - a.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, - POLICY_SOURCE_CLOUD, base::Value("google.com"), nullptr); - a.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, - POLICY_SOURCE_CLOUD, base::nullopt, CreateExternalDataFetcher("dummy")); - a.Set(kTestPolicyName3, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, - POLICY_SOURCE_CLOUD, base::Value(true), nullptr); - a.Set(kTestPolicyName4, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, - POLICY_SOURCE_CLOUD, base::nullopt, CreateExternalDataFetcher("a")); - a.Set(kTestPolicyName5, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, - POLICY_SOURCE_CLOUD, base::Value(false), nullptr); - a.Set(kTestPolicyName6, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE, - POLICY_SOURCE_CLOUD, base::Value("google.com/q={x}"), nullptr); - a.Set(kTestPolicyName7, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, - POLICY_SOURCE_CLOUD, base::Value(true), nullptr); - - PolicyMap b; - b.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, - POLICY_SOURCE_CLOUD, base::Value("google.com"), nullptr); - b.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, - POLICY_SOURCE_CLOUD, base::nullopt, CreateExternalDataFetcher("dummy")); - b.Set(kTestPolicyName3, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, - POLICY_SOURCE_CLOUD, base::Value(false), nullptr); - b.Set(kTestPolicyName4, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, - POLICY_SOURCE_CLOUD, base::nullopt, CreateExternalDataFetcher("b")); - b.Set(kTestPolicyName5, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, - POLICY_SOURCE_CLOUD, base::Value(false), nullptr); - b.Set(kTestPolicyName6, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, - POLICY_SOURCE_CLOUD, base::Value("google.com/q={x}"), nullptr); - b.Set(kTestPolicyName8, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, - POLICY_SOURCE_CLOUD, base::Value(true), nullptr); - - std::set diff; - std::set diff2; - a.GetDifferingKeys(b, &diff); - b.GetDifferingKeys(a, &diff2); - // Order shouldn't matter. - EXPECT_EQ(diff, diff2); - // No change. - EXPECT_TRUE(diff.find(kTestPolicyName1) == diff.end()); - EXPECT_TRUE(diff.find(kTestPolicyName2) == diff.end()); - // Different values. - EXPECT_TRUE(diff.find(kTestPolicyName3) != diff.end()); - // Different external data references. - EXPECT_TRUE(diff.find(kTestPolicyName4) != diff.end()); - // Different levels. - EXPECT_TRUE(diff.find(kTestPolicyName5) != diff.end()); - // Different scopes. - EXPECT_TRUE(diff.find(kTestPolicyName6) != diff.end()); - // Not in |a|. - EXPECT_TRUE(diff.find(kTestPolicyName8) != diff.end()); - // Not in |b|. - EXPECT_TRUE(diff.find(kTestPolicyName7) != diff.end()); - // No surprises. - EXPECT_EQ(6u, diff.size()); -} - TEST_F(PolicyMapTest, LoadFromSetsLevelScopeAndSource) { base::DictionaryValue policies; policies.SetString("TestPolicy1", "google.com"); diff --git a/content/browser/net/network_errors_listing_ui.cc b/content/browser/net/network_errors_listing_ui.cc index c34768990ae6a7..9362fb11a4cf8b 100644 --- a/content/browser/net/network_errors_listing_ui.cc +++ b/content/browser/net/network_errors_listing_ui.cc @@ -43,8 +43,7 @@ std::unique_ptr GetNetworkErrorData() { for (base::DictionaryValue::Iterator itr(*net_error_codes_dict); !itr.IsAtEnd(); itr.Advance()) { - int error_code; - itr.value().GetAsInteger(&error_code); + const int error_code = itr.value().GetInt(); // Exclude the aborted and pending codes as these don't return a page. if (error_code != net::Error::ERR_IO_PENDING && error_code != net::Error::ERR_ABORTED) { diff --git a/extensions/BUILD.gn b/extensions/BUILD.gn index 309b1900b24b60..2a69e0ec5b7243 100644 --- a/extensions/BUILD.gn +++ b/extensions/BUILD.gn @@ -147,8 +147,6 @@ static_library("test_support") { "//base", "//build:chromeos_buildflags", "//chrome/common:buildflags", - "//components/cast_certificate:test_support", - "//components/cast_channel:test_support", "//components/guest_view/browser:test_support", "//components/prefs:test_support", "//components/sync_preferences:test_support", @@ -280,7 +278,6 @@ source_set("chrome_extensions_browsertests") { "browser/api/app_window/app_window_apitest.cc", "browser/api/bluetooth/bluetooth_apitest.cc", "browser/api/bluetooth/bluetooth_private_apitest.cc", - "browser/api/cast_channel/cast_channel_apitest.cc", "browser/api/serial/serial_apitest.cc", "browser/api/usb/usb_manual_apitest.cc", "browser/app_window/app_window_browsertest.cc", @@ -318,7 +315,6 @@ source_set("chrome_extensions_browsertests") { "//extensions/common/api", "//google_apis:test_support", "//media:test_support", - "//media/cast:test_support", "//net", "//net:test_support", "//skia", diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 42c840cd3c0655..1b84b5d4676c7a 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn @@ -383,7 +383,6 @@ source_set("browser_sources") { "//base:i18n", "//build:chromeos_buildflags", "//components/cast_certificate", - "//components/cast_channel", "//components/crx_file", "//components/crx_file:crx_creator", "//components/guest_view/browser", @@ -624,8 +623,6 @@ source_set("unit_tests") { "api/api_resource_manager_unittest.cc", "api/bluetooth/bluetooth_event_router_unittest.cc", "api/bluetooth_socket/bluetooth_socket_api_unittest.cc", - "api/cast_channel/cast_channel_api_unittest.cc", - "api/cast_channel/cast_channel_enum_util_unittest.cc", "api/declarative/declarative_rule_unittest.cc", "api/declarative/deduping_factory_unittest.cc", "api/declarative/rules_registry_unittest.cc", diff --git a/extensions/browser/api/BUILD.gn b/extensions/browser/api/BUILD.gn index dfcebed101fc67..aaa7c59cc25781 100644 --- a/extensions/browser/api/BUILD.gn +++ b/extensions/browser/api/BUILD.gn @@ -109,7 +109,6 @@ group("api_implementations") { "//extensions/browser/api/bluetooth", "//extensions/browser/api/bluetooth_low_energy", "//extensions/browser/api/bluetooth_socket", - "//extensions/browser/api/cast_channel", "//extensions/browser/api/declarative_net_request", "//extensions/browser/api/dns", "//extensions/browser/api/feedback_private", diff --git a/extensions/browser/api/api_resource_manager.h b/extensions/browser/api/api_resource_manager.h index a9fce630571ac7..c7e1d3ae8b7dce 100644 --- a/extensions/browser/api/api_resource_manager.h +++ b/extensions/browser/api/api_resource_manager.h @@ -32,7 +32,6 @@ #include "extensions/common/extension.h" namespace extensions { -class CastChannelAsyncApiFunction; namespace api { class BluetoothSocketApiFunction; @@ -176,7 +175,6 @@ class ApiResourceManager : public BrowserContextKeyedAPI, // TODO(rockot): ApiResourceData could be moved out of ApiResourceManager and // we could avoid maintaining a friends list here. friend class BluetoothAPI; - friend class CastChannelAsyncApiFunction; friend class api::BluetoothSocketApiFunction; friend class api::BluetoothSocketEventDispatcher; friend class api::SerialConnectFunction; diff --git a/extensions/browser/api/cast_channel/BUILD.gn b/extensions/browser/api/cast_channel/BUILD.gn deleted file mode 100644 index 7251e1ac768328..00000000000000 --- a/extensions/browser/api/cast_channel/BUILD.gn +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//extensions/buildflags/buildflags.gni") - -assert(enable_extensions, - "Cannot depend on extensions because enable_extensions=false.") - -source_set("cast_channel") { - sources = [ - "cast_channel_api.cc", - "cast_channel_api.h", - "cast_channel_enum_util.cc", - "cast_channel_enum_util.h", - "cast_message_util.cc", - "cast_message_util.h", - ] - - deps = [ - "//base", - "//components/cast_channel", - "//extensions/browser/api", - "//extensions/common", - "//extensions/common/api", - "//net", - "//third_party/openscreen/src/cast/common/channel/proto:channel_proto", - ] - - public_deps = [ "//extensions/browser:browser_sources" ] -} diff --git a/extensions/browser/api/cast_channel/DEPS b/extensions/browser/api/cast_channel/DEPS deleted file mode 100644 index b7f785bf92d5ab..00000000000000 --- a/extensions/browser/api/cast_channel/DEPS +++ /dev/null @@ -1,11 +0,0 @@ -include_rules = [ - "+components/cast_certificate", - "+components/cast_channel", - "+third_party/zlib", -] - -specific_include_rules = { - "cast_channel_apitest\.cc": [ - "+chrome/browser/media/router", - ], -} diff --git a/extensions/browser/api/cast_channel/DIR_METADATA b/extensions/browser/api/cast_channel/DIR_METADATA deleted file mode 100644 index 1952c422d3ecd3..00000000000000 --- a/extensions/browser/api/cast_channel/DIR_METADATA +++ /dev/null @@ -1,3 +0,0 @@ -monorail { - component: "Internals>Cast>API" -} diff --git a/extensions/browser/api/cast_channel/OWNERS b/extensions/browser/api/cast_channel/OWNERS deleted file mode 100644 index 78c2174e575fa5..00000000000000 --- a/extensions/browser/api/cast_channel/OWNERS +++ /dev/null @@ -1 +0,0 @@ -file://components/cast_channel/OWNERS diff --git a/extensions/browser/api/cast_channel/cast_channel_api.cc b/extensions/browser/api/cast_channel/cast_channel_api.cc deleted file mode 100644 index 48334f68de1235..00000000000000 --- a/extensions/browser/api/cast_channel/cast_channel_api.cc +++ /dev/null @@ -1,546 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "extensions/browser/api/cast_channel/cast_channel_api.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include "base/bind.h" -#include "base/json/json_writer.h" -#include "base/lazy_instance.h" -#include "base/strings/string_number_conversions.h" -#include "base/values.h" -#include "components/cast_channel/cast_channel_enum.h" -#include "components/cast_channel/cast_message_util.h" -#include "components/cast_channel/cast_socket.h" -#include "components/cast_channel/cast_socket_service.h" -#include "components/cast_channel/keep_alive_delegate.h" -#include "components/cast_channel/logger.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "extensions/browser/api/cast_channel/cast_channel_enum_util.h" -#include "extensions/browser/api/cast_channel/cast_message_util.h" -#include "extensions/browser/event_router.h" -#include "extensions/browser/event_router_factory.h" -#include "extensions/browser/extensions_browser_client.h" -#include "net/base/ip_address.h" -#include "net/base/ip_endpoint.h" -#include "net/base/net_errors.h" -#include "third_party/openscreen/src/cast/common/channel/proto/cast_channel.pb.h" - -// Default timeout interval for connection setup. -// Used if not otherwise specified at ConnectInfo::timeout. -const int kDefaultConnectTimeoutMillis = 5000; // 5 seconds. - -namespace extensions { - -namespace Close = api::cast_channel::Close; -namespace OnError = api::cast_channel::OnError; -namespace OnMessage = api::cast_channel::OnMessage; -namespace Open = api::cast_channel::Open; -namespace Send = api::cast_channel::Send; -using api::cast_channel::ChannelInfo; -using api::cast_channel::ConnectInfo; -using api::cast_channel::ErrorInfo; -using api::cast_channel::MessageInfo; -using cast::channel::CastMessage; -using cast_channel::CastDeviceCapability; -using cast_channel::CastSocket; -using cast_channel::CastSocketImpl; -using cast_channel::CastTransport; -using cast_channel::ChannelError; -using cast_channel::KeepAliveDelegate; -using cast_channel::LastError; -using cast_channel::Logger; - -using content::BrowserThread; - -namespace { - -// T is an extension dictionary (MessageInfo or ChannelInfo) -template -std::string ParamToString(const T& info) { - std::unique_ptr dict = info.ToValue(); - std::string out; - base::JSONWriter::Write(*dict, &out); - return out; -} - -// Fills |channel_info| from the destination and state of |socket|. -void FillChannelInfo(const CastSocket& socket, ChannelInfo* channel_info) { - DCHECK(channel_info); - channel_info->channel_id = socket.id(); - const net::IPEndPoint& ip_endpoint = socket.ip_endpoint(); - channel_info->connect_info.ip_address = ip_endpoint.ToStringWithoutPort(); - channel_info->connect_info.port = ip_endpoint.port(); - channel_info->connect_info.auth = - api::cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED; - channel_info->ready_state = ToReadyState(socket.ready_state()); - channel_info->error_state = ToChannelError(socket.error_state()); - channel_info->keep_alive = socket.keep_alive(); - channel_info->audio_only = socket.audio_only(); -} - -// Fills |error_info| from |error_state| and |last_error|. -void FillErrorInfo(api::cast_channel::ChannelError error_state, - const LastError& last_error, - ErrorInfo* error_info) { - error_info->error_state = error_state; - if (last_error.channel_event != cast_channel::ChannelEvent::UNKNOWN) { - error_info->event_type = std::make_unique( - cast_channel::AsInteger(last_error.channel_event)); - } - if (last_error.challenge_reply_error != - cast_channel::ChallengeReplyError::NONE) { - error_info->challenge_reply_error_type = std::make_unique( - cast_channel::AsInteger(last_error.challenge_reply_error)); - } - if (last_error.net_return_value <= 0) { - error_info->net_return_value = - std::make_unique(last_error.net_return_value); - } -} - -bool IsValidConnectInfoPort(const ConnectInfo& connect_info) { - return connect_info.port > 0 && connect_info.port < - std::numeric_limits::max(); -} - -bool IsValidConnectInfoIpAddress(const ConnectInfo& connect_info) { - // Note: this isn't technically correct since policy or feature might allow - // public IPs, but this code path is no longer used. see TODO below. - net::IPAddress ip_address; - return ip_address.AssignFromIPLiteral(connect_info.ip_address) && - !ip_address.IsPubliclyRoutable(); -} - -} // namespace - -// TODO(https://crbug.com/752604): Remove unused cast.channel API functions now -// that in-browser Cast discovery has launched in M64. -CastChannelAPI::CastChannelAPI(content::BrowserContext* context) - : browser_context_(context), - cast_socket_service_(cast_channel::CastSocketService::GetInstance()) { - DCHECK(browser_context_); - - EventRouter* event_router = EventRouter::Get(context); - DCHECK(event_router); - event_router->RegisterObserver(this, - api::cast_channel::OnMessage::kEventName); - event_router->RegisterObserver(this, api::cast_channel::OnError::kEventName); -} - -// static -CastChannelAPI* CastChannelAPI::Get(content::BrowserContext* context) { - return BrowserContextKeyedAPIFactory::Get(context); -} - -void CastChannelAPI::SendEvent(const std::string& extension_id, - std::unique_ptr event) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - EventRouter* event_router = EventRouter::Get(GetBrowserContext()); - if (event_router) { - event_router->DispatchEventToExtension(extension_id, std::move(event)); - } -} - -static base::LazyInstance< - BrowserContextKeyedAPIFactory>::DestructorAtExit g_factory = - LAZY_INSTANCE_INITIALIZER; - -// static -BrowserContextKeyedAPIFactory* -CastChannelAPI::GetFactoryInstance() { - return g_factory.Pointer(); -} - -void CastChannelAPI::SetSocketForTest( - std::unique_ptr socket_for_test) { - socket_for_test_ = std::move(socket_for_test); -} - -std::unique_ptr CastChannelAPI::GetSocketForTest() { - return std::move(socket_for_test_); -} - -content::BrowserContext* CastChannelAPI::GetBrowserContext() const { - return browser_context_; -} - -CastChannelAPI::~CastChannelAPI() { - if (message_handler_) { - cast_socket_service_->task_runner()->DeleteSoon(FROM_HERE, - message_handler_.release()); - } -} - -void CastChannelAPI::OnListenerAdded(const EventListenerInfo& details) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - if (message_handler_) - return; - - message_handler_ = std::make_unique( - base::BindRepeating(&CastChannelAPI::SendEvent, AsWeakPtr(), - details.extension_id), - cast_socket_service_); - cast_socket_service_->task_runner()->PostTask( - FROM_HERE, base::BindOnce(&CastMessageHandler::Init, - base::Unretained(message_handler_.get()))); -} - -void CastChannelAPI::OnListenerRemoved(const EventListenerInfo& details) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - EventRouter* event_router = EventRouter::Get(browser_context_); - DCHECK(event_router); - - if (!event_router->HasEventListener( - api::cast_channel::OnMessage::kEventName) && - !event_router->HasEventListener(api::cast_channel::OnError::kEventName) && - message_handler_) { - cast_socket_service_->task_runner()->DeleteSoon(FROM_HERE, - message_handler_.release()); - } -} - -template <> -void BrowserContextKeyedAPIFactory< - CastChannelAPI>::DeclareFactoryDependencies() { - DependsOn(EventRouterFactory::GetInstance()); -} - -CastChannelAsyncApiFunction::CastChannelAsyncApiFunction() - : cast_socket_service_(nullptr) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); -} - -CastChannelAsyncApiFunction::~CastChannelAsyncApiFunction() { } - -bool CastChannelAsyncApiFunction::PrePrepare() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - cast_socket_service_ = - CastChannelAPI::Get(browser_context())->cast_socket_service(); - DCHECK(cast_socket_service_); - return true; -} - -bool CastChannelAsyncApiFunction::Respond() { - return GetError().empty(); -} - -void CastChannelAsyncApiFunction::SetResultFromSocket( - const CastSocket& socket) { - ChannelInfo channel_info; - FillChannelInfo(socket, &channel_info); - api::cast_channel::ChannelError error = ToChannelError(socket.error_state()); - if (error != api::cast_channel::CHANNEL_ERROR_NONE) { - SetError("Channel socket error = " + base::NumberToString(error)); - } - SetResultFromChannelInfo(channel_info); -} - -void CastChannelAsyncApiFunction::SetResultFromError( - int channel_id, - api::cast_channel::ChannelError error) { - ChannelInfo channel_info; - channel_info.channel_id = channel_id; - channel_info.ready_state = api::cast_channel::READY_STATE_CLOSED; - channel_info.error_state = error; - channel_info.connect_info.ip_address = ""; - channel_info.connect_info.port = 0; - channel_info.connect_info.auth = - api::cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED; - SetResultFromChannelInfo(channel_info); - SetError("Channel error = " + base::NumberToString(error)); -} - -void CastChannelAsyncApiFunction::SetResultFromChannelInfo( - const ChannelInfo& channel_info) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - SetResult(channel_info.ToValue()); -} - -CastChannelOpenFunction::CastChannelOpenFunction() {} - -CastChannelOpenFunction::~CastChannelOpenFunction() { } - -net::IPEndPoint* CastChannelOpenFunction::ParseConnectInfo( - const ConnectInfo& connect_info) { - net::IPAddress ip_address; - CHECK(ip_address.AssignFromIPLiteral(connect_info.ip_address)); - return new net::IPEndPoint(ip_address, - static_cast(connect_info.port)); -} - -bool CastChannelOpenFunction::PrePrepare() { - api_ = CastChannelAPI::Get(browser_context()); - return CastChannelAsyncApiFunction::PrePrepare(); -} - -bool CastChannelOpenFunction::Prepare() { - params_ = Open::Params::Create(*args_); - EXTENSION_FUNCTION_VALIDATE(params_.get()); - const ConnectInfo& connect_info = params_->connect_info; - if (!IsValidConnectInfoPort(connect_info)) { - SetError("Invalid connect_info (invalid port)"); - } else if (!IsValidConnectInfoIpAddress(connect_info)) { - SetError("Invalid connect_info (invalid IP address)"); - } else { - // Parse timeout parameters if they are set. - if (connect_info.liveness_timeout.get()) { - liveness_timeout_ = - base::TimeDelta::FromMilliseconds(*connect_info.liveness_timeout); - } - if (connect_info.ping_interval.get()) { - ping_interval_ = - base::TimeDelta::FromMilliseconds(*connect_info.ping_interval); - } - - // Validate timeout parameters. - if (liveness_timeout_ < base::TimeDelta() || - ping_interval_ < base::TimeDelta()) { - SetError("livenessTimeout and pingInterval must be greater than 0."); - } else if ((liveness_timeout_ > base::TimeDelta()) != - (ping_interval_ > base::TimeDelta())) { - SetError("livenessTimeout and pingInterval must be set together."); - } else if (liveness_timeout_ < ping_interval_) { - SetError("livenessTimeout must be longer than pingTimeout."); - } - } - - if (!GetError().empty()) { - return false; - } - - ip_endpoint_.reset(ParseConnectInfo(connect_info)); - return true; -} - -void CastChannelOpenFunction::AsyncWorkStart() { - DCHECK(api_); - DCHECK(ip_endpoint_.get()); - const ConnectInfo& connect_info = params_->connect_info; - - std::unique_ptr test_socket = api_->GetSocketForTest(); - if (test_socket.get()) - cast_socket_service_->SetSocketForTest(std::move(test_socket)); - - cast_channel::CastSocketOpenParams open_params( - *ip_endpoint_, - base::TimeDelta::FromMilliseconds(connect_info.timeout.get() - ? *connect_info.timeout - : kDefaultConnectTimeoutMillis), - liveness_timeout_, ping_interval_, - connect_info.capabilities.get() ? *connect_info.capabilities - : CastDeviceCapability::NONE); - - cast_socket_service_->OpenSocket( - base::BindRepeating([] { - return ExtensionsBrowserClient::Get()->GetSystemNetworkContext(); - }), - open_params, base::BindOnce(&CastChannelOpenFunction::OnOpen, this)); -} - -void CastChannelOpenFunction::OnOpen(CastSocket* socket) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - VLOG(1) << "Connect finished, OnOpen invoked."; - DCHECK(socket); - // TODO: If we failed to open the CastSocket, we may want to clean up here, - // rather than relying on the extension to call close(). This can be done by - // calling RemoveSocket() and api_->GetLogger()->ClearLastError(channel_id). - if (socket->error_state() != ChannelError::UNKNOWN) { - SetResultFromSocket(*socket); - } else { - // The socket is being destroyed. - SetResultFromError(socket->id(), api::cast_channel::CHANNEL_ERROR_UNKNOWN); - } - - AsyncWorkCompleted(); -} - -CastChannelSendFunction::CastChannelSendFunction() { } - -CastChannelSendFunction::~CastChannelSendFunction() { } - -bool CastChannelSendFunction::Prepare() { - params_ = Send::Params::Create(*args_); - EXTENSION_FUNCTION_VALIDATE(params_.get()); - if (params_->message.namespace_.empty()) { - SetError("message_info.namespace_ is required"); - return false; - } - if (params_->message.source_id.empty()) { - SetError("message_info.source_id is required"); - return false; - } - if (params_->message.destination_id.empty()) { - SetError("message_info.destination_id is required"); - return false; - } - switch (params_->message.data->type()) { - case base::Value::Type::STRING: - case base::Value::Type::BINARY: - break; - default: - SetError("Invalid type of message_info.data"); - return false; - } - return true; -} - -void CastChannelSendFunction::AsyncWorkStart() { - CastSocket* socket = - cast_socket_service_->GetSocket(params_->channel.channel_id); - if (!socket) { - SetResultFromError(params_->channel.channel_id, - api::cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID); - AsyncWorkCompleted(); - return; - } - - if (socket->ready_state() == cast_channel::ReadyState::CLOSED || - !socket->transport()) { - SetResultFromError(params_->channel.channel_id, - api::cast_channel::CHANNEL_ERROR_CHANNEL_NOT_OPEN); - AsyncWorkCompleted(); - return; - } - - CastMessage message_to_send; - if (!MessageInfoToCastMessage(params_->message, &message_to_send)) { - SetResultFromError(params_->channel.channel_id, - api::cast_channel::CHANNEL_ERROR_INVALID_MESSAGE); - AsyncWorkCompleted(); - return; - } - socket->transport()->SendMessage( - message_to_send, base::BindOnce(&CastChannelSendFunction::OnSend, this)); -} - -void CastChannelSendFunction::OnSend(int result) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - int channel_id = params_->channel.channel_id; - CastSocket* socket = cast_socket_service_->GetSocket(channel_id); - if (result < 0 || !socket) { - SetResultFromError(channel_id, - api::cast_channel::CHANNEL_ERROR_SOCKET_ERROR); - } else { - SetResultFromSocket(*socket); - } - AsyncWorkCompleted(); -} - -CastChannelCloseFunction::CastChannelCloseFunction() { } - -CastChannelCloseFunction::~CastChannelCloseFunction() { } - -bool CastChannelCloseFunction::PrePrepare() { - return CastChannelAsyncApiFunction::PrePrepare(); -} - -bool CastChannelCloseFunction::Prepare() { - params_ = Close::Params::Create(*args_); - EXTENSION_FUNCTION_VALIDATE(params_.get()); - return true; -} - -void CastChannelCloseFunction::AsyncWorkStart() { - CastSocket* socket = - cast_socket_service_->GetSocket(params_->channel.channel_id); - if (!socket) { - SetResultFromError(params_->channel.channel_id, - api::cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID); - AsyncWorkCompleted(); - } else { - socket->Close(base::BindOnce(&CastChannelCloseFunction::OnClose, this)); - } -} - -void CastChannelCloseFunction::OnClose(int result) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - VLOG(1) << "CastChannelCloseFunction::OnClose result = " << result; - int channel_id = params_->channel.channel_id; - CastSocket* socket = cast_socket_service_->GetSocket(channel_id); - if (result < 0 || !socket) { - SetResultFromError(channel_id, - api::cast_channel::CHANNEL_ERROR_SOCKET_ERROR); - } else { - SetResultFromSocket(*socket); - // This will delete |socket|. - cast_socket_service_->RemoveSocket(channel_id); - cast_socket_service_->GetLogger()->ClearLastError(channel_id); - } - AsyncWorkCompleted(); -} - -CastChannelAPI::CastMessageHandler::CastMessageHandler( - const EventDispatchCallback& ui_dispatch_cb, - cast_channel::CastSocketService* cast_socket_service) - : ui_dispatch_cb_(ui_dispatch_cb), - cast_socket_service_(cast_socket_service) { - DETACH_FROM_SEQUENCE(sequence_checker_); - DCHECK(cast_socket_service_); -} - -CastChannelAPI::CastMessageHandler::~CastMessageHandler() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - cast_socket_service_->RemoveObserver(this); -} - -void CastChannelAPI::CastMessageHandler::Init() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - cast_socket_service_->AddObserver(this); -} - -void CastChannelAPI::CastMessageHandler::OnError( - const cast_channel::CastSocket& socket, - ChannelError error_state) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - ChannelInfo channel_info; - FillChannelInfo(socket, &channel_info); - channel_info.error_state = ToChannelError(error_state); - ErrorInfo error_info; - FillErrorInfo(channel_info.error_state, - cast_socket_service_->GetLogger()->GetLastError(socket.id()), - &error_info); - - std::unique_ptr results = - OnError::Create(channel_info, error_info); - std::unique_ptr event(new Event( - events::CAST_CHANNEL_ON_ERROR, OnError::kEventName, std::move(results))); - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(ui_dispatch_cb_, std::move(event))); -} - -void CastChannelAPI::CastMessageHandler::OnMessage( - const cast_channel::CastSocket& socket, - const CastMessage& message) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - MessageInfo message_info; - CastMessageToMessageInfo(message, &message_info); - ChannelInfo channel_info; - FillChannelInfo(socket, &channel_info); - VLOG(1) << "Received message " << ParamToString(message_info) - << " on channel " << ParamToString(channel_info); - - std::unique_ptr results = - OnMessage::Create(channel_info, message_info); - std::unique_ptr event(new Event(events::CAST_CHANNEL_ON_MESSAGE, - OnMessage::kEventName, - std::move(results))); - content::GetUIThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(ui_dispatch_cb_, std::move(event))); -} - -} // namespace extensions diff --git a/extensions/browser/api/cast_channel/cast_channel_api.h b/extensions/browser/api/cast_channel/cast_channel_api.h deleted file mode 100644 index d9ecd088457ef8..00000000000000 --- a/extensions/browser/api/cast_channel/cast_channel_api.h +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_API_H_ -#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_API_H_ - -#include -#include - -#include "base/gtest_prod_util.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/sequence_checker.h" -#include "components/cast_channel/cast_channel_enum.h" -#include "components/cast_channel/cast_socket.h" -#include "extensions/browser/api/async_api_function.h" -#include "extensions/browser/browser_context_keyed_api_factory.h" -#include "extensions/browser/event_router.h" -#include "extensions/common/api/cast_channel.h" -#include "third_party/openscreen/src/cast/common/channel/proto/cast_channel.pb.h" - -class CastChannelAPITest; - -namespace content { -class BrowserContext; -} - -namespace net { -class IPEndPoint; -} - -namespace cast_channel { -class CastSocketService; -} // namespace cast_channel - -namespace extensions { - -struct Event; - -class CastChannelAPI : public BrowserContextKeyedAPI, - public EventRouter::Observer, - public base::SupportsWeakPtr { - public: - explicit CastChannelAPI(content::BrowserContext* context); - - static CastChannelAPI* Get(content::BrowserContext* context); - - // BrowserContextKeyedAPI implementation. - static BrowserContextKeyedAPIFactory* GetFactoryInstance(); - - // Sets the CastSocket instance to be used for testing. - void SetSocketForTest( - std::unique_ptr socket_for_test); - - // Returns a test CastSocket instance, if it is defined. - // Otherwise returns a scoped_ptr with a nullptr value. - std::unique_ptr GetSocketForTest(); - - // Returns the API browser context. - content::BrowserContext* GetBrowserContext() const; - - // Sends an event to the extension's EventRouter, if it exists. - void SendEvent(const std::string& extension_id, std::unique_ptr event); - - cast_channel::CastSocketService* cast_socket_service() { - return cast_socket_service_; - } - - private: - friend class BrowserContextKeyedAPIFactory; - friend class ::CastChannelAPITest; - friend class CastTransportDelegate; - - // Defines a callback used to send events to the extension's - // EventRouter. - // Parameter #0 is a unique pointer to the event payload. - using EventDispatchCallback = - base::RepeatingCallback)>; - - // Receives incoming messages and errors and provides additional API context. - // Created on the UI thread. All methods, including the destructor, must be - // invoked on the SeqeuncedTaskRunner given by |cast_socket_service_|. - class CastMessageHandler : public cast_channel::CastSocket::Observer { - public: - CastMessageHandler(const EventDispatchCallback& ui_dispatch_cb, - cast_channel::CastSocketService* cast_socket_service); - ~CastMessageHandler() override; - - // Adds |this| as an observer to |cast_socket_service_|. - void Init(); - - // CastSocket::Observer implementation. - void OnError(const cast_channel::CastSocket& socket, - cast_channel::ChannelError error_state) override; - void OnMessage(const cast_channel::CastSocket& socket, - const cast::channel::CastMessage& message) override; - - private: - // Callback for sending events to the extension. - // Should be bound to a weak pointer, to prevent any use-after-free - // conditions. - EventDispatchCallback const ui_dispatch_cb_; - - // The CastSocketService to observe. - cast_channel::CastSocketService* const cast_socket_service_; - - SEQUENCE_CHECKER(sequence_checker_); - - DISALLOW_COPY_AND_ASSIGN(CastMessageHandler); - }; - - ~CastChannelAPI() override; - - // EventRouter::Observer: - void OnListenerAdded(const EventListenerInfo& details) override; - void OnListenerRemoved(const EventListenerInfo& details) override; - - // BrowserContextKeyedAPI implementation. - static const char* service_name() { return "CastChannelAPI"; } - - static const bool kServiceIsNULLWhileTesting = true; - - content::BrowserContext* const browser_context_; - std::unique_ptr socket_for_test_; - // Created on UI thread, accessed and destroyed on |cast_socket_service_|'s - // task runner. - std::unique_ptr message_handler_; - - cast_channel::CastSocketService* const cast_socket_service_; - - DISALLOW_COPY_AND_ASSIGN(CastChannelAPI); -}; - -template <> -void BrowserContextKeyedAPIFactory< - CastChannelAPI>::DeclareFactoryDependencies(); - -class CastChannelAsyncApiFunction : public AsyncApiFunction { - public: - CastChannelAsyncApiFunction(); - - protected: - ~CastChannelAsyncApiFunction() override; - - // AsyncApiFunction: - bool PrePrepare() override; - bool Respond() override; - - // Sets the function result to a ChannelInfo obtained from the state of - // |socket|. - void SetResultFromSocket(const cast_channel::CastSocket& socket); - - // Sets the function result to a ChannelInfo populated with |channel_id| and - // |error|. - void SetResultFromError(int channel_id, - api::cast_channel::ChannelError error); - - // Raw pointer of leaky singleton CastSocketService, which manages creating - // and removing Cast sockets. - cast_channel::CastSocketService* cast_socket_service_; - - private: - // Sets the function result from |channel_info|. - void SetResultFromChannelInfo( - const api::cast_channel::ChannelInfo& channel_info); -}; - -class CastChannelOpenFunction : public CastChannelAsyncApiFunction { - public: - CastChannelOpenFunction(); - - protected: - ~CastChannelOpenFunction() override; - - // AsyncApiFunction: - bool PrePrepare() override; - bool Prepare() override; - void AsyncWorkStart() override; - - private: - DECLARE_EXTENSION_FUNCTION("cast.channel.open", CAST_CHANNEL_OPEN) - - // Validates that |connect_info| represents a valid IP end point and returns a - // new IPEndPoint if so. Otherwise returns nullptr. - static net::IPEndPoint* ParseConnectInfo( - const api::cast_channel::ConnectInfo& connect_info); - - // |socket|: raw pointer of newly created cast channel. Does not take - // ownership of |socket|. - void OnOpen(cast_channel::CastSocket* socket); - - std::unique_ptr params_; - CastChannelAPI* api_; - std::unique_ptr ip_endpoint_; - base::TimeDelta liveness_timeout_; - base::TimeDelta ping_interval_; - - FRIEND_TEST_ALL_PREFIXES(CastChannelOpenFunctionTest, TestParseConnectInfo); - DISALLOW_COPY_AND_ASSIGN(CastChannelOpenFunction); -}; - -class CastChannelSendFunction : public CastChannelAsyncApiFunction { - public: - CastChannelSendFunction(); - - protected: - ~CastChannelSendFunction() override; - - // AsyncApiFunction: - bool Prepare() override; - void AsyncWorkStart() override; - - private: - DECLARE_EXTENSION_FUNCTION("cast.channel.send", CAST_CHANNEL_SEND) - - void OnSend(int result); - - std::unique_ptr params_; - - DISALLOW_COPY_AND_ASSIGN(CastChannelSendFunction); -}; - -class CastChannelCloseFunction : public CastChannelAsyncApiFunction { - public: - CastChannelCloseFunction(); - - protected: - ~CastChannelCloseFunction() override; - - // AsyncApiFunction: - bool PrePrepare() override; - bool Prepare() override; - void AsyncWorkStart() override; - - private: - DECLARE_EXTENSION_FUNCTION("cast.channel.close", CAST_CHANNEL_CLOSE) - - void OnClose(int result); - - std::unique_ptr params_; - - DISALLOW_COPY_AND_ASSIGN(CastChannelCloseFunction); -}; - -} // namespace extensions - -#endif // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_API_H_ diff --git a/extensions/browser/api/cast_channel/cast_channel_api_unittest.cc b/extensions/browser/api/cast_channel/cast_channel_api_unittest.cc deleted file mode 100644 index d19dbccf09a506..00000000000000 --- a/extensions/browser/api/cast_channel/cast_channel_api_unittest.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "extensions/browser/api/cast_channel/cast_channel_api.h" - -#include - -#include "net/base/ip_endpoint.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace extensions { - -// Tests parsing of ConnectInfo. -TEST(CastChannelOpenFunctionTest, TestParseConnectInfo) { - typedef CastChannelOpenFunction ccof; - std::unique_ptr ip_endpoint; - - // Valid ConnectInfo - api::cast_channel::ConnectInfo connect_info; - connect_info.ip_address = "192.0.0.1"; - connect_info.port = 8009; - connect_info.auth = api::cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED; - - ip_endpoint.reset(ccof::ParseConnectInfo(connect_info)); - EXPECT_TRUE(ip_endpoint); - EXPECT_EQ(ip_endpoint->ToString(), "192.0.0.1:8009"); -} - -} // namespace extensions diff --git a/extensions/browser/api/cast_channel/cast_channel_apitest.cc b/extensions/browser/api/cast_channel/cast_channel_apitest.cc deleted file mode 100644 index aaffd12eced217..00000000000000 --- a/extensions/browser/api/cast_channel/cast_channel_apitest.cc +++ /dev/null @@ -1,503 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/memory/ptr_util.h" -#include "base/test/scoped_feature_list.h" -#include "base/timer/mock_timer.h" -#include "build/build_config.h" -#include "chrome/browser/extensions/extension_apitest.h" -#include "chrome/browser/extensions/extension_function_test_utils.h" -#include "chrome/browser/media/router/media_router_feature.h" -#include "chrome/browser/media/router/providers/cast/dual_media_sink_service.h" -#include "chrome/browser/media/router/test/noop_dual_media_sink_service.h" -#include "chrome/browser/ui/browser.h" -#include "components/cast_channel/cast_socket.h" -#include "components/cast_channel/cast_socket_service.h" -#include "components/cast_channel/cast_test_util.h" -#include "components/cast_channel/logger.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/test/browser_test.h" -#include "extensions/browser/api/cast_channel/cast_channel_api.h" -#include "extensions/common/api/cast_channel.h" -#include "extensions/common/extension_builder.h" -#include "extensions/common/switches.h" -#include "extensions/test/extension_test_message_listener.h" -#include "extensions/test/result_catcher.h" -#include "net/base/ip_address.h" -#include "net/base/net_errors.h" -#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "third_party/openscreen/src/cast/common/channel/proto/cast_channel.pb.h" - -using ::cast::channel::CastMessage; -using ::cast_channel::CastSocket; -using ::cast_channel::CastTransport; -using ::cast_channel::ChannelError; -using ::cast_channel::CreateIPEndPointForTest; -using ::cast_channel::LastError; -using ::cast_channel::Logger; -using ::cast_channel::MockCastSocket; -using ::cast_channel::MockCastTransport; -using ::cast_channel::ReadyState; -using extensions::Extension; -using extensions::api::cast_channel::ErrorInfo; -using extensions::api::cast_channel::MessageInfo; - -namespace utils = extension_function_test_utils; - -using ::testing::_; -using ::testing::A; -using ::testing::DoAll; -using ::testing::InSequence; -using ::testing::Invoke; -using ::testing::NotNull; -using ::testing::Return; -using ::testing::ReturnPointee; -using ::testing::ReturnRef; -using ::testing::SaveArg; -using ::testing::WithArgs; - -namespace { - -const char kTestExtensionId[] = "ddchlicdkolnonkihahngkmmmjnjlkkf"; - -static void FillCastMessage(const std::string& message, - CastMessage* cast_message) { - cast_message->set_namespace_("foo"); - cast_message->set_source_id("src"); - cast_message->set_destination_id("dest"); - cast_message->set_payload_utf8(message); - cast_message->set_payload_type(CastMessage::STRING); -} - -ACTION_TEMPLATE(InvokeCompletionCallback, - HAS_1_TEMPLATE_PARAMS(int, k), - AND_1_VALUE_PARAMS(result)) { - std::get(args).Run(result); -} - -} // namespace - -class CastChannelAPITest : public extensions::ExtensionApiTest { - public: - CastChannelAPITest() : ip_endpoint_(CreateIPEndPointForTest()) {} - - void SetUpCommandLine(base::CommandLine* command_line) override { - extensions::ExtensionApiTest::SetUpCommandLine(command_line); - command_line->AppendSwitchASCII( - extensions::switches::kAllowlistedExtensionID, kTestExtensionId); - } - - void SetUp() override { - // Stub out DualMediaSinkService so it does not interfere with the test. - media_router::DualMediaSinkService::SetInstanceForTest( - new media_router::NoopDualMediaSinkService()); - // The Media Route Providers must be disabled because they rely on the - // presence of a valid DualMediaSinkService. - feature_list_.InitWithFeatures( - {}, /* disabled_features */ {media_router::kDialMediaRouteProvider, - media_router::kCastMediaRouteProvider}); - extensions::ExtensionApiTest::SetUp(); - } - - void SetUpMockCastSocket() { - extensions::CastChannelAPI* api = GetApi(); - - net::IPEndPoint ip_endpoint(net::IPAddress(192, 168, 1, 1), 8009); - mock_cast_socket_ = new MockCastSocket(); - mock_cast_socket_->SetIPEndpoint(ip_endpoint_); - mock_cast_socket_->SetKeepAlive(false); - // Transfers ownership of the socket. - api->SetSocketForTest(base::WrapUnique(mock_cast_socket_)); - } - - void SetUpOpenSendClose() { - SetUpMockCastSocket(); - mock_cast_socket_->SetErrorState(ChannelError::NONE); - { - InSequence sequence; - - EXPECT_CALL(*mock_cast_socket_, ConnectInternal(_)) - .WillOnce(WithArgs<0>( - Invoke([&](const MockCastSocket::MockOnOpenCallback& callback) { - callback.Run(mock_cast_socket_); - }))); - EXPECT_CALL(*mock_cast_socket_, ready_state()) - .WillRepeatedly(Return(ReadyState::OPEN)); - EXPECT_CALL(*mock_cast_socket_->mock_transport(), - SendMessage(A(), _)) - .WillOnce(InvokeCompletionCallback<1>(net::OK)); - EXPECT_CALL(*mock_cast_socket_, ready_state()) - .WillOnce(Return(ReadyState::OPEN)); - EXPECT_CALL(*mock_cast_socket_, Close(_)) - .WillOnce(InvokeCompletionCallback<0>(net::OK)); - EXPECT_CALL(*mock_cast_socket_, ready_state()) - .WillOnce(Return(ReadyState::CLOSED)); - } - } - - void SetUpOpenErrorSend() { - SetUpMockCastSocket(); - mock_cast_socket_->SetErrorState(ChannelError::CONNECT_ERROR); - { - InSequence sequence; - - EXPECT_CALL(*mock_cast_socket_, ConnectInternal(_)) - .WillOnce(WithArgs<0>( - Invoke([&](const MockCastSocket::MockOnOpenCallback& callback) { - callback.Run(mock_cast_socket_); - }))); - EXPECT_CALL(*mock_cast_socket_, ready_state()) - .WillRepeatedly(Return(ReadyState::CLOSED)); - EXPECT_CALL(*mock_cast_socket_->mock_transport(), SendMessage(_, _)) - .Times(0); - EXPECT_CALL(*mock_cast_socket_, Close(_)) - .WillOnce(InvokeCompletionCallback<0>(net::OK)); - EXPECT_CALL(*mock_cast_socket_, ready_state()) - .WillOnce(Return(ReadyState::CLOSED)); - } - } - - void SetUpOpenPingTimeout() { - SetUpMockCastSocket(); - mock_cast_socket_->SetErrorState(ChannelError::NONE); - mock_cast_socket_->SetKeepAlive(true); - { - InSequence sequence; - EXPECT_CALL(*mock_cast_socket_, ConnectInternal(_)) - .WillOnce(WithArgs<0>( - Invoke([&](const MockCastSocket::MockOnOpenCallback& callback) { - callback.Run(mock_cast_socket_); - }))); - EXPECT_CALL(*mock_cast_socket_, ready_state()) - .WillOnce(Return(ReadyState::OPEN)) - .RetiresOnSaturation(); - EXPECT_CALL(*mock_cast_socket_, AddObserver(_)) - .WillOnce(SaveArg<0>(&message_observer_)); - EXPECT_CALL(*mock_cast_socket_, ready_state()) - .Times(2) - .WillRepeatedly(Return(ReadyState::CLOSED)); - } - EXPECT_CALL(*mock_cast_socket_, Close(_)) - .WillOnce(InvokeCompletionCallback<0>(net::OK)); - } - - extensions::CastChannelAPI* GetApi() { - return extensions::CastChannelAPI::Get(profile()); - } - - cast_channel::CastSocketService* GetCastSocketService() { - return cast_channel::CastSocketService::GetInstance(); - } - - // Logs some bogus error details and calls the OnError handler. - void DoCallOnError(cast_channel::CastSocketService* cast_socket_service) { - cast_socket_service->GetLogger()->LogSocketEventWithRv( - mock_cast_socket_->id(), cast_channel::ChannelEvent::SOCKET_WRITE, - net::ERR_FAILED); - message_observer_->OnError(*mock_cast_socket_, ChannelError::CONNECT_ERROR); - } - - protected: - void CallOnMessage(const std::string& message) { - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&CastChannelAPITest::DoCallOnMessage, - base::Unretained(this), GetApi(), - mock_cast_socket_, message)); - } - - void DoCallOnMessage(extensions::CastChannelAPI* api, - MockCastSocket* cast_socket, - const std::string& message) { - CastMessage cast_message; - FillCastMessage(message, &cast_message); - message_observer_->OnMessage(*cast_socket, cast_message); - } - - // Fires a timer on the IO thread. - void FireTimeout() { - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&CastChannelAPITest::DoFireTimeout, - base::Unretained(this), mock_cast_socket_)); - } - - void DoFireTimeout(MockCastSocket* cast_socket) { - message_observer_->OnError(*cast_socket, - cast_channel::ChannelError::PING_TIMEOUT); - } - - extensions::CastChannelOpenFunction* CreateOpenFunction( - scoped_refptr extension) { - extensions::CastChannelOpenFunction* cast_channel_open_function = - new extensions::CastChannelOpenFunction; - cast_channel_open_function->set_extension(extension.get()); - return cast_channel_open_function; - } - - extensions::CastChannelSendFunction* CreateSendFunction( - scoped_refptr extension) { - extensions::CastChannelSendFunction* cast_channel_send_function = - new extensions::CastChannelSendFunction; - cast_channel_send_function->set_extension(extension.get()); - return cast_channel_send_function; - } - - MockCastSocket* mock_cast_socket_; - net::IPEndPoint ip_endpoint_; - LastError last_error_; - CastSocket::Observer* message_observer_; - int channel_id_; - base::test::ScopedFeatureList feature_list_; -}; - -ACTION_P2(InvokeObserverOnError, api_test, cast_socket_service) { - content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&CastChannelAPITest::DoCallOnError, - base::Unretained(api_test), - base::Unretained(cast_socket_service))); -} - -// TODO(kmarshall): Win Dbg has a workaround that makes RunExtensionTest -// always return true without actually running the test. Remove when fixed. -#if defined(OS_WIN) && !defined(NDEBUG) -#define MAYBE_TestOpenSendClose DISABLED_TestOpenSendClose -#else -#define MAYBE_TestOpenSendClose TestOpenSendClose -#endif -// Test loading extension, opening a channel with ConnectInfo, adding a -// listener, writing, reading, and closing. -IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenSendClose) { - SetUpOpenSendClose(); - - EXPECT_TRUE(RunExtensionTest( - {.name = "cast_channel/api", .page_url = "test_open_send_close.html"})); -} - -// TODO(kmarshall): Win Dbg has a workaround that makes RunExtensionTest -// always return true without actually running the test. Remove when fixed. -#if defined(OS_WIN) && !defined(NDEBUG) -#define MAYBE_TestOpenErrorSend DISABLED_TestOpenErrorSend -#else -#define MAYBE_TestOpenErrorSend TestOpenErrorSend -#endif -// Test loading extension, failing to open a channel with ConnectInfo, sending -// message on closed channel, and closing. -IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenErrorSend) { - SetUpOpenErrorSend(); - - EXPECT_TRUE(RunExtensionTest( - {.name = "cast_channel/api", .page_url = "test_open_error_send.html"})); -} - -// TODO(kmarshall): Win Dbg has a workaround that makes RunExtensionTest -// always return true without actually running the test. Remove when fixed. -#if defined(OS_WIN) && !defined(NDEBUG) -#define MAYBE_TestPingTimeout DISABLED_TestPingTimeout -#else -#define MAYBE_TestPingTimeout TestPingTimeout -#endif -// Verify that timeout events are propagated through the API layer. -// (SSL, non-verified). -IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestPingTimeout) { - SetUpOpenPingTimeout(); - - ExtensionTestMessageListener channel_opened("channel_opened_ssl", false); - ExtensionTestMessageListener timeout("timeout_ssl", false); - EXPECT_TRUE(RunExtensionTest( - {.name = "cast_channel/api", .page_url = "test_open_timeout.html"})); - EXPECT_TRUE(channel_opened.WaitUntilSatisfied()); - FireTimeout(); - EXPECT_TRUE(timeout.WaitUntilSatisfied()); -} - -// TODO(kmarshall): Win Dbg has a workaround that makes RunExtensionTest -// always return true without actually running the test. Remove when fixed. -#if defined(OS_WIN) && !defined(NDEBUG) -#define MAYBE_TestPingTimeoutSslVerified DISABLED_TestPingTimeoutSslVerified -#else -#define MAYBE_TestPingTimeoutSslVerified TestPingTimeoutSslVerified -#endif -// Verify that timeout events are propagated through the API layer. -// (SSL, verified). -IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestPingTimeoutSslVerified) { - SetUpOpenPingTimeout(); - - ExtensionTestMessageListener channel_opened("channel_opened_ssl_verified", - false); - ExtensionTestMessageListener timeout("timeout_ssl_verified", false); - EXPECT_TRUE( - RunExtensionTest({.name = "cast_channel/api", - .page_url = "test_open_timeout_verified.html"})); - EXPECT_TRUE(channel_opened.WaitUntilSatisfied()); - FireTimeout(); - EXPECT_TRUE(timeout.WaitUntilSatisfied()); -} - -// TODO(kmarshall): Win Dbg has a workaround that makes RunExtensionTest -// always return true without actually running the test. Remove when fixed. -#if defined(OS_WIN) && !defined(NDEBUG) -#define MAYBE_TestOpenReceiveClose DISABLED_TestOpenReceiveClose -#else -#define MAYBE_TestOpenReceiveClose TestOpenReceiveClose -#endif -// Test loading extension, opening a channel, adding a listener, -// writing, reading, and closing. -IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenReceiveClose) { - SetUpMockCastSocket(); - mock_cast_socket_->SetErrorState(ChannelError::NONE); - - { - InSequence sequence; - - EXPECT_CALL(*mock_cast_socket_, ConnectInternal(_)) - .WillOnce(WithArgs<0>( - Invoke([&](const MockCastSocket::MockOnOpenCallback& callback) { - callback.Run(mock_cast_socket_); - }))); - EXPECT_CALL(*mock_cast_socket_, ready_state()) - .WillOnce(Return(ReadyState::OPEN)); - EXPECT_CALL(*mock_cast_socket_, AddObserver(_)) - .WillOnce(SaveArg<0>(&message_observer_)); - EXPECT_CALL(*mock_cast_socket_, ready_state()) - .Times(2) - .WillRepeatedly(Return(ReadyState::OPEN)); - EXPECT_CALL(*mock_cast_socket_, Close(_)) - .WillOnce(InvokeCompletionCallback<0>(net::OK)); - EXPECT_CALL(*mock_cast_socket_, ready_state()) - .WillOnce(Return(ReadyState::CLOSED)); - } - - EXPECT_TRUE(RunExtensionTest({.name = "cast_channel/api", - .page_url = "test_open_receive_close.html"})); - - extensions::ResultCatcher catcher; - CallOnMessage("some-message"); - CallOnMessage("some-message"); - EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); -} - -// TODO(kmarshall): Win Dbg has a workaround that makes RunExtensionTest -// always return true without actually running the test. Remove when fixed. -#if defined(OS_WIN) && !defined(NDEBUG) -#define MAYBE_TestOpenError DISABLED_TestOpenError -#else -#define MAYBE_TestOpenError TestOpenError -#endif -// Test the case when socket open results in an error. -IN_PROC_BROWSER_TEST_F(CastChannelAPITest, MAYBE_TestOpenError) { - SetUpMockCastSocket(); - - EXPECT_CALL(*mock_cast_socket_, AddObserver(_)) - .WillOnce(DoAll(SaveArg<0>(&message_observer_), - InvokeObserverOnError(this, GetCastSocketService()))); - EXPECT_CALL(*mock_cast_socket_, ConnectInternal(_)) - .WillOnce(WithArgs<0>( - Invoke([&](const MockCastSocket::MockOnOpenCallback& callback) { - callback.Run(mock_cast_socket_); - }))); - mock_cast_socket_->SetErrorState(ChannelError::CONNECT_ERROR); - EXPECT_CALL(*mock_cast_socket_, ready_state()) - .WillRepeatedly(Return(ReadyState::CLOSED)); - EXPECT_CALL(*mock_cast_socket_, Close(_)) - .WillOnce(InvokeCompletionCallback<0>(net::OK)); - - EXPECT_TRUE(RunExtensionTest( - {.name = "cast_channel/api", .page_url = "test_open_error.html"})); -} - -IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestOpenInvalidConnectInfo) { - scoped_refptr empty_extension = - extensions::ExtensionBuilder("Test").Build(); - scoped_refptr cast_channel_open_function; - - // Invalid IP address - cast_channel_open_function = CreateOpenFunction(empty_extension); - std::string error = utils::RunFunctionAndReturnError( - cast_channel_open_function.get(), - "[{\"ipAddress\": \"invalid_ip\", \"port\": 8009, \"auth\": " - "\"ssl_verified\"}]", - browser()); - EXPECT_EQ(error, "Invalid connect_info (invalid IP address)"); - - // Invalid port - cast_channel_open_function = CreateOpenFunction(empty_extension); - error = utils::RunFunctionAndReturnError(cast_channel_open_function.get(), - "[{\"ipAddress\": \"127.0.0.1\", " - "\"port\": -200, \"auth\": " - "\"ssl_verified\"}]", - browser()); - EXPECT_EQ(error, "Invalid connect_info (invalid port)"); -} - -IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestSendInvalidMessageInfo) { - scoped_refptr empty_extension( - extensions::ExtensionBuilder("Test").Build()); - scoped_refptr cast_channel_send_function; - - // Numbers are not supported - cast_channel_send_function = CreateSendFunction(empty_extension); - std::string error(utils::RunFunctionAndReturnError( - cast_channel_send_function.get(), - "[{\"channelId\": 1, " - "\"keepAlive\": true, " - "\"audioOnly\": false, " - "\"connectInfo\": " - "{\"ipAddress\": \"127.0.0.1\", \"port\": 8009, " - "\"auth\": \"ssl_verified\"}, \"readyState\": \"open\"}, " - "{\"namespace_\": \"foo\", \"sourceId\": \"src\", " - "\"destinationId\": \"dest\", \"data\": 1235}]", - browser())); - EXPECT_EQ(error, "Invalid type of message_info.data"); - - // Missing namespace_ - cast_channel_send_function = CreateSendFunction(empty_extension); - error = utils::RunFunctionAndReturnError( - cast_channel_send_function.get(), - "[{\"channelId\": 1, " - "\"keepAlive\": true, " - "\"audioOnly\": false, " - "\"connectInfo\": " - "{\"ipAddress\": \"127.0.0.1\", \"port\": 8009, " - "\"auth\": \"ssl_verified\"}, \"readyState\": \"open\"}, " - "{\"namespace_\": \"\", \"sourceId\": \"src\", " - "\"destinationId\": \"dest\", \"data\": \"data\"}]", - browser()); - EXPECT_EQ(error, "message_info.namespace_ is required"); - - // Missing source_id - cast_channel_send_function = CreateSendFunction(empty_extension); - error = utils::RunFunctionAndReturnError( - cast_channel_send_function.get(), - "[{\"channelId\": 1, " - "\"keepAlive\": true, " - "\"audioOnly\": false, " - "\"connectInfo\": " - "{\"ipAddress\": \"127.0.0.1\", \"port\": 8009, " - "\"auth\": \"ssl_verified\"}, \"readyState\": \"open\"}, " - "{\"namespace_\": \"foo\", \"sourceId\": \"\", " - "\"destinationId\": \"dest\", \"data\": \"data\"}]", - browser()); - EXPECT_EQ(error, "message_info.source_id is required"); - - // Missing destination_id - cast_channel_send_function = CreateSendFunction(empty_extension); - error = utils::RunFunctionAndReturnError( - cast_channel_send_function.get(), - "[{\"channelId\": 1, " - "\"keepAlive\": true, " - "\"audioOnly\": false, " - "\"connectInfo\": " - "{\"ipAddress\": \"127.0.0.1\", \"port\": 8009, " - "\"auth\": \"ssl_verified\"}, \"readyState\": \"open\"}, " - "{\"namespace_\": \"foo\", \"sourceId\": \"src\", " - "\"destinationId\": \"\", \"data\": \"data\"}]", - browser()); - EXPECT_EQ(error, "message_info.destination_id is required"); -} diff --git a/extensions/browser/api/cast_channel/cast_channel_enum_util.cc b/extensions/browser/api/cast_channel/cast_channel_enum_util.cc deleted file mode 100644 index 8532177e892170..00000000000000 --- a/extensions/browser/api/cast_channel/cast_channel_enum_util.cc +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "extensions/browser/api/cast_channel/cast_channel_enum_util.h" -#include "base/notreached.h" - -namespace extensions { - -api::cast_channel::ReadyState ToReadyState( - ::cast_channel::ReadyState ready_state) { - switch (ready_state) { - case ::cast_channel::ReadyState::NONE: - return api::cast_channel::READY_STATE_NONE; - case ::cast_channel::ReadyState::CONNECTING: - return api::cast_channel::READY_STATE_CONNECTING; - case ::cast_channel::ReadyState::OPEN: - return api::cast_channel::READY_STATE_OPEN; - case ::cast_channel::ReadyState::CLOSING: - return api::cast_channel::READY_STATE_CLOSING; - case ::cast_channel::ReadyState::CLOSED: - return api::cast_channel::READY_STATE_CLOSED; - } - NOTREACHED() << "Unknown ready_state " << ReadyStateToString(ready_state); - return api::cast_channel::READY_STATE_NONE; -} - -api::cast_channel::ChannelError ToChannelError( - ::cast_channel::ChannelError channel_error) { - switch (channel_error) { - case ::cast_channel::ChannelError::NONE: - return api::cast_channel::CHANNEL_ERROR_NONE; - case ::cast_channel::ChannelError::CHANNEL_NOT_OPEN: - return api::cast_channel::CHANNEL_ERROR_CHANNEL_NOT_OPEN; - case ::cast_channel::ChannelError::AUTHENTICATION_ERROR: - return api::cast_channel::CHANNEL_ERROR_AUTHENTICATION_ERROR; - case ::cast_channel::ChannelError::CONNECT_ERROR: - return api::cast_channel::CHANNEL_ERROR_CONNECT_ERROR; - case ::cast_channel::ChannelError::CAST_SOCKET_ERROR: - return api::cast_channel::CHANNEL_ERROR_SOCKET_ERROR; - case ::cast_channel::ChannelError::TRANSPORT_ERROR: - return api::cast_channel::CHANNEL_ERROR_TRANSPORT_ERROR; - case ::cast_channel::ChannelError::INVALID_MESSAGE: - return api::cast_channel::CHANNEL_ERROR_INVALID_MESSAGE; - case ::cast_channel::ChannelError::INVALID_CHANNEL_ID: - return api::cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID; - case ::cast_channel::ChannelError::CONNECT_TIMEOUT: - return api::cast_channel::CHANNEL_ERROR_CONNECT_TIMEOUT; - case ::cast_channel::ChannelError::PING_TIMEOUT: - return api::cast_channel::CHANNEL_ERROR_PING_TIMEOUT; - case ::cast_channel::ChannelError::UNKNOWN: - return api::cast_channel::CHANNEL_ERROR_UNKNOWN; - } - NOTREACHED() << "Unknown channel_error " - << ChannelErrorToString(channel_error); - return api::cast_channel::CHANNEL_ERROR_NONE; -} - -} // namespace extensions diff --git a/extensions/browser/api/cast_channel/cast_channel_enum_util.h b/extensions/browser/api/cast_channel/cast_channel_enum_util.h deleted file mode 100644 index f803769eb0e14f..00000000000000 --- a/extensions/browser/api/cast_channel/cast_channel_enum_util.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_TYPE_UTIL_H_ -#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_TYPE_UTIL_H_ - -#include "components/cast_channel/cast_channel_enum.h" -#include "extensions/common/api/cast_channel.h" - -namespace extensions { - -api::cast_channel::ReadyState ToReadyState( - ::cast_channel::ReadyState ready_state); -api::cast_channel::ChannelError ToChannelError( - ::cast_channel::ChannelError channel_error); - -} // namespace extensions - -#endif // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_TYPE_UTIL_H_ diff --git a/extensions/browser/api/cast_channel/cast_channel_enum_util_unittest.cc b/extensions/browser/api/cast_channel/cast_channel_enum_util_unittest.cc deleted file mode 100644 index 041a773e428c35..00000000000000 --- a/extensions/browser/api/cast_channel/cast_channel_enum_util_unittest.cc +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "extensions/browser/api/cast_channel/cast_channel_enum_util.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace extensions { - -TEST(CastChannelEnumUtilTest, TestToReadyState) { - EXPECT_EQ(api::cast_channel::READY_STATE_NONE, - ToReadyState(::cast_channel::ReadyState::NONE)); - EXPECT_EQ(api::cast_channel::READY_STATE_CONNECTING, - ToReadyState(::cast_channel::ReadyState::CONNECTING)); - EXPECT_EQ(api::cast_channel::READY_STATE_OPEN, - ToReadyState(::cast_channel::ReadyState::OPEN)); - EXPECT_EQ(api::cast_channel::READY_STATE_CLOSING, - ToReadyState(::cast_channel::ReadyState::CLOSING)); - EXPECT_EQ(api::cast_channel::READY_STATE_CLOSED, - ToReadyState(::cast_channel::ReadyState::CLOSED)); -} - -TEST(CastChannelEnumUtilTest, TestToChannelError) { - EXPECT_EQ(api::cast_channel::CHANNEL_ERROR_NONE, - ToChannelError(::cast_channel::ChannelError::NONE)); - EXPECT_EQ(api::cast_channel::CHANNEL_ERROR_CHANNEL_NOT_OPEN, - ToChannelError(::cast_channel::ChannelError::CHANNEL_NOT_OPEN)); - EXPECT_EQ(api::cast_channel::CHANNEL_ERROR_AUTHENTICATION_ERROR, - ToChannelError(::cast_channel::ChannelError::AUTHENTICATION_ERROR)); - EXPECT_EQ(api::cast_channel::CHANNEL_ERROR_CONNECT_ERROR, - ToChannelError(::cast_channel::ChannelError::CONNECT_ERROR)); - EXPECT_EQ(api::cast_channel::CHANNEL_ERROR_SOCKET_ERROR, - ToChannelError(::cast_channel::ChannelError::CAST_SOCKET_ERROR)); - EXPECT_EQ(api::cast_channel::CHANNEL_ERROR_TRANSPORT_ERROR, - ToChannelError(::cast_channel::ChannelError::TRANSPORT_ERROR)); - EXPECT_EQ(api::cast_channel::CHANNEL_ERROR_INVALID_MESSAGE, - ToChannelError(::cast_channel::ChannelError::INVALID_MESSAGE)); - EXPECT_EQ(api::cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID, - ToChannelError(::cast_channel::ChannelError::INVALID_CHANNEL_ID)); - EXPECT_EQ(api::cast_channel::CHANNEL_ERROR_CONNECT_TIMEOUT, - ToChannelError(::cast_channel::ChannelError::CONNECT_TIMEOUT)); - EXPECT_EQ(api::cast_channel::CHANNEL_ERROR_PING_TIMEOUT, - ToChannelError(::cast_channel::ChannelError::PING_TIMEOUT)); - EXPECT_EQ(api::cast_channel::CHANNEL_ERROR_UNKNOWN, - ToChannelError(::cast_channel::ChannelError::UNKNOWN)); -} - -} // namespace extensions diff --git a/extensions/browser/api/cast_channel/cast_message_util.cc b/extensions/browser/api/cast_channel/cast_message_util.cc deleted file mode 100644 index d216fdfc17fe12..00000000000000 --- a/extensions/browser/api/cast_channel/cast_message_util.cc +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "extensions/browser/api/cast_channel/cast_message_util.h" - -#include - -#include "base/check.h" -#include "base/containers/span.h" -#include "base/strings/string_number_conversions.h" -#include "base/values.h" -#include "extensions/common/api/cast_channel.h" -#include "third_party/openscreen/src/cast/common/channel/proto/cast_channel.pb.h" - -namespace extensions { - -bool MessageInfoToCastMessage(const api::cast_channel::MessageInfo& message, - ::cast::channel::CastMessage* message_proto) { - DCHECK(message_proto); - if (!message.data) - return false; - - message_proto->set_protocol_version( - ::cast::channel::CastMessage_ProtocolVersion_CASTV2_1_0); - message_proto->set_source_id(message.source_id); - message_proto->set_destination_id(message.destination_id); - message_proto->set_namespace_(message.namespace_); - // Determine the type of the base::Value and set the message payload - // appropriately. - switch (message.data->type()) { - // JS string - case base::Value::Type::STRING: { - std::string data; - if (message.data->GetAsString(&data)) { - message_proto->set_payload_type( - ::cast::channel::CastMessage_PayloadType_STRING); - message_proto->set_payload_utf8(std::move(data)); - } - break; - } - // JS ArrayBuffer - case base::Value::Type::BINARY: - message_proto->set_payload_type( - ::cast::channel::CastMessage_PayloadType_BINARY); - message_proto->set_payload_binary(message.data->GetBlob().data(), - message.data->GetBlob().size()); - break; - default: - // Unknown value type. message_proto will remain uninitialized because - // payload_type is unset. - break; - } - return message_proto->IsInitialized(); -} - -bool CastMessageToMessageInfo(const ::cast::channel::CastMessage& message_proto, - api::cast_channel::MessageInfo* message) { - DCHECK(message); - message->source_id = message_proto.source_id(); - message->destination_id = message_proto.destination_id(); - message->namespace_ = message_proto.namespace_(); - // Determine the type of the payload and fill base::Value appropriately. - base::Value value; - switch (message_proto.payload_type()) { - case ::cast::channel::CastMessage_PayloadType_STRING: - if (message_proto.has_payload_utf8()) - value = base::Value(message_proto.payload_utf8()); - break; - case ::cast::channel::CastMessage_PayloadType_BINARY: - if (message_proto.has_payload_binary()) { - value = base::Value( - base::as_bytes(base::make_span(message_proto.payload_binary()))); - } - break; - default: - // Unknown payload type. value will remain unset. - break; - } - if (value.is_none()) - return false; - - DCHECK(!message->data.get()); - message->data = base::Value::ToUniquePtrValue(std::move(value)); - return true; -} - -} // namespace extensions diff --git a/extensions/browser/api/cast_channel/cast_message_util.h b/extensions/browser/api/cast_channel/cast_message_util.h deleted file mode 100644 index d2a56f08d00681..00000000000000 --- a/extensions/browser/api/cast_channel/cast_message_util.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_MESSAGE_UTIL_H_ -#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_MESSAGE_UTIL_H_ - -#include - -#include "third_party/openscreen/src/cast/common/channel/proto/cast_channel.pb.h" - -namespace extensions { - -namespace api { -namespace cast_channel { -struct MessageInfo; -} // namespace cast_channel -} // namespace api - -// Fills |message_proto| from |message| and returns true on success. -bool MessageInfoToCastMessage( - const extensions::api::cast_channel::MessageInfo& message, - ::cast::channel::CastMessage* message_proto); - -// Fills |message| from |message_proto| and returns true on success. -bool CastMessageToMessageInfo( - const ::cast::channel::CastMessage& message_proto, - extensions::api::cast_channel::MessageInfo* message); - -} // namespace extensions - -#endif // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_MESSAGE_UTIL_H_ diff --git a/extensions/browser/browser_context_keyed_service_factories.cc b/extensions/browser/browser_context_keyed_service_factories.cc index 3742d938e5b576..a0872285cfc6f7 100644 --- a/extensions/browser/browser_context_keyed_service_factories.cc +++ b/extensions/browser/browser_context_keyed_service_factories.cc @@ -12,7 +12,6 @@ #include "extensions/browser/api/bluetooth/bluetooth_api.h" #include "extensions/browser/api/bluetooth/bluetooth_private_api.h" #include "extensions/browser/api/bluetooth_socket/bluetooth_socket_event_dispatcher.h" -#include "extensions/browser/api/cast_channel/cast_channel_api.h" #include "extensions/browser/api/declarative_net_request/rules_monitor_service.h" #include "extensions/browser/api/feedback_private/feedback_private_api.h" #include "extensions/browser/api/hid/hid_device_manager.h" @@ -67,7 +66,6 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() { AudioAPI::GetFactoryInstance(); BluetoothAPI::GetFactoryInstance(); BluetoothPrivateAPI::GetFactoryInstance(); - CastChannelAPI::GetFactoryInstance(); #if BUILDFLAG(IS_CHROMEOS_ASH) ClipboardAPI::GetFactoryInstance(); #endif diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json index c89ba3f84c35ed..4f8ce754691d90 100644 --- a/extensions/common/api/_permission_features.json +++ b/extensions/common/api/_permission_features.json @@ -167,15 +167,6 @@ ] } ], - "cast": { - "channel": "stable", - "extension_types": ["extension", "legacy_packaged_app", "platform_app"], - "allowlist": [ - "9448CAB302F268FB4917D06F70703893DCDA26C4", // Cast Test Extension - "63ED55E43214C211F82122ED56407FF1A807F2A3", // Media Router Dev - "226CF815E39A363090A1E547D53063472B8279FA" // Media Router Stable - ] - }, "cecPrivate": { "channel": "stable", "extension_types": ["platform_app"], diff --git a/extensions/common/api/cast_channel.idl b/extensions/common/api/cast_channel.idl deleted file mode 100644 index 9b80a4d339255f..00000000000000 --- a/extensions/common/api/cast_channel.idl +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// API for communicating with a Google Cast device over an authenticated -// channel. -namespace cast.channel { - // The state of the channel. - enum ReadyState { - // The channel is connecting. - connecting, - // The channel is open and available for messaging. - open, - // The channel is closing. - closing, - // The channel is closed. - closed - }; - - // Error conditions that the channel may encounter. All error conditions - // are terminal. When an error condition is encountered the API will: - // (1) Transition the channel to readyState == 'closed'. - // (2) Set ChannelInfo.lastError to the error condition. - // (3) Fire an onError event with the error condition. - // (4) Fire an onClose event. - enum ChannelError { - // cast.channel.send() was called when ChannelInfo.readyState != 'open'. - channel_not_open, - // Authentication was requested and the receiver could not be - // authenticated (invalid signature, invalid handhake, TLS error, etc.) - authentication_error, - // A new channel could not be created for reasons unrelated to - // authentication (e.g., there is already an open channel to the same URL). - connect_error, - // There was an error writing or reading from the underlying socket. - socket_error, - // A transport level occurred (like an unparseable message). - transport_error, - // The client attempted to send an unsupported message type through the - // channel. - invalid_message, - // An invalid channel id was passed. - invalid_channel_id, - // The connection could not be established before timing out. - connect_timeout, - // The receiving end became unresponsive. - ping_timeout, - // Unspecified error. - unknown - }; - - // Authentication methods that may be required to connect to a Cast receiver. - enum ChannelAuthType { - // SSL over TCP with challenge and receiver signature verification. - ssl_verified - }; - - // Describes the information needed to connect to a Cast receiver. - // This replaces the prior use of cast:// and casts:// URLs. - dictionary ConnectInfo { - // The IPV4 address of the Cast receiver, e.g. '198.1.0.2'. - // TODO(mfoltz): Investigate whether IPV6 addresses "just work." - DOMString ipAddress; - - // The port number to connect to, 0-65535. - long port; - - // The amount of time to wait in milliseconds before stopping the - // connection process. Timeouts are disabled if the value is zero. - // The default timeout is 8000ms. - long? timeout; - - // The authentication method required for the channel. - ChannelAuthType auth; - - // ------------------------------------------------------------------------ - // Both pingInterval and livenessTimeout must be set to enable keep-alive - // handling. - - // The amount of time to wait in milliseconds before sending pings - // to idle channels. - long? pingInterval; - - // The maximum amount of idle time allowed before a channel is closed. - long? livenessTimeout; - - // If set, CastDeviceCapability bitmask values describing capability of the - // cast device. - long? capabilities; - }; - - // Describes the state of a channel to a Cast receiver. - dictionary ChannelInfo { - // Id for the channel. - long channelId; - - // Connection information that was used to establish the channel to the - // receiver. - ConnectInfo connectInfo; - - // The current state of the channel. - ReadyState readyState; - - // If set, the last error condition encountered by the channel. - ChannelError? errorState; - - // If true, keep-alive messages are handled automatically by the channel. - boolean keepAlive; - - // Whether the channel is audio only as identified by the device - // certificate during channel authentication. - boolean audioOnly; - }; - - // Describes a message sent or received over the channel. Currently only - // string messages are supported, although ArrayBuffer and Blob types may be - // supported in the future. - dictionary MessageInfo { - // The message namespace. A namespace is a URN of the form - // urn:cast-x: that is used to interpret and route Cast messages. - DOMString namespace_; - - // source and destination ids identify the origin and destination of the - // message. They are used to route messages between endpoints that share a - // device-to-device channel. - // - // For messages between applications: - // - The sender application id is a unique identifier generated on behalf - // of the sender application. - // - The receiver id is always the the session id for the application. - // - // For messages to or from the sender or receiver platform, the special ids - // 'sender-0' and 'receiver-0' can be used. - // - // For messages intended for all endpoints using a given channel, the - // wildcard destination_id '*' can be used. - DOMString sourceId; - DOMString destinationId; - - // The content of the message. Must be either a string or an ArrayBuffer. - any data; - }; - - // Describes a terminal error encountered by the channel with details of the - // error that caused the channel to be closed. One or more of the optional - // fields may be set with specific error codes from the underlying - // implementation. - dictionary ErrorInfo { - // The type of error encountered by the channel. - ChannelError errorState; - - // The event that was occurring when the error happened. Values are defined - // in the enum EventType in logging.proto. - long? eventType; - - // An error encountered when processing the authentication handshake. - // Values are defined in the enum ChallengeReplyErrorType in logging.proto. - long? challengeReplyErrorType; - - // A return value from the underlying net:: socket libraries. Values are - // defined in net/base/net_error_list.h. - long? netReturnValue; - - // An error code returned by NSS. Values are defined in secerr.h. - long? nssErrorCode; - }; - - // Callback holding the result of a channel operation. - callback ChannelInfoCallback = void (ChannelInfo result); - - interface Functions { - // Opens a new channel to the Cast receiver specified by connectInfo. Only - // one channel may be connected to same receiver from the same extension at - // a time. If the open request is successful, the callback will be invoked - // with a ChannelInfo with readyState == 'connecting'. If unsuccessful, the - // callback will be invoked with a ChannelInfo with channel.readyState == - // 'closed', channel.errorState will be set to the error condition, and - // onError will be fired with error details. - [supportsPromises] static void open(ConnectInfo connectInfo, - ChannelInfoCallback callback); - - // Sends a message on the channel and invokes callback with the resulting - // channel status. The channel must be in readyState == 'open'. If - // unsuccessful, channel.readyState will be set to 'closed', - // channel.errorState will be set to the error condition, and onError will - // be fired with error details. - [supportsPromises] static void send(ChannelInfo channel, - MessageInfo message, - ChannelInfoCallback callback); - - // Requests that the channel be closed and invokes callback with the - // resulting channel status. The channel must be in readyState == 'open' or - // 'connecting'. If successful, onClose will be fired with readyState == - // 'closed'. If unsuccessful, channel.readyState will be set to 'closed', - // and channel.errorState will be set to the error condition. - [supportsPromises] static void close(ChannelInfo channel, - ChannelInfoCallback callback); - }; - - // Events on the channel. - interface Events { - // Fired when a message is received on an open channel. - static void onMessage(ChannelInfo channel, - MessageInfo message); - - // Fired when an error occurs as a result of a channel operation or a - // network event. |error| contains details of the error. - static void onError(ChannelInfo channel, ErrorInfo error); - }; -}; diff --git a/extensions/common/api/schema.gni b/extensions/common/api/schema.gni index 4c0782944f1dd0..9b060d74541dba 100644 --- a/extensions/common/api/schema.gni +++ b/extensions/common/api/schema.gni @@ -17,7 +17,6 @@ extensions_api_schema_files_ = [ "bluetooth_low_energy.idl", "bluetooth_private.idl", "bluetooth_socket.idl", - "cast_channel.idl", "cec_private.idl", "clipboard.idl", "declarative_net_request.idl", diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 33328a0265dc51..1380f7f287eeb5 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg @@ -32450,7 +32450,7 @@ buckets { cipd_version: "refs/heads/master" cmd: "luciexe" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.codesearch\",\"recipe\":\"chromium_codesearch\"}" + properties: "{\"$build/goma\":{\"enable_ats\":false,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.codesearch\",\"recipe\":\"chromium_codesearch\"}" execution_timeout_secs: 32400 expiration_secs: 7200 caches { @@ -42139,7 +42139,7 @@ buckets { cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" + properties: "{\"$build/goma\":{\"enable_ats\":false,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" execution_timeout_secs: 21600 expiration_secs: 7200 caches { @@ -42261,7 +42261,7 @@ buckets { cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" + properties: "{\"$build/goma\":{\"enable_ats\":false,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" execution_timeout_secs: 21600 expiration_secs: 7200 caches { @@ -42566,7 +42566,7 @@ buckets { cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" + properties: "{\"$build/goma\":{\"enable_ats\":false,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" execution_timeout_secs: 21600 expiration_secs: 7200 caches { @@ -42627,7 +42627,7 @@ buckets { cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" + properties: "{\"$build/goma\":{\"enable_ats\":false,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" execution_timeout_secs: 21600 expiration_secs: 7200 caches { @@ -42749,7 +42749,7 @@ buckets { cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" + properties: "{\"$build/goma\":{\"enable_ats\":false,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" execution_timeout_secs: 21600 expiration_secs: 7200 caches { @@ -42810,7 +42810,7 @@ buckets { cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" + properties: "{\"$build/goma\":{\"enable_ats\":false,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" execution_timeout_secs: 21600 expiration_secs: 7200 caches { @@ -42871,7 +42871,7 @@ buckets { cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" + properties: "{\"$build/goma\":{\"enable_ats\":false,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" execution_timeout_secs: 21600 expiration_secs: 7200 caches { @@ -52576,7 +52576,7 @@ buckets { cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.swangle\",\"recipe\":\"chromium_trybot\"}" + properties: "{\"$build/goma\":{\"enable_ats\":false,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.swangle\",\"recipe\":\"chromium_trybot\"}" execution_timeout_secs: 7200 expiration_secs: 7200 caches { @@ -52638,7 +52638,7 @@ buckets { cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.swangle\",\"recipe\":\"chromium_trybot\"}" + properties: "{\"$build/goma\":{\"enable_ats\":false,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.swangle\",\"recipe\":\"chromium_trybot\"}" execution_timeout_secs: 7200 expiration_secs: 7200 caches { @@ -53478,7 +53478,7 @@ buckets { cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" + properties: "{\"$build/goma\":{\"enable_ats\":false,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" execution_timeout_secs: 14400 expiration_secs: 7200 grace_period { @@ -53543,7 +53543,7 @@ buckets { cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" + properties: "{\"$build/goma\":{\"enable_ats\":false,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" execution_timeout_secs: 14400 expiration_secs: 7200 grace_period { diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star index 61dcbd20ff1ddb..ad44aa02f229fb 100644 --- a/infra/config/lib/builders.star +++ b/infra/config/lib/builders.star @@ -444,7 +444,9 @@ def builder( in the '$build/goma' property. By default, args.COMPUTE is set and 'enable_ats' fields is set only if ats need to be enabled by default. The 'enable_ats' on Windows will control cross compiling in server - side. cross compile if `enable_ats` is not True. + side. cross compile if `enable_ats` is False. + Note: if goma_enable_ats is not set, goma recipe modules sets + GOMA_ARBITRARY_TOOLCHAIN_SUPPORT=true on windows by default. * goma_jobs - a member of the `goma.jobs` enum indicating the number of jobs to be used by the builder. Sets the 'jobs' field of the '$build/goma' property will be set according to the enum member. By default, the 'jobs' diff --git a/infra/config/lib/ci.star b/infra/config/lib/ci.star index f21b6bf019de72..82a7436e3f99a0 100644 --- a/infra/config/lib/ci.star +++ b/infra/config/lib/ci.star @@ -107,7 +107,7 @@ def ci_builder( # in CI, enable ATS on windows. if os and os.category == os_category.WINDOWS: - goma_enable_ats = True + kwargs["goma_enable_ats"] = True # Define the builder first so that any validation of luci.builder arguments # (e.g. bucket) occurs before we try to use it @@ -119,7 +119,6 @@ def ci_builder( notifies = notifies, experiments = experiments, resultdb_index_by_timestamp = True, - goma_enable_ats = goma_enable_ats, **kwargs ) diff --git a/infra/config/lib/try.star b/infra/config/lib/try.star index 03156195d3d6cc..20240948829907 100644 --- a/infra/config/lib/try.star +++ b/infra/config/lib/try.star @@ -19,7 +19,7 @@ to set the default value. Can also be accessed through `try_.defaults`. load("./args.star", "args") load("./branches.star", "branches") -load("./builders.star", "builders") +load("./builders.star", "builders", "os_category") DEFAULT_EXCLUDE_REGEXPS = [ # Contains documentation that doesn't affect the outputs @@ -151,6 +151,14 @@ def try_builder( if subproject_list_view: list_view.append(subproject_list_view) + goma_enable_ats = defaults.get_value_from_kwargs("goma_enable_ats", kwargs) + if goma_enable_ats == args.COMPUTE: + os = defaults.get_value_from_kwargs("os", kwargs) + + # in CQ/try, disable ATS on windows. + if os and os.category == os_category.WINDOWS: + kwargs["goma_enable_ats"] = False + # Define the builder first so that any validation of luci.builder arguments # (e.g. bucket) occurs before we try to use it builders.builder( diff --git a/media/capture/video/video_capture_device_unittest.cc b/media/capture/video/video_capture_device_unittest.cc index 8ce31e46f7b1db..f6752723d05bc5 100644 --- a/media/capture/video/video_capture_device_unittest.cc +++ b/media/capture/video/video_capture_device_unittest.cc @@ -109,13 +109,9 @@ #define MAYBE_UsingRealWebcam_AllocateBadSize \ DISABLED_UsingRealWebcam_AllocateBadSize #define MAYBE_UsingRealWebcam_CaptureMjpeg UsingRealWebcam_CaptureMjpeg -// Flaky: https://crbug.com/1096082 -#define MAYBE_UsingRealWebcam_TakePhoto DISABLED_UsingRealWebcam_TakePhoto -#define MAYBE_UsingRealWebcam_GetPhotoState \ - DISABLED_UsingRealWebcam_GetPhotoState -// Flaky crash: https://crbug.com/1069608 -#define MAYBE_UsingRealWebcam_CaptureWithSize \ - DISABLED_UsingRealWebcam_CaptureWithSize +#define MAYBE_UsingRealWebcam_TakePhoto UsingRealWebcam_TakePhoto +#define MAYBE_UsingRealWebcam_GetPhotoState UsingRealWebcam_GetPhotoState +#define MAYBE_UsingRealWebcam_CaptureWithSize UsingRealWebcam_CaptureWithSize #define MAYBE_UsingRealWebcam_CheckPhotoCallbackRelease \ UsingRealWebcam_CheckPhotoCallbackRelease #elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) @@ -477,9 +473,8 @@ class VideoCaptureDeviceTest std::unique_ptr video_capture_device_factory_; }; -// Causes a flaky crash on Chrome OS. https://crbug.com/1069608 // Cause hangs on Windows Debug. http://crbug.com/417824 -#if BUILDFLAG(IS_CHROMEOS_ASH) || (defined(OS_WIN) && !defined(NDEBUG)) +#if (defined(OS_WIN) && !defined(NDEBUG)) #define MAYBE_OpenInvalidDevice DISABLED_OpenInvalidDevice #else #define MAYBE_OpenInvalidDevice OpenInvalidDevice @@ -707,13 +702,7 @@ void VideoCaptureDeviceTest::RunCaptureMjpegTestCase() { device->StopAndDeAllocate(); } -// Flaky on ChromeOS. See https://crbug.com/1096082 -#if BUILDFLAG(IS_CHROMEOS_ASH) -#define MAYBE_NoCameraSupportsPixelFormatMax \ - DISABLED_NoCameraSupportsPixelFormatMax -#else #define MAYBE_NoCameraSupportsPixelFormatMax NoCameraSupportsPixelFormatMax -#endif WRAPPED_TEST_P(VideoCaptureDeviceTest, MAYBE_NoCameraSupportsPixelFormatMax) { RunTestCase(base::BindOnce( &VideoCaptureDeviceTest::RunNoCameraSupportsPixelFormatMaxTestCase, diff --git a/sql/README.md b/sql/README.md new file mode 100644 index 00000000000000..e17936fc3f43ce --- /dev/null +++ b/sql/README.md @@ -0,0 +1,277 @@ +# SQLite abstraction layer + + +## SQLite for system designers + +[SQLite](https://www.sqlite.org/) is a +[relational database management system (RDBMS)](https://en.wikipedia.org/wiki/Relational_database#RDBMS) +that [supports most of SQL](https://www.sqlite.org/lang.html). + +SQLite is architected as a library that can be embedded in another application, +such as Chrome. SQLite runs in the application's process, and shares its memory +and other resources. This is similar to embedded databases like +[LevelDB](https://github.com/google/leveldb) and +[BerkeleyDB](https://en.wikipedia.org/wiki/Berkeley_DB). By contrast, most +popular RDMBSes, like [PostgreSQL](https://www.postgresql.org/) and +[MySQL](https://www.mysql.com/), are structured as standalone server processes +that accept queries from client processes. + +TODO: Explain the process model and locking + +TODO: Explain Chrome decisions -- exclusive locking, full per-feature isolation +(separate databases and page caches) + + +## SQLite for database designers + +The section summarizes aspects of SQLite that are relevant to schema and +query design, and may be surprising to readers with prior experience in other +popular SQL database systems, such as +[PostgreSQL](https://www.postgresql.org/) and [MySQL](https://www.mysql.com/). + + +### Data types + +SQLite stores data using [5 major types](https://www.sqlite.org/datatype3.html), +which are summarized below. + +1. NULL is a special type for the `NULL` value. + +2. INTEGER represents big-endian twos-complement integers. Boolean values + (`TRUE` and `FALSE`) are represented as the integer values 1 and 0. + +3. REAL represents IEEE 754-2008 64-bit floating point numbers. + +4. TEXT represents strings (sequences of characters) encoded using a + [supported SQLite encoding](https://www.sqlite.org/c3ref/c_any.html). These + values are + [sorted](https://www.sqlite.org/datatype3.html#sort_order) according to + [a collating sequence](https://www.sqlite.org/datatype3.html#collation) or + [a collating function](https://www.sqlite.org/c3ref/create_collation.html). + +5. BLOB represents sequences of bytes that are opaque to SQLite. These values are + sorted using the bitwise binary comparison offered by + [memcmp](https://en.cppreference.com/w/cpp/string/byte/memcmp). + +SQLite stores index keys and row values (records / tuples) using +[a tightly packed format](https://sqlite.org/fileformat2.html#record_format) +that makes heavy use of [varints](https://sqlite.org/fileformat2.html#varint) +and variable-length fields. The column types have almost no influence on the +encoding of values. This has the following consequences. + +* All SQL integer types, such as `TINYINT` and `BIGINT`, are treated as aliases + for `INTEGER`. +* All SQL non-integer numeric types, such as `DECIMAL`, `FLOAT`, and + `DOUBLE PRECISION` are treated as aliases for `REAL`. +* Numeric precision and scale specifiers, such as `DECIMAL(5,2)` are ignored. +* All string types, such as `CHAR`, `CHARACTER VARYING`, `VARCHAR`, and `CLOB`, + are treated as aliases for `TEXT`. +* Maximum string length specifiers, such as `CHAR(255)` are ignored. + +SQLite uses clever heuristics, called +[type affinity](https://www.sqlite.org/datatype3.html#type_affinity), +to map SQL column types such as `VARCHAR` to the major types above. + +Chrome database schemas should avoid type affinity, and should not include any +information ignored by SQLite. + + +### Indexing + +SQLite [uses B-trees](https://www.sqlite.org/fileformat2.html#pages) to store +both table and index data. + +The exclusive use of B-trees reduces the amount of schema design decisions. +Notable examples: + +* There is no equivalent to + [PostgreSQL's index types](https://www.postgresql.org/docs/13/indexes-types.html). + In particular, since there are no hashed indexes, the design does not need to + consider whether the index only needs to support equality queries, as opposed + to greater/smaller than comparisons. + +* There is no equivalent to + [PostgreSQL's table access methods](https://www.postgresql.org/docs/13/tableam.html). + Each table is clustered by a primary key index, which is implicitly stored in + the table's B-tree. + +By default, table rows (records / tuples) are stored in a B-tree keyed by +[rowid](https://sqlite.org/lang_createtable.html#rowid), an automatically +assigned 64-bit integer key. Effectively, these tables are clustered by rowid, +which acts as an implicit primary key. Opting out of this SQLite-specific +default requires appending +[`WITHOUT ROWID`](https://sqlite.org/withoutrowid.html) to the `CREATE TABLE` +instruction. + +SQLite's [B-tree page format](https://sqlite.org/fileformat2.html#b_tree_pages) +has optimized special cases for tables clustered by rowid. This makes rowid the +most efficient [surrogate key](https://en.wikipedia.org/wiki/Surrogate_key) +implementation in SQLite. To make this optimization easier to use, any column +that is a primary key and has an `INTEGER` type is considered an alias for +rowid. + + +### Query processing + +[At a high level](https://www.sqlite.org/arch.html), SQLite compiles SQL queries +into bytecode executed by a virtual machine called the VDBE, or +[the bytecode engine](https://www.sqlite.org/opcode.html). A compiled query can +be executed multiple times, amortizing the costs of query parsing and planning. +Chrome's SQLite abstraction layer makes it easy to use compiled queries. + +The following SQLite documentation pages cover the query planner and +optimizer. + +1. [query planner overview](https://www.sqlite.org/queryplanner.html) +2. [query optimizer overview](https://www.sqlite.org/optoverview.html) +3. [`EXPLAIN QUERY PLAN` output description](https://www.sqlite.org/eqp.html) + +TODO: Present a simplified model that's sufficient for most database design. + + +## General advice + +The following pieces of advice usually come up in code reviews. + +### SQL style + +SQLite queries are usually embedded as string literals in C++ code. The +advice here has the following goals. + +1. Easy to read queries. The best defense against subtle bugs is making the + queries very easy to read, so that any bugs become obvious at code review + time. SQL string literals don't benefit from our code analysis + infrastructure, so the only lines of defense against bugs are testing and + code review. + +2. Simplify crash debugging. We will always have a low volume of non-actionable + crash reports, because Chrome runs on billions of devices, some of which have + faulty RAM or processors. + +3. No unnecessary performance overheads. The C++ optimizer doesn't understand + SQL query literals, so the queries end up as written in the Chrome binary. + Extra characters cost binary size, as well as CPU time (which turns into + battery usage) during query parsing. + +4. Match the embedding language (C++) style guide. This reduces the mental + context switch overhead for folks who write and/or review C++ code that + contains SQL. + +Format statements like so. + +```cc + static constexpr char kOriginInfoSql[] = + // clang-format off + "CREATE TABLE origin_infos(" + "origin TEXT NOT NULL," + "last_modified INTEGER NOT NULL," + "secure INTEGER NOT NULL)"; + // clang-format on + + static constexpr char kInsertSql[] = + // clang-format off + "INSERT INTO infos(origin,last_modified,secure) " + "VALUES (?,?,?)"; + // clang-format on +``` + +* SQLite keywords should use ALL CAPS. This makes SQL query literals easier to + distinguish and search for. + +* Identifiers, such as table and row names, should use snake_case. + +* Identifiers, keywords, and parameter placeholders (`?`) should be separated by + exactly one character. Separators may be spaces (` `), commas (`,`), or + parentheses (`(`, `)`). + +* Statement-ending semicolons (`;`) are omitted. + +* SQL statements are stored in variables typed `static constexpr char[]`, or in + string literals passed directly to methods. + +* [`INSERT` statements](https://sqlite.org/lang_insert.html) should list all the + table columns by name, in the same order as the corresponding `CREATE TABLE` + statements. + +* Values must either be embedded in the SQL statement string literal, or bound + using [parameters](https://www.sqlite.org/lang_expr.html#varparam). + +* Parameter placeholders should always use the `?` syntax. Alternative syntaxes, + such as `?NNN` or `:AAAA`, have few benefits in a codebase where the `Bind` + statements are right next to the queries, and are less known to readers. + +* Do not execute multiple SQL statements (e.g., by calling `Step()` or `Run()` + on `sql::Statement`) on the same C++ line. It's difficult to get more than + line numbers from crash reports' stack traces. + + +### Schema style + +Column types should only be one of the the SQLite storage types (`INTEGER`, +`REAL`, `TEXT`, `BLOB`), so readers can avoid reasoning about SQLite's type +affinity. + +Columns that will store boolean values should have the `INTEGER` type. + +Columns that will store `base::Time` values should have the `INTEGER` type. +Values should be serialized using `sql::Statement::BindTime()` and deserialized +using `sql::Statement::ColumnTime()`. + +Column types should not include information ignored by SQLite, such as numeric +precision or scale specifiers, or string length specifiers. + +Columns should have the `NOT NULL` constraint whenever possible. This saves +maintainers from having to reason about the less intuitive cases of +[`NULL` handling](https://sqlite.org/nulls.html). + +Columns should avoid `DEFAULT` values. This moves the burden of checking that +`INSERT` statements aren't missing any columns from the code reviewer to SQLite. + +Surrogate primary keys should use the column type `INTEGER PRIMARY KEY`, to take +advantage of SQLite's rowid optimizations. +[`AUTOINCREMENT`](https://www.sqlite.org/autoinc.html) should only be used where +primary key reuse would be unacceptable. + + +### Discouraged features + +[`PRAGMA` statements](https://www.sqlite.org/pragma.html) should never be used +directly. Chrome's SQLite abstraction layer should be modified to support the +desired effects instead. + +Direct `PRAGMA` use limits our ability to customize and secure our SQLite build. +`PRAGMA` statements may turn on code paths with less testing / fuzzing coverage. +Furthermore, some `PRAGMA` statements invalidate previously compiled queries, +reducing the efficiency of Chrome's compiled query cache. + +[SQL foreign key constraints](https://sqlite.org/foreignkeys.html) should not be +used. All data validation should be performed using explicit `SELECT` statements +(generally wrapped as helper methods) inside transactions. Cascading deletions +should be performed using explicit `DELETE` statements inside transactions. + +Chrome features cannot rely on foreign key enforcement, due to the +possibility of data corruption. Furthermore, foreign key constraints make it +more difficult to reason about system behavior (Chrome feature code + SQLite) +when the database gets corrupted. Foreign key constraints also make it more +difficult to reason about query performance. + +After +[WebSQL](https://www.w3.org/TR/webdatabase/) is removed from Chrome, we plan +to disable SQLite's foreign key support using +[SQLITE_OMIT_FOREIGN_KEY](https://sqlite.org/compile.html#omit_foreign_key). + +[SQL triggers](https://sqlite.org/lang_createtrigger.html) should not be used. + +Triggers significantly increase the difficulty of reviewing and maintaining +Chrome features that use them. + +After [WebSQL](https://www.w3.org/TR/webdatabase/) is removed from Chrome, we +plan to disable SQLite's trigger support using +[SQLITE_OMIT_TRIGGER](https://sqlite.org/compile.html#omit_trigger). + +[`ATTACH DATABASE` statements](https://www.sqlite.org/lang_attach.html) should +not be used. Each Chrome feature should store its data in a single database. +Chrome code should not assume that transactions across multiple databases are +atomic. + +We plan to remove all existing `ATTACH DATABASE` use from Chrome. diff --git a/third_party/blink/renderer/core/execution_context/execution_context.cc b/third_party/blink/renderer/core/execution_context/execution_context.cc index 2126f73c7ca176..e4263066c4741c 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context.cc +++ b/third_party/blink/renderer/core/execution_context/execution_context.cc @@ -219,8 +219,11 @@ bool ExecutionContext::CheckSharedArrayBufferTransferAllowedAndReport() { // in the future, and the problem is encountered for the first time in this // execution context. This preserves postMessage performance during the // transition period. - if (!allowed || (!has_filed_shared_array_buffer_transfer_issue_ && - !CrossOriginIsolatedCapability())) { + if (!allowed || + (!has_filed_shared_array_buffer_transfer_issue_ && + !CrossOriginIsolatedCapability() && + !SchemeRegistry::ShouldTreatURLSchemeAsAllowingSharedArrayBuffers( + GetSecurityOrigin()->Protocol()))) { has_filed_shared_array_buffer_transfer_issue_ = true; auto source_location = SourceLocation::Capture(this); auto issue = CreateSharedArrayBufferIssue(source_location.get()); diff --git a/third_party/blink/renderer/core/html/conversion_measurement_parsing.cc b/third_party/blink/renderer/core/html/conversion_measurement_parsing.cc index 525d881d9299d6..4ece70b2adc33b 100644 --- a/third_party/blink/renderer/core/html/conversion_measurement_parsing.cc +++ b/third_party/blink/renderer/core/html/conversion_measurement_parsing.cc @@ -46,7 +46,7 @@ base::Optional GetImpression( ReportAttributionIssue( frame, mojom::blink::AttributionReportingIssueType::kPermissionPolicyDisabled, - element, base::nullopt); + frame->GetDevToolsFrameToken(), element); // TODO(crbug.com/1178400): Remove console message once the issue reported // above is actually shown in DevTools. @@ -87,7 +87,8 @@ base::Optional GetImpression( ReportAttributionIssue( frame, mojom::blink::AttributionReportingIssueType::kInvalidAttributionData, - element, base::nullopt, impression_data_string); + frame->GetDevToolsFrameToken(), element, base::nullopt, + impression_data_string); } // Provide a default of 0 if the impression data was not valid. diff --git a/third_party/blink/renderer/core/inspector/inspector_attribution_issue.h b/third_party/blink/renderer/core/inspector/inspector_attribution_issue.h index 37d80bf7a991d6..32474b5c94f86b 100644 --- a/third_party/blink/renderer/core/inspector/inspector_attribution_issue.h +++ b/third_party/blink/renderer/core/inspector/inspector_attribution_issue.h @@ -13,10 +13,19 @@ namespace blink { class Element; class LocalFrame; +// Reports an Attribution Reporting API issue to DevTools. +// |reporting_frame| is the current execution context in which the issue +// happens and is reported in (the "target" in DevTools terms). +// |offending_frame_token| is the offending frame that triggered the issue. +// |offending_frame_token| does not necessarly correspond to |reporting_frame|, +// e.g. when an impression click in an iframe is blocked due to an +// insecure main frame. void ReportAttributionIssue( - LocalFrame* frame, + LocalFrame* reporting_frame, mojom::blink::AttributionReportingIssueType type, - Element* element, + const base::Optional& offending_frame_token = + base::nullopt, + Element* element = nullptr, const base::Optional& request_id = base::nullopt, const base::Optional& invalid_parameter = base::nullopt); diff --git a/third_party/blink/renderer/core/inspector/inspector_issue.cc b/third_party/blink/renderer/core/inspector/inspector_issue.cc index 886b570c21f63c..9e5a6666aff0b1 100644 --- a/third_party/blink/renderer/core/inspector/inspector_issue.cc +++ b/third_party/blink/renderer/core/inspector/inspector_issue.cc @@ -41,15 +41,19 @@ const mojom::blink::InspectorIssueDetailsPtr& InspectorIssue::Details() const { void InspectorIssue::Trace(blink::Visitor* visitor) const {} -void ReportAttributionIssue(LocalFrame* frame, - mojom::blink::AttributionReportingIssueType type, - Element* element, - const base::Optional& request_id, - const base::Optional& invalid_parameter) { +void ReportAttributionIssue( + LocalFrame* reporting_frame, + mojom::blink::AttributionReportingIssueType type, + const base::Optional& offending_frame_token, + Element* element, + const base::Optional& request_id, + const base::Optional& invalid_parameter) { auto attribution_issue = mojom::blink::AttributionReportingIssue::New(); attribution_issue->violation_type = type; - attribution_issue->frame = mojom::blink::AffectedFrame::New( - IdentifiersFactory::IdFromToken(frame->GetDevToolsFrameToken())); + if (offending_frame_token) { + attribution_issue->frame = mojom::blink::AffectedFrame::New( + IdentifiersFactory::IdFromToken(*offending_frame_token)); + } if (element) attribution_issue->violating_node_id = DOMNodeIds::IdForNode(element); if (request_id) { @@ -65,7 +69,7 @@ void ReportAttributionIssue(LocalFrame* frame, auto issue = mojom::blink::InspectorIssueInfo::New( mojom::blink::InspectorIssueCode::kAttributionReportingIssue, std::move(issue_details)); - frame->AddInspectorIssue(std::move(issue)); + reporting_frame->AddInspectorIssue(std::move(issue)); } } // namespace blink diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc index 109edc29adf8f3..0de5bfe2511a36 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc @@ -817,7 +817,7 @@ bool FrameFetchContext::SendConversionRequestInsteadOfRedirecting( ReportAttributionIssue( GetFrame(), mojom::blink::AttributionReportingIssueType::kPermissionPolicyDisabled, - nullptr, devtools_request_id); + GetFrame()->GetDevToolsFrameToken(), nullptr, devtools_request_id); // TODO(crbug.com/1178400): Remove console message once the issue reported // above is actually shown in DevTools. diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h index a2bb698ac131f0..c48e5409ef3cbc 100644 --- a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h +++ b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source.h @@ -19,9 +19,6 @@ class MediaStreamComponent; class MODULES_EXPORT MediaStreamAudioTrackUnderlyingSource : public AudioFrameQueueUnderlyingSource, public WebMediaStreamAudioSink { - USING_PRE_FINALIZER(MediaStreamAudioTrackUnderlyingSource, - DisconnectFromTrack); - public: explicit MediaStreamAudioTrackUnderlyingSource( ScriptState*, diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source_test.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source_test.cc index 3a8b1be086207b..c2eb5465ef78a5 100644 --- a/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source_test.cc +++ b/third_party/blink/renderer/modules/breakout_box/media_stream_audio_track_underlying_source_test.cc @@ -253,25 +253,4 @@ TEST_F(MediaStreamAudioTrackUnderlyingSourceTest, QueueSizeCannotBeZero) { track->stopTrack(v8_scope.GetExecutionContext()); } -TEST_F(MediaStreamAudioTrackUnderlyingSourceTest, PlatformSourceAliveAfterGC) { - // This persistent is used to make |track->Component()| (and its - // MediaStreamAudioTrack) outlive |v8_scope| and stay alive after GC. - Persistent component; - { - V8TestingScope v8_scope; - auto* track = CreateTrack(v8_scope.GetExecutionContext()); - component = track->Component(); - auto* source = CreateSource(v8_scope.GetScriptState(), track); - ReadableStream::CreateWithCountQueueingStrategy(v8_scope.GetScriptState(), - source, 0); - // |source| is a sink of |track|. - EXPECT_TRUE(source->Track()); - } - blink::WebHeap::CollectAllGarbageForTesting(); - // At this point, if |source| were still a sink of the MediaStreamAudioTrack - // owned by |component|, the MediaStreamAudioTrack cleanup would crash since - // it would try to access |source|, which has been garbage collected. - // A scenario like this one could occur when an execution context is detached. -} - } // namespace blink diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source_test.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source_test.cc index 12688142a3f739..e8c9cbf9a68cdd 100644 --- a/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source_test.cc +++ b/third_party/blink/renderer/modules/breakout_box/media_stream_video_track_underlying_source_test.cc @@ -240,19 +240,4 @@ TEST_F(MediaStreamVideoTrackUnderlyingSourceTest, QueueSizeCannotBeZero) { track->stopTrack(v8_scope.GetExecutionContext()); } -TEST_F(MediaStreamVideoTrackUnderlyingSourceTest, PlatformSourceAliveAfterGC) { - Persistent component; - { - V8TestingScope v8_scope; - auto* track = CreateTrack(v8_scope.GetExecutionContext()); - component = track->Component(); - auto* source = CreateSource(v8_scope.GetScriptState(), track, 0u); - ReadableStream::CreateWithCountQueueingStrategy(v8_scope.GetScriptState(), - source, 0); - // |source| is a sink of |track|. - EXPECT_TRUE(source->Track()); - } - blink::WebHeap::CollectAllGarbageForTesting(); -} - } // namespace blink diff --git a/ui/ozone/platform/wayland/common/wayland_object.cc b/ui/ozone/platform/wayland/common/wayland_object.cc index 8827a5e9f493ae..467e604678c64d 100644 --- a/ui/ozone/platform/wayland/common/wayland_object.cc +++ b/ui/ozone/platform/wayland/common/wayland_object.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -158,6 +159,10 @@ void (*ObjectTraits::deleter)(wl_data_source*) = const wl_interface* ObjectTraits::interface = &wl_drm_interface; void (*ObjectTraits::deleter)(wl_drm*) = &wl_drm_destroy; +const wl_interface* ObjectTraits::interface = nullptr; +void (*ObjectTraits::deleter)(wl_event_queue*) = + &wl_event_queue_destroy; + const wl_interface* ObjectTraits::interface = &wl_display_interface; void (*ObjectTraits::deleter)(wl_display*) = &wl_display_disconnect; @@ -214,6 +219,9 @@ const wl_interface* ObjectTraits::interface = void (*ObjectTraits::deleter)( struct wp_presentation_feedback*) = &wp_presentation_feedback_destroy; +const wl_interface* ObjectTraits::interface = nullptr; +void (*ObjectTraits::deleter)(void*) = &wl_proxy_wrapper_destroy; + const wl_interface* ObjectTraits::interface = &wp_viewport_interface; void (*ObjectTraits::deleter)(wp_viewport*) = &wp_viewport_destroy; diff --git a/ui/ozone/platform/wayland/common/wayland_object.h b/ui/ozone/platform/wayland/common/wayland_object.h index d609c6150fa22a..170d806209485a 100644 --- a/ui/ozone/platform/wayland/common/wayland_object.h +++ b/ui/ozone/platform/wayland/common/wayland_object.h @@ -26,6 +26,7 @@ struct wl_data_device; struct wl_data_offer; struct wl_data_source; struct wl_drm; +struct wl_event_queue; struct wl_keyboard; struct wl_output; struct wl_pointer; @@ -40,6 +41,7 @@ struct wl_surface; struct wl_touch; struct wp_presentation; struct wp_presentation_feedback; +struct wl_proxy; struct wp_viewport; struct wp_viewporter; struct xdg_wm_base; @@ -189,6 +191,12 @@ struct ObjectTraits { static void (*deleter)(wl_drm*); }; +template <> +struct ObjectTraits { + static const wl_interface* interface; + static void (*deleter)(wl_event_queue*); +}; + template <> struct ObjectTraits { static const wl_interface* interface; @@ -279,6 +287,13 @@ struct ObjectTraits { static void (*deleter)(wp_presentation_feedback*); }; +template <> +struct ObjectTraits { + // Interface is null for proxy. + static const wl_interface* interface; + static void (*deleter)(void*); +}; + template <> struct ObjectTraits { static const wl_interface* interface; @@ -468,6 +483,7 @@ class Object : public std::unique_ptr { template wl::Object Bind(wl_registry* registry, uint32_t name, uint32_t version) { + DCHECK(ObjectTraits::interface); return wl::Object(wl::bind_registry( registry, name, ObjectTraits::interface, version)); } diff --git a/ui/ozone/platform/wayland/emulate/wayland_input_emulate.cc b/ui/ozone/platform/wayland/emulate/wayland_input_emulate.cc index ecf15403ed892b..d365526be0a223 100644 --- a/ui/ozone/platform/wayland/emulate/wayland_input_emulate.cc +++ b/ui/ozone/platform/wayland/emulate/wayland_input_emulate.cc @@ -42,7 +42,7 @@ WaylandInputEmulate::WaylandInputEmulate() { wayland_proxy->SetDelegate(this); - registry_ = wl_display_get_registry(wayland_proxy->GetDisplay()); + registry_ = wl_display_get_registry(wayland_proxy->GetDisplayWrapper()); if (!registry_) LOG(FATAL) << "Failed to get Wayland registry"; @@ -52,7 +52,7 @@ WaylandInputEmulate::WaylandInputEmulate() { wl_registry_add_listener(registry_, ®istry_listener, this); // Roundtrip one time to get the weston-test global. - wl_display_roundtrip(wayland_proxy->GetDisplay()); + wayland_proxy->RoundTripQueue(); if (!weston_test_) LOG(FATAL) << "weston-test is not available."; diff --git a/ui/ozone/platform/wayland/host/proxy/wayland_proxy.h b/ui/ozone/platform/wayland/host/proxy/wayland_proxy.h index fae92085432118..ff70da46bc1c19 100644 --- a/ui/ozone/platform/wayland/host/proxy/wayland_proxy.h +++ b/ui/ozone/platform/wayland/host/proxy/wayland_proxy.h @@ -52,8 +52,12 @@ class COMPONENT_EXPORT(WAYLAND_PROXY) WaylandProxy { // for the Delegate class. virtual void SetDelegate(Delegate* delegate) = 0; - // Returns the wl_display the WaylandConnection has the connection with. + // Returns the wl_display the WaylandConnection has the connection with. See + // WaylandConnection::display() and WaylandConnection::display_wrapper() to + // know the difference between the GetDisplay() and GetDisplayWrapper(). virtual wl_display* GetDisplay() = 0; + virtual wl_display* GetDisplayWrapper() = 0; + virtual void RoundTripQueue() = 0; // Returns wl_surface that backs the |widget|. virtual wl_surface* GetWlSurfaceForAcceleratedWidget( diff --git a/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.cc b/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.cc index 93aedb6ef8ba4d..ae80285ea5ec67 100644 --- a/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.cc +++ b/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.cc @@ -34,6 +34,14 @@ wl_display* WaylandProxyImpl::GetDisplay() { return connection_->display(); } +wl_display* WaylandProxyImpl::GetDisplayWrapper() { + return connection_->display_wrapper(); +} + +void WaylandProxyImpl::RoundTripQueue() { + connection_->RoundTripQueue(); +} + wl_surface* WaylandProxyImpl::GetWlSurfaceForAcceleratedWidget( gfx::AcceleratedWidget widget) { auto* window = connection_->wayland_window_manager()->GetWindow(widget); diff --git a/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.h b/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.h index 9805441d0b68dd..cf5ee8b568dbbd 100644 --- a/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.h +++ b/ui/ozone/platform/wayland/host/proxy/wayland_proxy_impl.h @@ -25,6 +25,8 @@ class WaylandProxyImpl : public WaylandProxy, public ui::WaylandWindowObserver { // WaylandProxy overrides: void SetDelegate(WaylandProxy::Delegate* delegate) override; wl_display* GetDisplay() override; + wl_display* GetDisplayWrapper() override; + void RoundTripQueue() override; wl_surface* GetWlSurfaceForAcceleratedWidget( gfx::AcceleratedWidget widget) override; wl_buffer* CreateShmBasedWlBuffer(const gfx::Size& buffer_size) override; diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc index 06ed07ede5b524..66bc2b5fe17604 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.cc +++ b/ui/ozone/platform/wayland/host/wayland_connection.cc @@ -128,7 +128,14 @@ bool WaylandConnection::Initialize() { return false; } - registry_.reset(wl_display_get_registry(display_.get())); + wrapped_display_.reset( + reinterpret_cast(wl_proxy_create_wrapper(display()))); + // Create a non-default event queue so that we wouldn't flush messages for + // client applications. + event_queue_.reset(wl_display_create_queue(display())); + wl_proxy_set_queue(wrapped_display_.get(), event_queue_.get()); + + registry_.reset(wl_display_get_registry(display_wrapper())); if (!registry_) { LOG(ERROR) << "Failed to get Wayland registry"; return false; @@ -137,13 +144,13 @@ bool WaylandConnection::Initialize() { // Now that the connection with the display server has been properly // estabilished, initialize the event source and input objects. DCHECK(!event_source_); - event_source_ = - std::make_unique(display(), wayland_window_manager()); + event_source_ = std::make_unique( + display(), event_queue_.get(), wayland_window_manager()); wl_registry_add_listener(registry_.get(), ®istry_listener, this); while (!wayland_output_manager_ || !wayland_output_manager_->IsOutputReady()) { - wl_display_roundtrip(display_.get()); + RoundTripQueue(); } buffer_manager_host_ = std::make_unique(this); @@ -168,7 +175,6 @@ bool WaylandConnection::Initialize() { if (UseTestConfigForPlatformWindows()) wayland_proxy_ = std::make_unique(this); - return true; } @@ -186,6 +192,11 @@ void WaylandConnection::ScheduleFlush() { } } +void WaylandConnection::RoundTripQueue() { + DCHECK(event_queue_.get()); + wl_display_roundtrip_queue(display(), event_queue_.get()); +} + void WaylandConnection::SetShutdownCb(base::OnceCallback shutdown_cb) { event_source()->SetShutdownCb(std::move(shutdown_cb)); } diff --git a/ui/ozone/platform/wayland/host/wayland_connection.h b/ui/ozone/platform/wayland/host/wayland_connection.h index 104b33c3774393..3a1f8022ff983c 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection.h +++ b/ui/ozone/platform/wayland/host/wayland_connection.h @@ -17,6 +17,7 @@ #include "ui/ozone/platform/wayland/host/wayland_window_manager.h" struct wl_cursor; +struct wl_event_queue; namespace gfx { class Point; @@ -67,11 +68,25 @@ class WaylandConnection { // Schedules a flush of the Wayland connection. void ScheduleFlush(); + // Calls wl_display_roundtrip_queue. Might be required during initialization + // of some objects that should block until they are initialized. + void RoundTripQueue(); + // Sets a callback that that shutdowns the browser in case of unrecoverable // error. Called by WaylandEventWatcher. void SetShutdownCb(base::OnceCallback shutdown_cb); + // A correct display must be chosen when creating objects or calling + // roundrips. That is, all the methods that deal with polling, pulling event + // queues, etc, must use original display. All the other methods that create + // various wayland objects must use |display_wrapper_| so that the new objects + // are associated with the correct event queue. Otherwise, they will use a + // default event queue, which we do not use. See the comment below about the + // |event_queue_|. wl_display* display() const { return display_.get(); } + wl_display* display_wrapper() const { + return reinterpret_cast(wrapped_display_.get()); + } wl_compositor* compositor() const { return compositor_.get(); } // The server version of the compositor interface (might be higher than the // version binded). @@ -218,6 +233,8 @@ class WaylandConnection { uint32_t compositor_version_ = 0; wl::Object display_; + wl::Object wrapped_display_; + wl::Object event_queue_; wl::Object registry_; wl::Object compositor_; wl::Object subcompositor_; diff --git a/ui/ozone/platform/wayland/host/wayland_connection_unittest.cc b/ui/ozone/platform/wayland/host/wayland_connection_unittest.cc index 4d6cabb6a2e3b7..d071f28cf72074 100644 --- a/ui/ozone/platform/wayland/host/wayland_connection_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_connection_unittest.cc @@ -27,6 +27,7 @@ TEST(WaylandConnectionTest, Ping) { ASSERT_TRUE(server.Start(kXdgVersionStable)); WaylandConnection connection; ASSERT_TRUE(connection.Initialize()); + connection.event_source()->UseSingleThreadedPollingForTesting(); connection.event_source()->StartProcessingEvents(); base::RunLoop().RunUntilIdle(); diff --git a/ui/ozone/platform/wayland/host/wayland_data_device_base.cc b/ui/ozone/platform/wayland/host/wayland_data_device_base.cc index 50be3ad35bc588..d68ed87b40d4ea 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_device_base.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_device_base.cc @@ -65,7 +65,8 @@ void WaylandDataDeviceBase::ReadClipboardDataFromFD( void WaylandDataDeviceBase::RegisterDeferredReadCallback() { DCHECK(!deferred_read_callback_); - deferred_read_callback_.reset(wl_display_sync(connection_->display())); + deferred_read_callback_.reset( + wl_display_sync(connection_->display_wrapper())); static const wl_callback_listener kListener = { WaylandDataDeviceBase::DeferredReadCallback}; diff --git a/ui/ozone/platform/wayland/host/wayland_drm.cc b/ui/ozone/platform/wayland/host/wayland_drm.cc index e387e48c6862ce..df692b6734a266 100644 --- a/ui/ozone/platform/wayland/host/wayland_drm.cc +++ b/ui/ozone/platform/wayland/host/wayland_drm.cc @@ -29,7 +29,7 @@ WaylandDrm::WaylandDrm(wl_drm* drm, WaylandConnection* connection) // A roundtrip after binding guarantees that the client has received all // supported formats and capabilities of the device. - wl_display_roundtrip(connection_->display()); + connection_->RoundTripQueue(); } WaylandDrm::~WaylandDrm() = default; @@ -106,7 +106,7 @@ void WaylandDrm::Authenticate(const char* drm_device_path) { // Do the roundtrip to make sure the server processes this request and // authenticates us. - wl_display_roundtrip(connection_->display()); + connection_->RoundTripQueue(); } void WaylandDrm::DrmDeviceAuthenticated(struct wl_drm* wl_drm) { diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.cc b/ui/ozone/platform/wayland/host/wayland_event_source.cc index 46327d9631e77d..5d9a6580cac8e8 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_source.cc +++ b/ui/ozone/platform/wayland/host/wayland_event_source.cc @@ -66,9 +66,11 @@ WaylandEventSource::TouchPoint::TouchPoint(gfx::PointF location, // WaylandEventSource implementation WaylandEventSource::WaylandEventSource(wl_display* display, + wl_event_queue* event_queue, WaylandWindowManager* window_manager) : window_manager_(window_manager), - event_watcher_(std::make_unique(display)) { + event_watcher_( + std::make_unique(display, event_queue)) { DCHECK(window_manager_); // Observes remove changes to know when touch points can be removed. @@ -81,12 +83,12 @@ void WaylandEventSource::SetShutdownCb(base::OnceCallback shutdown_cb) { event_watcher_->SetShutdownCb(std::move(shutdown_cb)); } -bool WaylandEventSource::StartProcessingEvents() { - return event_watcher_->StartProcessingEvents(); +void WaylandEventSource::StartProcessingEvents() { + event_watcher_->StartProcessingEvents(); } -bool WaylandEventSource::StopProcessingEvents() { - return event_watcher_->StopProcessingEvents(); +void WaylandEventSource::StopProcessingEvents() { + event_watcher_->StopProcessingEvents(); } void WaylandEventSource::OnKeyboardFocusChanged(WaylandWindow* window, @@ -318,6 +320,10 @@ void WaylandEventSource::ResetPointerFlags() { pointer_flags_ = 0; } +void WaylandEventSource::UseSingleThreadedPollingForTesting() { + event_watcher_->UseSingleThreadedPollingForTesting(); +} + void WaylandEventSource::OnDispatcherListChanged() { StartProcessingEvents(); } diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.h b/ui/ozone/platform/wayland/host/wayland_event_source.h index 9617a85b41e9b3..3efb7e5f19f9e7 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_source.h +++ b/ui/ozone/platform/wayland/host/wayland_event_source.h @@ -49,7 +49,9 @@ class WaylandEventSource : public PlatformEventSource, public WaylandPointer::Delegate, public WaylandTouch::Delegate { public: - WaylandEventSource(wl_display* display, WaylandWindowManager* window_manager); + WaylandEventSource(wl_display* display, + wl_event_queue* event_queue, + WaylandWindowManager* window_manager); WaylandEventSource(const WaylandEventSource&) = delete; WaylandEventSource& operator=(const WaylandEventSource&) = delete; ~WaylandEventSource() override; @@ -67,9 +69,9 @@ class WaylandEventSource : public PlatformEventSource, // Starts polling for events from the wayland connection file descriptor. // This method assumes connection is already estabilished and input objects // are already bound and properly initialized. - bool StartProcessingEvents(); + void StartProcessingEvents(); // Stops polling for events from input devices. - bool StopProcessingEvents(); + void StopProcessingEvents(); // Tells if pointer |button| is currently pressed. bool IsPointerButtonPressed(EventFlags button) const; @@ -79,6 +81,9 @@ class WaylandEventSource : public PlatformEventSource, // button released event is not delivered (e.g: window moving, drag and drop). void ResetPointerFlags(); + // See the comment near WaylandEventWatcher::use_dedicated_polling_thread_. + void UseSingleThreadedPollingForTesting(); + protected: // WaylandKeyboard::Delegate void OnKeyboardFocusChanged(WaylandWindow* window, bool focused) override; diff --git a/ui/ozone/platform/wayland/host/wayland_event_watcher.cc b/ui/ozone/platform/wayland/host/wayland_event_watcher.cc index c97a0e31bd306d..9a0769d5dc0fc9 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_watcher.cc +++ b/ui/ozone/platform/wayland/host/wayland_event_watcher.cc @@ -5,54 +5,118 @@ #include "ui/ozone/platform/wayland/host/wayland_event_watcher.h" #include +#include #include "base/bind.h" +#include "base/callback_forward.h" #include "base/check.h" #include "base/logging.h" +#include "base/macros.h" #include "base/task/current_thread.h" +#include "base/threading/thread.h" +#include "base/threading/thread_task_runner_handle.h" #include "ui/events/event.h" #include "ui/ozone/platform/wayland/common/wayland.h" namespace ui { -WaylandEventWatcher::WaylandEventWatcher(wl_display* display) - : controller_(FROM_HERE), display_(display) { - DCHECK(display_); +namespace { + +void DispatchPending(wl_display* display, wl_event_queue* event_queue) { + wl_display_dispatch_queue_pending(display, event_queue); } -WaylandEventWatcher::~WaylandEventWatcher() { - StopProcessingEvents(); +} // namespace + +// A dedicated thread for watching wl_display's file descriptor. The reason why +// watching happens on a separate thread is that the thread mustn't be blocked. +// Otherwise, if Chromium is used with Wayland EGL, a deadlock may happen. The +// deadlock happened when the thread that had been watching the file descriptor +// (it used to be the browser's UI thread) called wl_display_prepare_read, and +// then started to wait until the thread, which was used by the gpu service, +// completed a buffer swap and shutdowned itself (for example, a menu window is +// in the process of closing). However, that gpu thread hanged as it called +// Wayland EGL that also called wl_display_prepare_read internally and started +// to wait until the previous caller of the wl_display_prepare_read (that's by +// the design of the wayland-client library). This situation causes a deadlock +// as the first caller of the wl_display_prepare_read is unable to complete +// reading as it waits for another thread to complete, and that another thread +// is also unable to complete reading as it waits until the first caller reads +// the display's file descriptor. For more details, see the implementation of +// the wl_display_prepare_read in third_party/wayland/src/src/wayland-client.c. +class WaylandEventWatcherThread : public base::Thread { + public: + explicit WaylandEventWatcherThread( + base::OnceClosure start_processing_events_cb) + : base::Thread("wayland-fd"), + start_processing_events_cb_(std::move(start_processing_events_cb)) {} + ~WaylandEventWatcherThread() override { Stop(); } + + void Init() override { + DCHECK(!start_processing_events_cb_.is_null()); + std::move(start_processing_events_cb_).Run(); + } + + private: + base::OnceClosure start_processing_events_cb_; +}; + +WaylandEventWatcher::WaylandEventWatcher(wl_display* display, + wl_event_queue* event_queue) + : controller_(FROM_HERE), display_(display), event_queue_(event_queue) { + DCHECK(display_); } +WaylandEventWatcher::~WaylandEventWatcher() = default; + void WaylandEventWatcher::SetShutdownCb( base::OnceCallback shutdown_cb) { DCHECK(shutdown_cb_.is_null()); shutdown_cb_ = std::move(shutdown_cb); } -bool WaylandEventWatcher::StartProcessingEvents() { - DCHECK(display_); - if (watching_) - return true; +void WaylandEventWatcher::StartProcessingEvents() { + ui_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get(); + if (use_dedicated_polling_thread_ && !thread_) { + // FD watching will happen on a different thread. + DETACH_FROM_THREAD(thread_checker_); - DCHECK(display_); - MaybePrepareReadQueue(); - wl_display_flush(display_); - return StartWatchingFd(base::MessagePumpForUI::WATCH_READ); + thread_ = std::make_unique( + base::BindOnce(&WaylandEventWatcher::StartProcessingEventsInternal, + weak_factory_.GetWeakPtr())); + base::Thread::Options thread_options; + thread_options.message_pump_type = base::MessagePumpType::UI; + thread_options.priority = base::ThreadPriority::DISPLAY; + if (!thread_->StartWithOptions(thread_options)) + LOG(FATAL) << "Failed to create input thread"; + + } else if (!use_dedicated_polling_thread_) { + StartProcessingEventsInternal(); + } } -bool WaylandEventWatcher::StopProcessingEvents() { +void WaylandEventWatcher::StopProcessingEvents() { if (!watching_) - return false; + return; - DCHECK(base::CurrentUIThread::IsSet()); - watching_ = false; - return controller_.StopWatchingFileDescriptor(); + if (use_dedicated_polling_thread_) { + watching_thread_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&WaylandEventWatcher::StopProcessingEventsInternal, + weak_factory_.GetWeakPtr())); + } else { + StopProcessingEventsInternal(); + } +} + +void WaylandEventWatcher::UseSingleThreadedPollingForTesting() { + use_dedicated_polling_thread_ = false; } void WaylandEventWatcher::OnFileCanReadWithoutBlocking(int fd) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!CheckForErrors()) { - StopProcessingEvents(); + StopProcessingEventsInternal(); return; } @@ -62,7 +126,7 @@ void WaylandEventWatcher::OnFileCanReadWithoutBlocking(int fd) { // CheckForErrors. if (wl_display_read_events(display_) == -1) return; - wl_display_dispatch_pending(display_); + DispatchPendingQueue(); } MaybePrepareReadQueue(); @@ -82,6 +146,7 @@ void WaylandEventWatcher::OnFileCanReadWithoutBlocking(int fd) { } void WaylandEventWatcher::OnFileCanWriteWithoutBlocking(int fd) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); int ret = wl_display_flush(display_); if (ret != -1 || errno != EAGAIN) StartWatchingFd(base::MessagePumpForUI::WATCH_READ); @@ -91,8 +156,33 @@ void WaylandEventWatcher::OnFileCanWriteWithoutBlocking(int fd) { // Otherwise just continue watching in the same mode. } -bool WaylandEventWatcher::StartWatchingFd( +void WaylandEventWatcher::StartProcessingEventsInternal() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(display_); + if (watching_) + return; + + watching_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get(); + + DCHECK(display_); + MaybePrepareReadQueue(); + wl_display_flush(display_); + StartWatchingFd(base::MessagePumpForUI::WATCH_READ); +} + +void WaylandEventWatcher::StopProcessingEventsInternal() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + if (!watching_) + return; + + DCHECK(base::CurrentUIThread::IsSet()); + watching_ = !controller_.StopWatchingFileDescriptor(); + DCHECK(!watching_); +} + +void WaylandEventWatcher::StartWatchingFd( base::WatchableIOMessagePumpPosix::Mode mode) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (watching_) { // Stop watching first. watching_ = !controller_.StopWatchingFileDescriptor(); @@ -103,22 +193,36 @@ bool WaylandEventWatcher::StartWatchingFd( int display_fd = wl_display_get_fd(display_); watching_ = base::CurrentUIThread::Get()->WatchFileDescriptor( display_fd, true, mode, &controller_, this); - return watching_; + CHECK(watching_) << "Unable to start watching the wl_display's file " + "descriptor."; } void WaylandEventWatcher::MaybePrepareReadQueue() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (prepared_) return; - if (wl_display_prepare_read(display_) != -1) { + if (wl_display_prepare_read_queue(display_, event_queue_) != -1) { prepared_ = true; return; } // Nothing to read, send events to the queue. - wl_display_dispatch_pending(display_); + DispatchPendingQueue(); +} + +void WaylandEventWatcher::DispatchPendingQueue() { + if (ui_thread_task_runner_->BelongsToCurrentThread()) { + DCHECK(!use_dedicated_polling_thread_); + DispatchPending(display_, event_queue_); + } else { + DCHECK(use_dedicated_polling_thread_); + auto cb = base::BindOnce(&DispatchPending, display_, event_queue_); + ui_thread_task_runner_->PostTask(FROM_HERE, std::move(cb)); + } } bool WaylandEventWatcher::CheckForErrors() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Errors are fatal. If this function returns non-zero the display can no // longer be used. int err = wl_display_get_error(display_); diff --git a/ui/ozone/platform/wayland/host/wayland_event_watcher.h b/ui/ozone/platform/wayland/host/wayland_event_watcher.h index 6a13ea92f4bc2d..ee4749e3a1394b 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_watcher.h +++ b/ui/ozone/platform/wayland/host/wayland_event_watcher.h @@ -6,10 +6,18 @@ #define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_EVENT_WATCHER_H_ #include "base/callback.h" +#include "base/memory/weak_ptr.h" #include "base/message_loop/message_pump_for_ui.h" #include "base/message_loop/watchable_io_message_pump_posix.h" +#include "base/threading/thread_checker.h" struct wl_display; +struct wl_event_queue; + +namespace base { +class Thread; +class SingleThreadTaskRunner; +} // namespace base namespace ui { @@ -19,7 +27,7 @@ namespace ui { // into WaylandEventSource, so feeding the platform events pipeline. class WaylandEventWatcher : public base::MessagePumpForUI::FdWatcher { public: - explicit WaylandEventWatcher(wl_display* display); + WaylandEventWatcher(wl_display* display, wl_event_queue* event_queue); WaylandEventWatcher(const WaylandEventWatcher&) = delete; WaylandEventWatcher& operator=(const WaylandEventWatcher&) = delete; ~WaylandEventWatcher() override; @@ -31,18 +39,24 @@ class WaylandEventWatcher : public base::MessagePumpForUI::FdWatcher { // Starts polling for events from the wayland connection file descriptor. // This method assumes connection is already estabilished and input objects // are already bound and properly initialized. - bool StartProcessingEvents(); + void StartProcessingEvents(); // Stops polling for events from input devices. - bool StopProcessingEvents(); + void StopProcessingEvents(); + + // See the comment near WaylandEventWatcher::use_dedicated_polling_thread_. + void UseSingleThreadedPollingForTesting(); private: // base::MessagePumpForUI::FdWatcher void OnFileCanReadWithoutBlocking(int fd) override; void OnFileCanWriteWithoutBlocking(int fd) override; - bool StartWatchingFd(base::WatchableIOMessagePumpPosix::Mode mode); + void StartProcessingEventsInternal(); + void StopProcessingEventsInternal(); + void StartWatchingFd(base::WatchableIOMessagePumpPosix::Mode mode); void MaybePrepareReadQueue(); + void DispatchPendingQueue(); // Checks if |display_| has any error set. If so, |shutdown_cb_| is executed // and false is returned. @@ -51,11 +65,39 @@ class WaylandEventWatcher : public base::MessagePumpForUI::FdWatcher { base::MessagePumpForUI::FdWatchController controller_; wl_display* const display_; // Owned by WaylandConnection. + wl_event_queue* const event_queue_; // Owned by WaylandConnection. bool watching_ = false; bool prepared_ = false; + // A separate thread is not used in some tests (ozone_unittests), as it + // requires additional synchronization from the WaylandTest side. Otherwise, + // some tests complete without waiting until events come. That is, the tests + // suppose that our calls/requests are completed after calling Sync(), which + // resumes our fake Wayland server and sends out events, but as long as there + // is one additional "polling" thread involved, some additional + // synchronization mechanisms are needed. At this point, it's easier to + // continue to watch the file descriptor on the same thread where the + // ozone_unittests run. + bool use_dedicated_polling_thread_ = true; + base::OnceCallback shutdown_cb_; + + // Used to verify watching the fd happens on a valid thread. + THREAD_CHECKER(thread_checker_); + + // See the |use_dedicated_polling_thread_| and also the comment in the source + // file for this header. + // TODO(crbug.com/1117463): consider polling on I/O instead. + std::unique_ptr thread_; + + // The original ui task runner where |this| has been created. + scoped_refptr ui_thread_task_runner_; + + // The thread's task runner where the wl_display's fd is being watched. + scoped_refptr watching_thread_task_runner_; + + base::WeakPtrFactory weak_factory_{this}; }; } // namespace ui diff --git a/ui/ozone/platform/wayland/host/wayland_keyboard.cc b/ui/ozone/platform/wayland/host/wayland_keyboard.cc index 85fcd6a423b5af..94fdc79a25a3e2 100644 --- a/ui/ozone/platform/wayland/host/wayland_keyboard.cc +++ b/ui/ozone/platform/wayland/host/wayland_keyboard.cc @@ -207,7 +207,7 @@ void WaylandKeyboard::FlushInput(base::OnceClosure closure) { // wl_display_sync gives a chance for any key "up" events to arrive. // With a well behaved wayland compositor this should ensure we never // get spurious repeats. - sync_callback_.reset(wl_display_sync(connection_->display())); + sync_callback_.reset(wl_display_sync(connection_->display_wrapper())); wl_callback_add_listener(sync_callback_.get(), &callback_listener_, this); connection_->ScheduleFlush(); } diff --git a/ui/ozone/platform/wayland/host/wayland_zaura_shell_unittest.cc b/ui/ozone/platform/wayland/host/wayland_zaura_shell_unittest.cc index a8bba1eb24dd1c..6c45841d01fee7 100644 --- a/ui/ozone/platform/wayland/host/wayland_zaura_shell_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_zaura_shell_unittest.cc @@ -33,6 +33,7 @@ TEST(WaylandZauraShellTest, Foo) { WaylandConnection connection; ASSERT_TRUE(connection.Initialize()); + connection.event_source()->UseSingleThreadedPollingForTesting(); connection.event_source()->StartProcessingEvents(); base::RunLoop().RunUntilIdle(); diff --git a/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc b/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc index d82674b31371ea..812cc9f328a767 100644 --- a/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc +++ b/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc @@ -25,7 +25,7 @@ WaylandZwpLinuxDmabuf::WaylandZwpLinuxDmabuf( // A roundtrip after binding guarantees that the client has received all // supported formats. - wl_display_roundtrip(connection_->display()); + connection_->RoundTripQueue(); } WaylandZwpLinuxDmabuf::~WaylandZwpLinuxDmabuf() = default; diff --git a/ui/ozone/platform/wayland/test/wayland_test.cc b/ui/ozone/platform/wayland/test/wayland_test.cc index 5bc45ac1aeaa4d..bc378f0dc65062 100644 --- a/ui/ozone/platform/wayland/test/wayland_test.cc +++ b/ui/ozone/platform/wayland/test/wayland_test.cc @@ -12,6 +12,7 @@ #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" #include "ui/events/ozone/layout/scoped_keyboard_layout_engine.h" #include "ui/ozone/common/features.h" +#include "ui/ozone/platform/wayland/host/wayland_event_source.h" #include "ui/ozone/platform/wayland/host/wayland_output_manager.h" #include "ui/ozone/platform/wayland/host/wayland_screen.h" #include "ui/ozone/platform/wayland/test/mock_surface.h" @@ -68,6 +69,7 @@ void WaylandTest::SetUp() { ASSERT_TRUE(server_.Start(GetParam())); ASSERT_TRUE(connection_->Initialize()); + connection_->event_source()->UseSingleThreadedPollingForTesting(); screen_ = connection_->wayland_output_manager()->CreateWaylandScreen(); EXPECT_CALL(delegate_, OnAcceleratedWidgetAvailable(_)) .WillOnce(SaveArg<0>(&widget_)); diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc index d383ce7660a410..001471fedfc670 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc @@ -463,10 +463,7 @@ std::string DesktopWindowTreeHostPlatform::GetWorkspace() const { } gfx::Rect DesktopWindowTreeHostPlatform::GetWorkAreaBoundsInScreen() const { - // TODO(sky): GetDisplayNearestWindow() should take a const aura::Window*. - return display::Screen::GetScreen() - ->GetDisplayNearestWindow(const_cast(window())) - .work_area(); + return GetDisplayNearestRootWindow().work_area(); } void DesktopWindowTreeHostPlatform::SetShape( @@ -693,10 +690,8 @@ gfx::Transform DesktopWindowTreeHostPlatform::GetRootTransform() const { // This might be called before the |platform_window| is created. Thus, // explicitly check if that exists before trying to access its visibility and // the display where it is shown. - if (platform_window()) { - display = display::Screen::GetScreen()->GetDisplayNearestWindow( - GetWidget()->GetNativeWindow()); - } + if (platform_window()) + display = GetDisplayNearestRootWindow(); float scale = display.device_scale_factor(); gfx::Transform transform; @@ -844,6 +839,15 @@ bool DesktopWindowTreeHostPlatform::ShouldUseLayerForShapedWindow() const { return platform_window()->ShouldUseLayerForShapedWindow(); } +display::Display DesktopWindowTreeHostPlatform::GetDisplayNearestRootWindow() + const { + DCHECK(window()); + DCHECK(window()->IsRootWindow()); + // TODO(sky): GetDisplayNearestWindow() should take a const aura::Window*. + return display::Screen::GetScreen()->GetDisplayNearestWindow( + const_cast(window())); +} + //////////////////////////////////////////////////////////////////////////////// // DesktopWindowTreeHost: diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h index c2f139c51db91b..db230ea6c4e122 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h @@ -162,6 +162,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostPlatform // window mask, otherwise false when window shape is already updated in views. virtual bool ShouldUseLayerForShapedWindow() const; + // Helper method that returns the display for the |window()|. + display::Display GetDisplayNearestRootWindow() const; + internal::NativeWidgetDelegate* const native_widget_delegate_; DesktopNativeWidgetAura* const desktop_native_widget_aura_; diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn index fb2c6656112121..a236cf27189fd3 100644 --- a/weblayer/BUILD.gn +++ b/weblayer/BUILD.gn @@ -448,6 +448,7 @@ source_set("weblayer_lib_base") { "//components/policy/core/browser", "//components/pref_registry:pref_registry", "//components/prefs", + "//components/profile_metrics", "//components/safe_browsing/content/browser:client_side_detection", "//components/safe_browsing/content/common:interfaces", "//components/safe_browsing/content/renderer:throttles", diff --git a/weblayer/browser/DEPS b/weblayer/browser/DEPS index 5ab225d76361b3..abfd830b05daa5 100644 --- a/weblayer/browser/DEPS +++ b/weblayer/browser/DEPS @@ -53,6 +53,7 @@ include_rules = [ "+components/permissions", "+components/pref_registry", "+components/prefs", + "+components/profile_metrics", "+components/no_state_prefetch/browser", "+components/no_state_prefetch/common", "+components/resources/android", diff --git a/weblayer/browser/profile_impl.cc b/weblayer/browser/profile_impl.cc index d5368b2e0f300c..de85cd782bb27e 100644 --- a/weblayer/browser/profile_impl.cc +++ b/weblayer/browser/profile_impl.cc @@ -19,6 +19,7 @@ #include "build/build_config.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/prefs/pref_service.h" +#include "components/profile_metrics/browser_profile_type.h" #include "components/web_cache/browser/web_cache_manager.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -191,6 +192,11 @@ ProfileImpl::ProfileImpl(const std::string& name, bool is_incognito) } GetProfiles().insert(this); + profile_metrics::SetBrowserProfileType( + GetBrowserContext(), is_incognito + ? profile_metrics::BrowserProfileType::kIncognito + : profile_metrics::BrowserProfileType::kRegular); + for (auto& observer : GetObservers()) observer.ProfileCreated(this);