diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-09-07 13:12:05 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-11-09 10:02:59 +0000 |
commit | 33fc33aa94d4add0878ec30dc818e34e1dd3cc2a (patch) | |
tree | f6af110909c79b2759136554f1143d8b0572af0a /chromium/weblayer | |
parent | 7d2c5d177e9813077a621df8d18c0deda73099b3 (diff) | |
download | qtwebengine-chromium-33fc33aa94d4add0878ec30dc818e34e1dd3cc2a.tar.gz |
BASELINE: Update Chromium to 104.0.5112.120
Change-Id: I5d2726c2ab018d75d055739b6ba64317904f05bb
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/438935
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/weblayer')
104 files changed, 1926 insertions, 536 deletions
diff --git a/chromium/weblayer/BUILD.gn b/chromium/weblayer/BUILD.gn index b33b3d23d46..97b2f3eef91 100644 --- a/chromium/weblayer/BUILD.gn +++ b/chromium/weblayer/BUILD.gn @@ -14,6 +14,8 @@ import("//device/vr/buildflags/buildflags.gni") import("//gpu/vulkan/features.gni") import("//media/media_options.gni") import("//mojo/public/tools/bindings/mojom.gni") +import("//pdf/features.gni") +import("//printing/buildflags/buildflags.gni") import("//tools/grit/grit_rule.gni") import("//tools/grit/repack.gni") import("//tools/v8_context_snapshot/v8_context_snapshot.gni") @@ -45,6 +47,13 @@ if (is_android) { grit("generate_components_strings") { source = "../components/components_strings.grd" + defines = [ + "enable_arcore=$enable_arcore", + "enable_pdf=$enable_pdf", + "enable_print_preview=$enable_print_preview", + "enable_vr=$enable_vr", + ] + # components_strings contains strings from all components. WebLayer # will never display most of them, so we try to limit the included # strings. @@ -144,6 +153,8 @@ source_set("weblayer_lib_base") { "app/content_main_delegate_impl.cc", "app/content_main_delegate_impl.h", "app/main.cc", + "browser/accept_languages_service_factory.cc", + "browser/accept_languages_service_factory.h", "browser/autofill_client_impl.cc", "browser/autofill_client_impl.h", "browser/background_download_service_factory.cc", @@ -294,8 +305,6 @@ source_set("weblayer_lib_base") { "browser/system_network_context_manager.h", "browser/tab_impl.cc", "browser/tab_impl.h", - "browser/translate_accept_languages_factory.cc", - "browser/translate_accept_languages_factory.h", "browser/translate_client_impl.cc", "browser/translate_client_impl.h", "browser/translate_ranker_factory.cc", @@ -463,6 +472,7 @@ source_set("weblayer_lib_base") { "//components/profile_metrics", "//components/safe_browsing/content/browser", "//components/safe_browsing/content/browser:client_side_detection", + "//components/safe_browsing/content/browser/web_ui", "//components/safe_browsing/content/common:interfaces", "//components/safe_browsing/content/renderer:throttles", "//components/safe_browsing/content/renderer/phishing_classifier", @@ -509,7 +519,6 @@ source_set("weblayer_lib_base") { "//components/webrtc", "//content:content_resources", "//content:dev_ui_content_resources", - "//content/app/resources", "//content/public/app", "//content/public/browser", "//content/public/child", @@ -692,8 +701,14 @@ source_set("weblayer_lib_base") { "browser/url_bar/trusted_cdn_observer.h", "browser/verdict_cache_manager_factory.cc", "browser/verdict_cache_manager_factory.h", + "browser/webapps/webapk_install_scheduler.cc", + "browser/webapps/webapk_install_scheduler.h", + "browser/webapps/webapk_install_scheduler_bridge.cc", + "browser/webapps/webapk_install_scheduler_bridge.h", "browser/webapps/webapps_utils.cc", "browser/webapps/webapps_utils.h", + "browser/webapps/weblayer_app_banner_manager_android.cc", + "browser/webapps/weblayer_app_banner_manager_android.h", "browser/webapps/weblayer_webapps_client.cc", "browser/webapps/weblayer_webapps_client.h", "browser/weblayer_factory_impl_android.cc", @@ -708,8 +723,6 @@ source_set("weblayer_lib_base") { "common/crash_reporter/crash_reporter_client.h", ] deps += [ - "//android_webview:generate_aw_resources", - "//android_webview:generate_aw_strings", "//components/android_autofill/browser", "//components/android_autofill/browser:android", "//components/android_system_error_page", diff --git a/chromium/weblayer/README.md b/chromium/weblayer/README.md index e14c53c1461..2d8f00cb115 100644 --- a/chromium/weblayer/README.md +++ b/chromium/weblayer/README.md @@ -103,22 +103,38 @@ The following tests the latest client library against M80: To run WPT on android against weblayer do the following: ``` - $ export WPT_TEST= test you want to run, relative to wpt directory. - $ autoninja -C out/Default run_weblayer_shell weblayer_shell_wpt - $ out/Default/bin/run_weblayer_shell - $ testing/scripts/run_android_wpt.py --webdriver-binary=out/Default/clang_x64/chromedriver --product android_weblayer --isolated-script-test-output /tmp/weblayer_out.json --include $WPT_TEST --ignore-browser-specific-expectations --ignore-default-expectations + $ WPT_TEST=badging/badge-success.https.html # test or directory you want to run, relative to wpt directory. + $ autoninja -C out/Default weblayer_shell_wpt + $ out/Default/bin/run_weblayer_shell_wpt \ + -t Default \ + --isolated-script-test-output out/Default/weblayer_out.json \ + --include $WPT_TEST \ + --ignore-browser-specific-expectations \ + --ignore-default-expectations \ + --avd-config tools/android/avd/proto/generic_android28.textpb +``` + +The script will write test artifacts to a directory named `layout-test-results` that is a sibling of `--isolated-script-test-output`. +You can view the results by serving them over HTTP: + +``` + $ python3 -m http.server 8080 -d out/Default/layout-test-results ``` -`run_android_wpt.py` does not install `weblayer-shell`, you need to do that -yourself (executing `run_weblayer_shell` will do that). +Then, navigate to `<host>:8080/results.html` in your browser. To run against clank: ``` - $ export WPT_TEST= test you want to run, relative to wpt directory. - $ autoninja -C out/Default monochrome_public_apk - $ out/Default/bin/monochrome_public_apk install - $ testing/scripts/run_android_wpt.py --webdriver-binary=out/Default/clang_x64/chromedriver --product chrome_android --chrome-package-name org.chromium.chrome --isolated-script-test-output /tmp/clank_out.json --include $WPT_TEST --ignore-browser-specific-expectations --ignore-default-expectations + $ WPT_TEST=badging/badge-success.https.html # test or directory you want to run, relative to wpt directory. + $ autoninja -C out/Default chrome_public_wpt + $ out/Default/bin/run_chrome_public_wpt \ + -t Default \ + --isolated-script-test-output out/Default/clank_out.json \ + --include $WPT_TEST \ + --ignore-browser-specific-expectations \ + --ignore-default-expectations \ + --avd-config tools/android/avd/proto/generic_android28.textpb ``` The `--ignore-browser-specific-expectations --ignore-default-expectations` flags will prevent @@ -128,16 +144,18 @@ Once a test is fixed, rerun it without those flags to ensure the Expectations fi To run against linux with wptrunner (same runner we use on android, which runs normal chrome): ``` - $ export WPT_TEST= test you want to run, relative to wpt directory. + $ WPT_TEST=badging/badge-success.https.html # test or directory you want to run, relative to wpt directory. $ autoninja -C out/Default wpt_tests_isolate - $ cd testing/scripts - $ ./run_wpt_tests.py -t Default $WPT_TEST + $ out/Default/bin/run_wpt_tests_isolate \ + -t Default \ + --isolated-script-test-output out/Default/chrome_out.json \ + --include $WPT_TEST ```` -To run against linux with run_web_tests (same runner we use on CI, which runs content_shell): +To run against linux with `run_web_tests` (same runner we use on CI, which runs `content_shell`): ``` - $ export WPT_TEST= test you want to run, relative to wpt directory. + $ WPT_TEST=badging/badge-success.https.html # test or directory you want to run, relative to wpt directory. $ autoninja -C out/Default blink_tests $ ./third_party/blink/tools/run_web_tests.py -t Default external/wpt/$WPT_TEST ``` diff --git a/chromium/weblayer/app/content_main_delegate_impl.cc b/chromium/weblayer/app/content_main_delegate_impl.cc index d9456e9ff95..cb033a0b45c 100644 --- a/chromium/weblayer/app/content_main_delegate_impl.cc +++ b/chromium/weblayer/app/content_main_delegate_impl.cc @@ -235,10 +235,11 @@ bool ContentMainDelegateImpl::BasicStartupComplete(int* exit_code) { return false; } -bool ContentMainDelegateImpl::ShouldCreateFeatureList() { +bool ContentMainDelegateImpl::ShouldCreateFeatureList(InvokedIn invoked_in) { #if BUILDFLAG(IS_ANDROID) - // On android WebLayer is in charge of creating its own FeatureList. - return false; + // On android WebLayer is in charge of creating its own FeatureList in the + // browser process. + return invoked_in == InvokedIn::kChildProcess; #else // TODO(weblayer-dev): Support feature lists on desktop. return true; @@ -297,8 +298,9 @@ void ContentMainDelegateImpl::PreSandboxStartup() { #endif } -void ContentMainDelegateImpl::PostEarlyInitialization(bool is_running_tests) { - browser_client_->CreateFeatureListAndFieldTrials(); +void ContentMainDelegateImpl::PostEarlyInitialization(InvokedIn invoked_in) { + if (invoked_in != InvokedIn::kChildProcess) + browser_client_->CreateFeatureListAndFieldTrials(); } absl::variant<int, content::MainFunctionParams> diff --git a/chromium/weblayer/app/content_main_delegate_impl.h b/chromium/weblayer/app/content_main_delegate_impl.h index 5da2e801499..151ecc647a5 100644 --- a/chromium/weblayer/app/content_main_delegate_impl.h +++ b/chromium/weblayer/app/content_main_delegate_impl.h @@ -29,10 +29,10 @@ class ContentMainDelegateImpl : public content::ContentMainDelegate { // ContentMainDelegate implementation: bool BasicStartupComplete(int* exit_code) override; - bool ShouldCreateFeatureList() override; + bool ShouldCreateFeatureList(InvokedIn invoked_in) override; variations::VariationsIdsProvider* CreateVariationsIdsProvider() override; void PreSandboxStartup() override; - void PostEarlyInitialization(bool is_running_tests) override; + void PostEarlyInitialization(InvokedIn invoked_in) override; absl::variant<int, content::MainFunctionParams> RunProcess( const std::string& process_type, content::MainFunctionParams main_function_params) override; diff --git a/chromium/weblayer/browser/translate_accept_languages_factory.cc b/chromium/weblayer/browser/accept_languages_service_factory.cc index 904887fd3a2..b6c89140f52 100644 --- a/chromium/weblayer/browser/translate_accept_languages_factory.cc +++ b/chromium/weblayer/browser/accept_languages_service_factory.cc @@ -2,49 +2,47 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "weblayer/browser/translate_accept_languages_factory.h" +#include "weblayer/browser/accept_languages_service_factory.h" #include "base/no_destructor.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/language/core/browser/accept_languages_service.h" #include "components/language/core/browser/pref_names.h" #include "components/prefs/pref_service.h" -#include "components/translate/core/browser/translate_accept_languages.h" #include "components/user_prefs/user_prefs.h" #include "content/public/browser/browser_context.h" namespace weblayer { // static -translate::TranslateAcceptLanguages* -TranslateAcceptLanguagesFactory::GetForBrowserContext( +language::AcceptLanguagesService* +AcceptLanguagesServiceFactory::GetForBrowserContext( content::BrowserContext* context) { - return static_cast<translate::TranslateAcceptLanguages*>( + return static_cast<language::AcceptLanguagesService*>( GetInstance()->GetServiceForBrowserContext(context, true)); } // static -TranslateAcceptLanguagesFactory* -TranslateAcceptLanguagesFactory::GetInstance() { - static base::NoDestructor<TranslateAcceptLanguagesFactory> factory; +AcceptLanguagesServiceFactory* AcceptLanguagesServiceFactory::GetInstance() { + static base::NoDestructor<AcceptLanguagesServiceFactory> factory; return factory.get(); } -TranslateAcceptLanguagesFactory::TranslateAcceptLanguagesFactory() +AcceptLanguagesServiceFactory::AcceptLanguagesServiceFactory() : BrowserContextKeyedServiceFactory( - "TranslateAcceptLanguages", + "AcceptLanguagesService", BrowserContextDependencyManager::GetInstance()) {} -TranslateAcceptLanguagesFactory::~TranslateAcceptLanguagesFactory() = default; +AcceptLanguagesServiceFactory::~AcceptLanguagesServiceFactory() = default; -KeyedService* TranslateAcceptLanguagesFactory::BuildServiceInstanceFor( +KeyedService* AcceptLanguagesServiceFactory::BuildServiceInstanceFor( content::BrowserContext* browser_context) const { - return new translate::TranslateAcceptLanguages( + return new language::AcceptLanguagesService( user_prefs::UserPrefs::Get(browser_context), language::prefs::kAcceptLanguages); } -content::BrowserContext* -TranslateAcceptLanguagesFactory::GetBrowserContextToUse( +content::BrowserContext* AcceptLanguagesServiceFactory::GetBrowserContextToUse( content::BrowserContext* context) const { return context; } diff --git a/chromium/weblayer/browser/accept_languages_service_factory.h b/chromium/weblayer/browser/accept_languages_service_factory.h new file mode 100644 index 00000000000..422da296df6 --- /dev/null +++ b/chromium/weblayer/browser/accept_languages_service_factory.h @@ -0,0 +1,44 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBLAYER_BROWSER_ACCEPT_LANGUAGES_SERVICE_FACTORY_H_ +#define WEBLAYER_BROWSER_ACCEPT_LANGUAGES_SERVICE_FACTORY_H_ + +#include "base/no_destructor.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace language { +class AcceptLanguagesService; +} + +namespace weblayer { + +// AcceptLanguagesServiceFactory is a way to associate an +// AcceptLanguagesService instance to a BrowserContext. +class AcceptLanguagesServiceFactory : public BrowserContextKeyedServiceFactory { + public: + AcceptLanguagesServiceFactory(const AcceptLanguagesServiceFactory&) = delete; + AcceptLanguagesServiceFactory& operator=( + const AcceptLanguagesServiceFactory&) = delete; + + static language::AcceptLanguagesService* GetForBrowserContext( + content::BrowserContext* browser_context); + static AcceptLanguagesServiceFactory* GetInstance(); + + private: + friend class base::NoDestructor<AcceptLanguagesServiceFactory>; + + AcceptLanguagesServiceFactory(); + ~AcceptLanguagesServiceFactory() override; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* profile) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; +}; + +} // namespace weblayer + +#endif // WEBLAYER_BROWSER_ACCEPT_LANGUAGES_SERVICE_FACTORY_H_ diff --git a/chromium/weblayer/browser/ad_tagging_browsertest.cc b/chromium/weblayer/browser/ad_tagging_browsertest.cc index 3c5a57a186a..3994d265b9e 100644 --- a/chromium/weblayer/browser/ad_tagging_browsertest.cc +++ b/chromium/weblayer/browser/ad_tagging_browsertest.cc @@ -105,7 +105,7 @@ IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest, DISABLED_FramesByURL) { // Main frame. NavigateAndWaitForCompletion(GetURL("frame_factory.html"), shell()); EXPECT_FALSE(observer.GetIsAdSubframe( - web_contents()->GetMainFrame()->GetFrameTreeNodeId())); + web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId())); // (1) Vanilla child. content::RenderFrameHost* vanilla_child = subresource_filter::CreateSrcFrame( diff --git a/chromium/weblayer/browser/android/ad_density_intervention_browsertest.cc b/chromium/weblayer/browser/android/ad_density_intervention_browsertest.cc index 9763dfb7613..1a70e6b1d6b 100644 --- a/chromium/weblayer/browser/android/ad_density_intervention_browsertest.cc +++ b/chromium/weblayer/browser/android/ad_density_intervention_browsertest.cc @@ -94,7 +94,8 @@ IN_PROC_BROWSER_TEST_F( // blank_with_adiframe_writer loads a script tagged as an ad, verify it is not // loaded and the subresource filter UI for ad blocking is shown. - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); EXPECT_EQ(infobars::ContentInfoBarManager::FromWebContents(web_contents()) ->infobar_count(), 1u); @@ -146,7 +147,8 @@ IN_PROC_BROWSER_TEST_F( // blank_with_adiframe_writer loads a script tagged as an ad, verify it is // loaded as ads are not blocked and the subresource filter UI is not // shown. - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); // No ads blocked infobar should be shown as we have not triggered the // intervention. @@ -215,7 +217,8 @@ IN_PROC_BROWSER_TEST_F( // We are not enforcing ad blocking on ads violations, site should load // as expected without subresource filter UI. - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); // No ads blocked infobar should be shown as we have not triggered the // intervention. diff --git a/chromium/weblayer/browser/android/javatests/BUILD.gn b/chromium/weblayer/browser/android/javatests/BUILD.gn index efb21824176..f41e1b58f1b 100644 --- a/chromium/weblayer/browser/android/javatests/BUILD.gn +++ b/chromium/weblayer/browser/android/javatests/BUILD.gn @@ -57,7 +57,6 @@ android_library("weblayer_java_tests") { "//content/public/test/android:content_java_test_support", "//net/android:net_java_test_support", "//third_party/android_deps:espresso_java", - "//third_party/android_sdk:android_support_chromium_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/androidx:androidx_activity_activity_java", diff --git a/chromium/weblayer/browser/android/javatests/skew/expectations.txt b/chromium/weblayer/browser/android/javatests/skew/expectations.txt index d73b58cd7d3..3afaaf290cc 100644 --- a/chromium/weblayer/browser/android/javatests/skew/expectations.txt +++ b/chromium/weblayer/browser/android/javatests/skew/expectations.txt @@ -5,7 +5,7 @@ # with versions less than or equal to $VERSION of the implementation. # # These lines are not comments! They define the set of known tags and other information. -# tags: [ client_lte_91 client_lte_94 client_lte_95 impl_lte_95 client_lte_98 impl_lte_98 ] +# tags: [ client_lte_91 client_lte_94 client_lte_95 impl_lte_95 client_lte_98 impl_lte_98 client_lte_103 ] # 'all' disables the test from any skew test. # tags: [ all ] # results: [ Skip ] @@ -111,3 +111,6 @@ crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigatio crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testUserClicksLinkToPageWithExternalIntentLaunchedViaOnLoad [ Skip ] crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testAvoidDisambiguationDialog [ Skip ] crbug.com/1278017 [ impl_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testAvoidDisambiguationDialog [ Skip ] + +# In 104 we started to cap maximum cookie expiration date +crbug.com/1264458 [ client_lte_103 ] org.chromium.weblayer.test.CookieManagerTest#testGetResponseCookiesAllAttributes [ Skip ] diff --git a/chromium/weblayer/browser/autofill_assistant/weblayer_dependencies.cc b/chromium/weblayer/browser/autofill_assistant/weblayer_dependencies.cc index b4293382f70..4acb24024f8 100644 --- a/chromium/weblayer/browser/autofill_assistant/weblayer_dependencies.cc +++ b/chromium/weblayer/browser/autofill_assistant/weblayer_dependencies.cc @@ -4,12 +4,27 @@ #include "weblayer/browser/autofill_assistant/weblayer_dependencies.h" +#include "base/android/jni_string.h" +#include "base/android/locale_utils.h" +#include "components/autofill_assistant/browser/android/dependencies_android.h" +#include "components/autofill_assistant/browser/common_dependencies.h" +#include "components/autofill_assistant/browser/dependencies_util.h" +#include "components/autofill_assistant/browser/platform_dependencies.h" +#include "components/keyed_service/core/simple_factory_key.h" +#include "components/version_info/android/channel_getter.h" #include "weblayer/browser/autofill_assistant/weblayer_assistant_field_trial_util.h" +#include "weblayer/browser/browser_context_impl.h" #include "weblayer/browser/feature_list_creator.h" #include "weblayer/browser/java/jni/WebLayerAssistantStaticDependencies_jni.h" +#include "weblayer/browser/profile_impl.h" -using ::autofill_assistant::Dependencies; +using ::autofill_assistant::CommonDependencies; +using ::autofill_assistant::DependenciesAndroid; +using ::autofill_assistant::PlatformDependencies; +using ::base::android::AttachCurrentThread; +using ::base::android::ConvertJavaStringToUTF8; using ::base::android::JavaParamRef; +using ::base::android::ScopedJavaLocalRef; namespace weblayer { @@ -17,23 +32,59 @@ static jlong JNI_WebLayerAssistantStaticDependencies_Init( JNIEnv* env, const JavaParamRef<jobject>& jstatic_dependencies) { // The dynamic_cast is necessary here to safely cast the resulting intptr back - // to Dependencies using reinterpret_cast. - return reinterpret_cast<intptr_t>(dynamic_cast<Dependencies*>( + // to DependenciesAndroid using reinterpret_cast. + return reinterpret_cast<intptr_t>(dynamic_cast<DependenciesAndroid*>( new WebLayerDependencies(env, jstatic_dependencies))); } +static ScopedJavaLocalRef<jobject> +JNI_WebLayerAssistantStaticDependencies_GetJavaProfile( + JNIEnv* env, + const JavaParamRef<jobject>& java_web_contents) { + content::WebContents* web_contents = + content::WebContents::FromJavaWebContents(java_web_contents); + if (!web_contents) { + return nullptr; + } + return ScopedJavaLocalRef<jobject>( + ProfileImpl::FromBrowserContext(web_contents->GetBrowserContext()) + ->GetJavaProfile()); +} + +static jlong JNI_WebLayerAssistantStaticDependencies_GetSimpleFactoryKey( + JNIEnv* env, + jlong browser_context_ptr) { + content::BrowserContext* browser_context = + reinterpret_cast<content::BrowserContext*>(browser_context_ptr); + if (!browser_context) { + return 0; + } + SimpleFactoryKey* key = + static_cast<BrowserContextImpl*>(browser_context)->simple_factory_key(); + return reinterpret_cast<intptr_t>(key); +} + WebLayerDependencies::WebLayerDependencies( JNIEnv* env, const JavaParamRef<jobject>& jstatic_dependencies) - : Dependencies(env, jstatic_dependencies) {} + : DependenciesAndroid(env, jstatic_dependencies) {} + +const CommonDependencies* WebLayerDependencies::GetCommonDependencies() const { + return this; +} + +const PlatformDependencies* WebLayerDependencies::GetPlatformDependencies() + const { + return this; +} std::unique_ptr<::autofill_assistant::AssistantFieldTrialUtil> WebLayerDependencies::CreateFieldTrialUtil() const { return std::make_unique<WebLayerAssistantFieldTrialUtil>(); } -autofill::PersonalDataManager* WebLayerDependencies::GetPersonalDataManager() - const { +autofill::PersonalDataManager* WebLayerDependencies::GetPersonalDataManager( + content::BrowserContext* browser_context) const { // TODO(b/222671580): Add NOTREACHED? return nullptr; } @@ -45,15 +96,30 @@ WebLayerDependencies::GetPasswordManagerClient( return nullptr; } -std::string WebLayerDependencies::GetChromeSignedInEmailAddress( - content::WebContents* web_contents) const { - return ""; - // TODO(b/222671580): Implement +std::string WebLayerDependencies::GetSignedInEmail( + content::BrowserContext* browser_context) const { + DCHECK(browser_context); + ProfileImpl* profile = ProfileImpl::FromBrowserContext(browser_context); + const ScopedJavaLocalRef<jstring> email = + Java_WebLayerAssistantStaticDependencies_getEmailOrNull( + AttachCurrentThread(), jstatic_dependencies_, + profile->GetJavaProfile()); + return email.is_null() ? "" : ConvertJavaStringToUTF8(email); } -variations::VariationsService* WebLayerDependencies::GetVariationsService() - const { - return FeatureListCreator::GetInstance()->variations_service(); +bool WebLayerDependencies::IsSupervisedUser( + content::BrowserContext* browser_context) const { + // WebLayer does not support supervised users. + return false; +} + +std::string WebLayerDependencies::GetLocale() const { + return base::android::GetDefaultLocaleString(); +} + +std::string WebLayerDependencies::GetCountryCode() const { + return autofill_assistant::dependencies_util::GetCountryCode( + FeatureListCreator::GetInstance()->variations_service()); } ::autofill_assistant::AnnotateDomModelService* @@ -72,4 +138,14 @@ bool WebLayerDependencies::IsWebLayer() const { return true; } +signin::IdentityManager* WebLayerDependencies::GetIdentityManager( + content::BrowserContext* browser_context) const { + // TODO(b/222671580): implement. + return nullptr; +} + +version_info::Channel WebLayerDependencies::GetChannel() const { + return version_info::android::GetChannel(); +} + } // namespace weblayer diff --git a/chromium/weblayer/browser/autofill_assistant/weblayer_dependencies.h b/chromium/weblayer/browser/autofill_assistant/weblayer_dependencies.h index 9ef12f5298d..940fbac9cbf 100644 --- a/chromium/weblayer/browser/autofill_assistant/weblayer_dependencies.h +++ b/chromium/weblayer/browser/autofill_assistant/weblayer_dependencies.h @@ -7,8 +7,10 @@ #include "base/android/scoped_java_ref.h" #include "base/strings/string_piece.h" -#include "components/autofill_assistant/browser/android/dependencies.h" +#include "components/autofill_assistant/browser/android/dependencies_android.h" #include "components/autofill_assistant/browser/assistant_field_trial_util.h" +#include "components/autofill_assistant/browser/common_dependencies.h" +#include "components/autofill_assistant/browser/platform_dependencies.h" #include "components/autofill_assistant/content/browser/annotate_dom_model_service.h" #include "components/metrics/metrics_service_accessor.h" #include "components/password_manager/core/browser/password_manager_client.h" @@ -20,32 +22,45 @@ namespace weblayer { // Interface for platform delegates that provide platform-dependent features // and dependencies to the starter. -class WebLayerDependencies : public ::autofill_assistant::Dependencies { +// TODO(b/201964911): rename to make it consistent with the other dependencies +// classes. +class WebLayerDependencies : public ::autofill_assistant::DependenciesAndroid, + public ::autofill_assistant::CommonDependencies, + public ::autofill_assistant::PlatformDependencies { public: WebLayerDependencies( JNIEnv* env, const base::android::JavaParamRef<jobject>& jstatic_dependencies); + // Overrides DependenciesAndroid + const ::autofill_assistant::CommonDependencies* GetCommonDependencies() + const override; + const ::autofill_assistant::PlatformDependencies* GetPlatformDependencies() + const override; + + // Overrides CommonDependencies std::unique_ptr<::autofill_assistant::AssistantFieldTrialUtil> CreateFieldTrialUtil() const override; - - autofill::PersonalDataManager* GetPersonalDataManager() const override; - + autofill::PersonalDataManager* GetPersonalDataManager( + content::BrowserContext* browser_context) const override; password_manager::PasswordManagerClient* GetPasswordManagerClient( content::WebContents* web_contents) const override; - - variations::VariationsService* GetVariationsService() const override; - - std::string GetChromeSignedInEmailAddress( - content::WebContents* web_contents) const override; - + std::string GetLocale() const override; + std::string GetCountryCode() const override; + std::string GetSignedInEmail( + content::BrowserContext* browser_context) const override; + bool IsSupervisedUser( + content::BrowserContext* browser_context) const override; ::autofill_assistant::AnnotateDomModelService* GetOrCreateAnnotateDomModelService( content::BrowserContext* browser_context) const override; + bool IsWebLayer() const override; + signin::IdentityManager* GetIdentityManager( + content::BrowserContext* browser_context) const override; + version_info::Channel GetChannel() const override; + // Overrides PlatformDependencies bool IsCustomTab(const content::WebContents& web_contents) const override; - - bool IsWebLayer() const override; }; } // namespace weblayer diff --git a/chromium/weblayer/browser/autofill_client_impl.cc b/chromium/weblayer/browser/autofill_client_impl.cc index 3bae229b675..2d870b5716c 100644 --- a/chromium/weblayer/browser/autofill_client_impl.cc +++ b/chromium/weblayer/browser/autofill_client_impl.cc @@ -7,7 +7,6 @@ #include "build/build_config.h" #include "components/autofill/core/browser/data_model/autofill_profile.h" #include "components/autofill/core/browser/ui/suggestion.h" -#include "components/ukm/content/source_url_recorder.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/ssl_status.h" #include "content/public/browser/web_contents.h" @@ -292,7 +291,7 @@ bool AutofillClientImpl::IsPasswordManagerEnabled() { } void AutofillClientImpl::PropagateAutofillPredictions( - content::RenderFrameHost* rfh, + autofill::AutofillDriver* driver, const std::vector<autofill::FormStructure*>& forms) { NOTREACHED(); } @@ -322,6 +321,10 @@ void AutofillClientImpl::ExecuteCommand(int id) { NOTREACHED(); } +void AutofillClientImpl::OpenPromoCodeOfferDetailsURL(const GURL& url) { + NOTREACHED(); +} + void AutofillClientImpl::LoadRiskData( base::OnceCallback<void(const std::string&)> callback) { NOTREACHED(); diff --git a/chromium/weblayer/browser/autofill_client_impl.h b/chromium/weblayer/browser/autofill_client_impl.h index 56382efac7a..6cc60bc6b81 100644 --- a/chromium/weblayer/browser/autofill_client_impl.h +++ b/chromium/weblayer/browser/autofill_client_impl.h @@ -124,7 +124,7 @@ class AutofillClientImpl bool IsAutocompleteEnabled() override; bool IsPasswordManagerEnabled() override; void PropagateAutofillPredictions( - content::RenderFrameHost* rfh, + autofill::AutofillDriver* driver, const std::vector<autofill::FormStructure*>& forms) override; void DidFillOrPreviewField(const std::u16string& autofilled_value, const std::u16string& profile_full_name) override; @@ -132,6 +132,7 @@ class AutofillClientImpl bool ShouldShowSigninPromo() override; bool AreServerCardsSupported() const override; void ExecuteCommand(int id) override; + void OpenPromoCodeOfferDetailsURL(const GURL& url) override; // RiskDataLoader: void LoadRiskData( diff --git a/chromium/weblayer/browser/background_fetch/background_fetch_download.cc b/chromium/weblayer/browser/background_fetch/background_fetch_download.cc index 1daa5a96e9d..a7083e650a0 100644 --- a/chromium/weblayer/browser/background_fetch/background_fetch_download.cc +++ b/chromium/weblayer/browser/background_fetch/background_fetch_download.cc @@ -104,7 +104,9 @@ const SkBitmap* BackgroundFetchDownload::GetLargeIcon() { } void BackgroundFetchDownload::OnFinished(bool activated) { - controller_->OnUiFinished(job_id_, activated); + if (activated) + controller_->OnUiActivated(job_id_); + controller_->OnUiFinished(job_id_); // |this| is deleted. } diff --git a/chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.cc b/chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.cc index b31d5542fa4..9b3137904f6 100644 --- a/chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.cc +++ b/chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.cc @@ -71,4 +71,13 @@ void WebLayerBluetoothDelegateImplClient::ShowBluetoothDeviceCredentialsDialog( NOTREACHED(); } +void WebLayerBluetoothDelegateImplClient::ShowBluetoothDevicePairConfirmDialog( + content::RenderFrameHost* frame, + const std::u16string& device_identifier, + content::BluetoothDelegate::PairConfirmCallback callback) { + // Web Bluetooth is not supported for desktop in WebLayer and Android already + // bonds on demand, so this should not be called on any platform. + NOTREACHED(); +} + } // namespace weblayer diff --git a/chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h b/chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h index 5352e4367e1..9eb8028100a 100644 --- a/chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h +++ b/chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h @@ -47,6 +47,10 @@ class WebLayerBluetoothDelegateImplClient content::RenderFrameHost* frame, const std::u16string& device_identifier, content::BluetoothDelegate::CredentialsCallback callback) override; + void ShowBluetoothDevicePairConfirmDialog( + content::RenderFrameHost* frame, + const std::u16string& device_identifier, + content::BluetoothDelegate::PairConfirmCallback callback) override; }; } // namespace weblayer diff --git a/chromium/weblayer/browser/browser_controls_navigation_state_handler.cc b/chromium/weblayer/browser/browser_controls_navigation_state_handler.cc index 5b6c5f2a24f..afe0790a91a 100644 --- a/chromium/weblayer/browser/browser_controls_navigation_state_handler.cc +++ b/chromium/weblayer/browser/browser_controls_navigation_state_handler.cc @@ -46,15 +46,12 @@ BrowserControlsNavigationStateHandler:: bool BrowserControlsNavigationStateHandler::IsRendererControllingOffsets() { if (IsRendererHungOrCrashed()) return false; - return !web_contents()->GetMainFrame()->GetProcess()->IsBlocked(); + return !web_contents()->GetPrimaryMainFrame()->GetProcess()->IsBlocked(); } void BrowserControlsNavigationStateHandler::DidStartNavigation( content::NavigationHandle* navigation_handle) { is_crashed_ = false; - // TODO(https://crbug.com/1218946): With MPArch there may be multiple main - // frames. This caller was converted automatically to the primary main frame - // to preserve its semantics. Follow up to confirm correctness. if (navigation_handle->IsInPrimaryMainFrame() && !navigation_handle->IsSameDocument()) { forced_show_during_load_timer_.Stop(); @@ -64,9 +61,6 @@ void BrowserControlsNavigationStateHandler::DidStartNavigation( void BrowserControlsNavigationStateHandler::DidFinishNavigation( content::NavigationHandle* navigation_handle) { - // TODO(https://crbug.com/1218946): With MPArch there may be multiple main - // frames. This caller was converted automatically to the primary main frame - // to preserve its semantics. Follow up to confirm correctness. if (navigation_handle->IsInPrimaryMainFrame()) { if (!navigation_handle->HasCommitted()) { // There will be no DidFinishLoad or DidFailLoad, so hide the topview @@ -95,7 +89,7 @@ void BrowserControlsNavigationStateHandler::DidFailLoad( if (is_main_frame) ScheduleStopDelayedForceShow(); if (render_frame_host->IsActive() && - (render_frame_host == web_contents()->GetMainFrame())) { + (render_frame_host == web_contents()->GetPrimaryMainFrame())) { UpdateState(); } } diff --git a/chromium/weblayer/browser/browser_main_parts_impl.cc b/chromium/weblayer/browser/browser_main_parts_impl.cc index b71f46fa843..a9647f7f0a4 100644 --- a/chromium/weblayer/browser/browser_main_parts_impl.cc +++ b/chromium/weblayer/browser/browser_main_parts_impl.cc @@ -32,6 +32,7 @@ #include "content/public/common/result_codes.h" #include "content/public/common/url_constants.h" #include "ui/base/resource/resource_bundle.h" +#include "weblayer/browser/accept_languages_service_factory.h" #include "weblayer/browser/browser_process.h" #include "weblayer/browser/cookie_settings_factory.h" #include "weblayer/browser/feature_list_creator.h" @@ -43,7 +44,6 @@ #include "weblayer/browser/permissions/weblayer_permissions_client.h" #include "weblayer/browser/stateful_ssl_host_state_delegate_factory.h" #include "weblayer/browser/subresource_filter_profile_context_factory.h" -#include "weblayer/browser/translate_accept_languages_factory.h" #include "weblayer/browser/translate_ranker_factory.h" #include "weblayer/browser/web_data_service_factory.h" #include "weblayer/browser/webui/web_ui_controller_factory.h" @@ -123,7 +123,7 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() { HostContentSettingsMapFactory::GetInstance(); StatefulSSLHostStateDelegateFactory::GetInstance(); CookieSettingsFactory::GetInstance(); - TranslateAcceptLanguagesFactory::GetInstance(); + AcceptLanguagesServiceFactory::GetInstance(); TranslateRankerFactory::GetInstance(); NoStatePrefetchLinkManagerFactory::GetInstance(); NoStatePrefetchManagerFactory::GetInstance(); @@ -153,11 +153,8 @@ void StopMessageLoop(base::OnceClosure quit_closure) { BrowserMainPartsImpl::BrowserMainPartsImpl( MainParams* params, - content::MainFunctionParams main_function_params, std::unique_ptr<PrefService> local_state) - : params_(params), - main_function_params_(std::move(main_function_params)), - local_state_(std::move(local_state)) {} + : params_(params), local_state_(std::move(local_state)) {} BrowserMainPartsImpl::~BrowserMainPartsImpl() = default; diff --git a/chromium/weblayer/browser/browser_main_parts_impl.h b/chromium/weblayer/browser/browser_main_parts_impl.h index 1238ecef804..f73b83378e4 100644 --- a/chromium/weblayer/browser/browser_main_parts_impl.h +++ b/chromium/weblayer/browser/browser_main_parts_impl.h @@ -33,7 +33,6 @@ struct MainParams; class BrowserMainPartsImpl : public content::BrowserMainParts { public: BrowserMainPartsImpl(MainParams* params, - content::MainFunctionParams main_function_params, std::unique_ptr<PrefService> local_state); BrowserMainPartsImpl(const BrowserMainPartsImpl&) = delete; @@ -62,9 +61,6 @@ class BrowserMainPartsImpl : public content::BrowserMainParts { std::unique_ptr<crash_reporter::ChildExitObserver> child_exit_observer_; #endif // BUILDFLAG(IS_ANDROID) - // For running weblayer_browsertests. - content::MainFunctionParams main_function_params_; - // Ownership of this moves to BrowserProcess. See // ContentBrowserClientImpl::local_state_ for details. std::unique_ptr<PrefService> local_state_; diff --git a/chromium/weblayer/browser/client_hints_browsertest.cc b/chromium/weblayer/browser/client_hints_browsertest.cc index 3ea034fa635..f72494a893e 100644 --- a/chromium/weblayer/browser/client_hints_browsertest.cc +++ b/chromium/weblayer/browser/client_hints_browsertest.cc @@ -65,7 +65,7 @@ class ClientHintsBrowserTest : public WebLayerBrowserTest { content::RenderProcessHost* child_process = static_cast<TabImpl*>(shell()->tab()) ->web_contents() - ->GetMainFrame() + ->GetPrimaryMainFrame() ->GetProcess(); content::RenderProcessHostWatcher crash_observer( child_process, diff --git a/chromium/weblayer/browser/content_browser_client_impl.cc b/chromium/weblayer/browser/content_browser_client_impl.cc index 2df6361d277..214354fffe0 100644 --- a/chromium/weblayer/browser/content_browser_client_impl.cc +++ b/chromium/weblayer/browser/content_browser_client_impl.cc @@ -4,6 +4,7 @@ #include "weblayer/browser/content_browser_client_impl.h" +#include <memory> #include <utility> #include "base/command_line.h" @@ -80,6 +81,7 @@ #include "services/network/public/mojom/network_service.mojom.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/blink/public/common/loader/url_loader_throttle.h" +#include "third_party/blink/public/common/permissions/permission_utils.h" #include "third_party/blink/public/common/user_agent/user_agent_metadata.h" #include "third_party/blink/public/common/web_preferences/web_preferences.h" #include "ui/base/l10n/l10n_util.h" @@ -309,13 +311,12 @@ ContentBrowserClientImpl::~ContentBrowserClientImpl() = default; std::unique_ptr<content::BrowserMainParts> ContentBrowserClientImpl::CreateBrowserMainParts( - content::MainFunctionParams parameters) { + bool /* is_integration_test */) { // This should be called after CreateFeatureListAndFieldTrials(), which // creates |local_state_|. DCHECK(local_state_); std::unique_ptr<BrowserMainPartsImpl> browser_main_parts = - std::make_unique<BrowserMainPartsImpl>(params_, std::move(parameters), - std::move(local_state_)); + std::make_unique<BrowserMainPartsImpl>(params_, std::move(local_state_)); return browser_main_parts; } @@ -392,12 +393,12 @@ bool ContentBrowserClientImpl::AllowWorkerWebLocks( url, CookieSettingsFactory::GetForBrowserContext(browser_context).get()); } -content::WebContentsViewDelegate* +std::unique_ptr<content::WebContentsViewDelegate> ContentBrowserClientImpl::GetWebContentsViewDelegate( content::WebContents* web_contents) { performance_manager::PerformanceManagerRegistry::GetInstance() ->MaybeCreatePageNodeForWebContents(web_contents); - return new WebContentsViewDelegateImpl(web_contents); + return std::make_unique<WebContentsViewDelegateImpl>(web_contents); } bool ContentBrowserClientImpl::CanShutdownGpuProcessNowOnIOThread() { @@ -1217,7 +1218,7 @@ bool ContentBrowserClientImpl::IsClipboardPasteAllowed( browser_context->GetPermissionController(); blink::mojom::PermissionStatus status = permission_controller->GetPermissionStatusForCurrentDocument( - content::PermissionType::CLIPBOARD_READ_WRITE, render_frame_host); + blink::PermissionType::CLIPBOARD_READ_WRITE, render_frame_host); if (!render_frame_host->HasTransientUserActivation() && status != blink::mojom::PermissionStatus::GRANTED) { diff --git a/chromium/weblayer/browser/content_browser_client_impl.h b/chromium/weblayer/browser/content_browser_client_impl.h index b4149623bad..bde0818adc6 100644 --- a/chromium/weblayer/browser/content_browser_client_impl.h +++ b/chromium/weblayer/browser/content_browser_client_impl.h @@ -50,7 +50,7 @@ class ContentBrowserClientImpl : public content::ContentBrowserClient { // ContentBrowserClient overrides. std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts( - content::MainFunctionParams parameters) override; + bool is_integration_test) override; std::string GetApplicationLocale() override; std::string GetAcceptLangs(content::BrowserContext* context) override; content::AllowServiceWorkerResult AllowServiceWorker( @@ -85,7 +85,7 @@ class ContentBrowserClientImpl : public content::ContentBrowserClient { content::BrowserContext* browser_context, const std::vector<content::GlobalRenderFrameHostId>& render_frames) override; - content::WebContentsViewDelegate* GetWebContentsViewDelegate( + std::unique_ptr<content::WebContentsViewDelegate> GetWebContentsViewDelegate( content::WebContents* web_contents) override; bool CanShutdownGpuProcessNowOnIOThread() override; std::unique_ptr<content::DevToolsManagerDelegate> diff --git a/chromium/weblayer/browser/cookie_manager_impl.cc b/chromium/weblayer/browser/cookie_manager_impl.cc index 9a2510f7126..5e2352d6859 100644 --- a/chromium/weblayer/browser/cookie_manager_impl.cc +++ b/chromium/weblayer/browser/cookie_manager_impl.cc @@ -211,9 +211,8 @@ bool CookieManagerImpl::FireFlushTimerForTesting() { bool CookieManagerImpl::SetCookieInternal(const GURL& url, const std::string& value, SetCookieCallback callback) { - auto cc = - net::CanonicalCookie::Create(url, value, base::Time::Now(), absl::nullopt, - net::CookiePartitionKey::Todo()); + auto cc = net::CanonicalCookie::Create(url, value, base::Time::Now(), + absl::nullopt, absl::nullopt); if (!cc) { return false; } diff --git a/chromium/weblayer/browser/download_manager_delegate_impl.cc b/chromium/weblayer/browser/download_manager_delegate_impl.cc index e74bfa971c9..ff8e7a70a88 100644 --- a/chromium/weblayer/browser/download_manager_delegate_impl.cc +++ b/chromium/weblayer/browser/download_manager_delegate_impl.cc @@ -91,7 +91,7 @@ bool DownloadManagerDelegateImpl::DetermineDownloadTarget( download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, download::DownloadItem::MixedContentStatus::UNKNOWN, item->GetForcedFilePath(), base::FilePath(), - absl::nullopt /*download_schedule*/, + std::string() /*mime_type*/, absl::nullopt /*download_schedule*/, download::DOWNLOAD_INTERRUPT_REASON_NONE); return true; } @@ -263,7 +263,8 @@ void DownloadManagerDelegateImpl::OnDownloadPathGenerated( download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, download::DownloadItem::MixedContentStatus::UNKNOWN, suggested_path.AddExtension(FILE_PATH_LITERAL(".crdownload")), - base::FilePath(), absl::nullopt /*download_schedule*/, + base::FilePath(), std::string() /*mime_type*/, + absl::nullopt /*download_schedule*/, download::DOWNLOAD_INTERRUPT_REASON_NONE); } diff --git a/chromium/weblayer/browser/favicon/favicon_tab_helper.cc b/chromium/weblayer/browser/favicon/favicon_tab_helper.cc index ff075d26523..ccb2eac3ca3 100644 --- a/chromium/weblayer/browser/favicon/favicon_tab_helper.cc +++ b/chromium/weblayer/browser/favicon/favicon_tab_helper.cc @@ -104,18 +104,10 @@ void FaviconTabHelper::OnFaviconUpdated( delegate.OnFaviconChanged(favicon_); } -void FaviconTabHelper::DidFinishNavigation( - content::NavigationHandle* navigation_handle) { - // TODO(https://crbug.com/1218946): With MPArch there may be multiple main - // frames. This caller was converted automatically to the primary main frame - // to preserve its semantics. Follow up to confirm correctness. - if (!navigation_handle->IsInPrimaryMainFrame() || - !navigation_handle->HasCommitted() || navigation_handle->IsErrorPage() || - navigation_handle->IsSameDocument()) { +void FaviconTabHelper::PrimaryPageChanged(content::Page& page) { + if (page.GetMainDocument().IsErrorDocument() || favicon_.IsEmpty()) { return; } - if (favicon_.IsEmpty()) - return; favicon_ = gfx::Image(); for (FaviconFetcherDelegate& delegate : delegates_) diff --git a/chromium/weblayer/browser/favicon/favicon_tab_helper.h b/chromium/weblayer/browser/favicon/favicon_tab_helper.h index 1f44c66c1a3..5ff23818980 100644 --- a/chromium/weblayer/browser/favicon/favicon_tab_helper.h +++ b/chromium/weblayer/browser/favicon/favicon_tab_helper.h @@ -71,8 +71,7 @@ class FaviconTabHelper : public content::WebContentsUserData<FaviconTabHelper>, const gfx::Image& image) override; // content::WebContentsObserver: - void DidFinishNavigation( - content::NavigationHandle* navigation_handle) override; + void PrimaryPageChanged(content::Page& page) override; raw_ptr<content::WebContents> web_contents_; // Number of observers attached. diff --git a/chromium/weblayer/browser/feature_list_creator.cc b/chromium/weblayer/browser/feature_list_creator.cc index 76adcf86ce5..70304626019 100644 --- a/chromium/weblayer/browser/feature_list_creator.cc +++ b/chromium/weblayer/browser/feature_list_creator.cc @@ -5,6 +5,7 @@ #include "weblayer/browser/feature_list_creator.h" #include "base/base_switches.h" +#include "base/command_line.h" #include "build/build_config.h" #include "components/metrics/metrics_state_manager.h" #include "components/prefs/pref_service.h" @@ -55,6 +56,36 @@ void FeatureListCreator::SetSystemNetworkContextManager( system_network_context_manager_ = system_network_context_manager; } +void FeatureListCreator::CreateFeatureListAndFieldTrials() { +#if BUILDFLAG(IS_ANDROID) + WebLayerMetricsServiceClient::GetInstance()->Initialize(local_state_); +#endif + SetUpFieldTrials(); +} + +void FeatureListCreator::PerformPreMainMessageLoopStartup() { +#if BUILDFLAG(IS_ANDROID) + // It is expected this is called after SetUpFieldTrials(). + DCHECK(variations_service_); + variations_service_->PerformPreMainMessageLoopStartup(); +#endif +} + +void FeatureListCreator::OnBrowserFragmentStarted() { + if (has_browser_fragment_started_) + return; + + has_browser_fragment_started_ = true; + // It is expected this is called after SetUpFieldTrials(). + DCHECK(variations_service_); + + // This function is called any time a BrowserFragment is started. + // OnAppEnterForeground() really need only be called once, and because our + // notion of a fragment doesn't really map to the Application as a whole, + // call this function once. + variations_service_->OnAppEnterForeground(); +} + void FeatureListCreator::SetUpFieldTrials() { #if BUILDFLAG(IS_ANDROID) // The FieldTrialList should have been instantiated in @@ -86,34 +117,4 @@ void FeatureListCreator::SetUpFieldTrials() { #endif } -void FeatureListCreator::CreateFeatureListAndFieldTrials() { -#if BUILDFLAG(IS_ANDROID) - WebLayerMetricsServiceClient::GetInstance()->Initialize(local_state_); -#endif - SetUpFieldTrials(); -} - -void FeatureListCreator::PerformPreMainMessageLoopStartup() { -#if BUILDFLAG(IS_ANDROID) - // It is expected this is called after SetUpFieldTrials(). - DCHECK(variations_service_); - variations_service_->PerformPreMainMessageLoopStartup(); -#endif -} - -void FeatureListCreator::OnBrowserFragmentStarted() { - if (has_browser_fragment_started_) - return; - - has_browser_fragment_started_ = true; - // It is expected this is called after SetUpFieldTrials(). - DCHECK(variations_service_); - - // This function is called any time a BrowserFragment is started. - // OnAppEnterForeground() really need only be called once, and because our - // notion of a fragment doesn't really map to the Application as a whole, - // call this function once. - variations_service_->OnAppEnterForeground(); -} - } // namespace weblayer diff --git a/chromium/weblayer/browser/google_accounts_browsertest.cc b/chromium/weblayer/browser/google_accounts_browsertest.cc index 47995f8e687..6687fda8dbf 100644 --- a/chromium/weblayer/browser/google_accounts_browsertest.cc +++ b/chromium/weblayer/browser/google_accounts_browsertest.cc @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/strings/escape.h" #include "base/strings/strcat.h" #include "components/signin/core/browser/signin_header_helper.h" #include "google_apis/gaia/gaia_switches.h" #include "google_apis/gaia/gaia_urls.h" -#include "net/base/escape.h" #include "net/base/url_util.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/default_handlers.h" @@ -100,7 +100,7 @@ class GoogleAccountsBrowserTest : public WebLayerBrowserTest, http_response->set_code(net::HTTP_MOVED_PERMANENTLY); http_response->AddCustomHeader( "Location", - net::UnescapeBinaryURLComponent(request.GetURL().query_piece())); + base::UnescapeBinaryURLComponent(request.GetURL().query_piece())); } else { http_response->set_code(net::HTTP_OK); } diff --git a/chromium/weblayer/browser/java/BUILD.gn b/chromium/weblayer/browser/java/BUILD.gn index e9a2f5a4b10..b4a9e6834e6 100644 --- a/chromium/weblayer/browser/java/BUILD.gn +++ b/chromium/weblayer/browser/java/BUILD.gn @@ -107,6 +107,8 @@ android_library("base_module_java") { ":base_module_interfaces_java", "$google_play_services_package:google_play_services_basement_java", "//base:base_java", + "//base:jni_java", + "//build/android:build_java", "//components/embedder_support/android:application_java", "//content/public/android:content_java", ] @@ -167,6 +169,9 @@ android_library("java") { "org/chromium/weblayer_private/TabImpl.java", "org/chromium/weblayer_private/TranslateCompactInfoBar.java", "org/chromium/weblayer_private/UrlBarControllerImpl.java", + "org/chromium/weblayer_private/WebApkInstallSchedulerBridge.java", + "org/chromium/weblayer_private/WebApkInstallSchedulerClient.java", + "org/chromium/weblayer_private/WebApkServiceConnection.java", "org/chromium/weblayer_private/WebContentsGestureStateTracker.java", "org/chromium/weblayer_private/WebLayerAccessibilityUtil.java", "org/chromium/weblayer_private/WebLayerExceptionFilter.java", @@ -178,8 +183,10 @@ android_library("java") { "org/chromium/weblayer_private/WebMessageReplyProxyImpl.java", "org/chromium/weblayer_private/WebShareServiceFactory.java", "org/chromium/weblayer_private/WebappsHelper.java", + "org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantBrowserControls.java", "org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantDependencies.java", "org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantStaticDependencies.java", + "org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantTabChangeObserver.java", "org/chromium/weblayer_private/bluetooth/WebLayerBluetoothChooserAndroidDelegate.java", "org/chromium/weblayer_private/bluetooth/WebLayerBluetoothScanningPromptAndroidDelegate.java", "org/chromium/weblayer_private/media/MediaRouteDialogFragmentImpl.java", @@ -208,6 +215,8 @@ android_library("java") { ":weblayer_bundle_utils", ":weblayer_resources", "//base:base_java", + "//base:jni_java", + "//build/android:build_java", "//cc:cc_java", "//components/android_autofill/browser:java", "//components/autofill_assistant/android:public_dependencies_java", @@ -245,6 +254,7 @@ android_library("java") { "//components/embedder_support/android:application_java", "//components/embedder_support/android:content_view_java", "//components/embedder_support/android:context_menu_java", + "//components/embedder_support/android:simple_factory_key_java", "//components/embedder_support/android:util_java", "//components/embedder_support/android:web_contents_delegate_java", "//components/embedder_support/android/metrics:java", @@ -282,7 +292,9 @@ android_library("java") { "//components/user_prefs/android:java", "//components/variations/android:variations_java", "//components/version_info/android:version_constants_java", + "//components/webapk/android/libs/client:java", "//components/webapps/browser/android:java", + "//components/webapps/common/android:webapk_install_java", "//components/webauthn/android:java", "//components/webrtc/android:java", "//content/public/android:content_java", @@ -370,7 +382,8 @@ android_library("test_java") { ":java", ":test_interfaces_java", ":weblayer_test_resources", - "//base:base_java", + "//base:jni_java", + "//build/android:build_java", "//components/android_autofill/browser:java", "//components/android_autofill/browser/test_support:component_autofill_provider_java_test_support", "//components/browser_ui/accessibility/android:java", @@ -401,7 +414,6 @@ android_library("junit_test_support") { testonly = true deps = [ ":java", - "//base:base_java", "//components/payments/content/android:java", "//components/payments/content/android:junit_test_support", "//components/payments/content/android:service_java", @@ -430,7 +442,6 @@ junit_binary("weblayer_junit_tests") { deps = [ ":java", ":junit_test_support", - "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", "//components/payments/content/android:java", @@ -495,6 +506,7 @@ generate_jni("jni") { "org/chromium/weblayer_private/TabImpl.java", "org/chromium/weblayer_private/TranslateCompactInfoBar.java", "org/chromium/weblayer_private/UrlBarControllerImpl.java", + "org/chromium/weblayer_private/WebApkInstallSchedulerBridge.java", "org/chromium/weblayer_private/WebLayerExceptionFilter.java", "org/chromium/weblayer_private/WebLayerFactoryImpl.java", "org/chromium/weblayer_private/WebLayerImpl.java", diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java index c1faa3b0eda..f3eb434b15f 100644 --- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java @@ -190,7 +190,8 @@ public final class BrowserViewController mBottomSheetController = BottomSheetControllerFactory.createBottomSheetController( () -> mScrim, (v) -> {}, ContextUtils.activityFromContext(context).getWindow(), - KeyboardVisibilityDelegate.getInstance(), () -> mBottomSheetContainer); + KeyboardVisibilityDelegate.getInstance(), () -> mBottomSheetContainer, + () -> mContentViewRenderView.getHeight()); BottomSheetControllerFactory.attach(mWindowAndroid, mBottomSheetController); mPwaBottomSheetController = PwaBottomSheetControllerFactory.createPwaBottomSheetController( diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java index 40bcb18cc19..5b76ecfde73 100644 --- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java @@ -62,7 +62,7 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat @Override public void dispatchAuthenticatedIntent(Intent intent) { // This method should never be invoked in WebLayer as this class always returns false for - // isIntentToInstantApp(). + // handlesInstantAppLaunchingInternally(). assert false; } @@ -181,11 +181,6 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat } @Override - public boolean isIntentToInstantApp(Intent intent) { - return false; - } - - @Override public boolean isIntentToAutofillAssistant(Intent intent) { return false; } diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java index c49a5862873..3723120fcf2 100644 --- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java @@ -63,6 +63,7 @@ import org.chromium.content_public.browser.WebContentsObserver; import org.chromium.ui.base.ViewAndroidDelegate; import org.chromium.ui.base.WindowAndroid; import org.chromium.url.GURL; +import org.chromium.weblayer_private.autofill_assistant.WebLayerAssistantTabChangeObserver; import org.chromium.weblayer_private.interfaces.APICallException; import org.chromium.weblayer_private.interfaces.IContextMenuParams; import org.chromium.weblayer_private.interfaces.IErrorPageCallbackClient; @@ -152,6 +153,9 @@ public final class TabImpl extends ITab.Stub { private WebLayerAccessibilityUtil.Observer mAccessibilityObserver; + private final WebLayerAssistantTabChangeObserver mWebLayerAssistantTabChangeObserver = + new WebLayerAssistantTabChangeObserver(); + private Set<FaviconCallbackProxy> mFaviconCallbackProxies = new HashSet<>(); // Only non-null if scroll offsets have been requested. @@ -354,7 +358,7 @@ public final class TabImpl extends ITab.Stub { * Sets the BrowserImpl this TabImpl is contained in. */ public void attachToBrowser(BrowserImpl browser) { - // NOTE: during tab creation this is called with |mBrowser| set to |browser|. This happens + // NOTE: during tab creation this is called with |browser| set to |mBrowser|. This happens // because the tab is created with |mBrowser| already set (to avoid having a bunch of null // checks). mBrowser = browser; @@ -399,6 +403,8 @@ public final class TabImpl extends ITab.Stub { new AutofillActionModeCallback(mBrowser.getContext(), mAutofillProvider)); } } + + mWebLayerAssistantTabChangeObserver.onBrowserAttachmentChanged(mWebContents); } @VisibleForTesting @@ -1001,6 +1007,8 @@ public final class TabImpl extends ITab.Stub { TabImplJni.get().removeTabFromBrowserBeforeDestroying(mNativeTab); + mWebLayerAssistantTabChangeObserver.onTabDestroyed(mWebContents); + // Notify the client that this instance is being destroyed to prevent it from calling // back into this object if the embedder mistakenly tries to do so. try { diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TranslateCompactInfoBar.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TranslateCompactInfoBar.java index 90844b919ec..6c1d8dbe391 100644 --- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TranslateCompactInfoBar.java +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TranslateCompactInfoBar.java @@ -206,13 +206,13 @@ public class TranslateCompactInfoBar extends InfoBar switch (menuType) { case TranslateMenu.MENU_OVERFLOW: mOverflowMenuHelper = new TranslateMenuHelper(getContext(), mMenuButton, mOptions, - this, isIncognito, isSourceLangUnknown); + this, isIncognito, isSourceLangUnknown, () -> null); return; case TranslateMenu.MENU_TARGET_LANGUAGE: case TranslateMenu.MENU_SOURCE_LANGUAGE: if (mLanguageMenuHelper == null) { mLanguageMenuHelper = new TranslateMenuHelper(getContext(), mMenuButton, - mOptions, this, isIncognito, isSourceLangUnknown); + mOptions, this, isIncognito, isSourceLangUnknown, () -> null); } return; default: diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebApkInstallSchedulerBridge.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebApkInstallSchedulerBridge.java new file mode 100644 index 00000000000..1c4d13af83d --- /dev/null +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebApkInstallSchedulerBridge.java @@ -0,0 +1,74 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.weblayer_private; + +import android.graphics.Bitmap; + +import org.chromium.base.Callback; +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; +import org.chromium.components.webapps.WebApkInstallResult; + +/** + * Java counterpart to webapk_install_scheduler_bridge. + * Contains functionality to schedule WebAPK installs with the {@link + * WebApkInstallCoordinatorService} in Chrome. This Java object is created by and owned by the + * native WebApkInstallSchedulerBridge. + */ +@JNINamespace("weblayer") +public class WebApkInstallSchedulerBridge { + // Raw pointer to the native WebApkInstallSchedulerBridge that is cleared when the native object + // destroys this object. + private long mNativePointer; + + /** + * This callback is passed via the {@link WebApkInstallSchedulerClient} to the Chrome + * {@link WebApkInstallCoordinatorService} and will be called from there with the result + * of the install. This result is passed along to the native side. + */ + Callback<Integer> mOnInstallCompleteCallback = (result) -> { + if (mNativePointer != 0) { + WebApkInstallSchedulerBridgeJni.get().onInstallFinished( + mNativePointer, WebApkInstallSchedulerBridge.this, result); + } + }; + + private WebApkInstallSchedulerBridge(long nativePtr) { + mNativePointer = nativePtr; + } + + @CalledByNative + private static WebApkInstallSchedulerBridge create(long nativePtr) { + return new WebApkInstallSchedulerBridge(nativePtr); + } + + @CalledByNative + public void scheduleInstall( + byte[] apkProto, Bitmap primaryIcon, boolean isPrimaryIconMaskable) { + WebApkInstallSchedulerClient.scheduleInstall( + apkProto, primaryIcon, isPrimaryIconMaskable, mOnInstallCompleteCallback); + } + + /** + * Returns if the {@link WebApkInstallCoordinatorService} is available. + */ + @CalledByNative + public static boolean isInstallServiceAvailable() { + return WebApkInstallSchedulerClient.isInstallServiceAvailable(); + } + + @CalledByNative + private void destroy() { + // Remove the reference to the native side. + mNativePointer = 0; + } + + @NativeMethods + interface Natives { + void onInstallFinished(long nativeWebApkInstallSchedulerBridge, + WebApkInstallSchedulerBridge caller, @WebApkInstallResult int result); + } +} diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebApkInstallSchedulerClient.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebApkInstallSchedulerClient.java new file mode 100644 index 00000000000..5cce0992589 --- /dev/null +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebApkInstallSchedulerClient.java @@ -0,0 +1,102 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.weblayer_private; + +import android.graphics.Bitmap; +import android.os.RemoteException; + +import androidx.annotation.BinderThread; +import androidx.annotation.MainThread; + +import org.chromium.base.Callback; +import org.chromium.base.Log; +import org.chromium.base.Promise; +import org.chromium.base.task.PostTask; +import org.chromium.components.webapk_install.IOnFinishInstallCallback; +import org.chromium.components.webapk_install.IWebApkInstallCoordinatorService; +import org.chromium.components.webapps.WebApkInstallResult; +import org.chromium.content_public.browser.UiThreadTaskTraits; + +/** + * Contains functionality to connect to the {@link WebApkInstallCoordinatorService} in Chrome using + * the {@link WebApkServiceConnection}, schedule the install of one WebAPK and receive the install + * result via the {@link IOnFinishInstallCallback}. + */ +public class WebApkInstallSchedulerClient { + private static final String TAG = "WebApkInstallClient"; + + /** + * Casts an int to {@link WebApkInstallResult}. + */ + public @WebApkInstallResult static int asWebApkInstallResult(int webApkInstallResult) { + return webApkInstallResult; + } + + @MainThread + Promise<Integer> startInstallTask(byte[] apkProto, Bitmap primaryIcon, + boolean isPrimaryIconMaskable, IWebApkInstallCoordinatorService serviceInterface) { + Promise<Integer> whenInstallTaskCompleted = new Promise<>(); + IOnFinishInstallCallback.Stub serviceCallback = new IOnFinishInstallCallback.Stub() { + @Override + @BinderThread + public void handleOnFinishInstall(int result) { + // Post the task back to the main thread as promises have to be accessed from a + // single thread. + PostTask.postTask(UiThreadTaskTraits.DEFAULT, + () -> { whenInstallTaskCompleted.fulfill(result); }); + } + }; + + try { + serviceInterface.scheduleInstallAsync( + apkProto, primaryIcon, isPrimaryIconMaskable, serviceCallback); + } catch (RemoteException e) { + Log.w(TAG, "Failed to schedule install with Chrome WebAPK install service.", e); + whenInstallTaskCompleted.reject(); + } + + return whenInstallTaskCompleted; + } + + /** + * Schedules the install of one WebAPK with Chrome's {@link WebApkInstallCoordinatorService}. + * The {@code onInstallFinishedCallback} is triggered when the install finished or failed. + */ + @MainThread + public static void scheduleInstall(byte[] apkProto, Bitmap primaryIcon, + boolean isPrimaryIconMaskable, Callback<Integer> onInstallFinishedCallback) { + WebApkInstallSchedulerClient client = new WebApkInstallSchedulerClient(); + + WebApkServiceConnection webApkServiceConnection = new WebApkServiceConnection(); + Promise<IWebApkInstallCoordinatorService> whenServiceConnected = + webApkServiceConnection.connect(); + whenServiceConnected + .then( + /*fulfilled */ + (IWebApkInstallCoordinatorService serviceInterface) + -> client.startInstallTask(apkProto, primaryIcon, + isPrimaryIconMaskable, serviceInterface)) + .then( + /*fulfilled */ + installResult + -> { + webApkServiceConnection.unbindIfNeeded(); + onInstallFinishedCallback.onResult( + asWebApkInstallResult(installResult)); + }, + /*rejected*/ + err -> { + webApkServiceConnection.unbindIfNeeded(); + onInstallFinishedCallback.onResult(WebApkInstallResult.FAILURE); + }); + } + + /** + * Returns if the {@link WebApkInstallCoordinatorService} is available. + */ + public static boolean isInstallServiceAvailable() { + return WebApkServiceConnection.isInstallServiceAvailable(); + } +} diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebApkServiceConnection.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebApkServiceConnection.java new file mode 100644 index 00000000000..35d83891b63 --- /dev/null +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebApkServiceConnection.java @@ -0,0 +1,107 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.weblayer_private; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.pm.ResolveInfo; +import android.os.IBinder; + +import org.chromium.base.ContextUtils; +import org.chromium.base.Log; +import org.chromium.base.Promise; +import org.chromium.components.webapk_install.IWebApkInstallCoordinatorService; + +/** + * Service Connection to the {@link WebApkInstallCoordinatorService} in Chrome. + */ +class WebApkServiceConnection implements ServiceConnection { + private static final String TAG = "WebApkServiceConn"; + + private static final String BIND_WEBAPK_SCHEDULE_INSTALL_INTENT_ACTION = + "org.chromium.intent.action.INSTALL_WEB_APK"; + + // TODO(swestphal): set package name of production chrome apk + private static final String CHROME_PACKAGE_NAME = "com.google.android.apps.chrome"; + + private Context mContext; + private boolean mIsBound; + // The promise is fulfilled as soon as the connection is established, it will then provide the + // {@link IWebApkInstallCoordinatorService}. It will be rejected if the connection to the + // service cannot be established. Retrieve the {@code mPromiseServiceInterface} by calling + // {@link connect()}. + Promise<IWebApkInstallCoordinatorService> mPromiseServiceInterface; + + WebApkServiceConnection() { + mContext = ContextUtils.getApplicationContext(); + mPromiseServiceInterface = new Promise<>(); + } + + private static Intent createChromeInstallServiceIntent() { + Intent intent = new Intent(BIND_WEBAPK_SCHEDULE_INSTALL_INTENT_ACTION); + intent.setPackage(CHROME_PACKAGE_NAME); + return intent; + } + + /** + * Tries to bind to the service, returns a promise which will be fulfilled as + * soon as the connection is established or rejected in the failure case. + * This function must only be called once. + */ + Promise<IWebApkInstallCoordinatorService> connect() { + Intent intent = createChromeInstallServiceIntent(); + + try { + mIsBound = mContext.bindService(intent, this, Context.BIND_AUTO_CREATE); + if (!mIsBound) { + Log.w(TAG, "Failed to bind to Chrome install service."); + mPromiseServiceInterface.reject(); + } + } catch (SecurityException e) { + Log.w(TAG, "SecurityException while binding to Chrome install service.", e); + mPromiseServiceInterface.reject(); + } + + return mPromiseServiceInterface; + } + + /** + * Unbinds the service connection if it is currently bound. + */ + void unbindIfNeeded() { + if (mIsBound) { + mContext.unbindService(this); + } + mIsBound = false; + } + + /** + * Returns if the {@link WebApkInstallCoordinatorService} is available. + */ + public static boolean isInstallServiceAvailable() { + ResolveInfo info = ContextUtils.getApplicationContext().getPackageManager().resolveService( + createChromeInstallServiceIntent(), 0); + return info != null; + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + IWebApkInstallCoordinatorService serviceInterface = + IWebApkInstallCoordinatorService.Stub.asInterface(service); + + mPromiseServiceInterface.fulfill(serviceInterface); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + if (!mPromiseServiceInterface.isFulfilled() && !mPromiseServiceInterface.isRejected()) { + mPromiseServiceInterface.reject(); + } + // Called when the Service closes the connection so we still might need to unbind. + unbindIfNeeded(); + } +} diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java index e7756831a6c..e632f4d7b16 100644 --- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java @@ -66,6 +66,8 @@ import org.chromium.components.component_updater.EmbeddedComponentLoader; import org.chromium.components.embedder_support.application.ClassLoaderContextWrapperFactory; import org.chromium.components.embedder_support.application.FirebaseConfig; import org.chromium.components.payments.PaymentDetailsUpdateService; +import org.chromium.components.webapk.lib.client.ChromeWebApkHostSignature; +import org.chromium.components.webapk.lib.client.WebApkValidator; import org.chromium.content_public.browser.BrowserStartupController; import org.chromium.content_public.browser.ChildProcessCreationParams; import org.chromium.content_public.browser.ChildProcessLauncherHelper; @@ -299,6 +301,9 @@ public final class WebLayerImpl extends IWebLayer.Stub { /*readCommandLine=*/true); TraceEvent.begin("WebLayer init"); + WebApkValidator.init( + ChromeWebApkHostSignature.EXPECTED_SIGNATURE, ChromeWebApkHostSignature.PUBLIC_KEY); + BuildInfo.setBrowserPackageInfo(packageInfo); BuildInfo.setFirebaseAppId( FirebaseConfig.getFirebaseAppIdForPackage(packageInfo.packageName)); diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantBrowserControls.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantBrowserControls.java new file mode 100644 index 00000000000..37e4f18857a --- /dev/null +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantBrowserControls.java @@ -0,0 +1,55 @@ + +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.weblayer_private.autofill_assistant; + +import org.chromium.components.autofill_assistant.AssistantBrowserControls; + +/** + * Implementation of {@link AssistantBrowserControls} for WebLayer. + */ +public class WebLayerAssistantBrowserControls implements AssistantBrowserControls { + private AssistantBrowserControls.Observer mObserver; + + @Override + public int getBottomControlsHeight() { + // TODO(b/222671580): Implement + return 0; + } + + @Override + public int getBottomControlOffset() { + // TODO(b/222671580): Implement + return 0; + } + + @Override + public int getContentOffset() { + // TODO(b/222671580): Implement + return 0; + } + + @Override + public float getTopVisibleContentOffset() { + // TODO(b/222671580): Implement + return 0; + } + + @Override + public void setObserver(AssistantBrowserControls.Observer browserControlsObserver) { + mObserver = browserControlsObserver; + } + + @Override + public void destroy() {} + + public void onControlsOffsetChanged() { + mObserver.onControlsOffsetChanged(); + } + + public void onBottomControlsHeightChanged() { + mObserver.onBottomControlsHeightChanged(); + } +} diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantDependencies.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantDependencies.java index cdf282349fa..22786c01ed6 100644 --- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantDependencies.java +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantDependencies.java @@ -8,12 +8,15 @@ import android.app.Activity; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.Nullable; + import org.chromium.base.lifetime.Destroyable; import org.chromium.components.autofill_assistant.AssistantBrowserControlsFactory; import org.chromium.components.autofill_assistant.AssistantDependencies; import org.chromium.components.autofill_assistant.AssistantSnackbarFactory; import org.chromium.components.autofill_assistant.AssistantTabChangeObserver; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.KeyboardVisibilityDelegate; import org.chromium.ui.base.ApplicationViewportInsetSupplier; @@ -24,50 +27,61 @@ import org.chromium.ui.base.WindowAndroid; */ public class WebLayerAssistantDependencies extends WebLayerAssistantStaticDependencies implements AssistantDependencies { - public WebLayerAssistantDependencies(Activity activity) { - maybeUpdateDependencies(activity); + public WebLayerAssistantDependencies(WebContents webContents, + WebLayerAssistantTabChangeObserver webLayerAssistantTabChangeObserver) { + super(webContents, webLayerAssistantTabChangeObserver); + maybeUpdateDependencies(webContents); } + /** + * Returns true if all dependencies are available. + */ @Override - public boolean maybeUpdateDependencies(Activity activity) { - // TODO(b/222671580): Implement - return true; + public boolean maybeUpdateDependencies(WebContents webContents) { + assert webContents == mWebContents; + return getWindowAndroid() != null && getActivity() != null; } @Override - public boolean maybeUpdateDependencies(WebContents webContents) { - // TODO(b/222671580): Implement - return true; + @Nullable + public WindowAndroid getWindowAndroid() { + return mWebContents.getTopLevelNativeWindow(); } @Override + @Nullable public Activity getActivity() { - // TODO(b/222671580): Implement - return null; - } + WindowAndroid windowAndroid = getWindowAndroid(); + if (windowAndroid == null) return null; - @Override - public WindowAndroid getWindowAndroid() { - // TODO(b/222671580): Implement - return null; + return windowAndroid.getActivity().get(); } @Override + @Nullable public BottomSheetController getBottomSheetController() { - // TODO(b/222671580): Implement - return null; + WindowAndroid windowAndroid = getWindowAndroid(); + if (windowAndroid == null) return null; + + return BottomSheetControllerProvider.from(windowAndroid); } @Override + @Nullable public KeyboardVisibilityDelegate getKeyboardVisibilityDelegate() { - // TODO(b/222671580): Implement - return null; + WindowAndroid windowAndroid = getWindowAndroid(); + if (windowAndroid == null) return null; + + return windowAndroid.getKeyboardDelegate(); } @Override + @Nullable public ApplicationViewportInsetSupplier getBottomInsetProvider() { - // TODO(b/222671580): Implement - return null; + WindowAndroid windowAndroid = getWindowAndroid(); + if (windowAndroid == null) return null; + + return windowAndroid.getApplicationBottomInsetProvider(); } @Override @@ -90,13 +104,12 @@ public class WebLayerAssistantDependencies @Override public AssistantBrowserControlsFactory createBrowserControlsFactory() { - // TODO(b/222671580): Implement - return null; + return () -> new WebLayerAssistantBrowserControls(); } @Override public Destroyable observeTabChanges(AssistantTabChangeObserver tabChangeObserver) { - // TODO(b/222671580): Implement - return null; + mWebLayerAssistantTabChangeObserver.addObserver(tabChangeObserver); + return () -> mWebLayerAssistantTabChangeObserver.removeObserver(tabChangeObserver); } } diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantStaticDependencies.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantStaticDependencies.java index a62499a12f0..d20ca076e6e 100644 --- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantStaticDependencies.java +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantStaticDependencies.java @@ -6,10 +6,12 @@ package org.chromium.weblayer_private.autofill_assistant; import android.app.Activity; import android.content.Context; +import android.os.RemoteException; import androidx.annotation.DimenRes; import androidx.annotation.Nullable; +import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; import org.chromium.components.autofill_assistant.AssistantAccessTokenUtil; @@ -22,27 +24,47 @@ import org.chromium.components.autofill_assistant.AssistantSettingsUtil; import org.chromium.components.autofill_assistant.AssistantStaticDependencies; import org.chromium.components.autofill_assistant.AssistantTabObscuringUtil; import org.chromium.components.autofill_assistant.AssistantTabUtil; +import org.chromium.components.embedder_support.simple_factory_key.SimpleFactoryKeyHandle; import org.chromium.components.favicon.LargeIconBridge; import org.chromium.components.image_fetcher.ImageFetcher; +import org.chromium.components.image_fetcher.ImageFetcherConfig; +import org.chromium.components.image_fetcher.ImageFetcherFactory; import org.chromium.content_public.browser.BrowserContextHandle; +import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.util.AccessibilityUtil; +import org.chromium.weblayer_private.ProfileImpl; import org.chromium.weblayer_private.WebLayerAccessibilityUtil; +import org.chromium.weblayer_private.interfaces.IUserIdentityCallbackClient; /** * Provides default implementations of {@link AssistantStaticDependencies} for WebLayer. */ @JNINamespace("weblayer") -public class WebLayerAssistantStaticDependencies implements AssistantStaticDependencies { +public class WebLayerAssistantStaticDependencies + implements AssistantStaticDependencies, SimpleFactoryKeyHandle { + protected final WebContents mWebContents; + protected final WebLayerAssistantTabChangeObserver mWebLayerAssistantTabChangeObserver; + + // There exists one instance of this class per WebContents and per TabImpl. + WebLayerAssistantStaticDependencies(WebContents webContents, + WebLayerAssistantTabChangeObserver webLayerAssistantTabChangeObserver) { + mWebContents = webContents; + mWebLayerAssistantTabChangeObserver = webLayerAssistantTabChangeObserver; + } + + // AssistantStaticDependencies implementation: + @Override public long createNative() { return WebLayerAssistantStaticDependenciesJni.get().init( - new WebLayerAssistantStaticDependencies()); + new WebLayerAssistantStaticDependencies( + mWebContents, mWebLayerAssistantTabChangeObserver)); } @Override public AssistantDependencies createDependencies(Activity activity) { - return new WebLayerAssistantDependencies(activity); + return new WebLayerAssistantDependencies(mWebContents, mWebLayerAssistantTabChangeObserver); } @Override @@ -71,8 +93,8 @@ public class WebLayerAssistantStaticDependencies implements AssistantStaticDepen @Override public AssistantTabUtil createTabUtil() { - // TODO(b/222671580): Implement - return null; + // This method should do nothing under WebLayer as it is only used to close CCTs in Chrome. + return (activity) -> {}; } @Override @@ -89,27 +111,29 @@ public class WebLayerAssistantStaticDependencies implements AssistantStaticDepen @Override public BrowserContextHandle getBrowserContext() { - // TODO(b/222671580): Implement - return null; + return WebLayerAssistantStaticDependenciesJni.get().getJavaProfile(mWebContents); } @Override public ImageFetcher createImageFetcher() { - // TODO(b/222671580): Implement - return null; + return ImageFetcherFactory.createImageFetcher(ImageFetcherConfig.DISK_CACHE_ONLY, this); } @Override public LargeIconBridge createIconBridge() { - // TODO(b/222671580): Implement - return null; + BrowserContextHandle browserContext = getBrowserContext(); + if (browserContext == null) return null; + + return new LargeIconBridge(getBrowserContext()); } - @Override @Nullable - public String getSignedInAccountEmailOrNull() { - // TODO(b/222671580): Implement - return null; + @CalledByNative + private String getEmailOrNull(ProfileImpl profile) throws RemoteException { + IUserIdentityCallbackClient userIdentityCallback = profile.getUserIdentityCallbackClient(); + if (userIdentityCallback == null) return null; + + return userIdentityCallback.getEmail(); } @Override @@ -121,13 +145,32 @@ public class WebLayerAssistantStaticDependencies implements AssistantStaticDepen } @Override + @Nullable public AssistantEditorFactory createEditorFactory() { - // TODO(b/222671580): Implement + // This factory should not be used in a WebLayer context. All code paths leading to the + // use of this factory point to a misconfiguration. For WebLayer, the external editors + // should be used. return null; } + // SimpleFactoryKeyHandle implementation: + + @Override + public long getNativeSimpleFactoryKeyPointer() { + BrowserContextHandle browserContext = getBrowserContext(); + if (browserContext == null) return 0; + long nativeBrowserContextPointer = browserContext.getNativeBrowserContextPointer(); + if (nativeBrowserContextPointer == 0) return 0; + return WebLayerAssistantStaticDependenciesJni.get().getSimpleFactoryKey( + nativeBrowserContextPointer); + } + @NativeMethods interface Natives { long init(AssistantStaticDependencies staticDependencies); + + ProfileImpl getJavaProfile(WebContents webContents); + + long getSimpleFactoryKey(long browserContext); } } diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantTabChangeObserver.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantTabChangeObserver.java new file mode 100644 index 00000000000..30663c0f033 --- /dev/null +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantTabChangeObserver.java @@ -0,0 +1,43 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.weblayer_private.autofill_assistant; + +import org.chromium.base.ObserverList; +import org.chromium.components.autofill_assistant.AssistantTabChangeObserver; +import org.chromium.content_public.browser.WebContents; + +/** + * Notifies of changes to a WebLayer tab. + * The functions onContentChanged and onWebContentsSwapped are never called on WebLayer since the + * tab never changes WebContents. + */ +public class WebLayerAssistantTabChangeObserver { + private final ObserverList<AssistantTabChangeObserver> mTabChangeObservers = + new ObserverList<AssistantTabChangeObserver>(); + + // TODO(b/222671580): onObservingDifferentTab + // TODO(b/222671580): onInteractabilityChanged + + public void addObserver(AssistantTabChangeObserver tabChangeObserver) { + mTabChangeObservers.addObserver(tabChangeObserver); + } + + public void removeObserver(AssistantTabChangeObserver tabChangeObserver) { + mTabChangeObservers.removeObserver(tabChangeObserver); + } + + public void onBrowserAttachmentChanged(WebContents webContents) { + for (AssistantTabChangeObserver tabChangeObserver : mTabChangeObservers) { + tabChangeObserver.onActivityAttachmentChanged( + webContents, webContents.getTopLevelNativeWindow()); + } + } + + public void onTabDestroyed(WebContents webContents) { + for (AssistantTabChangeObserver tabChangeObserver : mTabChangeObservers) { + tabChangeObserver.onDestroyed(webContents); + } + } +} diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java index 082c675e3ed..23f8f61a4f2 100644 --- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java @@ -129,7 +129,7 @@ public class WebLayerPaymentRequestService implements BrowserPaymentRequest { // Implements BrowserPaymentRequest: @Override @Nullable - public String onShowCalledAndAppsQueriedAndDetailsFinalized(boolean isUserGestureShow) { + public String onShowCalledAndAppsQueriedAndDetailsFinalized() { assert !mAvailableApps.isEmpty() : "triggerPaymentAppUiSkipIfApplicable() should be called only when there is any " + "available app."; diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java index 632712937fd..bc50d513f50 100644 --- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java @@ -64,7 +64,6 @@ public class WebLayerPaymentRequestServiceTest { private PaymentRequestClient mClient; private PaymentAppFactoryInterface mFactory; private PaymentApp mPaymentApp; - private boolean mIsUserGesture; private boolean mWaitForUpdatedDetails; @Before @@ -119,7 +118,7 @@ public class WebLayerPaymentRequestServiceTest { } private void show(PaymentRequest request) { - request.show(mIsUserGesture, mWaitForUpdatedDetails); + request.show(mWaitForUpdatedDetails); } private void assertNoError() { diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerAccessibilitySettingsDelegate.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerAccessibilitySettingsDelegate.java index 30ddfe73a35..dca56b11fac 100644 --- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerAccessibilitySettingsDelegate.java +++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerAccessibilitySettingsDelegate.java @@ -35,4 +35,9 @@ public class WebLayerAccessibilitySettingsDelegate implements AccessibilitySetti @Override public void addExtraPreferences(PreferenceFragmentCompat fragment) {} + + @Override + public boolean showPageZoomSettingsUI() { + return false; + } } diff --git a/chromium/weblayer/browser/js_communication/web_message_browsertest.cc b/chromium/weblayer/browser/js_communication/web_message_browsertest.cc index cdfdfde1fe1..49ed8e48637 100644 --- a/chromium/weblayer/browser/js_communication/web_message_browsertest.cc +++ b/chromium/weblayer/browser/js_communication/web_message_browsertest.cc @@ -67,7 +67,7 @@ class WebMessageHostImpl : public WebMessageHost { // First time called, send a message to the page. std::unique_ptr<WebMessage> m2 = std::make_unique<WebMessage>(); m2->message = u"from c++"; - proxy_->PostMessage(std::move(m2)); + proxy_->PostWebMessage(std::move(m2)); } else { // On subsequent calls quit. quit_closure_.Run(); diff --git a/chromium/weblayer/browser/js_communication/web_message_host_factory_wrapper.cc b/chromium/weblayer/browser/js_communication/web_message_host_factory_wrapper.cc index c3ef27a3821..8b314810960 100644 --- a/chromium/weblayer/browser/js_communication/web_message_host_factory_wrapper.cc +++ b/chromium/weblayer/browser/js_communication/web_message_host_factory_wrapper.cc @@ -44,11 +44,11 @@ class WebMessageHostWrapper : public js_injection::WebMessageHost, } // WebMessageReplyProxy: - void PostMessage(std::unique_ptr<WebMessage> message) override { + void PostWebMessage(std::unique_ptr<WebMessage> message) override { std::unique_ptr<js_injection::WebMessage> w = std::make_unique<js_injection::WebMessage>(); w->message = std::move(message->message); - proxy_->PostMessage(std::move(w)); + proxy_->PostWebMessage(std::move(w)); } bool IsInBackForwardCache() override { return proxy_->IsInBackForwardCache(); diff --git a/chromium/weblayer/browser/js_communication/web_message_reply_proxy_impl.cc b/chromium/weblayer/browser/js_communication/web_message_reply_proxy_impl.cc index d484d9d91ad..f4a49c72a26 100644 --- a/chromium/weblayer/browser/js_communication/web_message_reply_proxy_impl.cc +++ b/chromium/weblayer/browser/js_communication/web_message_reply_proxy_impl.cc @@ -40,7 +40,7 @@ void WebMessageReplyProxyImpl::PostMessage( auto message = std::make_unique<WebMessage>(); base::android::ConvertJavaStringToUTF16(env, message_contents, &(message->message)); - reply_proxy_->PostMessage(std::move(message)); + reply_proxy_->PostWebMessage(std::move(message)); } bool WebMessageReplyProxyImpl::IsActive(JNIEnv* env) { diff --git a/chromium/weblayer/browser/large_sticky_ad_intervention_browsertest.cc b/chromium/weblayer/browser/large_sticky_ad_intervention_browsertest.cc index 34a5699bd94..d54e6387091 100644 --- a/chromium/weblayer/browser/large_sticky_ad_intervention_browsertest.cc +++ b/chromium/weblayer/browser/large_sticky_ad_intervention_browsertest.cc @@ -62,7 +62,8 @@ IN_PROC_BROWSER_TEST_F(LargeStickyAdViolationBrowserTest, // ad script is loaded and that the subresource filter UI doesn't show up. EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( "SubresourceFilter.Actions2", subresource_filter::SubresourceFilterAction::kUIShown, 0); @@ -88,7 +89,8 @@ IN_PROC_BROWSER_TEST_F(LargeStickyAdViolationBrowserTest, // shows up. EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( "SubresourceFilter.Actions2", subresource_filter::SubresourceFilterAction::kUIShown, 1); @@ -134,7 +136,8 @@ IN_PROC_BROWSER_TEST_F(LargeStickyAdViolationBrowserTestWithoutEnforcement, // running in dry run mode. EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( "SubresourceFilter.Actions2", subresource_filter::SubresourceFilterAction::kUIShown, 0); diff --git a/chromium/weblayer/browser/navigation_browsertest.cc b/chromium/weblayer/browser/navigation_browsertest.cc index b0c9fdc7f67..e94a2eb8f62 100644 --- a/chromium/weblayer/browser/navigation_browsertest.cc +++ b/chromium/weblayer/browser/navigation_browsertest.cc @@ -7,6 +7,7 @@ #include "base/callback.h" #include "base/callback_helpers.h" +#include "base/command_line.h" #include "base/files/file_path.h" #include "base/memory/raw_ptr.h" #include "base/strings/stringprintf.h" diff --git a/chromium/weblayer/browser/navigation_controller_impl.cc b/chromium/weblayer/browser/navigation_controller_impl.cc index fdff0f0c698..25564bb8925 100644 --- a/chromium/weblayer/browser/navigation_controller_impl.cc +++ b/chromium/weblayer/browser/navigation_controller_impl.cc @@ -595,9 +595,10 @@ void NavigationControllerImpl::DidFinishNavigation( // any delays from surface sync, ie a frame submitted by renderer may not // be displayed immediately. Such situations should be rare however, so // this should be good enough for the purposes needed. - web_contents()->GetMainFrame()->InsertVisualStateCallback(base::BindOnce( - &NavigationControllerImpl::OldPageNoLongerRendered, - weak_ptr_factory_.GetWeakPtr(), navigation_handle->GetURL())); + web_contents()->GetPrimaryMainFrame()->InsertVisualStateCallback( + base::BindOnce(&NavigationControllerImpl::OldPageNoLongerRendered, + weak_ptr_factory_.GetWeakPtr(), + navigation_handle->GetURL())); navigation_map_.erase(navigation_map_.find(navigation_handle)); } diff --git a/chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc b/chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc index 944e081aec6..65257ab6cfd 100644 --- a/chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc +++ b/chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc @@ -17,15 +17,9 @@ PrerenderTabHelper::PrerenderTabHelper(content::WebContents* web_contents) PrerenderTabHelper::~PrerenderTabHelper() = default; -void PrerenderTabHelper::DidFinishNavigation( - content::NavigationHandle* navigation_handle) { - // TODO(https://crbug.com/1218946): With MPArch there may be multiple main - // frames. This caller was converted automatically to the primary main frame - // to preserve its semantics. Follow up to confirm correctness. - if (!navigation_handle->IsInPrimaryMainFrame() || - !navigation_handle->HasCommitted() || navigation_handle->IsErrorPage()) { +void PrerenderTabHelper::PrimaryPageChanged(content::Page& page) { + if (page.GetMainDocument().IsErrorDocument()) return; - } prerender::NoStatePrefetchManager* no_state_prefetch_manager = NoStatePrefetchManagerFactory::GetForBrowserContext( @@ -33,7 +27,8 @@ void PrerenderTabHelper::DidFinishNavigation( if (no_state_prefetch_manager && !no_state_prefetch_manager->IsWebContentsPrefetching(web_contents())) - no_state_prefetch_manager->RecordNavigation(navigation_handle->GetURL()); + no_state_prefetch_manager->RecordNavigation( + page.GetMainDocument().GetLastCommittedURL()); } WEB_CONTENTS_USER_DATA_KEY_IMPL(PrerenderTabHelper); diff --git a/chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.h b/chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.h index 9ca3a4fc586..5d4f344fa15 100644 --- a/chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.h +++ b/chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.h @@ -29,8 +29,7 @@ class PrerenderTabHelper PrerenderTabHelper& operator=(const PrerenderTabHelper&) = delete; // content::WebContentsObserver implementation. - void DidFinishNavigation( - content::NavigationHandle* navigation_handle) override; + void PrimaryPageChanged(content::Page& page) override; private: explicit PrerenderTabHelper(content::WebContents* web_contents); diff --git a/chromium/weblayer/browser/overlay_popup_ad_intervention_browsertest.cc b/chromium/weblayer/browser/overlay_popup_ad_intervention_browsertest.cc index e28caab19f7..0424fe82790 100644 --- a/chromium/weblayer/browser/overlay_popup_ad_intervention_browsertest.cc +++ b/chromium/weblayer/browser/overlay_popup_ad_intervention_browsertest.cc @@ -70,7 +70,8 @@ IN_PROC_BROWSER_TEST_F(OverlayPopupAdViolationBrowserTest, // ad script is loaded and that the subresource filter UI doesn't show up. EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( "SubresourceFilter.Actions2", subresource_filter::SubresourceFilterAction::kUIShown, 0); @@ -104,7 +105,8 @@ IN_PROC_BROWSER_TEST_F(OverlayPopupAdViolationBrowserTest, // shows up. EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( "SubresourceFilter.Actions2", subresource_filter::SubresourceFilterAction::kUIShown, 1); @@ -150,7 +152,8 @@ IN_PROC_BROWSER_TEST_F(OverlayPopupAdViolationBrowserTestWithoutEnforcement, // running in dry run mode. EXPECT_TRUE(content::NavigateToURL(web_contents(), url)); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents()->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents()->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( "SubresourceFilter.Actions2", subresource_filter::SubresourceFilterAction::kUIShown, 0); diff --git a/chromium/weblayer/browser/page_load_metrics_browsertest.cc b/chromium/weblayer/browser/page_load_metrics_browsertest.cc index e10bb6e7db7..f6f7dc153fc 100644 --- a/chromium/weblayer/browser/page_load_metrics_browsertest.cc +++ b/chromium/weblayer/browser/page_load_metrics_browsertest.cc @@ -25,6 +25,14 @@ class PageLoadMetricsObserver ~PageLoadMetricsObserver() override = default; // page_load_metrics::PageLoadMetricsObserver implementation: + + // TODO(https://crbug.com/1317494): Audit and use appropriate policy. + ObservePolicy OnFencedFramesStart( + content::NavigationHandle* navigation_handle, + const GURL& currently_committed_url) override { + return STOP_OBSERVING; + } + void OnFirstPaintInPage( const page_load_metrics::mojom::PageLoadTiming& timing) override { on_first_paint_seen_ = true; diff --git a/chromium/weblayer/browser/page_load_metrics_observer_impl.cc b/chromium/weblayer/browser/page_load_metrics_observer_impl.cc index 94a6d5850c6..fdaeaf80c79 100644 --- a/chromium/weblayer/browser/page_load_metrics_observer_impl.cc +++ b/chromium/weblayer/browser/page_load_metrics_observer_impl.cc @@ -18,6 +18,14 @@ namespace weblayer { +// TODO(https://crbug.com/1317494): Audit and use appropriate policy. +page_load_metrics::PageLoadMetricsObserver::ObservePolicy +PageLoadMetricsObserverImpl::OnFencedFramesStart( + content::NavigationHandle* navigation_handle, + const GURL& currently_committed_url) { + return STOP_OBSERVING; +} + PageLoadMetricsObserverImpl::ObservePolicy PageLoadMetricsObserverImpl::OnCommit( content::NavigationHandle* navigation_handle) { diff --git a/chromium/weblayer/browser/page_load_metrics_observer_impl.h b/chromium/weblayer/browser/page_load_metrics_observer_impl.h index c026b794db1..c6d94133cd9 100644 --- a/chromium/weblayer/browser/page_load_metrics_observer_impl.h +++ b/chromium/weblayer/browser/page_load_metrics_observer_impl.h @@ -16,6 +16,9 @@ class PageLoadMetricsObserverImpl ~PageLoadMetricsObserverImpl() override = default; // page_load_metrics::PageLoadMetricsObserver implementation: + ObservePolicy OnFencedFramesStart( + content::NavigationHandle* navigation_handle, + const GURL& currently_committed_url) override; ObservePolicy FlushMetricsOnAppEnterBackground( const page_load_metrics::mojom::PageLoadTiming& timing) override; ObservePolicy OnHidden( diff --git a/chromium/weblayer/browser/page_specific_content_settings_delegate.cc b/chromium/weblayer/browser/page_specific_content_settings_delegate.cc index 09e6d7c95c6..ef410233789 100644 --- a/chromium/weblayer/browser/page_specific_content_settings_delegate.cc +++ b/chromium/weblayer/browser/page_specific_content_settings_delegate.cc @@ -59,15 +59,6 @@ void PageSpecificContentSettingsDelegate::SetDefaultRendererContentSettingRules( content::RenderFrameHost* rfh, RendererContentSettingRules* rules) {} -ContentSetting PageSpecificContentSettingsDelegate::GetEmbargoSetting( - const GURL& request_origin, - ContentSettingsType permission) { - return PermissionDecisionAutoBlockerFactory::GetForBrowserContext( - web_contents_->GetBrowserContext()) - ->GetEmbargoResult(request_origin, permission) - .content_setting; -} - std::vector<storage::FileSystemType> PageSpecificContentSettingsDelegate::GetAdditionalFileSystemTypes() { return {}; diff --git a/chromium/weblayer/browser/page_specific_content_settings_delegate.h b/chromium/weblayer/browser/page_specific_content_settings_delegate.h index cb549cde0f0..ac13b12027f 100644 --- a/chromium/weblayer/browser/page_specific_content_settings_delegate.h +++ b/chromium/weblayer/browser/page_specific_content_settings_delegate.h @@ -32,8 +32,6 @@ class PageSpecificContentSettingsDelegate void SetDefaultRendererContentSettingRules( content::RenderFrameHost* rfh, RendererContentSettingRules* rules) override; - ContentSetting GetEmbargoSetting(const GURL& request_origin, - ContentSettingsType permission) override; std::vector<storage::FileSystemType> GetAdditionalFileSystemTypes() override; browsing_data::CookieHelper::IsDeletionDisabledCallback GetIsDeletionDisabledCallback() override; diff --git a/chromium/weblayer/browser/password_manager_driver_factory.cc b/chromium/weblayer/browser/password_manager_driver_factory.cc index 2cc6841da5d..814beb62e2b 100644 --- a/chromium/weblayer/browser/password_manager_driver_factory.cc +++ b/chromium/weblayer/browser/password_manager_driver_factory.cc @@ -72,9 +72,13 @@ class PasswordManagerDriverFactory::PasswordManagerDriver const std::u16string& typed_username, int options, const gfx::RectF& bounds) override {} + +#if BUILDFLAG(IS_ANDROID) void ShowTouchToFill( autofill::mojom::SubmissionReadinessState submission_readiness) override { } +#endif + void CheckSafeBrowsingReputation(const GURL& form_action, const GURL& frame_url) override {} void FocusedInputChanged( @@ -120,7 +124,7 @@ PasswordManagerDriverFactory::GetDriverForFrame( content::RenderFrameHost* render_frame_host) { DCHECK_EQ(web_contents(), content::WebContents::FromRenderFrameHost(render_frame_host)); - DCHECK(render_frame_host->IsRenderFrameCreated()); + DCHECK(render_frame_host->IsRenderFrameLive()); auto [it, inserted] = frame_driver_map_.try_emplace(render_frame_host, render_frame_host); diff --git a/chromium/weblayer/browser/permissions/geolocation_permission_context_delegate.cc b/chromium/weblayer/browser/permissions/geolocation_permission_context_delegate.cc index e77fbe0fb4c..1cc75b41b0f 100644 --- a/chromium/weblayer/browser/permissions/geolocation_permission_context_delegate.cc +++ b/chromium/weblayer/browser/permissions/geolocation_permission_context_delegate.cc @@ -15,7 +15,6 @@ namespace weblayer { bool GeolocationPermissionContextDelegate::DecidePermission( - content::WebContents* web_contents, const permissions::PermissionRequestID& id, const GURL& requesting_origin, bool user_gesture, diff --git a/chromium/weblayer/browser/permissions/geolocation_permission_context_delegate.h b/chromium/weblayer/browser/permissions/geolocation_permission_context_delegate.h index afb61850192..0f236b09275 100644 --- a/chromium/weblayer/browser/permissions/geolocation_permission_context_delegate.h +++ b/chromium/weblayer/browser/permissions/geolocation_permission_context_delegate.h @@ -22,7 +22,6 @@ class GeolocationPermissionContextDelegate // GeolocationPermissionContext::Delegate: bool DecidePermission( - content::WebContents* web_contents, const permissions::PermissionRequestID& id, const GURL& requesting_origin, bool user_gesture, diff --git a/chromium/weblayer/browser/permissions/permission_manager_factory.cc b/chromium/weblayer/browser/permissions/permission_manager_factory.cc index feb2e7dd4d4..ef813c2e918 100644 --- a/chromium/weblayer/browser/permissions/permission_manager_factory.cc +++ b/chromium/weblayer/browser/permissions/permission_manager_factory.cc @@ -12,8 +12,9 @@ #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/permissions/permission_context_base.h" #include "components/permissions/permission_manager.h" +#include "components/permissions/permission_util.h" #include "components/webrtc/media_stream_device_enumerator_impl.h" -#include "content/public/browser/permission_type.h" +#include "third_party/blink/public/common/permissions/permission_utils.h" #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h" #include "weblayer/browser/background_fetch/background_fetch_permission_context.h" #include "weblayer/browser/host_content_settings_map_factory.h" @@ -118,14 +119,14 @@ permissions::PermissionManager::PermissionContextMap CreatePermissionContexts( // For now, all requests are denied. As features are added, their permission // contexts can be added here instead of DeniedPermissionContext. - for (content::PermissionType type : content::GetAllPermissionTypes()) { + for (blink::PermissionType type : blink::GetAllPermissionTypes()) { #if !BUILDFLAG(IS_ANDROID) // PROTECTED_MEDIA_IDENTIFIER is only supported on Android. - if (type == content::PermissionType::PROTECTED_MEDIA_IDENTIFIER) + if (type == blink::PermissionType::PROTECTED_MEDIA_IDENTIFIER) continue; #endif ContentSettingsType content_settings_type = - permissions::PermissionManager::PermissionTypeToContentSetting(type); + permissions::PermissionUtil::PermissionTypeToContentSetting(type); if (permission_contexts.find(content_settings_type) == permission_contexts.end()) { permission_contexts[content_settings_type] = diff --git a/chromium/weblayer/browser/profile_impl.cc b/chromium/weblayer/browser/profile_impl.cc index b514745352c..8748a5f3f3c 100644 --- a/chromium/weblayer/browser/profile_impl.cc +++ b/chromium/weblayer/browser/profile_impl.cc @@ -300,7 +300,8 @@ void ProfileImpl::ClearBrowsingData( remove_mask |= BrowsingDataRemoverDelegate::DATA_TYPE_FAVICONS; remove_mask |= BrowsingDataRemoverDelegate::DATA_TYPE_AD_INTERVENTIONS; remove_mask |= content::BrowsingDataRemover::DATA_TYPE_TRUST_TOKENS; - remove_mask |= content::BrowsingDataRemover::DATA_TYPE_CONVERSIONS; + remove_mask |= + content::BrowsingDataRemover::DATA_TYPE_ATTRIBUTION_REPORTING; remove_mask |= content::BrowsingDataRemover::DATA_TYPE_AGGREGATION_SERVICE; break; diff --git a/chromium/weblayer/browser/proxying_url_loader_factory_impl.cc b/chromium/weblayer/browser/proxying_url_loader_factory_impl.cc index 2a2cce4de5e..9cece1dc32d 100644 --- a/chromium/weblayer/browser/proxying_url_loader_factory_impl.cc +++ b/chromium/weblayer/browser/proxying_url_loader_factory_impl.cc @@ -45,8 +45,6 @@ void StartCachedLoad( const std::string& data) { mojo::Remote<network::mojom::URLLoaderClient> client( std::move(pending_client)); - client->OnReceiveResponse(std::move(response_head), - mojo::ScopedDataPipeConsumerHandle()); mojo::ScopedDataPipeProducerHandle producer; mojo::ScopedDataPipeConsumerHandle consumer; @@ -56,7 +54,7 @@ void StartCachedLoad( return; } - client->OnStartLoadingResponseBody(std::move(consumer)); + client->OnReceiveResponse(std::move(response_head), std::move(consumer)); auto write_data = std::make_unique<WriteData>(); write_data->client = std::move(client); diff --git a/chromium/weblayer/browser/safe_browsing/client_side_detection_service_browsertest.cc b/chromium/weblayer/browser/safe_browsing/client_side_detection_service_browsertest.cc index 6b5fa6af7c5..b25e1e8fe84 100644 --- a/chromium/weblayer/browser/safe_browsing/client_side_detection_service_browsertest.cc +++ b/chromium/weblayer/browser/safe_browsing/client_side_detection_service_browsertest.cc @@ -70,7 +70,7 @@ IN_PROC_BROWSER_TEST_F(ClientSideDetectionServiceBrowserTest, base::RunLoop run_loop; - content::RenderFrameHost* rfh = GetWebContents()->GetMainFrame(); + content::RenderFrameHost* rfh = GetWebContents()->GetPrimaryMainFrame(); mojo::Remote<safe_browsing::mojom::PhishingDetector> phishing_detector; rfh->GetRemoteInterfaces()->GetInterface( phishing_detector.BindNewPipeAndPassReceiver()); diff --git a/chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc b/chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc index baa0919c7a1..df3e9e863eb 100644 --- a/chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc +++ b/chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc @@ -6,7 +6,7 @@ #include "base/memory/raw_ptr.h" #include "components/prefs/pref_service.h" -#include "components/safe_browsing/android/safe_browsing_api_handler.h" +#include "components/safe_browsing/android/safe_browsing_api_handler_bridge.h" #include "components/safe_browsing/content/browser/base_blocking_page.h" #include "components/safe_browsing/content/browser/safe_browsing_blocking_page.h" #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h" @@ -117,56 +117,50 @@ class SafeBrowsingErrorNavigationObserver : public NavigationObserver { base::RunLoop run_loop_; }; -void RunCallbackOnIOThread( - std::unique_ptr<safe_browsing::SafeBrowsingApiHandler::URLCheckCallbackMeta> - callback, - safe_browsing::SBThreatType threat_type, - const safe_browsing::ThreatMetadata& metadata) { +using SbBridge = safe_browsing::SafeBrowsingApiHandlerBridge; + +void RunCallbackOnIOThread(std::unique_ptr<SbBridge::ResponseCallback> callback, + safe_browsing::SBThreatType threat_type, + const safe_browsing::ThreatMetadata& metadata) { content::GetIOThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(std::move(*callback), threat_type, metadata)); } } // namespace -class FakeSafeBrowsingApiHandler - : public safe_browsing::SafeBrowsingApiHandler { +class TestUrlCheckInterceptor : public safe_browsing::UrlCheckInterceptor { public: - // SafeBrowsingApiHandler - void StartURLCheck( - std::unique_ptr<URLCheckCallbackMeta> callback, - const GURL& url, - const safe_browsing::SBThreatTypeSet& threat_types) override { - RunCallbackOnIOThread(std::move(callback), GetSafeBrowsingRestriction(url), - safe_browsing::ThreatMetadata()); - } - bool StartCSDAllowlistCheck(const GURL& url) override { return false; } - bool StartHighConfidenceAllowlistCheck(const GURL& url) override { - return false; + void Add(const GURL& url, safe_browsing::SBThreatType threat_type) { + map_[url] = threat_type; } - void AddRestriction(const GURL& url, - const safe_browsing::SBThreatType& threat_type) { - restrictions_[url] = threat_type; - } + void Clear() { map_.clear(); } - void ClearRestrictions() { restrictions_.clear(); } + // safe_browsing::UrlCheckInterceptor + void Check(std::unique_ptr<SbBridge::ResponseCallback> callback, + const GURL& url) const override { + RunCallbackOnIOThread(std::move(callback), Find(url), + safe_browsing::ThreatMetadata()); + } + ~TestUrlCheckInterceptor() override{}; private: - safe_browsing::SBThreatType GetSafeBrowsingRestriction(const GURL& url) { - auto restrictions_iter = restrictions_.find(url); - if (restrictions_iter == restrictions_.end()) { - // if the url is not in restrictions assume it's safe. - return safe_browsing::SB_THREAT_TYPE_SAFE; - } - return restrictions_iter->second; + safe_browsing::SBThreatType Find(const GURL& url) const { + auto it = map_.find(url); + if (it != map_.end()) + return it->second; + + // If the url is not in the map assume it is safe. + return safe_browsing::SB_THREAT_TYPE_SAFE; } - std::map<GURL, safe_browsing::SBThreatType> restrictions_; + std::map<GURL, safe_browsing::SBThreatType> map_; }; class SafeBrowsingBrowserTest : public WebLayerBrowserTest { public: - SafeBrowsingBrowserTest() : fake_handler_(new FakeSafeBrowsingApiHandler()) {} + SafeBrowsingBrowserTest() + : url_check_interceptor_(std::make_unique<TestUrlCheckInterceptor>()) {} SafeBrowsingBrowserTest(const SafeBrowsingBrowserTest&) = delete; SafeBrowsingBrowserTest& operator=(const SafeBrowsingBrowserTest&) = delete; @@ -184,11 +178,13 @@ class SafeBrowsingBrowserTest : public WebLayerBrowserTest { void TearDown() override { profile()->SetGoogleAccountAccessTokenFetchDelegate(nullptr); + SbBridge::GetInstance().SetInterceptorForTesting(nullptr); } void InitializeOnMainThread() { NavigateAndWaitForCompletion(GURL("about:blank"), shell()); - safe_browsing::SafeBrowsingApiHandler::SetInstance(fake_handler_.get()); + SbBridge::GetInstance().SetInterceptorForTesting( + url_check_interceptor_.get()); // Some tests need to be able to navigate to URLs on domains that are not // explicitly localhost (e.g., so that realtime URL lookups occur on these @@ -221,7 +217,7 @@ class SafeBrowsingBrowserTest : public WebLayerBrowserTest { void NavigateWithThreatType(const safe_browsing::SBThreatType& threatType, bool expect_interstitial) { - fake_handler_->AddRestriction(url_, threatType); + url_check_interceptor_->Add(url_, threatType); Navigate(url_, expect_interstitial); } @@ -244,7 +240,7 @@ class SafeBrowsingBrowserTest : public WebLayerBrowserTest { GURL page_with_script_url = embedded_test_server()->GetURL("/simple_page_with_script.html"); GURL script_url = embedded_test_server()->GetURL("/script.js"); - fake_handler_->AddRestriction(script_url, threat_type); + url_check_interceptor_->Add(script_url, threat_type); Navigate(page_with_script_url, expect_interstitial); } @@ -272,7 +268,7 @@ class SafeBrowsingBrowserTest : public WebLayerBrowserTest { content::RenderProcessHost* child_process = static_cast<TabImpl*>(shell()->tab()) ->web_contents() - ->GetMainFrame() + ->GetPrimaryMainFrame() ->GetProcess(); content::RenderProcessHostWatcher crash_observer( child_process, @@ -281,7 +277,7 @@ class SafeBrowsingBrowserTest : public WebLayerBrowserTest { crash_observer.Wait(); } - std::unique_ptr<FakeSafeBrowsingApiHandler> fake_handler_; + std::unique_ptr<TestUrlCheckInterceptor> url_check_interceptor_; GURL url_; ProfileImpl* profile() { @@ -343,8 +339,8 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, CheckNavigationErrorType) { for (auto threat_type : threat_types) { SafeBrowsingErrorNavigationObserver observer(url_, shell()); - fake_handler_->ClearRestrictions(); - fake_handler_->AddRestriction(url_, threat_type); + url_check_interceptor_->Clear(); + url_check_interceptor_->Add(url_, threat_type); shell()->tab()->GetNavigationController()->Navigate(url_); observer.WaitForNavigationFailureWithSafeBrowsingError(); diff --git a/chromium/weblayer/browser/safe_browsing/safe_browsing_service.cc b/chromium/weblayer/browser/safe_browsing/safe_browsing_service.cc index 2d309026484..2ab68fa146a 100644 --- a/chromium/weblayer/browser/safe_browsing/safe_browsing_service.cc +++ b/chromium/weblayer/browser/safe_browsing/safe_browsing_service.cc @@ -95,11 +95,6 @@ void SafeBrowsingService::Initialize() { return; } - safe_browsing_api_handler_ = - std::make_unique<safe_browsing::SafeBrowsingApiHandlerBridge>(); - safe_browsing::SafeBrowsingApiHandler::SetInstance( - safe_browsing_api_handler_.get()); - base::FilePath user_data_dir; bool result = base::PathService::Get(base::DIR_ANDROID_APP_DATA, &user_data_dir); diff --git a/chromium/weblayer/browser/safe_browsing/safe_browsing_service.h b/chromium/weblayer/browser/safe_browsing/safe_browsing_service.h index 712cf995381..820b32d6f38 100644 --- a/chromium/weblayer/browser/safe_browsing/safe_browsing_service.h +++ b/chromium/weblayer/browser/safe_browsing/safe_browsing_service.h @@ -34,7 +34,7 @@ namespace safe_browsing { class UrlCheckerDelegate; class RealTimeUrlLookupServiceBase; class RemoteSafeBrowsingDatabaseManager; -class SafeBrowsingApiHandler; +class SafeBrowsingApiHandlerBridge; class SafeBrowsingNetworkContext; class TriggerManager; } // namespace safe_browsing @@ -118,7 +118,7 @@ class SafeBrowsingService { scoped_refptr<UrlCheckerDelegateImpl> safe_browsing_url_checker_delegate_; - std::unique_ptr<safe_browsing::SafeBrowsingApiHandler> + std::unique_ptr<safe_browsing::SafeBrowsingApiHandlerBridge> safe_browsing_api_handler_; std::string user_agent_; diff --git a/chromium/weblayer/browser/safe_browsing/weblayer_ping_manager_browsertest.cc b/chromium/weblayer/browser/safe_browsing/weblayer_ping_manager_browsertest.cc index 6683efcd3d2..3f1f2bcb050 100644 --- a/chromium/weblayer/browser/safe_browsing/weblayer_ping_manager_browsertest.cc +++ b/chromium/weblayer/browser/safe_browsing/weblayer_ping_manager_browsertest.cc @@ -8,6 +8,8 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/time/time.h" +#include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h" +#include "components/safe_browsing/core/browser/test_safe_browsing_token_fetcher.h" #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" @@ -18,11 +20,14 @@ #include "weblayer/browser/browser_context_impl.h" #include "weblayer/browser/profile_impl.h" #include "weblayer/browser/safe_browsing/weblayer_ping_manager_factory.h" +#include "weblayer/browser/safe_browsing/weblayer_user_population_helper.h" #include "weblayer/test/weblayer_browser_test.h" -namespace weblayer { +using safe_browsing::ClientSafeBrowsingReportRequest; +using ReportThreatDetailsResult = + safe_browsing::PingManager::ReportThreatDetailsResult; -class TestSafeBrowsingTokenFetcher; +namespace weblayer { class WeblayerPingManagerTest : public WebLayerBrowserTest { public: @@ -44,7 +49,7 @@ class WeblayerPingManagerTest : public WebLayerBrowserTest { bool is_remove_cookies_feature_enabled_ = true; private: - TestSafeBrowsingTokenFetcher* SetUpTokenFetcher( + safe_browsing::TestSafeBrowsingTokenFetcher* SetUpTokenFetcher( safe_browsing::PingManager* ping_manager); }; class RemoveCookiesFeatureDisabledWeblayerPingManagerTest @@ -74,32 +79,11 @@ class IncognitoModeWeblayerPingManagerTest : public WeblayerPingManagerTest { IncognitoModeWeblayerPingManagerTest() { SetShellStartsInIncognitoMode(); } }; -class TestSafeBrowsingTokenFetcher - : public safe_browsing::SafeBrowsingTokenFetcher { - public: - TestSafeBrowsingTokenFetcher() = default; - ~TestSafeBrowsingTokenFetcher() override { RunAccessTokenCallback(""); } - - void Start(Callback callback) override { - callback_ = std::move(callback); - was_start_called_ = true; - } - void RunAccessTokenCallback(std::string token) { - if (callback_) { - std::move(callback_).Run(token); - } - } - bool WasStartCalled() { return was_start_called_; } - MOCK_METHOD1(OnInvalidAccessToken, void(const std::string&)); - - private: - Callback callback_; - bool was_start_called_ = false; -}; - -TestSafeBrowsingTokenFetcher* WeblayerPingManagerTest::SetUpTokenFetcher( +safe_browsing::TestSafeBrowsingTokenFetcher* +WeblayerPingManagerTest::SetUpTokenFetcher( safe_browsing::PingManager* ping_manager) { - auto token_fetcher = std::make_unique<TestSafeBrowsingTokenFetcher>(); + auto token_fetcher = + std::make_unique<safe_browsing::TestSafeBrowsingTokenFetcher>(); auto* raw_token_fetcher = token_fetcher.get(); ping_manager->SetTokenFetcherForTesting(std::move(token_fetcher)); return raw_token_fetcher; @@ -110,6 +94,7 @@ void WeblayerPingManagerTest::RunReportThreatDetailsTest( bool is_signed_in, bool expect_access_token, bool expect_cookies_removed) { + base::RunLoop csbrr_logged_run_loop; base::HistogramTester histogram_tester; if (is_enhanced_protection) { SetSafeBrowsingState(GetProfile()->GetBrowserContext()->pref_service(), @@ -121,13 +106,29 @@ void WeblayerPingManagerTest::RunReportThreatDetailsTest( auto* ping_manager = WebLayerPingManagerFactory::GetForBrowserContext( GetProfile()->GetBrowserContext()); auto* raw_token_fetcher = SetUpTokenFetcher(ping_manager); + safe_browsing::WebUIInfoSingleton::GetInstance()->AddListenerForTesting(); + safe_browsing::WebUIInfoSingleton::GetInstance() + ->SetOnCSBRRLoggedCallbackForTesting(csbrr_logged_run_loop.QuitClosure()); std::string access_token = "testing_access_token"; - std::string report_content = "testing_report_content"; + std::string input_report_content; + std::unique_ptr<ClientSafeBrowsingReportRequest> report = + std::make_unique<ClientSafeBrowsingReportRequest>(); + // The report must be non-empty. The selected property to set is arbitrary. + report->set_type(ClientSafeBrowsingReportRequest::URL_PHISHING); + EXPECT_TRUE(report->SerializeToString(&input_report_content)); + ClientSafeBrowsingReportRequest expected_report; + expected_report.ParseFromString(input_report_content); + *expected_report.mutable_population() = + GetUserPopulationForBrowserContext(GetProfile()->GetBrowserContext()); + std::string expected_report_content; + EXPECT_TRUE(expected_report.SerializeToString(&expected_report_content)); + EXPECT_NE(input_report_content, expected_report_content); + network::TestURLLoaderFactory test_url_loader_factory; test_url_loader_factory.SetInterceptor( base::BindLambdaForTesting([&](const network::ResourceRequest& request) { - EXPECT_EQ(GetUploadData(request), report_content); + EXPECT_EQ(GetUploadData(request), expected_report_content); std::string header_value; bool found_header = request.headers.GetHeader( net::HttpRequestHeaders::kAuthorization, &header_value); @@ -148,11 +149,18 @@ void WeblayerPingManagerTest::RunReportThreatDetailsTest( base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory)); - ping_manager->ReportThreatDetails(report_content); + ReportThreatDetailsResult result = + ping_manager->ReportThreatDetails(std::move(report)); + EXPECT_EQ(result, ReportThreatDetailsResult::SUCCESS); EXPECT_EQ(raw_token_fetcher->WasStartCalled(), expect_access_token); if (expect_access_token) { raw_token_fetcher->RunAccessTokenCallback(access_token); } + csbrr_logged_run_loop.Run(); + EXPECT_EQ( + safe_browsing::WebUIInfoSingleton::GetInstance()->csbrrs_sent().size(), + 1u); + safe_browsing::WebUIInfoSingleton::GetInstance()->ClearListenerForTesting(); } IN_PROC_BROWSER_TEST_F(WeblayerPingManagerTest, diff --git a/chromium/weblayer/browser/safe_browsing/weblayer_ping_manager_factory.cc b/chromium/weblayer/browser/safe_browsing/weblayer_ping_manager_factory.cc index e11eaa152f3..35c8d7bb5a5 100644 --- a/chromium/weblayer/browser/safe_browsing/weblayer_ping_manager_factory.cc +++ b/chromium/weblayer/browser/safe_browsing/weblayer_ping_manager_factory.cc @@ -6,13 +6,16 @@ #include "base/no_destructor.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h" #include "components/safe_browsing/core/browser/ping_manager.h" #include "components/safe_browsing/core/common/features.h" +#include "content/public/browser/browser_task_traits.h" #include "weblayer/browser/browser_context_impl.h" #include "weblayer/browser/browser_process.h" #include "weblayer/browser/profile_impl.h" #include "weblayer/browser/safe_browsing/safe_browsing_service.h" #include "weblayer/browser/safe_browsing/safe_browsing_token_fetcher_impl.h" +#include "weblayer/browser/safe_browsing/weblayer_user_population_helper.h" namespace weblayer { @@ -51,7 +54,10 @@ KeyedService* WebLayerPingManagerFactory::BuildServiceInstanceFor( base::Unretained(ProfileImpl::FromBrowserContext(context)))), base::BindRepeating( &WebLayerPingManagerFactory::ShouldFetchAccessTokenForReport, - base::Unretained(this), context)); + base::Unretained(this), context), + safe_browsing::WebUIInfoSingleton::GetInstance(), + content::GetUIThreadTaskRunner({}), + base::BindRepeating(&GetUserPopulationForBrowserContext, context)); } bool WebLayerPingManagerFactory::ShouldFetchAccessTokenForReport( diff --git a/chromium/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.cc b/chromium/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.cc index 1e898b2f1a7..694f4fcef53 100644 --- a/chromium/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.cc +++ b/chromium/weblayer/browser/safe_browsing/weblayer_safe_browsing_blocking_page_factory.cc @@ -13,7 +13,6 @@ #include "weblayer/browser/safe_browsing/safe_browsing_metrics_collector_factory.h" #include "weblayer/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" #include "weblayer/browser/safe_browsing/safe_browsing_service.h" -#include "weblayer/browser/safe_browsing/weblayer_user_population_helper.h" namespace weblayer { @@ -49,7 +48,6 @@ WebLayerSafeBrowsingBlockingPageFactory::CreateSafeBrowsingPage( display_options, should_trigger_reporting, // WebLayer doesn't integrate //components/history. /*history_service=*/nullptr, - base::BindRepeating(&GetUserPopulationForBrowserContext, browser_context), SafeBrowsingNavigationObserverManagerFactory::GetForBrowserContext( browser_context), SafeBrowsingMetricsCollectorFactory::GetForBrowserContext( diff --git a/chromium/weblayer/browser/signin_url_loader_throttle.cc b/chromium/weblayer/browser/signin_url_loader_throttle.cc index a32816acdbe..92919d5be7b 100644 --- a/chromium/weblayer/browser/signin_url_loader_throttle.cc +++ b/chromium/weblayer/browser/signin_url_loader_throttle.cc @@ -50,8 +50,7 @@ void ProcessMirrorHeader(content::WebContents::Getter web_contents_getter, void MaybeAddQueryParams(GURL* url) { // Add manage=true to query parameters for sign out URLs to make sure we // receive the Mirror response headers instead of the normal sign out page. - if (gaia::IsGaiaSignonRealm(url->DeprecatedGetOriginAsURL()) && - url->path_piece() == kSignOutPath) { + if (gaia::HasGaiaSchemeHostPort(*url) && url->path_piece() == kSignOutPath) { *url = net::AppendOrReplaceQueryParameter(*url, "manage", "true"); } } @@ -163,8 +162,8 @@ void SigninURLLoaderThrottle::ProcessRequest( void SigninURLLoaderThrottle::ProcessResponse( const net::HttpResponseHeaders* headers) { - if (!gaia::IsGaiaSignonRealm(request_url_.DeprecatedGetOriginAsURL()) || - !is_main_frame_ || !headers) { + if (!gaia::HasGaiaSchemeHostPort(request_url_) || !is_main_frame_ || + !headers) { return; } diff --git a/chromium/weblayer/browser/site_isolation_browsertest.cc b/chromium/weblayer/browser/site_isolation_browsertest.cc index e5ba58108a1..d88b2f5bc22 100644 --- a/chromium/weblayer/browser/site_isolation_browsertest.cc +++ b/chromium/weblayer/browser/site_isolation_browsertest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/base_switches.h" +#include "base/command_line.h" #include "base/files/file_path.h" #include "base/memory/raw_ptr.h" #include "base/system/sys_info.h" @@ -125,8 +126,9 @@ IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, // foo.com should not be isolated to start with. Verify that a cross-site // iframe does not become an OOPIF. - EXPECT_FALSE( - contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess()); + EXPECT_FALSE(contents->GetPrimaryMainFrame() + ->GetSiteInstance() + ->RequiresDedicatedProcess()); std::string kAppendIframe = R"( var i = document.createElement('iframe'); i.id = 'child'; @@ -134,7 +136,8 @@ IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, EXPECT_TRUE(content::ExecJs(contents, kAppendIframe)); GURL bar_url(embedded_test_server()->GetURL("bar.com", "/simple_page.html")); EXPECT_TRUE(NavigateIframeToURL(contents, "child", bar_url)); - content::RenderFrameHost* child = ChildFrameAt(contents->GetMainFrame(), 0); + content::RenderFrameHost* child = + ChildFrameAt(contents->GetPrimaryMainFrame(), 0); EXPECT_FALSE(child->IsCrossProcessSubframe()); // Fill a form and submit through a <input type="submit"> button. @@ -150,11 +153,12 @@ IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, // swapped BrowsingInstances and put the result of the form submission into a // dedicated process, locked to foo.com. Check that a cross-site iframe now // becomes an OOPIF. - EXPECT_TRUE( - contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess()); + EXPECT_TRUE(contents->GetPrimaryMainFrame() + ->GetSiteInstance() + ->RequiresDedicatedProcess()); EXPECT_TRUE(ExecJs(contents, kAppendIframe)); EXPECT_TRUE(NavigateIframeToURL(contents, "child", bar_url)); - child = ChildFrameAt(contents->GetMainFrame(), 0); + child = ChildFrameAt(contents->GetPrimaryMainFrame(), 0); EXPECT_TRUE(child->IsCrossProcessSubframe()); } @@ -175,7 +179,7 @@ IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, NavigateAndWaitForCompletion(saved_url, shell()); EXPECT_TRUE(GetWebContents() - ->GetMainFrame() + ->GetPrimaryMainFrame() ->GetSiteInstance() ->RequiresDedicatedProcess()); @@ -200,14 +204,17 @@ IN_PROC_BROWSER_TEST_F(SiteIsolationBrowserTest, embedded_test_server()->GetURL("foo.com", "/simple_page3.html"); NavigateAndWaitForCompletion(saved_url, shell()); content::WebContents* contents = GetWebContents(); - EXPECT_TRUE( - contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess()); + EXPECT_TRUE(contents->GetPrimaryMainFrame() + ->GetSiteInstance() + ->RequiresDedicatedProcess()); NavigateAndWaitForCompletion(saved2_url, shell()); - EXPECT_TRUE( - contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess()); + EXPECT_TRUE(contents->GetPrimaryMainFrame() + ->GetSiteInstance() + ->RequiresDedicatedProcess()); NavigateAndWaitForCompletion(foo_url, shell()); - EXPECT_FALSE( - contents->GetMainFrame()->GetSiteInstance()->RequiresDedicatedProcess()); + EXPECT_FALSE(contents->GetPrimaryMainFrame() + ->GetSiteInstance() + ->RequiresDedicatedProcess()); } #endif diff --git a/chromium/weblayer/browser/site_isolation_policy_unittest.cc b/chromium/weblayer/browser/site_isolation_policy_unittest.cc index 3aea36d2247..e2af4108135 100644 --- a/chromium/weblayer/browser/site_isolation_policy_unittest.cc +++ b/chromium/weblayer/browser/site_isolation_policy_unittest.cc @@ -5,6 +5,7 @@ #include "components/site_isolation/site_isolation_policy.h" #include "base/base_switches.h" +#include "base/command_line.h" #include "base/system/sys_info.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" diff --git a/chromium/weblayer/browser/subresource_filter_browsertest.cc b/chromium/weblayer/browser/subresource_filter_browsertest.cc index 9c574c42fe3..c83c037d1ae 100644 --- a/chromium/weblayer/browser/subresource_filter_browsertest.cc +++ b/chromium/weblayer/browser/subresource_filter_browsertest.cc @@ -179,7 +179,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, console_observer.Wait(); // ... but it should not have blocked the subframe from being loaded. - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); // Do a different-document navigation to ensure that that the next navigation // to |test_url| executes as desired (e.g., to avoid any optimizations from @@ -188,7 +189,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, // seen flake on the Windows trybot that indicates that such optimizations are // occurring. NavigateAndWaitForCompletion(GURL("about:blank"), shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); // Verify that the "ad" subframe is blocked if it is flagged by the // ruleset. @@ -196,7 +198,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); // Do a different-document navigation to ensure that that the next navigation // to |test_url| executes as desired (e.g., to avoid any optimizations from @@ -205,12 +208,14 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, // seen flake on the Windows trybot that indicates that such optimizations are // occurring. NavigateAndWaitForCompletion(GURL("about:blank"), shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); // The main frame document should never be filtered. SetRulesetToDisallowURLsWithPathSuffix("frame_with_included_script.html"); NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); } // Verifies that subframes are not blocked on non-activated URLs. @@ -227,7 +232,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, "suffix-that-does-not-match-anything")); NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); // Verify that the "ad" subframe is loaded if even it is flagged by the // ruleset as the URL is not activated. @@ -235,7 +241,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, SetRulesetToDisallowURLsWithPathSuffix("included_script.js")); NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); } IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, @@ -250,7 +257,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, ActivateSubresourceFilterInWebContentsForURL(web_contents, test_url); NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); content::WebContentsConsoleObserver console_observer(web_contents); console_observer.SetPattern(subresource_filter::kActivationConsoleMessage); @@ -263,7 +271,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, test_url, test_url, ContentSettingsType::ADS, CONTENT_SETTING_ALLOW); NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); // No message for allowlisted url. EXPECT_TRUE(console_observer.messages().empty()); @@ -281,7 +290,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, ActivateSubresourceFilterInWebContentsForURL(web_contents, test_url); NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); content::WebContentsConsoleObserver console_observer(web_contents); console_observer.SetPattern(subresource_filter::kActivationConsoleMessage); @@ -294,7 +304,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, CONTENT_SETTING_ALLOW); NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); // No message for loads that are not activated. EXPECT_TRUE(console_observer.messages().empty()); @@ -360,14 +371,16 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, ActivateSubresourceFilterInWebContentsForURL(web_contents, test_url); NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); // Allowlist via a reload. content::TestNavigationObserver navigation_observer(web_contents, 1); GetPrimaryPageThrottleManager()->OnReloadRequested(); navigation_observer.Wait(); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); } IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, @@ -381,28 +394,32 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, ActivateSubresourceFilterInWebContentsForURL(web_contents, test_url); NavigateAndWaitForCompletion(test_url, shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); // Allowlist via a reload. content::TestNavigationObserver navigation_observer(web_contents, 1); GetPrimaryPageThrottleManager()->OnReloadRequested(); navigation_observer.Wait(); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); // Another navigation to the same domain should be allowed too. NavigateAndWaitForCompletion( embedded_test_server()->GetURL( "/subresource_filter/frame_with_included_script.html?query"), shell()); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); // A cross site blocklisted navigation should stay activated, however. GURL a_url(embedded_test_server()->GetURL( "a.com", "/subresource_filter/frame_with_included_script.html")); ActivateSubresourceFilterInWebContentsForURL(web_contents, a_url); NavigateAndWaitForCompletion(a_url, shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); } IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, @@ -425,7 +442,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, // Should not trigger activation as the URL is not on the blocklist and // has no active ads interventions. NavigateAndWaitForCompletion(url, shell()); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0); histogram_tester.ExpectTotalCount(kTimeSinceAdsInterventionTriggeredHistogram, 0); @@ -436,11 +454,12 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, // Trigger an ads violation and renavigate the page. Should trigger // subresource filter activation. GetPrimaryPageThrottleManager()->OnAdsViolationTriggered( - web_contents->GetMainFrame(), + web_contents->GetPrimaryMainFrame(), subresource_filter::mojom::AdsViolation::kMobileAdDensityByHeightAbove30); NavigateAndWaitForCompletion(url, shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( kAdsInterventionRecordedHistogram, static_cast<int>(subresource_filter::mojom::AdsViolation:: @@ -465,7 +484,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, test_clock->Advance(subresource_filter::kAdsInterventionDuration.Get()); NavigateAndWaitForCompletion(url, shell()); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( kAdsInterventionRecordedHistogram, static_cast<int>(subresource_filter::mojom::AdsViolation:: @@ -512,7 +532,8 @@ IN_PROC_BROWSER_TEST_F( // Should not trigger activation as the URL is not on the blocklist and // has no active ads interventions. NavigateAndWaitForCompletion(url, shell()); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); histogram_tester.ExpectTotalCount(kAdsInterventionRecordedHistogram, 0); histogram_tester.ExpectTotalCount(kTimeSinceAdsInterventionTriggeredHistogram, 0); @@ -523,11 +544,12 @@ IN_PROC_BROWSER_TEST_F( // Trigger an ads violation and renavigate the page. Should trigger // subresource filter activation. GetPrimaryPageThrottleManager()->OnAdsViolationTriggered( - web_contents->GetMainFrame(), + web_contents->GetPrimaryMainFrame(), subresource_filter::mojom::AdsViolation::kMobileAdDensityByHeightAbove30); NavigateAndWaitForCompletion(url, shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( kAdsInterventionRecordedHistogram, static_cast<int>(subresource_filter::mojom::AdsViolation:: @@ -553,7 +575,7 @@ IN_PROC_BROWSER_TEST_F( test_clock->Advance(subresource_filter::kAdsInterventionDuration.Get() - base::Minutes(30)); GetPrimaryPageThrottleManager()->OnAdsViolationTriggered( - web_contents->GetMainFrame(), + web_contents->GetPrimaryMainFrame(), subresource_filter::mojom::AdsViolation::kMobileAdDensityByHeightAbove30); // Advance the clock to to kAdsInterventionDuration from the first @@ -561,7 +583,8 @@ IN_PROC_BROWSER_TEST_F( test_clock->Advance(base::Minutes(30)); NavigateAndWaitForCompletion(url, shell()); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( kAdsInterventionRecordedHistogram, static_cast<int>(subresource_filter::mojom::AdsViolation:: @@ -620,7 +643,8 @@ IN_PROC_BROWSER_TEST_F( // Should not trigger activation as the URL is not on the blocklist and // has no active ads interventions. NavigateAndWaitForCompletion(url, shell()); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); auto entries = ukm_recorder.GetEntriesByName( ukm::builders::AdsIntervention_LastIntervention::kEntryName); EXPECT_EQ(0u, entries.size()); @@ -628,14 +652,15 @@ IN_PROC_BROWSER_TEST_F( // Trigger an ads violation and renavigate to the page. Interventions are not // enforced so no activation should occur. GetPrimaryPageThrottleManager()->OnAdsViolationTriggered( - web_contents->GetMainFrame(), + web_contents->GetPrimaryMainFrame(), subresource_filter::mojom::AdsViolation::kMobileAdDensityByHeightAbove30); const base::TimeDelta kRenavigationDelay = base::Hours(2); test_clock->Advance(kRenavigationDelay); NavigateAndWaitForCompletion(url, shell()); - EXPECT_TRUE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_TRUE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( kAdsInterventionRecordedHistogram, static_cast<int>(subresource_filter::mojom::AdsViolation:: @@ -687,7 +712,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, // First load should trigger the UI. NavigateAndWaitForCompletion(a_url, shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( kSubresourceFilterActionsHistogram, @@ -698,7 +724,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, // Second load should not trigger the UI, but should still filter content. NavigateAndWaitForCompletion(a_url, shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( kSubresourceFilterActionsHistogram, @@ -711,7 +738,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, // Load to another domain should trigger the UI. NavigateAndWaitForCompletion(b_url, shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( kSubresourceFilterActionsHistogram, @@ -724,7 +752,8 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, subresource_filter::SubresourceFilterContentSettingsManager:: kDelayBeforeShowingInfobarAgain); NavigateAndWaitForCompletion(a_url, shell()); - EXPECT_FALSE(WasParsedScriptElementLoaded(web_contents->GetMainFrame())); + EXPECT_FALSE( + WasParsedScriptElementLoaded(web_contents->GetPrimaryMainFrame())); histogram_tester.ExpectBucketCount( kSubresourceFilterActionsHistogram, diff --git a/chromium/weblayer/browser/tab_impl.cc b/chromium/weblayer/browser/tab_impl.cc index b2afe8ab042..30a1743caab 100644 --- a/chromium/weblayer/browser/tab_impl.cc +++ b/chromium/weblayer/browser/tab_impl.cc @@ -52,14 +52,18 @@ #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" +#include "content/public/browser/permission_controller.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/renderer_preferences_util.h" #include "content/public/browser/web_contents.h" +#include "third_party/blink/public/common/permissions/permission_utils.h" #include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h" #include "third_party/blink/public/common/web_preferences/web_preferences.h" #include "third_party/blink/public/mojom/context_menu/context_menu.mojom.h" +#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h" +#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h" #include "third_party/blink/public/mojom/window_features/window_features.mojom.h" #include "ui/base/window_open_disposition.h" #include "weblayer/browser/autofill_client_impl.h" @@ -79,7 +83,6 @@ #include "weblayer/browser/page_load_metrics_initialize.h" #include "weblayer/browser/page_specific_content_settings_delegate.h" #include "weblayer/browser/password_manager_driver_factory.h" -#include "weblayer/browser/permissions/permission_manager_factory.h" #include "weblayer/browser/persistence/browser_persister.h" #include "weblayer/browser/popup_navigation_delegate_impl.h" #include "weblayer/browser/profile_impl.h" @@ -130,6 +133,7 @@ #include "weblayer/browser/safe_browsing/weblayer_safe_browsing_tab_observer_delegate.h" #include "weblayer/browser/translate_client_impl.h" #include "weblayer/browser/url_bar/trusted_cdn_observer.h" +#include "weblayer/browser/webapps/weblayer_app_banner_manager_android.h" #include "weblayer/browser/weblayer_factory_impl_android.h" #include "weblayer/browser/webrtc/media_stream_manager.h" #include "weblayer/common/features.h" @@ -435,6 +439,11 @@ TabImpl::TabImpl(ProfileImpl* profile, PrerenderTabHelper::CreateForWebContents(web_contents_.get()); webapps::InstallableManager::CreateForWebContents(web_contents_.get()); + +#if BUILDFLAG(IS_ANDROID) + // Must be created after InstallableManager. + WebLayerAppBannerManagerAndroid::CreateForWebContents(web_contents_.get()); +#endif } TabImpl::~TabImpl() { @@ -543,12 +552,12 @@ void TabImpl::ExecuteScript(const std::u16string& script, bool use_separate_isolate, JavaScriptResultCallback callback) { if (use_separate_isolate) { - web_contents_->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld( + web_contents_->GetPrimaryMainFrame()->ExecuteJavaScriptInIsolatedWorld( script, std::move(callback), ISOLATED_WORLD_ID_WEBLAYER); } else { content::RenderFrameHost::AllowInjectingJavaScript(); - web_contents_->GetMainFrame()->ExecuteJavaScript(script, - std::move(callback)); + web_contents_->GetPrimaryMainFrame()->ExecuteJavaScript( + script, std::move(callback)); } } @@ -587,8 +596,8 @@ void TabImpl::RemoveWebMessageHostFactory( void TabImpl::ExecuteScriptWithUserGestureForTests( const std::u16string& script) { - web_contents_->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests( - script, base::NullCallback()); + web_contents_->GetPrimaryMainFrame() + ->ExecuteJavaScriptWithUserGestureForTests(script, base::NullCallback()); } std::unique_ptr<FaviconFetcher> TabImpl::CreateFaviconFetcher( @@ -1121,8 +1130,9 @@ void TabImpl::RequestMediaAccessPermission( MediaStreamManager::FromWebContents(web_contents) ->RequestMediaAccessPermission(request, std::move(callback)); #else - std::move(callback).Run( - {}, blink::mojom::MediaStreamRequestResult::NOT_SUPPORTED, nullptr); + std::move(callback).Run(blink::mojom::StreamDevicesSet(), + blink::mojom::MediaStreamRequestResult::NOT_SUPPORTED, + nullptr); #endif } @@ -1132,15 +1142,25 @@ bool TabImpl::CheckMediaAccessPermission( blink::mojom::MediaStreamType type) { DCHECK(type == blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE || type == blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE); - ContentSettingsType content_settings_type = + blink::PermissionType permission_type = type == blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE - ? ContentSettingsType::MEDIASTREAM_MIC - : ContentSettingsType::MEDIASTREAM_CAMERA; - return PermissionManagerFactory::GetForBrowserContext( - render_frame_host->GetBrowserContext()) - ->GetPermissionStatusForFrame(content_settings_type, - render_frame_host, security_origin) - .content_setting == CONTENT_SETTING_ALLOW; + ? blink::PermissionType::AUDIO_CAPTURE + : blink::PermissionType::VIDEO_CAPTURE; + + // TODO(crbug.com/1321100): Remove `security_origin`. + if (render_frame_host->GetLastCommittedOrigin().GetURL() != security_origin) { + return false; + } + // It is OK to ignore `security_origin` because it will be calculated from + // `render_frame_host` and we always ignore `requesting_origin` for + // `AUDIO_CAPTURE` and `VIDEO_CAPTURE`. + // `render_frame_host->GetMainFrame()->GetLastCommittedOrigin()` will be used + // instead. + return render_frame_host->GetBrowserContext() + ->GetPermissionController() + ->GetPermissionStatusForCurrentDocument(permission_type, + render_frame_host) == + blink::mojom::PermissionStatus::GRANTED; } void TabImpl::EnterFullscreenModeForTab( @@ -1392,16 +1412,13 @@ void TabImpl::InitializeAutofillDriver() { AutofillClientImpl::CreateForWebContents(web_contents); - autofill::AutofillManager::AutofillDownloadManagerState - enable_autofill_download_manager = - autofill::AutofillProvider::is_download_manager_disabled_for_testing() - ? autofill::AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER - : autofill::AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER; - autofill::ContentAutofillDriverFactory::CreateForWebContentsAndDelegate( web_contents, AutofillClientImpl::FromWebContents(web_contents), - i18n::GetApplicationLocale(), enable_autofill_download_manager, - base::BindRepeating(&autofill::AndroidAutofillManager::Create)); + base::BindRepeating(&autofill::AndroidDriverInitHook, + AutofillClientImpl::FromWebContents(web_contents), + autofill::AutofillManager::EnableDownloadManager( + !autofill::AutofillProvider:: + is_download_manager_disabled_for_testing()))); } #endif // BUILDFLAG(IS_ANDROID) diff --git a/chromium/weblayer/browser/translate_accept_languages_factory.h b/chromium/weblayer/browser/translate_accept_languages_factory.h deleted file mode 100644 index 257bcf1ed64..00000000000 --- a/chromium/weblayer/browser/translate_accept_languages_factory.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef WEBLAYER_BROWSER_TRANSLATE_ACCEPT_LANGUAGES_FACTORY_H_ -#define WEBLAYER_BROWSER_TRANSLATE_ACCEPT_LANGUAGES_FACTORY_H_ - -#include "base/no_destructor.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace translate { -class TranslateAcceptLanguages; -} - -namespace weblayer { - -// TranslateAcceptLanguagesFactory is a way to associate a -// TranslateAcceptLanguages instance to a BrowserContext. -class TranslateAcceptLanguagesFactory - : public BrowserContextKeyedServiceFactory { - public: - TranslateAcceptLanguagesFactory(const TranslateAcceptLanguagesFactory&) = - delete; - TranslateAcceptLanguagesFactory& operator=( - const TranslateAcceptLanguagesFactory&) = delete; - - static translate::TranslateAcceptLanguages* GetForBrowserContext( - content::BrowserContext* browser_context); - static TranslateAcceptLanguagesFactory* GetInstance(); - - private: - friend class base::NoDestructor<TranslateAcceptLanguagesFactory>; - - TranslateAcceptLanguagesFactory(); - ~TranslateAcceptLanguagesFactory() override; - - // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* profile) const override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; -}; - -} // namespace weblayer - -#endif // WEBLAYER_BROWSER_TRANSLATE_ACCEPT_LANGUAGES_FACTORY_H_ diff --git a/chromium/weblayer/browser/translate_client_impl.cc b/chromium/weblayer/browser/translate_client_impl.cc index 5b02cad7367..99c1b298b9e 100644 --- a/chromium/weblayer/browser/translate_client_impl.cc +++ b/chromium/weblayer/browser/translate_client_impl.cc @@ -17,12 +17,12 @@ #include "components/variations/service/variations_service.h" #include "content/public/common/url_constants.h" #include "url/gurl.h" +#include "weblayer/browser/accept_languages_service_factory.h" #include "weblayer/browser/browser_context_impl.h" #include "weblayer/browser/feature_list_creator.h" #include "weblayer/browser/navigation_controller_impl.h" #include "weblayer/browser/page_impl.h" #include "weblayer/browser/tab_impl.h" -#include "weblayer/browser/translate_accept_languages_factory.h" #include "weblayer/browser/translate_ranker_factory.h" #if BUILDFLAG(IS_ANDROID) @@ -114,9 +114,9 @@ TranslateClientImpl::GetTranslatePrefs() { return CreateTranslatePrefs(GetPrefs()); } -translate::TranslateAcceptLanguages* -TranslateClientImpl::GetTranslateAcceptLanguages() { - return TranslateAcceptLanguagesFactory::GetForBrowserContext( +language::AcceptLanguagesService* +TranslateClientImpl::GetAcceptLanguagesService() { + return AcceptLanguagesServiceFactory::GetForBrowserContext( web_contents()->GetBrowserContext()); } @@ -148,16 +148,16 @@ void TranslateClientImpl::OnLanguageDetermined( // to the most recently committed primary main-frame navigation, if one exists // (see the call to SetPageLanguageInNavigation() in // ContentTranslateDriver::RegisterPage()); this corresponds to - // WebContents::GetMainFrame()::GetPage(). Note also that in certain corner - // cases (e.g., tab startup) there might not be such a committed primary - // main-frame navigation; in those cases there won't be a weblayer::Page - // corresponding to the primary page, as weblayer::Page objects are created - // only at navigation commit. + // WebContents::GetPrimaryMainFrame()::GetPage(). Note also that in certain + // corner cases (e.g., tab startup) there might not be such a committed + // primary main-frame navigation; in those cases there won't be a + // weblayer::Page corresponding to the primary page, as weblayer::Page objects + // are created only at navigation commit. // TODO(crbug.com/1231889): Rearchitect translate's renderer-browser Mojo // connection to be able to explicitly determine the document/content::Page // with which this language determination event is associated. PageImpl* page = - PageImpl::GetForPage(web_contents()->GetMainFrame()->GetPage()); + PageImpl::GetForPage(web_contents()->GetPrimaryMainFrame()->GetPage()); if (page) { std::string language = details.adopted_language; diff --git a/chromium/weblayer/browser/translate_client_impl.h b/chromium/weblayer/browser/translate_client_impl.h index db471c840e7..a5b025a75a5 100644 --- a/chromium/weblayer/browser/translate_client_impl.h +++ b/chromium/weblayer/browser/translate_client_impl.h @@ -53,7 +53,7 @@ class TranslateClientImpl translate::TranslateDriver* GetTranslateDriver() override; PrefService* GetPrefs() override; std::unique_ptr<translate::TranslatePrefs> GetTranslatePrefs() override; - translate::TranslateAcceptLanguages* GetTranslateAcceptLanguages() override; + language::AcceptLanguagesService* GetAcceptLanguagesService() override; #if BUILDFLAG(IS_ANDROID) std::unique_ptr<infobars::InfoBar> CreateInfoBar( std::unique_ptr<translate::TranslateInfoBarDelegate> delegate) diff --git a/chromium/weblayer/browser/web_contents_view_delegate_impl.cc b/chromium/weblayer/browser/web_contents_view_delegate_impl.cc index cf0ca040635..40efc02920b 100644 --- a/chromium/weblayer/browser/web_contents_view_delegate_impl.cc +++ b/chromium/weblayer/browser/web_contents_view_delegate_impl.cc @@ -4,6 +4,8 @@ #include "weblayer/browser/web_contents_view_delegate_impl.h" +#include <memory> + #include "weblayer/browser/tab_impl.h" namespace weblayer { @@ -22,9 +24,9 @@ void WebContentsViewDelegateImpl::ShowContextMenu( tab->ShowContextMenu(params); } -content::WebContentsViewDelegate* CreateWebContentsViewDelegate( +std::unique_ptr<content::WebContentsViewDelegate> CreateWebContentsViewDelegate( content::WebContents* web_contents) { - return new WebContentsViewDelegateImpl(web_contents); + return std::make_unique<WebContentsViewDelegateImpl>(web_contents); } } // namespace weblayer diff --git a/chromium/weblayer/browser/webapps/webapk_install_scheduler.cc b/chromium/weblayer/browser/webapps/webapk_install_scheduler.cc new file mode 100644 index 00000000000..fe275568059 --- /dev/null +++ b/chromium/weblayer/browser/webapps/webapk_install_scheduler.cc @@ -0,0 +1,126 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "weblayer/browser/webapps/webapk_install_scheduler.h" + +#include <utility> + +#include "base/bind.h" +#include "base/task/task_runner_util.h" +#include "base/task/thread_pool.h" +#include "components/webapps/browser/android/shortcut_info.h" +#include "components/webapps/browser/android/webapk/webapk_icon_hasher.h" +#include "components/webapps/browser/android/webapk/webapk_proto_builder.h" +#include "components/webapps/browser/android/webapk/webapk_types.h" +#include "components/webapps/browser/android/webapps_utils.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/browser/web_contents.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "url/gurl.h" +#include "weblayer/browser/webapps/webapk_install_scheduler_bridge.h" + +namespace weblayer { + +WebApkInstallScheduler::WebApkInstallScheduler( + const webapps::ShortcutInfo& shortcut_info, + const SkBitmap& primary_icon, + bool is_primary_icon_maskable, + WebApkInstallFinishedCallback callback) + : webapps_client_callback_(std::move(callback)), + primary_icon_(primary_icon), + is_primary_icon_maskable_(is_primary_icon_maskable) { + shortcut_info_ = std::make_unique<webapps::ShortcutInfo>(shortcut_info); +} + +WebApkInstallScheduler::~WebApkInstallScheduler() = default; + +// static +void WebApkInstallScheduler::FetchProtoAndScheduleInstall( + content::WebContents* web_contents, + const webapps::ShortcutInfo& shortcut_info, + const SkBitmap& primary_icon, + bool is_primary_icon_maskable, + WebApkInstallFinishedCallback callback) { + // Self owned WebApkInstallScheduler that destroys itself as soon as its + // OnResult function is called when the scheduled installation failed or + // finished. + WebApkInstallScheduler* scheduler = + new WebApkInstallScheduler(shortcut_info, primary_icon, + is_primary_icon_maskable, std::move(callback)); + scheduler->FetchMurmur2Hashes(web_contents); +} + +void WebApkInstallScheduler::FetchProtoAndScheduleInstallForTesting( + content::WebContents* web_contents) { + FetchMurmur2Hashes(web_contents); +} + +void WebApkInstallScheduler::FetchMurmur2Hashes( + content::WebContents* web_contents) { + // We need to take the hash of the bitmap at the icon URL prior to any + // transformations being applied to the bitmap (such as encoding/decoding + // the bitmap). The icon hash is used to determine whether the icon that + // the user sees matches the icon of a WebAPK that the WebAPK server + // generated for another user. (The icon can be dynamically generated.) + // + // We redownload the icon in order to take the Murmur2 hash. The redownload + // should be fast because the icon should be in the HTTP cache. + std::set<GURL> icons = shortcut_info_->GetWebApkIcons(); + + webapps::WebApkIconHasher::DownloadAndComputeMurmur2Hash( + web_contents->GetBrowserContext() + ->GetDefaultStoragePartition() + ->GetURLLoaderFactoryForBrowserProcess() + .get(), + web_contents->GetWeakPtr(), url::Origin::Create(shortcut_info_->url), + icons, + base::BindOnce(&WebApkInstallScheduler::OnGotIconMurmur2HashesBuildProto, + weak_ptr_factory_.GetWeakPtr())); +} + +void WebApkInstallScheduler::OnGotIconMurmur2HashesBuildProto( + absl::optional<std::map<std::string, webapps::WebApkIconHasher::Icon>> + hashes) { + if (!hashes) { + OnResult(webapps::WebApkInstallResult::ICON_HASHER_ERROR); + return; + } + + webapps::BuildProto( + *shortcut_info_.get(), std::string() /* primary_icon_data */, + is_primary_icon_maskable_, std::string() /* splash_icon_data */, + "" /* package_name */, "" /* version */, std::move(*hashes), + false /* is_manifest_stale */, + false /* is_app_identity_update_supported */, + base::BindOnce(&WebApkInstallScheduler::ScheduleWithChrome, + weak_ptr_factory_.GetWeakPtr())); +} + +void WebApkInstallScheduler::ScheduleWithChrome( + std::unique_ptr<std::string> serialized_proto) { + WebApkInstallSchedulerBridge::ScheduleWebApkInstallWithChrome( + std::move(serialized_proto), primary_icon_, is_primary_icon_maskable_, + base::BindOnce(&WebApkInstallScheduler::OnResult, + weak_ptr_factory_.GetWeakPtr())); +} + +void WebApkInstallScheduler::OnResult(webapps::WebApkInstallResult result) { + // Toasts have to be called on the UI thread, but the + // WebApkInstallSchedulerClient already makes sure that the callback, which is + // triggered by the Chrome-service, is invoked on the UI thread. + webapps::WebappsUtils::ShowWebApkInstallResultToast(result); + + std::move(webapps_client_callback_).Run(shortcut_info_->manifest_url); + delete this; +} + +// static +bool WebApkInstallScheduler::IsInstallServiceAvailable() { + return WebApkInstallSchedulerBridge::IsInstallServiceAvailable(); +} + +} // namespace weblayer
\ No newline at end of file diff --git a/chromium/weblayer/browser/webapps/webapk_install_scheduler.h b/chromium/weblayer/browser/webapps/webapk_install_scheduler.h new file mode 100644 index 00000000000..7ff51611f6b --- /dev/null +++ b/chromium/weblayer/browser/webapps/webapk_install_scheduler.h @@ -0,0 +1,88 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBLAYER_BROWSER_WEBAPPS_WEBAPK_INSTALL_SCHEDULER_H_ +#define WEBLAYER_BROWSER_WEBAPPS_WEBAPK_INSTALL_SCHEDULER_H_ + +#include <memory> + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "components/webapps/browser/android/webapk/webapk_icon_hasher.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "weblayer/browser/webapps/weblayer_webapps_client.h" + +namespace content { +class WebContents; +} // namespace content + +namespace webapps { +struct ShortcutInfo; +enum class WebApkInstallResult; +} // namespace webapps + +namespace weblayer { + +class WebApkInstallSchedulerBridge; + +// Class that schedules the WebAPK installation via the Chrome +// WebApkInstallCoordinatorService. Creates a self-owned +// WebApkInstallSchedulerBridge instance when building the proto is complete. +// |finish_callback| is called once the install completed or failed. +class WebApkInstallScheduler { + public: + // Called when the scheduling of an WebAPK-installation with the Chrome + // service finished or failed. + using FinishCallback = base::OnceCallback<void(webapps::WebApkInstallResult)>; + + virtual ~WebApkInstallScheduler(); + using WebApkInstallFinishedCallback = + weblayer::WebLayerWebappsClient::WebApkInstallFinishedCallback; + + WebApkInstallScheduler(const WebApkInstallScheduler&) = delete; + WebApkInstallScheduler& operator=(const WebApkInstallScheduler&) = delete; + + static void FetchProtoAndScheduleInstall( + content::WebContents* web_contents, + const webapps::ShortcutInfo& shortcut_info, + const SkBitmap& primary_icon, + bool is_primary_icon_maskable, + WebApkInstallFinishedCallback callback); + + void FetchProtoAndScheduleInstallForTesting( + content::WebContents* web_contents); + + static bool IsInstallServiceAvailable(); + + private: + WebApkInstallScheduler(const webapps::ShortcutInfo& shortcut_info, + const SkBitmap& primary_icon, + bool is_primary_icon_maskable, + WebApkInstallFinishedCallback callback); + + friend class TestWebApkInstallScheduler; + + void FetchMurmur2Hashes(content::WebContents* web_contents); + + void OnGotIconMurmur2HashesBuildProto( + absl::optional<std::map<std::string, webapps::WebApkIconHasher::Icon>> + hashes); + + virtual void ScheduleWithChrome( + std::unique_ptr<std::string> serialized_proto); + + virtual void OnResult(webapps::WebApkInstallResult result); + + WebApkInstallFinishedCallback webapps_client_callback_; + std::unique_ptr<webapps::ShortcutInfo> shortcut_info_; + const SkBitmap primary_icon_; + bool is_primary_icon_maskable_; + + // Used to get |weak_ptr_|. + base::WeakPtrFactory<WebApkInstallScheduler> weak_ptr_factory_{this}; +}; + +} // namespace weblayer + +#endif // WEBLAYER_BROWSER_WEBAPPS_WEBAPK_INSTALL_SCHEDULER_H_ diff --git a/chromium/weblayer/browser/webapps/webapk_install_scheduler_bridge.cc b/chromium/weblayer/browser/webapps/webapk_install_scheduler_bridge.cc new file mode 100644 index 00000000000..ef8d641412d --- /dev/null +++ b/chromium/weblayer/browser/webapps/webapk_install_scheduler_bridge.cc @@ -0,0 +1,84 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "weblayer/browser/webapps/webapk_install_scheduler_bridge.h" + +#include <jni.h> +#include <string> + +#include "base/android/jni_array.h" +#include "base/android/jni_string.h" +#include "components/webapps/browser/android/webapk/webapk_types.h" +#include "ui/gfx/android/java_bitmap.h" +#include "url/gurl.h" +#include "weblayer/browser/java/jni/WebApkInstallSchedulerBridge_jni.h" + +using base::android::ConvertUTF16ToJavaString; +using base::android::ScopedJavaLocalRef; +using base::android::ToJavaByteArray; +using gfx::ConvertToJavaBitmap; + +namespace weblayer { + +// static +bool WebApkInstallSchedulerBridge::IsInstallServiceAvailable() { + return Java_WebApkInstallSchedulerBridge_isInstallServiceAvailable( + base::android::AttachCurrentThread()); +} + +WebApkInstallSchedulerBridge::WebApkInstallSchedulerBridge( + FinishCallback finish_callback) { + finish_callback_ = std::move(finish_callback); + + JNIEnv* env = base::android::AttachCurrentThread(); + java_ref_.Reset(Java_WebApkInstallSchedulerBridge_create( + env, reinterpret_cast<intptr_t>(this))); +} + +WebApkInstallSchedulerBridge::~WebApkInstallSchedulerBridge() { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_WebApkInstallSchedulerBridge_destroy(env, java_ref_); + java_ref_.Reset(); +} + +// static +void WebApkInstallSchedulerBridge::ScheduleWebApkInstallWithChrome( + std::unique_ptr<std::string> serialized_proto, + const SkBitmap& primary_icon, + bool is_primary_icon_maskable, + FinishCallback finish_callback) { + // WebApkInstallSchedulerBridge owns itself and deletes itself when finished. + WebApkInstallSchedulerBridge* bridge = + new WebApkInstallSchedulerBridge(std::move(finish_callback)); + bridge->ScheduleWebApkInstallWithChrome( + std::move(serialized_proto), primary_icon, is_primary_icon_maskable); +} + +void WebApkInstallSchedulerBridge::ScheduleWebApkInstallWithChrome( + std::unique_ptr<std::string> serialized_proto, + const SkBitmap& primary_icon, + bool is_primary_icon_maskable) { + JNIEnv* env = base::android::AttachCurrentThread(); + + ScopedJavaLocalRef<jbyteArray> java_serialized_proto = + ToJavaByteArray(env, *serialized_proto); + ScopedJavaLocalRef<jobject> java_primary_icon = + ConvertToJavaBitmap(primary_icon); + + Java_WebApkInstallSchedulerBridge_scheduleInstall( + env, java_ref_, java_serialized_proto, java_primary_icon, + is_primary_icon_maskable); +} + +void WebApkInstallSchedulerBridge::OnInstallFinished( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jint result) { + std::move(finish_callback_) + .Run(static_cast<webapps::WebApkInstallResult>(result)); + + delete this; +} + +} // namespace weblayer
\ No newline at end of file diff --git a/chromium/weblayer/browser/webapps/webapk_install_scheduler_bridge.h b/chromium/weblayer/browser/webapps/webapk_install_scheduler_bridge.h new file mode 100644 index 00000000000..41e10e47f66 --- /dev/null +++ b/chromium/weblayer/browser/webapps/webapk_install_scheduler_bridge.h @@ -0,0 +1,59 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBLAYER_BROWSER_WEBAPPS_WEBAPK_INSTALL_SCHEDULER_BRIDGE_H_ +#define WEBLAYER_BROWSER_WEBAPPS_WEBAPK_INSTALL_SCHEDULER_BRIDGE_H_ + +#include "base/android/scoped_java_ref.h" +#include "components/webapps/browser/android/webapk/webapk_icon_hasher.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "weblayer/browser/webapps/webapk_install_scheduler.h" + +namespace webapps { +enum class WebApkInstallResult; +} // namespace webapps + +namespace weblayer { + +// The native WebApkInstallSchedulerBridge owns itself, and deletes itself and +// its Java counterpart when finished. +class WebApkInstallSchedulerBridge { + public: + using FinishCallback = WebApkInstallScheduler::FinishCallback; + + ~WebApkInstallSchedulerBridge(); + + WebApkInstallSchedulerBridge(const WebApkInstallSchedulerBridge&) = delete; + WebApkInstallSchedulerBridge& operator=(const WebApkInstallSchedulerBridge&) = + delete; + + static void ScheduleWebApkInstallWithChrome( + std::unique_ptr<std::string> serialized_proto, + const SkBitmap& primary_icon, + bool is_primary_icon_maskable, + FinishCallback finish_callback); + + static bool IsInstallServiceAvailable(); + + void OnInstallFinished(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + jint result); + + private: + WebApkInstallSchedulerBridge(FinishCallback finish_callback); + + void ScheduleWebApkInstallWithChrome( + std::unique_ptr<std::string> serialized_proto, + const SkBitmap& primary_icon, + bool is_primary_icon_maskable); + + FinishCallback finish_callback_; + + // Points to the Java Object. + base::android::ScopedJavaGlobalRef<jobject> java_ref_; +}; + +} // namespace weblayer + +#endif // WEBLAYER_BROWSER_WEBAPPS_WEBAPK_INSTALL_SCHEDULER_BRIDGE_H_ diff --git a/chromium/weblayer/browser/webapps/webapk_install_scheduler_browsertest.cc b/chromium/weblayer/browser/webapps/webapk_install_scheduler_browsertest.cc new file mode 100644 index 00000000000..6f563ebbb8e --- /dev/null +++ b/chromium/weblayer/browser/webapps/webapk_install_scheduler_browsertest.cc @@ -0,0 +1,234 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "weblayer/browser/webapps/webapk_install_scheduler.h" + +#include "base/files/file_path.h" +#include "base/run_loop.h" +#include "components/webapps/browser/android/shortcut_info.h" +#include "components/webapps/browser/android/webapk/webapk_types.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "weblayer/browser/tab_impl.h" +#include "weblayer/shell/browser/shell.h" +#include "weblayer/test/weblayer_browser_test.h" + +// Keep these tests in sync with tests for building the WebAPK-proto in +// chrome/browser/android/webapk/webapk_installer_unittest.cc. + +namespace { + +const base::FilePath::CharType kTestDataDir[] = + FILE_PATH_LITERAL("components/test/data/webapps"); + +// Start URL for the WebAPK +const char* kStartUrl = "/index.html"; + +// The URLs of best icons from Web Manifest. We use a random file in the test +// data directory. Since WebApkInstallScheduler does not try to decode the file +// as an image it is OK that the file is not an image. +const char* kBestPrimaryIconUrl = "/simple.html"; +const char* kBestSplashIconUrl = "/nostore.html"; +const char* kBestShortcutIconUrl = "/title1.html"; + +// Icon which has Cross-Origin-Resource-Policy: same-origin set. +const char* kBestPrimaryIconCorpUrl = "/cors_same_origin.png"; + +} // namespace + +namespace weblayer { + +class TestWebApkInstallScheduler : public WebApkInstallScheduler { + public: + TestWebApkInstallScheduler(const webapps::ShortcutInfo& shortcut_info, + const SkBitmap& primary_icon, + bool is_primary_icon_maskable, + WebApkInstallFinishedCallback callback) + : WebApkInstallScheduler(shortcut_info, + primary_icon, + is_primary_icon_maskable, + std::move(callback)) {} + + TestWebApkInstallScheduler(const TestWebApkInstallScheduler&) = delete; + TestWebApkInstallScheduler& operator=(const TestWebApkInstallScheduler&) = + delete; + + void ScheduleWithChrome( + std::unique_ptr<std::string> serialized_proto) override { + PostTaskToRunSuccessCallback(); + } + + // Function used for testing FetchProtoAndScheduleInstall. |callback| can + // be set to forward the result-value in the OnResult-callback to a test for + // verification. + void FetchProtoAndScheduleInstallForTesting( + content::WebContents* web_contents, + WebApkInstallScheduler::FinishCallback callback) { + callback_ = std::move(callback); + + WebApkInstallScheduler::FetchProtoAndScheduleInstallForTesting( + web_contents); + } + + void OnResult(webapps::WebApkInstallResult result) override { + // Pass the |result| to the callback for verification. + std::move(callback_).Run(result); + + WebApkInstallScheduler::OnResult(result); + } + + void PostTaskToRunSuccessCallback() { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&TestWebApkInstallScheduler::OnResult, + base::Unretained(this), + webapps::WebApkInstallResult::SUCCESS)); + } + + private: + WebApkInstallScheduler::FinishCallback callback_; +}; + +// Wrapper class for running WebApkInstallScheduler#FetchProtoAndScheduleInstall +// that makes the WebApkInstallResult that is received in the OnResult-callback +// accessible for testing. +class WebApkInstallSchedulerRunner { + public: + WebApkInstallSchedulerRunner() {} + + WebApkInstallSchedulerRunner(const WebApkInstallSchedulerRunner&) = delete; + WebApkInstallSchedulerRunner& operator=(const WebApkInstallSchedulerRunner&) = + delete; + + ~WebApkInstallSchedulerRunner() {} + + void RunFetchProtoAndScheduleInstall( + std::unique_ptr<TestWebApkInstallScheduler> fetcher, + content::WebContents* web_contents) { + base::RunLoop run_loop; + on_completed_callback_ = run_loop.QuitClosure(); + + // WebApkInstallScheduler owns itself. + fetcher.release()->FetchProtoAndScheduleInstallForTesting( + web_contents, base::BindOnce(&WebApkInstallSchedulerRunner::OnCompleted, + base::Unretained(this))); + + run_loop.Run(); + } + + webapps::WebApkInstallResult result() { return result_; } + + private: + void OnCompleted(webapps::WebApkInstallResult result) { + result_ = result; + std::move(on_completed_callback_).Run(); + } + + // Called after the installation process has succeeded or failed. + base::OnceClosure on_completed_callback_; + + // The result of the installation process. + webapps::WebApkInstallResult result_; +}; + +class WebApkInstallSchedulerTest : public WebLayerBrowserTest { + public: + WebApkInstallSchedulerTest() = default; + ~WebApkInstallSchedulerTest() override = default; + + WebApkInstallSchedulerTest(const WebApkInstallSchedulerTest&) = delete; + WebApkInstallSchedulerTest& operator=(const WebApkInstallSchedulerTest&) = + delete; + + void SetUpOnMainThread() override { + WebLayerBrowserTest::SetUpOnMainThread(); + + web_contents_ = static_cast<TabImpl*>(shell()->tab())->web_contents(); + + test_server_.AddDefaultHandlers(base::FilePath(kTestDataDir)); + ASSERT_TRUE(test_server_.Start()); + } + + content::WebContents* web_contents() { return web_contents_; } + + net::test_server::EmbeddedTestServer* test_server() { return &test_server_; } + + std::unique_ptr<TestWebApkInstallScheduler> DefaultWebApkInstallScheduler( + webapps::ShortcutInfo info) { + std::unique_ptr<TestWebApkInstallScheduler> scheduler_bridge( + new TestWebApkInstallScheduler( + info, SkBitmap(), false, + base::BindOnce(&WebApkInstallSchedulerTest::OnInstallFinished, + base::Unretained(this)))); + return scheduler_bridge; + } + + webapps::ShortcutInfo DefaultShortcutInfo() { + webapps::ShortcutInfo info(test_server_.GetURL(kStartUrl)); + info.best_primary_icon_url = test_server_.GetURL(kBestPrimaryIconUrl); + info.splash_image_url = test_server_.GetURL(kBestSplashIconUrl); + info.best_shortcut_icon_urls.push_back( + test_server_.GetURL(kBestShortcutIconUrl)); + return info; + } + + private: + content::WebContents* web_contents_; + + net::EmbeddedTestServer test_server_; + + void OnInstallFinished(GURL manifest_url) {} +}; + +// Test building the WebAPK-proto is succeeding. +IN_PROC_BROWSER_TEST_F(WebApkInstallSchedulerTest, Success) { + WebApkInstallSchedulerRunner runner; + runner.RunFetchProtoAndScheduleInstall( + DefaultWebApkInstallScheduler(DefaultShortcutInfo()), web_contents()); + EXPECT_EQ(webapps::WebApkInstallResult::SUCCESS, runner.result()); +} + +// Test that building the WebAPK-proto succeeds when the primary icon is guarded +// by a Cross-Origin-Resource-Policy: same-origin header and the icon is +// same-origin with the start URL. +IN_PROC_BROWSER_TEST_F(WebApkInstallSchedulerTest, + CrossOriginResourcePolicySameOriginIconSuccess) { + webapps::ShortcutInfo shortcut_info = DefaultShortcutInfo(); + shortcut_info.best_primary_icon_url = + test_server()->GetURL(kBestPrimaryIconCorpUrl); + + WebApkInstallSchedulerRunner runner; + runner.RunFetchProtoAndScheduleInstall( + DefaultWebApkInstallScheduler(shortcut_info), web_contents()); + EXPECT_EQ(webapps::WebApkInstallResult::SUCCESS, runner.result()); +} + +// Test that building the WebAPK-proto fails if fetching the bitmap at the best +// primary icon URL returns no content. In a perfect world the fetch would +// always succeed because the fetch for the same icon succeeded recently. +IN_PROC_BROWSER_TEST_F(WebApkInstallSchedulerTest, + BestPrimaryIconUrlDownloadTimesOut) { + webapps::ShortcutInfo shortcut_info = DefaultShortcutInfo(); + shortcut_info.best_primary_icon_url = test_server()->GetURL("/nocontent"); + + WebApkInstallSchedulerRunner runner; + runner.RunFetchProtoAndScheduleInstall( + DefaultWebApkInstallScheduler(shortcut_info), web_contents()); + EXPECT_EQ(webapps::WebApkInstallResult::ICON_HASHER_ERROR, runner.result()); +} + +// Test that building the WebAPK-proto fails if fetching the bitmap at the best +// splash icon URL returns no content. In a perfect world the fetch would always +// succeed because the fetch for the same icon succeeded recently. +IN_PROC_BROWSER_TEST_F(WebApkInstallSchedulerTest, + BestSplashIconUrlDownloadTimesOut) { + webapps::ShortcutInfo shortcut_info = DefaultShortcutInfo(); + shortcut_info.best_primary_icon_url = test_server()->GetURL("/nocontent"); + + WebApkInstallSchedulerRunner runner; + runner.RunFetchProtoAndScheduleInstall( + DefaultWebApkInstallScheduler(shortcut_info), web_contents()); + EXPECT_EQ(webapps::WebApkInstallResult::ICON_HASHER_ERROR, runner.result()); +} + +} // namespace weblayer diff --git a/chromium/weblayer/browser/webapps/weblayer_app_banner_manager_android.cc b/chromium/weblayer/browser/webapps/weblayer_app_banner_manager_android.cc new file mode 100644 index 00000000000..7ccebde8123 --- /dev/null +++ b/chromium/weblayer/browser/webapps/weblayer_app_banner_manager_android.cc @@ -0,0 +1,55 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "weblayer/browser/webapps/weblayer_app_banner_manager_android.h" + +#include "components/webapps/browser/android/app_banner_manager_android.h" + +namespace weblayer { + +WebLayerAppBannerManagerAndroid::WebLayerAppBannerManagerAndroid( + content::WebContents* web_contents) + : AppBannerManagerAndroid(web_contents), + content::WebContentsUserData<WebLayerAppBannerManagerAndroid>( + *web_contents) {} + +WebLayerAppBannerManagerAndroid::~WebLayerAppBannerManagerAndroid() = default; + +webapps::InstallableParams +WebLayerAppBannerManagerAndroid::ParamsToPerformInstallableWebAppCheck() { + webapps::InstallableParams params = + AppBannerManagerAndroid::ParamsToPerformInstallableWebAppCheck(); + params.fetch_screenshots = true; + return params; +} + +void WebLayerAppBannerManagerAndroid::ShowAmbientBadge() { + webapps::WebappInstallSource install_source = + webapps::InstallableMetrics::GetInstallSource( + web_contents(), webapps::InstallTrigger::AMBIENT_BADGE); + if (!MaybeShowPwaBottomSheetController(/* expand_sheet= */ false, + install_source)) { + AppBannerManagerAndroid::ShowAmbientBadge(); + } +} + +void WebLayerAppBannerManagerAndroid::ShowBannerUi( + webapps::WebappInstallSource install_source) { + if (!native_app_data_.is_null()) { + AppBannerManagerAndroid::ShowBannerUi(install_source); + return; + } + + if (!MaybeShowPwaBottomSheetController(/* expand_sheet= */ true, + install_source)) { + AppBannerManagerAndroid::ShowBannerUi(install_source); + return; + } + + ReportStatus(webapps::SHOWING_WEB_APP_BANNER); +} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(WebLayerAppBannerManagerAndroid); + +} // namespace weblayer diff --git a/chromium/weblayer/browser/webapps/weblayer_app_banner_manager_android.h b/chromium/weblayer/browser/webapps/weblayer_app_banner_manager_android.h new file mode 100644 index 00000000000..302f25c156e --- /dev/null +++ b/chromium/weblayer/browser/webapps/weblayer_app_banner_manager_android.h @@ -0,0 +1,40 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBLAYER_BROWSER_WEBAPPS_WEBLAYER_APP_BANNER_MANAGER_ANDROID_H_ +#define WEBLAYER_BROWSER_WEBAPPS_WEBLAYER_APP_BANNER_MANAGER_ANDROID_H_ + +#include "components/webapps/browser/android/app_banner_manager_android.h" +#include "content/public/browser/web_contents_user_data.h" + +namespace weblayer { + +class WebLayerAppBannerManagerAndroid + : public webapps::AppBannerManagerAndroid, + public content::WebContentsUserData<WebLayerAppBannerManagerAndroid> { + public: + explicit WebLayerAppBannerManagerAndroid(content::WebContents* web_contents); + WebLayerAppBannerManagerAndroid(const WebLayerAppBannerManagerAndroid&) = + delete; + WebLayerAppBannerManagerAndroid& operator=( + const WebLayerAppBannerManagerAndroid&) = delete; + ~WebLayerAppBannerManagerAndroid() override; + + using content::WebContentsUserData< + WebLayerAppBannerManagerAndroid>::FromWebContents; + + protected: + webapps::InstallableParams ParamsToPerformInstallableWebAppCheck() override; + void ShowAmbientBadge() override; + void ShowBannerUi(webapps::WebappInstallSource install_source) override; + + private: + friend class content::WebContentsUserData<WebLayerAppBannerManagerAndroid>; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); +}; + +} // namespace weblayer + +#endif // WEBLAYER_BROWSER_WEBAPPS_WEBLAYER_APP_BANNER_MANAGER_ANDROID_H_ diff --git a/chromium/weblayer/browser/webapps/weblayer_webapps_client.cc b/chromium/weblayer/browser/webapps/weblayer_webapps_client.cc index 3f6b0c06878..4de77f5ef12 100644 --- a/chromium/weblayer/browser/webapps/weblayer_webapps_client.cc +++ b/chromium/weblayer/browser/webapps/weblayer_webapps_client.cc @@ -17,10 +17,13 @@ #include "components/webapps/browser/android/add_to_homescreen_params.h" #include "components/webapps/browser/android/shortcut_info.h" #include "components/webapps/browser/installable/installable_metrics.h" +#include "content/public/browser/browser_context.h" #include "ui/android/color_utils_android.h" #include "ui/gfx/android/java_bitmap.h" #include "url/gurl.h" +#include "weblayer/browser/webapps/webapk_install_scheduler.h" #include "weblayer/browser/webapps/webapps_utils.h" +#include "weblayer/browser/webapps/weblayer_app_banner_manager_android.h" namespace weblayer { @@ -29,6 +32,9 @@ using base::android::ConvertUTF8ToJavaString; using base::android::JavaParamRef; using base::android::ScopedJavaLocalRef; +WebLayerWebappsClient::WebLayerWebappsClient() = default; +WebLayerWebappsClient::~WebLayerWebappsClient() = default; + // static void WebLayerWebappsClient::Create() { static base::NoDestructor<WebLayerWebappsClient> instance; @@ -53,27 +59,27 @@ WebLayerWebappsClient::GetInfoBarManagerForWebContents( webapps::WebappInstallSource WebLayerWebappsClient::GetInstallSource( content::WebContents* web_contents, webapps::InstallTrigger trigger) { - NOTIMPLEMENTED(); + if (trigger == webapps::InstallTrigger::AMBIENT_BADGE) { + // RICH_INSTALL_UI is the new name for AMBIENT_BADGE. + return webapps::WebappInstallSource::RICH_INSTALL_UI_WEBLAYER; + } return webapps::WebappInstallSource::COUNT; } webapps::AppBannerManager* WebLayerWebappsClient::GetAppBannerManager( content::WebContents* web_contents) { - NOTIMPLEMENTED(); - return nullptr; + return WebLayerAppBannerManagerAndroid::FromWebContents(web_contents); } bool WebLayerWebappsClient::IsInstallationInProgress( content::WebContents* web_contents, const GURL& manifest_url) { - NOTIMPLEMENTED(); - return false; + return current_installs_.count(manifest_url) > 0; } bool WebLayerWebappsClient::CanShowAppBanners( content::WebContents* web_contents) { - NOTIMPLEMENTED(); - return false; + return WebApkInstallScheduler::IsInstallServiceAvailable(); } void WebLayerWebappsClient::OnWebApkInstallInitiatedFromAppMenu( @@ -82,7 +88,13 @@ void WebLayerWebappsClient::OnWebApkInstallInitiatedFromAppMenu( void WebLayerWebappsClient::InstallWebApk( content::WebContents* web_contents, const webapps::AddToHomescreenParams& params) { - NOTIMPLEMENTED(); + DCHECK(current_installs_.count(params.shortcut_info->manifest_url) == 0); + current_installs_.insert(params.shortcut_info->manifest_url); + WebApkInstallScheduler::FetchProtoAndScheduleInstall( + web_contents, *(params.shortcut_info), params.primary_icon, + params.has_maskable_primary_icon, + base::BindOnce(&WebLayerWebappsClient::OnInstallFinished, + weak_ptr_factory_.GetWeakPtr())); } void WebLayerWebappsClient::InstallShortcut( @@ -95,4 +107,9 @@ void WebLayerWebappsClient::InstallShortcut( params.has_maskable_primary_icon); } +void WebLayerWebappsClient::OnInstallFinished(GURL manifest_url) { + DCHECK(current_installs_.count(manifest_url) == 1); + current_installs_.erase(manifest_url); +} + } // namespace weblayer diff --git a/chromium/weblayer/browser/webapps/weblayer_webapps_client.h b/chromium/weblayer/browser/webapps/weblayer_webapps_client.h index 7f32306035f..86d8941fc67 100644 --- a/chromium/weblayer/browser/webapps/weblayer_webapps_client.h +++ b/chromium/weblayer/browser/webapps/weblayer_webapps_client.h @@ -5,14 +5,23 @@ #ifndef WEBLAYER_BROWSER_WEBAPPS_WEBLAYER_WEBAPPS_CLIENT_H_ #define WEBLAYER_BROWSER_WEBAPPS_WEBLAYER_WEBAPPS_CLIENT_H_ +#include <set> + +#include "base/memory/weak_ptr.h" #include "base/no_destructor.h" #include "build/build_config.h" #include "components/webapps/browser/webapps_client.h" +class GURL; + namespace weblayer { class WebLayerWebappsClient : public webapps::WebappsClient { public: + // Called when the scheduling of an WebAPK installation with the Chrome + // service finished or failed. + using WebApkInstallFinishedCallback = base::OnceCallback<void(GURL)>; + WebLayerWebappsClient(const WebLayerWebappsClient&) = delete; WebLayerWebappsClient& operator=(const WebLayerWebappsClient&) = delete; @@ -43,7 +52,15 @@ class WebLayerWebappsClient : public webapps::WebappsClient { private: friend base::NoDestructor<WebLayerWebappsClient>; - WebLayerWebappsClient() = default; + WebLayerWebappsClient(); + ~WebLayerWebappsClient() override; + + void OnInstallFinished(GURL manifest_url); + + std::set<GURL> current_installs_; + + // Used to get |weak_ptr_|. + base::WeakPtrFactory<WebLayerWebappsClient> weak_ptr_factory_{this}; }; } // namespace weblayer diff --git a/chromium/weblayer/browser/weblayer_variations_http_browsertest.cc b/chromium/weblayer/browser/weblayer_variations_http_browsertest.cc index b191f7d7d42..f3983536a25 100644 --- a/chromium/weblayer/browser/weblayer_variations_http_browsertest.cc +++ b/chromium/weblayer/browser/weblayer_variations_http_browsertest.cc @@ -4,6 +4,7 @@ #include "weblayer/test/weblayer_browser_test.h" +#include "base/command_line.h" #include "base/synchronization/lock.h" #include "base/thread_annotations.h" #include "components/variations/variations_ids_provider.h" diff --git a/chromium/weblayer/browser/webrtc/media_stream_manager.cc b/chromium/weblayer/browser/webrtc/media_stream_manager.cc index 9575a1f5fad..c15b2227829 100644 --- a/chromium/weblayer/browser/webrtc/media_stream_manager.cc +++ b/chromium/weblayer/browser/webrtc/media_stream_manager.cc @@ -10,6 +10,7 @@ #include "components/webrtc/media_stream_devices_controller.h" #include "content/public/browser/media_stream_request.h" #include "content/public/browser/web_contents.h" +#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h" #include "weblayer/browser/java/jni/MediaStreamManager_jni.h" using base::android::AttachCurrentThread; @@ -26,17 +27,6 @@ struct UserData : public base::SupportsUserData::Data { MediaStreamManager* manager = nullptr; }; -void FindStreamTypes(const blink::MediaStreamDevices& devices, - bool* audio, - bool* video) { - for (const auto& device : devices) { - if (device.type == blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE) - *audio = true; - if (device.type == blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE) - *video = true; - } -} - } // namespace // A class that tracks the lifecycle of a single active media stream. Ownership @@ -44,10 +34,14 @@ void FindStreamTypes(const blink::MediaStreamDevices& devices, class MediaStreamManager::StreamUi : public content::MediaStreamUI { public: StreamUi(base::WeakPtr<MediaStreamManager> manager, - const blink::MediaStreamDevices& devices) + const blink::mojom::StreamDevicesSet& stream_devices) : manager_(manager) { DCHECK(manager_); - FindStreamTypes(devices, &streaming_audio_, &streaming_video_); + DCHECK_EQ(1u, stream_devices.stream_devices.size()); + streaming_audio_ = + stream_devices.stream_devices[0]->audio_device.has_value(); + streaming_video_ = + stream_devices.stream_devices[0]->video_device.has_value(); } StreamUi(const StreamUi&) = delete; StreamUi& operator=(const StreamUi&) = delete; @@ -69,6 +63,10 @@ class MediaStreamManager::StreamUi : public content::MediaStreamUI { manager_->RegisterStream(this); return 0; } + void OnDeviceStoppedForSourceChange( + const std::string& label, + const content::DesktopMediaID& old_media_id, + const content::DesktopMediaID& new_media_id) override {} void OnDeviceStopped(const std::string& label, const content::DesktopMediaID& media_id) override {} @@ -127,12 +125,13 @@ void MediaStreamManager::OnClientReadyToStream(JNIEnv* env, CHECK(request != requests_pending_client_approval_.end()); if (allowed) { std::move(request->second.callback) - .Run(request->second.devices, request->second.result, + .Run(*request->second.stream_devices_set_, request->second.result, std::make_unique<StreamUi>(weak_factory_.GetWeakPtr(), - request->second.devices)); + *request->second.stream_devices_set_)); } else { std::move(request->second.callback) - .Run({}, blink::mojom::MediaStreamRequestResult::NO_HARDWARE, {}); + .Run(blink::mojom::StreamDevicesSet(), + blink::mojom::MediaStreamRequestResult::NO_HARDWARE, {}); } requests_pending_client_approval_.erase(request); } @@ -145,24 +144,29 @@ void MediaStreamManager::StopStreaming(JNIEnv* env) { void MediaStreamManager::OnMediaAccessPermissionResult( content::MediaResponseCallback callback, - const blink::MediaStreamDevices& devices, + const blink::mojom::StreamDevicesSet& stream_devices_set, blink::mojom::MediaStreamRequestResult result, bool blocked_by_permissions_policy, ContentSetting audio_setting, ContentSetting video_setting) { + // TODO(crbug.com/1300883): Generalize to multiple streams. + DCHECK((result != blink::mojom::MediaStreamRequestResult::OK && + stream_devices_set.stream_devices.empty()) || + (result == blink::mojom::MediaStreamRequestResult::OK && + stream_devices_set.stream_devices.size() == 1u)); if (result != blink::mojom::MediaStreamRequestResult::OK) { - std::move(callback).Run(devices, result, {}); + std::move(callback).Run(stream_devices_set, result, {}); return; } int request_id = next_request_id_++; - bool audio = false; - bool video = false; - FindStreamTypes(devices, &audio, &video); - requests_pending_client_approval_[request_id] = - RequestPendingClientApproval(std::move(callback), devices, result); - Java_MediaStreamManager_prepareToStream(base::android::AttachCurrentThread(), - j_object_, audio, video, request_id); + requests_pending_client_approval_[request_id] = RequestPendingClientApproval( + std::move(callback), stream_devices_set, result); + Java_MediaStreamManager_prepareToStream( + base::android::AttachCurrentThread(), j_object_, + stream_devices_set.stream_devices[0]->audio_device.has_value(), + stream_devices_set.stream_devices[0]->video_device.has_value(), + request_id); } void MediaStreamManager::RegisterStream(StreamUi* stream) { @@ -204,9 +208,11 @@ MediaStreamManager::RequestPendingClientApproval:: MediaStreamManager::RequestPendingClientApproval::RequestPendingClientApproval( content::MediaResponseCallback callback, - const blink::MediaStreamDevices& devices, + const blink::mojom::StreamDevicesSet& stream_devices_set, blink::mojom::MediaStreamRequestResult result) - : callback(std::move(callback)), devices(devices), result(result) {} + : callback(std::move(callback)), + stream_devices_set_(stream_devices_set.Clone()), + result(result) {} MediaStreamManager::RequestPendingClientApproval:: ~RequestPendingClientApproval() = default; diff --git a/chromium/weblayer/browser/webrtc/media_stream_manager.h b/chromium/weblayer/browser/webrtc/media_stream_manager.h index 4ed5dc6829d..7013b3ff6ef 100644 --- a/chromium/weblayer/browser/webrtc/media_stream_manager.h +++ b/chromium/weblayer/browser/webrtc/media_stream_manager.h @@ -12,6 +12,7 @@ #include "base/memory/weak_ptr.h" #include "components/content_settings/core/common/content_settings.h" #include "content/public/browser/media_stream_request.h" +#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h" namespace content { class WebContents; @@ -56,7 +57,7 @@ class MediaStreamManager { void OnMediaAccessPermissionResult( content::MediaResponseCallback callback, - const blink::MediaStreamDevices& devices, + const blink::mojom::StreamDevicesSet& stream_devices_set, blink::mojom::MediaStreamRequestResult result, bool blocked_by_permissions_policy, ContentSetting audio_setting, @@ -72,16 +73,17 @@ class MediaStreamManager { // approval. struct RequestPendingClientApproval { RequestPendingClientApproval(); - RequestPendingClientApproval(content::MediaResponseCallback callback, - const blink::MediaStreamDevices& devices, - blink::mojom::MediaStreamRequestResult result); + RequestPendingClientApproval( + content::MediaResponseCallback callback, + const blink::mojom::StreamDevicesSet& stream_devices_set, + blink::mojom::MediaStreamRequestResult result); ~RequestPendingClientApproval(); RequestPendingClientApproval& operator=( RequestPendingClientApproval&& other); content::MediaResponseCallback callback; - blink::MediaStreamDevices devices; + blink::mojom::StreamDevicesSetPtr stream_devices_set_; blink::mojom::MediaStreamRequestResult result; }; std::map<int, RequestPendingClientApproval> requests_pending_client_approval_; diff --git a/chromium/weblayer/browser/webui/net_export_ui.cc b/chromium/weblayer/browser/webui/net_export_ui.cc index 90c3111467a..1ad56cabbfe 100644 --- a/chromium/weblayer/browser/webui/net_export_ui.cc +++ b/chromium/weblayer/browser/webui/net_export_ui.cc @@ -4,6 +4,7 @@ #include "weblayer/browser/webui/net_export_ui.h" +#include "base/command_line.h" #include "base/memory/raw_ptr.h" #include "base/scoped_observation.h" #include "base/strings/utf_string_conversions.h" @@ -40,7 +41,7 @@ class NetExportMessageHandler NetExportMessageHandler(const NetExportMessageHandler&) = delete; NetExportMessageHandler& operator=(const NetExportMessageHandler&) = delete; - ~NetExportMessageHandler() override { file_writer_->StopNetLog(nullptr); } + ~NetExportMessageHandler() override { file_writer_->StopNetLog(); } // content::WebUIMessageHandler implementation. void RegisterMessages() override { @@ -87,9 +88,7 @@ class NetExportMessageHandler StartNetLog(base::FilePath()); } - void OnStopNetLog(const base::ListValue* list) { - file_writer_->StopNetLog(nullptr); - } + void OnStopNetLog(const base::ListValue* list) { file_writer_->StopNetLog(); } void OnSendNetLog(const base::ListValue* list) { file_writer_->GetFilePathToCompletedLog( diff --git a/chromium/weblayer/common/DEPS b/chromium/weblayer/common/DEPS index 3234fb857d8..04c923da20b 100644 --- a/chromium/weblayer/common/DEPS +++ b/chromium/weblayer/common/DEPS @@ -1,6 +1,5 @@ include_rules = [ "+components/embedder_support/origin_trials", - "+content/app/resources", "+content/public/common", "+gpu/config", "+third_party/blink/public/strings/grit/blink_strings.h", diff --git a/chromium/weblayer/common/content_client_impl.cc b/chromium/weblayer/common/content_client_impl.cc index 8493a0de103..89e0e2de77e 100644 --- a/chromium/weblayer/common/content_client_impl.cc +++ b/chromium/weblayer/common/content_client_impl.cc @@ -6,7 +6,6 @@ #include "build/build_config.h" #include "components/embedder_support/origin_trials/origin_trial_policy_impl.h" -#include "content/app/resources/grit/content_resources.h" #include "gpu/config/gpu_info.h" #include "gpu/config/gpu_util.h" #include "third_party/blink/public/strings/grit/blink_strings.h" diff --git a/chromium/weblayer/grit_strings_allowlist.txt b/chromium/weblayer/grit_strings_allowlist.txt index 98241f8ddb7..3b4dfe4f3a5 100644 --- a/chromium/weblayer/grit_strings_allowlist.txt +++ b/chromium/weblayer/grit_strings_allowlist.txt @@ -6,7 +6,7 @@ IDS_BLOCKED_ADS_INFOBAR_MESSAGE IDS_BLOCKED_ADS_MESSAGE_PRIMARY_TEXT IDS_ACCESSIBILITY_EVENTS_INFOBAR_TEXT IDS_ACCESSIBILITY_EVENTS_PERMISSION_FRAGMENT -IDS_AR_AND_MEDIA_CAPTURE_VIDEO_INFOBAR_TEXT +IDS_AMBIENT_BADGE_INSTALL IDS_AR_INFOBAR_TEXT IDS_AR_PERMISSION_FRAGMENT IDS_BEFORERELOAD_APP_MESSAGEBOX_TITLE diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/UserIdentityCallback.java b/chromium/weblayer/public/java/org/chromium/weblayer/UserIdentityCallback.java index 5a0b334952e..e3957868f76 100644 --- a/chromium/weblayer/public/java/org/chromium/weblayer/UserIdentityCallback.java +++ b/chromium/weblayer/public/java/org/chromium/weblayer/UserIdentityCallback.java @@ -13,7 +13,7 @@ import androidx.annotation.NonNull; * Used to provide details about the current user's identity. * * If this callback is implemented and set on {@link Profile}, the information is used to better - * organize contact details in the navigator.contacts UI. + * organize contact details in the navigator.contacts UI as well as by Autofill Assistant. */ public abstract class UserIdentityCallback { /** diff --git a/chromium/weblayer/public/javatests/BUILD.gn b/chromium/weblayer/public/javatests/BUILD.gn index e7453c384a1..37a292fc152 100644 --- a/chromium/weblayer/public/javatests/BUILD.gn +++ b/chromium/weblayer/public/javatests/BUILD.gn @@ -12,7 +12,6 @@ android_library("weblayer_public_javatests") { "org/chromium/weblayer/WebViewCompatibilityHelperTest.java", ] deps = [ - "//base:base_java", "//base:base_java_test_support", "//third_party/android_support_test_runner:runner_java", "//third_party/androidx:androidx_test_runner_java", diff --git a/chromium/weblayer/public/js_communication/web_message_reply_proxy.h b/chromium/weblayer/public/js_communication/web_message_reply_proxy.h index 64063648219..f4a9ee6b5fa 100644 --- a/chromium/weblayer/public/js_communication/web_message_reply_proxy.h +++ b/chromium/weblayer/public/js_communication/web_message_reply_proxy.h @@ -15,7 +15,10 @@ struct WebMessage; // Used to send messages to the page. class WebMessageReplyProxy { public: - virtual void PostMessage(std::unique_ptr<WebMessage>) = 0; + // To match the JavaScript call, this function would ideally be named + // PostMessage(), but that conflicts with a Windows macro, so PostWebMessage() + // is used. + virtual void PostWebMessage(std::unique_ptr<WebMessage>) = 0; // Returns true if the page is in the back/forward cache. virtual bool IsInBackForwardCache() = 0; diff --git a/chromium/weblayer/renderer/content_renderer_client_impl.cc b/chromium/weblayer/renderer/content_renderer_client_impl.cc index 3177eb77ef4..5046b828aaf 100644 --- a/chromium/weblayer/renderer/content_renderer_client_impl.cc +++ b/chromium/weblayer/renderer/content_renderer_client_impl.cc @@ -217,9 +217,11 @@ void ContentRendererClientImpl::GetSupportedKeySystems( media::GetSupportedKeySystemsCB cb) { media::KeySystemPropertiesVector key_systems; #if BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(ENABLE_WIDEVINE) cdm::AddAndroidWidevine(&key_systems); +#endif // BUILDFLAG(ENABLE_WIDEVINE) cdm::AddAndroidPlatformKeySystems(&key_systems); -#endif +#endif // BUILDFLAG(IS_ANDROID) std::move(cb).Run(std::move(key_systems)); } diff --git a/chromium/weblayer/shell/BUILD.gn b/chromium/weblayer/shell/BUILD.gn index 6ace4a85b81..775f815080a 100644 --- a/chromium/weblayer/shell/BUILD.gn +++ b/chromium/weblayer/shell/BUILD.gn @@ -146,7 +146,6 @@ repack("support_pak") { "$root_gen_dir/components/strings/components_chromium_strings_en-US.pak", "$root_gen_dir/components/strings/components_locale_settings_en-US.pak", "$root_gen_dir/components/strings/components_strings_en-US.pak", - "$root_gen_dir/content/app/resources/content_resources_100_percent.pak", "$root_gen_dir/content/content_resources.pak", "$root_gen_dir/content/dev_ui_content_resources.pak", "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak", @@ -167,7 +166,6 @@ repack("support_pak") { "//components/strings", "//content:content_resources", "//content:dev_ui_content_resources", - "//content/app/resources", "//mojo/public/js:resources", "//net:net_resources", "//third_party/blink/public:resources", diff --git a/chromium/weblayer/shell/android/BUILD.gn b/chromium/weblayer/shell/android/BUILD.gn index 535d316e3ba..74362f16869 100644 --- a/chromium/weblayer/shell/android/BUILD.gn +++ b/chromium/weblayer/shell/android/BUILD.gn @@ -45,8 +45,9 @@ android_library("weblayer_shell_java") { "$google_play_services_package:google_play_services_base_java", "//base:base_java", "//components/strictmode/android:java", - "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_java", + "//third_party/androidx:androidx_fragment_fragment_java", "//weblayer/public/java", ] sources = [ @@ -234,7 +235,6 @@ android_apk("weblayer_support_apk") { "//android_webview:locale_pak_assets", "//android_webview:pak_file_assets", "//android_webview:weblayer_webview_assets", - "//base:base_java", "//weblayer:locale_pak_assets", "//weblayer/browser/java", "//weblayer/browser/java:test_java", @@ -285,20 +285,22 @@ android_apk("weblayer_support_apk") { } script_test("weblayer_shell_wpt") { - script = "//testing/scripts/run_android_wpt.py" + script = "//testing/scripts/run_wpt_tests.py" args = [ - "--product=android_weblayer", - "--weblayer-shell=apks/WebLayerShell.apk", - "--weblayer-support=apks/WebLayerSupport.apk", - "--webdriver-binary=clang_x64/chromedriver", + "--product", + "android_weblayer", + "--browser-apk", + "@WrappedPath(apks/WebLayerShell.apk)", + "--additional-apk", + "@WrappedPath(apks/WebLayerSupport.apk)", + "--webdriver-binary", + "@WrappedPath(clang_x64/chromedriver)", "-v", ] data_deps = [ ":weblayer_shell_apk", ":weblayer_support_apk", - "//build/android:test_runner_py", "//chrome/test/chromedriver:chromedriver($host_toolchain)", "//third_party/blink/tools:wpt_tests_android_isolate", - "//tools/imagediff", ] } diff --git a/chromium/weblayer/test/BUILD.gn b/chromium/weblayer/test/BUILD.gn index b32968d0fef..8f8ca44d65d 100644 --- a/chromium/weblayer/test/BUILD.gn +++ b/chromium/weblayer/test/BUILD.gn @@ -38,6 +38,7 @@ if (is_android) { "//base:base_java", "//base:base_java_test_support", "//base:jni_java", + "//build/android:build_java", "//components/embedder_support/android:application_java", "//components/safe_browsing/android:safe_browsing_java", "//components/translate/content/android:java", @@ -221,6 +222,7 @@ test("weblayer_browsertests") { "../browser/safe_browsing/safe_browsing_browsertest.cc", "../browser/safe_browsing/weblayer_ping_manager_browsertest.cc", "../browser/url_bar/page_info_browsertest.cc", + "../browser/webapps/webapk_install_scheduler_browsertest.cc", "../shell/android/browsertests_apk/translate_test_bridge.cc", "../shell/android/browsertests_apk/translate_test_bridge.h", "../shell/android/browsertests_apk/weblayer_browser_tests_jni_onload.cc", @@ -231,7 +233,6 @@ test("weblayer_browsertests") { ":weblayer_browsertests_java", ":weblayer_browsertests_jni", ":weblayer_test_assets", - "//android_webview:generate_aw_strings_grit", "//android_webview:locale_pak_assets", "//android_webview:pak_file_assets", "//components/android_autofill/browser:test_support", @@ -242,11 +243,14 @@ test("weblayer_browsertests") { "//components/safe_browsing/android:safe_browsing_api_handler", "//components/safe_browsing/content/browser", "//components/safe_browsing/content/browser:client_side_detection", + "//components/safe_browsing/content/browser/web_ui", "//components/safe_browsing/content/common:interfaces", "//components/safe_browsing/core/browser:token_fetcher", + "//components/safe_browsing/core/browser:token_fetcher_testing_helper", "//components/safe_browsing/core/common", "//components/safe_browsing/core/common/proto:client_model_proto", "//components/viz/service:service_java", + "//components/webapps/browser:browser", "//content/public/test/android:android_test_message_pump_support_java", "//content/test:android_test_message_pump_support", "//content/test:android_test_message_pump_support", |