summaryrefslogtreecommitdiff
path: root/chromium/weblayer
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-09-29 16:16:15 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-11-09 10:04:06 +0000
commita95a7417ad456115a1ef2da4bb8320531c0821f1 (patch)
treeedcd59279e486d2fd4a8f88a7ed025bcf925c6e6 /chromium/weblayer
parent33fc33aa94d4add0878ec30dc818e34e1dd3cc2a (diff)
downloadqtwebengine-chromium-a95a7417ad456115a1ef2da4bb8320531c0821f1.tar.gz
BASELINE: Update Chromium to 106.0.5249.126
Change-Id: Ib0bb21c437a7d1686e21c33f2d329f2ac425b7ab Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/438936 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/weblayer')
-rw-r--r--chromium/weblayer/API_OWNERS1
-rw-r--r--chromium/weblayer/BUILD.gn4
-rw-r--r--chromium/weblayer/app/content_main_delegate_impl.cc17
-rw-r--r--chromium/weblayer/app/content_main_delegate_impl.h4
-rw-r--r--chromium/weblayer/browser/DEPS1
-rw-r--r--chromium/weblayer/browser/ad_tagging_browsertest.cc28
-rw-r--r--chromium/weblayer/browser/android/javatests/BUILD.gn1
-rw-r--r--chromium/weblayer/browser/android/javatests/skew/expectations.txt4
-rwxr-xr-xchromium/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py3
-rw-r--r--chromium/weblayer/browser/android/metrics/metrics_browsertest.cc6
-rw-r--r--chromium/weblayer/browser/autofill_client_impl.cc14
-rw-r--r--chromium/weblayer/browser/autofill_client_impl.h4
-rw-r--r--chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.cc21
-rw-r--r--chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h11
-rw-r--r--chromium/weblayer/browser/browser_context_impl.cc7
-rw-r--r--chromium/weblayer/browser/browser_context_impl.h2
-rw-r--r--chromium/weblayer/browser/browser_controls_container_view.cc11
-rw-r--r--chromium/weblayer/browser/browser_controls_navigation_state_handler.cc10
-rw-r--r--chromium/weblayer/browser/browser_controls_navigation_state_handler_browsertest.cc80
-rw-r--r--chromium/weblayer/browser/client_hints_factory.cc1
-rw-r--r--chromium/weblayer/browser/content_browser_client_impl.cc70
-rw-r--r--chromium/weblayer/browser/content_view_render_view.cc22
-rw-r--r--chromium/weblayer/browser/content_view_render_view.h11
-rw-r--r--chromium/weblayer/browser/download_manager_delegate_impl.cc4
-rw-r--r--chromium/weblayer/browser/feature_list_creator.cc8
-rw-r--r--chromium/weblayer/browser/java/BUILD.gn10
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java12
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/ArCoreVersionUtils.java4
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java25
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java19
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java5
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java14
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/FragmentHostingRemoteFragmentImpl.java4
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java6
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java2
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java11
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/WebContentsGestureStateTracker.java6
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java14
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl6
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/PRESUBMIT.py13
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java9
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerSiteSettingsDelegate.java15
-rw-r--r--chromium/weblayer/browser/overlay_popup_ad_intervention_browsertest.cc3
-rw-r--r--chromium/weblayer/browser/page_load_metrics_browsertest.cc14
-rw-r--r--chromium/weblayer/browser/page_load_metrics_observer_impl.cc15
-rw-r--r--chromium/weblayer/browser/page_load_metrics_observer_impl.h2
-rw-r--r--chromium/weblayer/browser/password_manager_driver_factory.cc6
-rw-r--r--chromium/weblayer/browser/permissions/permission_manager_factory.cc2
-rw-r--r--chromium/weblayer/browser/permissions/weblayer_permissions_client.cc6
-rw-r--r--chromium/weblayer/browser/permissions/weblayer_permissions_client.h2
-rw-r--r--chromium/weblayer/browser/profile_impl.cc2
-rw-r--r--chromium/weblayer/browser/reduce_accept_language_factory.cc50
-rw-r--r--chromium/weblayer/browser/reduce_accept_language_factory.h42
-rw-r--r--chromium/weblayer/browser/reduce_accept_language_service_browsertest.cc92
-rw-r--r--chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc19
-rw-r--r--chromium/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc12
-rw-r--r--chromium/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h5
-rw-r--r--chromium/weblayer/browser/site_isolation_browsertest.cc6
-rw-r--r--chromium/weblayer/browser/ssl_error_controller_client.cc3
-rw-r--r--chromium/weblayer/browser/tab_impl.cc3
-rw-r--r--chromium/weblayer/browser/translate_client_impl.cc3
-rw-r--r--chromium/weblayer/browser/url_bar/page_info_browsertest.cc7
-rw-r--r--chromium/weblayer/browser/url_bar/page_info_delegate_impl.cc23
-rw-r--r--chromium/weblayer/browser/url_bar/page_info_delegate_impl.h7
-rw-r--r--chromium/weblayer/browser/webapps/webapk_install_scheduler.cc10
-rw-r--r--chromium/weblayer/browser/webapps/webapk_install_scheduler_browsertest.cc3
-rw-r--r--chromium/weblayer/browser/webui/net_export_ui.cc28
-rw-r--r--chromium/weblayer/grit_strings_allowlist.txt4
-rw-r--r--chromium/weblayer/public/java/BUILD.gn74
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/Browser.java138
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/BrowserFragment.java300
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/FragmentParams.java79
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/Tab.java153
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/TabManager.java120
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/TabNavigationController.java103
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/TabObserver.java43
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/TabObserverDelegate.java84
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/WebMessageCallback.java45
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/WebMessageReplyProxy.java33
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBooleanCallback.aidl9
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserFragmentDelegate.aidl35
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserFragmentDelegateClient.aidl12
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserSandboxCallback.aidl11
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserSandboxService.aidl17
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IFragmentParams.aidl11
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IStringCallback.aidl9
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabCallback.aidl11
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabNavigationControllerProxy.aidl16
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabObserverDelegate.aidl14
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabParams.aidl14
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabProxy.aidl19
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IWebMessageCallback.aidl13
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IWebMessageReplyProxy.aidl9
-rw-r--r--chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/OWNERS2
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/Browser.java86
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java46
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragmentDelegate.java189
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragmentTabDelegate.java86
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/BrowserSandboxService.java64
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/RemoteFragment.java19
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/Tab.java13
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/TabNavigationControllerProxy.java62
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/TabParams.java24
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/TabProxy.java119
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/WebMessageReplyProxyProxy.java29
-rw-r--r--chromium/weblayer/renderer/content_renderer_client_impl.cc3
-rw-r--r--chromium/weblayer/renderer/content_renderer_client_impl.h3
-rw-r--r--chromium/weblayer/renderer/error_page_helper.cc6
-rw-r--r--chromium/weblayer/renderer/weblayer_render_thread_observer.cc3
-rw-r--r--chromium/weblayer/shell/android/BUILD.gn99
-rw-r--r--chromium/weblayer/shell/android/browser_sandbox_apk/AndroidManifest.xml26
-rw-r--r--chromium/weblayer/shell/android/browserfragment_shell_apk/AndroidManifest.xml27
-rw-r--r--chromium/weblayer/shell/android/browserfragment_shell_apk/res/layout/main.xml31
-rw-r--r--chromium/weblayer/shell/android/browserfragment_shell_apk/res/values/styles.xml4
-rw-r--r--chromium/weblayer/shell/android/browserfragment_shell_apk/src/org/chromium/browserfragment/shell/BrowserFragmentShellActivity.java200
-rw-r--r--chromium/weblayer/shell/android/shell_apk/DEPS1
-rw-r--r--chromium/weblayer/test/BUILD.gn5
-rwxr-xr-xchromium/weblayer/tools/run_weblayer_shell.py6
118 files changed, 3161 insertions, 253 deletions
diff --git a/chromium/weblayer/API_OWNERS b/chromium/weblayer/API_OWNERS
index 8098e861f7d..4357e6a00c9 100644
--- a/chromium/weblayer/API_OWNERS
+++ b/chromium/weblayer/API_OWNERS
@@ -3,5 +3,6 @@
#
blundell@chromium.org
boliu@chromium.org
+cduvall@chromium.org
jam@chromium.org
sky@chromium.org
diff --git a/chromium/weblayer/BUILD.gn b/chromium/weblayer/BUILD.gn
index 97b2f3eef91..5de93877db5 100644
--- a/chromium/weblayer/BUILD.gn
+++ b/chromium/weblayer/BUILD.gn
@@ -293,6 +293,8 @@ source_set("weblayer_lib_base") {
"browser/profile_disk_operations.h",
"browser/profile_impl.cc",
"browser/profile_impl.h",
+ "browser/reduce_accept_language_factory.cc",
+ "browser/reduce_accept_language_factory.h",
"browser/signin_url_loader_throttle.cc",
"browser/signin_url_loader_throttle.h",
"browser/ssl_error_controller_client.cc",
@@ -449,7 +451,6 @@ source_set("weblayer_lib_base") {
"//components/language/core/browser",
"//components/leveldb_proto",
"//components/metrics",
- "//components/metrics:content",
"//components/net_log",
"//components/network_time",
"//components/no_state_prefetch/browser",
@@ -470,6 +471,7 @@ source_set("weblayer_lib_base") {
"//components/pref_registry:pref_registry",
"//components/prefs",
"//components/profile_metrics",
+ "//components/reduce_accept_language/browser",
"//components/safe_browsing/content/browser",
"//components/safe_browsing/content/browser:client_side_detection",
"//components/safe_browsing/content/browser/web_ui",
diff --git a/chromium/weblayer/app/content_main_delegate_impl.cc b/chromium/weblayer/app/content_main_delegate_impl.cc
index cb033a0b45c..cfc13162d70 100644
--- a/chromium/weblayer/app/content_main_delegate_impl.cc
+++ b/chromium/weblayer/app/content_main_delegate_impl.cc
@@ -30,6 +30,7 @@
#include "content/public/common/url_constants.h"
#include "media/base/media_switches.h"
#include "services/network/public/cpp/features.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "ui/base/resource/resource_bundle.h"
@@ -153,11 +154,7 @@ ContentMainDelegateImpl::ContentMainDelegateImpl(MainParams params)
ContentMainDelegateImpl::~ContentMainDelegateImpl() = default;
-bool ContentMainDelegateImpl::BasicStartupComplete(int* exit_code) {
- int dummy;
- if (!exit_code)
- exit_code = &dummy;
-
+absl::optional<int> ContentMainDelegateImpl::BasicStartupComplete() {
// Disable features which are not currently supported in WebLayer. This allows
// sites to do feature detection, and prevents crashes in some not fully
// implemented features.
@@ -232,14 +229,14 @@ bool ContentMainDelegateImpl::BasicStartupComplete(int* exit_code) {
RegisterPathProvider();
- return false;
+ return absl::nullopt;
}
bool ContentMainDelegateImpl::ShouldCreateFeatureList(InvokedIn invoked_in) {
#if BUILDFLAG(IS_ANDROID)
// On android WebLayer is in charge of creating its own FeatureList in the
// browser process.
- return invoked_in == InvokedIn::kChildProcess;
+ return absl::holds_alternative<InvokedInChildProcess>(invoked_in);
#else
// TODO(weblayer-dev): Support feature lists on desktop.
return true;
@@ -298,9 +295,11 @@ void ContentMainDelegateImpl::PreSandboxStartup() {
#endif
}
-void ContentMainDelegateImpl::PostEarlyInitialization(InvokedIn invoked_in) {
- if (invoked_in != InvokedIn::kChildProcess)
+absl::optional<int> ContentMainDelegateImpl::PostEarlyInitialization(
+ InvokedIn invoked_in) {
+ if (absl::holds_alternative<InvokedInBrowserProcess>(invoked_in))
browser_client_->CreateFeatureListAndFieldTrials();
+ return absl::nullopt;
}
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 151ecc647a5..9268e56e0f6 100644
--- a/chromium/weblayer/app/content_main_delegate_impl.h
+++ b/chromium/weblayer/app/content_main_delegate_impl.h
@@ -28,11 +28,11 @@ class ContentMainDelegateImpl : public content::ContentMainDelegate {
~ContentMainDelegateImpl() override;
// ContentMainDelegate implementation:
- bool BasicStartupComplete(int* exit_code) override;
+ absl::optional<int> BasicStartupComplete() override;
bool ShouldCreateFeatureList(InvokedIn invoked_in) override;
variations::VariationsIdsProvider* CreateVariationsIdsProvider() override;
void PreSandboxStartup() override;
- void PostEarlyInitialization(InvokedIn invoked_in) override;
+ absl::optional<int> 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/DEPS b/chromium/weblayer/browser/DEPS
index 46c1627bae1..14ac55d622e 100644
--- a/chromium/weblayer/browser/DEPS
+++ b/chromium/weblayer/browser/DEPS
@@ -60,6 +60,7 @@ include_rules = [
"+components/profile_metrics",
"+components/no_state_prefetch/browser",
"+components/no_state_prefetch/common",
+ "+components/reduce_accept_language/browser",
"+components/resources/android",
"+components/safe_browsing/android",
"+components/safe_browsing/content/browser",
diff --git a/chromium/weblayer/browser/ad_tagging_browsertest.cc b/chromium/weblayer/browser/ad_tagging_browsertest.cc
index 3994d265b9e..2e4cbc84096 100644
--- a/chromium/weblayer/browser/ad_tagging_browsertest.cc
+++ b/chromium/weblayer/browser/ad_tagging_browsertest.cc
@@ -55,8 +55,8 @@ IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest,
subresource_filter::CreateSrcFrame(web_contents(), ad_url);
// Verify that we are not evaluating subframe loads.
- EXPECT_FALSE(observer.GetSubframeLoadPolicy(ad_url).has_value());
- EXPECT_FALSE(observer.GetIsAdSubframe(ad_frame->GetFrameTreeNodeId()));
+ EXPECT_FALSE(observer.GetChildFrameLoadPolicy(ad_url).has_value());
+ EXPECT_FALSE(observer.GetIsAdFrame(ad_frame->GetFrameTreeNodeId()));
// Child frame created by ad script.
content::RenderFrameHost* ad_frame_tagged_by_script =
@@ -64,8 +64,8 @@ IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest,
web_contents(), GetURL("frame_factory.html?1"));
// No frames should be detected by script heuristics.
- EXPECT_FALSE(observer.GetIsAdSubframe(
- ad_frame_tagged_by_script->GetFrameTreeNodeId()));
+ EXPECT_FALSE(
+ observer.GetIsAdFrame(ad_frame_tagged_by_script->GetFrameTreeNodeId()));
}
// TODO(crbug.com/1210190): This test is flaky.
@@ -85,8 +85,8 @@ IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest,
subresource_filter::CreateSrcFrame(web_contents(), ad_url);
// Verify that we are evaluating subframe loads.
- EXPECT_TRUE(observer.GetSubframeLoadPolicy(ad_url).has_value());
- EXPECT_TRUE(observer.GetIsAdSubframe(ad_frame->GetFrameTreeNodeId()));
+ EXPECT_TRUE(observer.GetChildFrameLoadPolicy(ad_url).has_value());
+ EXPECT_TRUE(observer.GetIsAdFrame(ad_frame->GetFrameTreeNodeId()));
// Child frame created by ad script.
content::RenderFrameHost* ad_frame_tagged_by_script =
@@ -94,8 +94,8 @@ IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest,
web_contents(), GetURL("frame_factory.html?1"));
// Frames should be detected by script heuristics.
- EXPECT_TRUE(observer.GetIsAdSubframe(
- ad_frame_tagged_by_script->GetFrameTreeNodeId()));
+ EXPECT_TRUE(
+ observer.GetIsAdFrame(ad_frame_tagged_by_script->GetFrameTreeNodeId()));
}
// TODO(crbug.com/1210190): This test is flaky.
@@ -104,18 +104,18 @@ IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest, DISABLED_FramesByURL) {
// Main frame.
NavigateAndWaitForCompletion(GetURL("frame_factory.html"), shell());
- EXPECT_FALSE(observer.GetIsAdSubframe(
+ EXPECT_FALSE(observer.GetIsAdFrame(
web_contents()->GetPrimaryMainFrame()->GetFrameTreeNodeId()));
// (1) Vanilla child.
content::RenderFrameHost* vanilla_child = subresource_filter::CreateSrcFrame(
web_contents(), GetURL("frame_factory.html?1"));
- EXPECT_FALSE(observer.GetIsAdSubframe(vanilla_child->GetFrameTreeNodeId()));
+ EXPECT_FALSE(observer.GetIsAdFrame(vanilla_child->GetFrameTreeNodeId()));
// (2) Ad child.
content::RenderFrameHost* ad_child = subresource_filter::CreateSrcFrame(
web_contents(), GetURL("frame_factory.html?2&ad=true"));
- EXPECT_TRUE(observer.GetIsAdSubframe(ad_child->GetFrameTreeNodeId()));
+ EXPECT_TRUE(observer.GetIsAdFrame(ad_child->GetFrameTreeNodeId()));
EXPECT_TRUE(subresource_filter::EvidenceForFrameComprises(
ad_child, /*parent_is_ad=*/false,
blink::mojom::FilterListResult::kMatchedBlockingRule,
@@ -124,7 +124,7 @@ IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest, DISABLED_FramesByURL) {
// (3) Ad child of 2.
content::RenderFrameHost* ad_child_2 = subresource_filter::CreateSrcFrame(
ad_child, GetURL("frame_factory.html?sub=1&3&ad=true"));
- EXPECT_TRUE(observer.GetIsAdSubframe(ad_child_2->GetFrameTreeNodeId()));
+ EXPECT_TRUE(observer.GetIsAdFrame(ad_child_2->GetFrameTreeNodeId()));
EXPECT_TRUE(subresource_filter::EvidenceForFrameComprises(
ad_child_2, /*parent_is_ad=*/true,
blink::mojom::FilterListResult::kMatchedBlockingRule,
@@ -134,7 +134,7 @@ IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest, DISABLED_FramesByURL) {
content::RenderFrameHost* vanilla_child_2 =
subresource_filter::CreateSrcFrame(ad_child,
GetURL("frame_factory.html?4"));
- EXPECT_TRUE(observer.GetIsAdSubframe(vanilla_child_2->GetFrameTreeNodeId()));
+ EXPECT_TRUE(observer.GetIsAdFrame(vanilla_child_2->GetFrameTreeNodeId()));
EXPECT_TRUE(subresource_filter::EvidenceForFrameComprises(
vanilla_child_2, /*parent_is_ad=*/true,
blink::mojom::FilterListResult::kMatchedNoRules,
@@ -148,7 +148,7 @@ IN_PROC_BROWSER_TEST_F(AdTaggingBrowserTest, DISABLED_FramesByURL) {
content::RenderFrameHost* vanilla_child_3 =
subresource_filter::CreateSrcFrame(vanilla_child,
GetURL("frame_factory.html?5"));
- EXPECT_FALSE(observer.GetIsAdSubframe(vanilla_child_3->GetFrameTreeNodeId()));
+ EXPECT_FALSE(observer.GetIsAdFrame(vanilla_child_3->GetFrameTreeNodeId()));
}
} // namespace weblayer
diff --git a/chromium/weblayer/browser/android/javatests/BUILD.gn b/chromium/weblayer/browser/android/javatests/BUILD.gn
index f41e1b58f1b..3f575f96faa 100644
--- a/chromium/weblayer/browser/android/javatests/BUILD.gn
+++ b/chromium/weblayer/browser/android/javatests/BUILD.gn
@@ -352,7 +352,6 @@ instrumentation_test_runner("weblayer_bundle_test") {
"fr-CA",
]
android_test_apk = ":weblayer_bundle_test_apk"
- android_test_apk_name = "WebLayerBundleTest"
additional_apks = [ "//net/android:net_test_support_apk" ]
data = [ "//weblayer/test/data/" ]
never_incremental = true
diff --git a/chromium/weblayer/browser/android/javatests/skew/expectations.txt b/chromium/weblayer/browser/android/javatests/skew/expectations.txt
index 3afaaf290cc..5c69edd9c55 100644
--- a/chromium/weblayer/browser/android/javatests/skew/expectations.txt
+++ b/chromium/weblayer/browser/android/javatests/skew/expectations.txt
@@ -11,6 +11,10 @@
# results: [ Skip ]
# conflicts_allowed: True
+# Test is flaky, with the particular flake signaled in the bug below but the underlying cause likely
+# being crbug.com/1277901.
+crbug.com/1329813 [ all ] org.chromium.weblayer.test.ExternalNavigationTest#testNonHandledExternalIntentWithFallbackUrlThatLaunchesIntentAfterRedirectBlocksFallbackIntent [ Skip ]
+
# No real changes to weblayer APIs, changes should only affect chrome-internal behavior around
# navigation which the test depends on.
crbug.com/1196803 [ client_lte_91 ] org.chromium.weblayer.test.ExternalNavigationTest#testExternalIntentWithNoRedirectInBrowserStartupInIncognitoBlockedWhenBackgroundLaunchesAllowedAndUserForbids [ Skip ]
diff --git a/chromium/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py b/chromium/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py
index f9ecc347772..704bdb8ef90 100755
--- a/chromium/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py
+++ b/chromium/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py
@@ -185,9 +185,6 @@ def main():
'--test-apk',
os.path.join(args.client_outdir,
'apks/WebLayerInstrumentationTest.apk'),
- '--test-jar',
- os.path.join(args.client_outdir,
- 'test.lib.java/WebLayerInstrumentationTest.jar'),
'--apk-under-test',
os.path.join(args.client_outdir, 'apks/WebLayerShellSystemWebView.apk'),
'--use-webview-provider',
diff --git a/chromium/weblayer/browser/android/metrics/metrics_browsertest.cc b/chromium/weblayer/browser/android/metrics/metrics_browsertest.cc
index cdbde5aa596..16f50c9c21c 100644
--- a/chromium/weblayer/browser/android/metrics/metrics_browsertest.cc
+++ b/chromium/weblayer/browser/android/metrics/metrics_browsertest.cc
@@ -11,6 +11,7 @@
#include "components/metrics/metrics_log_uploader.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics/metrics_switches.h"
+#include "components/metrics/stability_metrics_helper.h"
#include "content/public/test/browser_test_utils.h"
#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
#include "weblayer/browser/android/metrics/metrics_test_helper.h"
@@ -147,6 +148,7 @@ IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, PageLoadsEnableMultipleUploads) {
}
IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, NavigationIncrementsPageLoadCount) {
+ base::HistogramTester histogram_tester;
ASSERT_TRUE(embedded_test_server()->Start());
metrics::ChromeUserMetricsExtension log = WaitForNextMetricsLog();
// The initial log should not have a page load count (because nothing was
@@ -155,6 +157,8 @@ IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, NavigationIncrementsPageLoadCount) {
const metrics::SystemProfileProto& system_profile = log.system_profile();
ASSERT_TRUE(system_profile.has_stability());
EXPECT_EQ(0, system_profile.stability().page_load_count());
+ histogram_tester.ExpectBucketCount(
+ "Stability.Counts2", metrics::StabilityEventType::kPageLoad, 0);
}
// Loading a page should increment the page load count.
@@ -165,6 +169,8 @@ IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, NavigationIncrementsPageLoadCount) {
const metrics::SystemProfileProto& system_profile = log.system_profile();
ASSERT_TRUE(system_profile.has_stability());
EXPECT_EQ(1, system_profile.stability().page_load_count());
+ histogram_tester.ExpectBucketCount(
+ "Stability.Counts2", metrics::StabilityEventType::kPageLoad, 1);
}
}
diff --git a/chromium/weblayer/browser/autofill_client_impl.cc b/chromium/weblayer/browser/autofill_client_impl.cc
index 2d870b5716c..6c20c132d82 100644
--- a/chromium/weblayer/browser/autofill_client_impl.cc
+++ b/chromium/weblayer/browser/autofill_client_impl.cc
@@ -237,6 +237,20 @@ void AutofillClientImpl::ScanCreditCard(CreditCardScanCallback callback) {
NOTREACHED();
}
+bool AutofillClientImpl::IsTouchToFillCreditCardSupported() {
+ return false;
+}
+
+bool AutofillClientImpl::ShowTouchToFillCreditCard(
+ base::WeakPtr<autofill::TouchToFillDelegate> delegate) {
+ NOTREACHED();
+ return false;
+}
+
+void AutofillClientImpl::HideTouchToFillCreditCard() {
+ NOTREACHED();
+}
+
void AutofillClientImpl::ShowAutofillPopup(
const autofill::AutofillClient::PopupOpenArgs& open_args,
base::WeakPtr<autofill::AutofillPopupDelegate> delegate) {
diff --git a/chromium/weblayer/browser/autofill_client_impl.h b/chromium/weblayer/browser/autofill_client_impl.h
index 6cc60bc6b81..b4b70fc9a41 100644
--- a/chromium/weblayer/browser/autofill_client_impl.h
+++ b/chromium/weblayer/browser/autofill_client_impl.h
@@ -109,6 +109,10 @@ class AutofillClientImpl
AddressProfileSavePromptCallback callback) override;
bool HasCreditCardScanFeature() override;
void ScanCreditCard(CreditCardScanCallback callback) override;
+ bool IsTouchToFillCreditCardSupported() override;
+ bool ShowTouchToFillCreditCard(
+ base::WeakPtr<autofill::TouchToFillDelegate> delegate) override;
+ void HideTouchToFillCreditCard() override;
void ShowAutofillPopup(
const autofill::AutofillClient::PopupOpenArgs& open_args,
base::WeakPtr<autofill::AutofillPopupDelegate> delegate) override;
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 9b3137904f6..7a0e6d2e03b 100644
--- a/chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.cc
+++ b/chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.cc
@@ -59,25 +59,16 @@ WebLayerBluetoothDelegateImplClient::ShowBluetoothScanningPrompt(
#endif
}
-void WebLayerBluetoothDelegateImplClient::ShowBluetoothDeviceCredentialsDialog(
+void WebLayerBluetoothDelegateImplClient::ShowBluetoothDevicePairDialog(
content::RenderFrameHost* frame,
const std::u16string& device_identifier,
- content::BluetoothDelegate::CredentialsCallback callback) {
+ content::BluetoothDelegate::PairPromptCallback callback,
+ content::BluetoothDelegate::PairingKind,
+ const absl::optional<std::u16string>& pin) {
// Web Bluetooth is not supported for desktop in WebLayer and Android already
// bonds on demand, so this should not be called on any platform.
- std::move(callback).Run(
- content::BluetoothDelegate::DeviceCredentialsPromptResult::kCancelled,
- /*result=*/std::u16string());
+ std::move(callback).Run(content::BluetoothDelegate::PairPromptResult(
+ content::BluetoothDelegate::PairPromptStatus::kCancelled));
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 9eb8028100a..403c9577e23 100644
--- a/chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h
+++ b/chromium/weblayer/browser/bluetooth/weblayer_bluetooth_delegate_impl_client.h
@@ -43,14 +43,13 @@ class WebLayerBluetoothDelegateImplClient
content::RenderFrameHost* frame,
const content::BluetoothScanningPrompt::EventHandler& event_handler)
override;
- void ShowBluetoothDeviceCredentialsDialog(
- content::RenderFrameHost* frame,
- const std::u16string& device_identifier,
- content::BluetoothDelegate::CredentialsCallback callback) override;
- void ShowBluetoothDevicePairConfirmDialog(
+
+ void ShowBluetoothDevicePairDialog(
content::RenderFrameHost* frame,
const std::u16string& device_identifier,
- content::BluetoothDelegate::PairConfirmCallback callback) override;
+ content::BluetoothDelegate::PairPromptCallback callback,
+ content::BluetoothDelegate::PairingKind,
+ const absl::optional<std::u16string>& pin) override;
};
} // namespace weblayer
diff --git a/chromium/weblayer/browser/browser_context_impl.cc b/chromium/weblayer/browser/browser_context_impl.cc
index 6d4bfe5e783..09095cf6e9b 100644
--- a/chromium/weblayer/browser/browser_context_impl.cc
+++ b/chromium/weblayer/browser/browser_context_impl.cc
@@ -23,6 +23,7 @@
#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
+#include "components/reduce_accept_language/browser/reduce_accept_language_service.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h"
#include "components/site_isolation/pref_names.h"
@@ -47,6 +48,7 @@
#include "weblayer/browser/client_hints_factory.h"
#include "weblayer/browser/heavy_ad_service_factory.h"
#include "weblayer/browser/permissions/permission_manager_factory.h"
+#include "weblayer/browser/reduce_accept_language_factory.h"
#include "weblayer/browser/stateful_ssl_host_state_delegate_factory.h"
#include "weblayer/public/common/switches.h"
@@ -220,6 +222,11 @@ BrowserContextImpl::GetBrowsingDataRemoverDelegate() {
return BrowsingDataRemoverDelegateFactory::GetForBrowserContext(this);
}
+content::ReduceAcceptLanguageControllerDelegate*
+BrowserContextImpl::GetReduceAcceptLanguageControllerDelegate() {
+ return ReduceAcceptLanguageFactory::GetForBrowserContext(this);
+}
+
download::InProgressDownloadManager*
BrowserContextImpl::RetriveInProgressDownloadManager() {
// Override this to provide a connection to the wake lock service.
diff --git a/chromium/weblayer/browser/browser_context_impl.h b/chromium/weblayer/browser/browser_context_impl.h
index b2fb37566ae..47169d7325e 100644
--- a/chromium/weblayer/browser/browser_context_impl.h
+++ b/chromium/weblayer/browser/browser_context_impl.h
@@ -65,6 +65,8 @@ class BrowserContextImpl : public content::BrowserContext {
download::InProgressDownloadManager* RetriveInProgressDownloadManager()
override;
content::ContentIndexProvider* GetContentIndexProvider() override;
+ content::ReduceAcceptLanguageControllerDelegate*
+ GetReduceAcceptLanguageControllerDelegate() override;
ProfileImpl* profile_impl() const { return profile_impl_; }
diff --git a/chromium/weblayer/browser/browser_controls_container_view.cc b/chromium/weblayer/browser/browser_controls_container_view.cc
index 13ce69ecca9..96a7e5b8126 100644
--- a/chromium/weblayer/browser/browser_controls_container_view.cc
+++ b/chromium/weblayer/browser/browser_controls_container_view.cc
@@ -36,7 +36,7 @@ BrowserControlsContainerView::BrowserControlsContainerView(
is_top_(is_top) {
DCHECK(content_view_render_view_);
if (!is_top_) {
- content_view_render_view_->SetHeightChangedListener(
+ content_view_render_view_->SetContentHeightChangedListener(
base::BindRepeating(&BrowserControlsContainerView::ContentHeightChanged,
base::Unretained(this)));
}
@@ -44,7 +44,7 @@ BrowserControlsContainerView::BrowserControlsContainerView(
BrowserControlsContainerView::~BrowserControlsContainerView() {
if (!is_top_) {
- content_view_render_view_->SetHeightChangedListener(
+ content_view_render_view_->SetContentHeightChangedListener(
base::RepeatingClosure());
}
}
@@ -75,7 +75,8 @@ int BrowserControlsContainerView::GetContentHeightDelta() {
if (is_top_)
return web_contents()->GetNativeView()->GetLayer()->position().y();
- return content_view_render_view_->height() - controls_layer_->position().y();
+ return content_view_render_view_->content_height() -
+ controls_layer_->position().y();
}
bool BrowserControlsContainerView::IsFullyVisible() const {
@@ -175,8 +176,8 @@ void BrowserControlsContainerView::DoSetBottomControlsOffset() {
if (!controls_layer_)
return;
controls_layer_->SetPosition(
- gfx::PointF(0, content_view_render_view_->height() - GetControlsHeight() +
- GetControlsOffset()));
+ gfx::PointF(0, content_view_render_view_->content_height() -
+ GetControlsHeight() + GetControlsOffset()));
}
static jlong
diff --git a/chromium/weblayer/browser/browser_controls_navigation_state_handler.cc b/chromium/weblayer/browser/browser_controls_navigation_state_handler.cc
index afe0790a91a..77eb49759ae 100644
--- a/chromium/weblayer/browser/browser_controls_navigation_state_handler.cc
+++ b/chromium/weblayer/browser/browser_controls_navigation_state_handler.cc
@@ -74,9 +74,7 @@ void BrowserControlsNavigationStateHandler::DidFinishNavigation(
void BrowserControlsNavigationStateHandler::DidFinishLoad(
content::RenderFrameHost* render_frame_host,
const GURL& validated_url) {
- const bool is_main_frame =
- render_frame_host->GetMainFrame() == render_frame_host;
- if (is_main_frame)
+ if (render_frame_host->IsInPrimaryMainFrame())
ScheduleStopDelayedForceShow();
}
@@ -84,12 +82,8 @@ void BrowserControlsNavigationStateHandler::DidFailLoad(
content::RenderFrameHost* render_frame_host,
const GURL& validated_url,
int error_code) {
- const bool is_main_frame =
- render_frame_host->GetMainFrame() == render_frame_host;
- if (is_main_frame)
+ if (render_frame_host->IsInPrimaryMainFrame()) {
ScheduleStopDelayedForceShow();
- if (render_frame_host->IsActive() &&
- (render_frame_host == web_contents()->GetPrimaryMainFrame())) {
UpdateState();
}
}
diff --git a/chromium/weblayer/browser/browser_controls_navigation_state_handler_browsertest.cc b/chromium/weblayer/browser/browser_controls_navigation_state_handler_browsertest.cc
new file mode 100644
index 00000000000..10ba23562e8
--- /dev/null
+++ b/chromium/weblayer/browser/browser_controls_navigation_state_handler_browsertest.cc
@@ -0,0 +1,80 @@
+// Copyright 2021 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 "content/public/browser/web_contents.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "weblayer/browser/browser_controls_navigation_state_handler.h"
+#include "weblayer/browser/browser_controls_navigation_state_handler_delegate.h"
+#include "weblayer/browser/tab_impl.h"
+#include "weblayer/shell/browser/shell.h"
+#include "weblayer/test/weblayer_browser_test.h"
+#include "weblayer/test/weblayer_browser_test_utils.h"
+
+namespace weblayer {
+
+class BrowserConrolsNavigationStateHandlerBrowserTest
+ : public WebLayerBrowserTest {
+ public:
+ BrowserConrolsNavigationStateHandlerBrowserTest() = default;
+ ~BrowserConrolsNavigationStateHandlerBrowserTest() override = default;
+
+ // WebLayerBrowserTest:
+ void SetUpOnMainThread() override {
+ WebLayerBrowserTest::SetUpOnMainThread();
+ ASSERT_TRUE(embedded_test_server()->Start());
+ }
+
+ content::WebContents* web_contents() {
+ return static_cast<TabImpl*>(shell()->tab())->web_contents();
+ }
+
+ private:
+};
+
+class TestBrowserControlsNavigationStateHandlerDelegate
+ : public BrowserControlsNavigationStateHandlerDelegate {
+ public:
+ // BrowserControlsNavigationStateHandlerDelegate:
+ void OnBrowserControlsStateStateChanged(
+ ControlsVisibilityReason reason,
+ cc::BrowserControlsState state) override {
+ state_ = state;
+ if (quit_callback_)
+ std::move(quit_callback_).Run();
+ }
+ void OnUpdateBrowserControlsStateBecauseOfProcessSwitch(
+ bool did_commit) override {}
+
+ void WaitForStateChanged() {
+ base::RunLoop run_loop;
+ quit_callback_ = run_loop.QuitClosure();
+ run_loop.Run();
+ }
+
+ cc::BrowserControlsState state() { return state_; }
+
+ private:
+ base::OnceClosure quit_callback_;
+ cc::BrowserControlsState state_ = cc::BrowserControlsState::kBoth;
+};
+
+// Tests that BrowserConrolsNavigationStateHandler informs that the status is
+// updated according to navigation progress.
+IN_PROC_BROWSER_TEST_F(BrowserConrolsNavigationStateHandlerBrowserTest, Basic) {
+ TestBrowserControlsNavigationStateHandlerDelegate test_delegate;
+ BrowserControlsNavigationStateHandler
+ browser_controls_navigation_state_handler(web_contents(), &test_delegate);
+ GURL test_url(embedded_test_server()->GetURL("/simple_page.html"));
+ NavigateAndWaitForStart(test_url, shell()->tab());
+ // `test_delegate` should get the status is updated to `kShown` on
+ // DidStartNavigation();
+ EXPECT_EQ(test_delegate.state(), cc::BrowserControlsState::kShown);
+ test_delegate.WaitForStateChanged();
+ // `test_delegate` should get the status is updated to `kBoth` on
+ // DidFinishLoad();
+ EXPECT_EQ(web_contents()->GetLastCommittedURL(), test_url);
+ EXPECT_EQ(test_delegate.state(), cc::BrowserControlsState::kBoth);
+}
+
+} // namespace weblayer
diff --git a/chromium/weblayer/browser/client_hints_factory.cc b/chromium/weblayer/browser/client_hints_factory.cc
index d65a8d2c554..7a16852e2ef 100644
--- a/chromium/weblayer/browser/client_hints_factory.cc
+++ b/chromium/weblayer/browser/client_hints_factory.cc
@@ -32,6 +32,7 @@ ClientHintsFactory::ClientHintsFactory()
"ClientHints",
BrowserContextDependencyManager::GetInstance()) {
DependsOn(HostContentSettingsMapFactory::GetInstance());
+ DependsOn(CookieSettingsFactory::GetInstance());
}
ClientHintsFactory::~ClientHintsFactory() = default;
diff --git a/chromium/weblayer/browser/content_browser_client_impl.cc b/chromium/weblayer/browser/content_browser_client_impl.cc
index 214354fffe0..2f24cb0e0db 100644
--- a/chromium/weblayer/browser/content_browser_client_impl.cc
+++ b/chromium/weblayer/browser/content_browser_client_impl.cc
@@ -259,7 +259,7 @@ void AllowEmptyOriginIdCB(base::OnceCallback<void(bool)> callback) {
void CreateMediaDrmStorage(
content::RenderFrameHost* render_frame_host,
mojo::PendingReceiver<::media::mojom::MediaDrmStorage> receiver) {
- DCHECK(render_frame_host);
+ CHECK(render_frame_host);
if (render_frame_host->GetLastCommittedOrigin().opaque()) {
DVLOG(1) << __func__ << ": Unique origin.";
@@ -269,7 +269,7 @@ void CreateMediaDrmStorage(
// The object will be deleted on connection error, or when the frame navigates
// away.
new cdm::MediaDrmStorageImpl(
- render_frame_host, base::BindRepeating(&CreateOriginId),
+ *render_frame_host, base::BindRepeating(&CreateOriginId),
base::BindRepeating(&AllowEmptyOriginIdCB), std::move(receiver));
}
#endif // BUILDFLAG(IS_ANDROID)
@@ -336,6 +336,7 @@ content::AllowServiceWorkerResult ContentBrowserClientImpl::AllowServiceWorker(
const absl::optional<url::Origin>& top_frame_origin,
const GURL& script_url,
content::BrowserContext* context) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
return embedder_support::AllowServiceWorker(
scope, site_for_cookies, top_frame_origin,
CookieSettingsFactory::GetForBrowserContext(context).get(),
@@ -875,23 +876,26 @@ void ContentBrowserClientImpl::
// TODO(https://crbug.com/1265864): Move the registry logic below to a
// dedicated file to ensure security review coverage.
// TODO(lingqi): Swap the parameters so that lambda functions are not needed.
- associated_registry.AddInterface(base::BindRepeating(
- [](content::RenderFrameHost* render_frame_host,
- mojo::PendingAssociatedReceiver<autofill::mojom::AutofillDriver>
- receiver) {
- autofill::ContentAutofillDriverFactory::BindAutofillDriver(
- std::move(receiver), render_frame_host);
- },
- &render_frame_host));
- associated_registry.AddInterface(base::BindRepeating(
- [](content::RenderFrameHost* render_frame_host,
- mojo::PendingAssociatedReceiver<autofill::mojom::PasswordManagerDriver>
- receiver) {
- PasswordManagerDriverFactory::BindPasswordManagerDriver(
- std::move(receiver), render_frame_host);
- },
- &render_frame_host));
- associated_registry.AddInterface(base::BindRepeating(
+ associated_registry.AddInterface<autofill::mojom::AutofillDriver>(
+ base::BindRepeating(
+ [](content::RenderFrameHost* render_frame_host,
+ mojo::PendingAssociatedReceiver<autofill::mojom::AutofillDriver>
+ receiver) {
+ autofill::ContentAutofillDriverFactory::BindAutofillDriver(
+ std::move(receiver), render_frame_host);
+ },
+ &render_frame_host));
+ associated_registry.AddInterface<autofill::mojom::PasswordManagerDriver>(
+ base::BindRepeating(
+ [](content::RenderFrameHost* render_frame_host,
+ mojo::PendingAssociatedReceiver<
+ autofill::mojom::PasswordManagerDriver> receiver) {
+ PasswordManagerDriverFactory::BindPasswordManagerDriver(
+ std::move(receiver), render_frame_host);
+ },
+ &render_frame_host));
+ associated_registry.AddInterface<
+ content_capture::mojom::ContentCaptureReceiver>(base::BindRepeating(
[](content::RenderFrameHost* render_frame_host,
mojo::PendingAssociatedReceiver<
content_capture::mojom::ContentCaptureReceiver> receiver) {
@@ -899,15 +903,17 @@ void ContentBrowserClientImpl::
std::move(receiver), render_frame_host);
},
&render_frame_host));
- associated_registry.AddInterface(base::BindRepeating(
- [](content::RenderFrameHost* render_frame_host,
- mojo::PendingAssociatedReceiver<
- page_load_metrics::mojom::PageLoadMetrics> receiver) {
- page_load_metrics::MetricsWebContentsObserver::BindPageLoadMetrics(
- std::move(receiver), render_frame_host);
- },
- &render_frame_host));
- associated_registry.AddInterface(base::BindRepeating(
+ associated_registry.AddInterface<page_load_metrics::mojom::PageLoadMetrics>(
+ base::BindRepeating(
+ [](content::RenderFrameHost* render_frame_host,
+ mojo::PendingAssociatedReceiver<
+ page_load_metrics::mojom::PageLoadMetrics> receiver) {
+ page_load_metrics::MetricsWebContentsObserver::BindPageLoadMetrics(
+ std::move(receiver), render_frame_host);
+ },
+ &render_frame_host));
+ associated_registry.AddInterface<
+ security_interstitials::mojom::InterstitialCommands>(base::BindRepeating(
[](content::RenderFrameHost* render_frame_host,
mojo::PendingAssociatedReceiver<
security_interstitials::mojom::InterstitialCommands> receiver) {
@@ -915,7 +921,8 @@ void ContentBrowserClientImpl::
BindInterstitialCommands(std::move(receiver), render_frame_host);
},
&render_frame_host));
- associated_registry.AddInterface(base::BindRepeating(
+ associated_registry.AddInterface<
+ subresource_filter::mojom::SubresourceFilterHost>(base::BindRepeating(
[](content::RenderFrameHost* render_frame_host,
mojo::PendingAssociatedReceiver<
subresource_filter::mojom::SubresourceFilterHost> receiver) {
@@ -938,8 +945,9 @@ void ContentBrowserClientImpl::ExposeInterfacesToRenderer(
mojo::MakeSelfOwnedReceiver(std::make_unique<SpellCheckHostImpl>(),
std::move(receiver));
};
- registry->AddInterface(base::BindRepeating(create_spellcheck_host),
- content::GetUIThreadTaskRunner({}));
+ registry->AddInterface<spellcheck::mojom::SpellCheckHost>(
+ base::BindRepeating(create_spellcheck_host),
+ content::GetUIThreadTaskRunner({}));
if (base::FeatureList::IsEnabled(features::kWebLayerSafeBrowsing) &&
IsSafebrowsingSupported()) {
diff --git a/chromium/weblayer/browser/content_view_render_view.cc b/chromium/weblayer/browser/content_view_render_view.cc
index b6e60b8f939..6453be9bf27 100644
--- a/chromium/weblayer/browser/content_view_render_view.cc
+++ b/chromium/weblayer/browser/content_view_render_view.cc
@@ -46,13 +46,13 @@ ContentViewRenderView::ContentViewRenderView(JNIEnv* env,
}
ContentViewRenderView::~ContentViewRenderView() {
- DCHECK(height_changed_listener_.is_null());
+ DCHECK(content_height_changed_listener_.is_null());
}
-void ContentViewRenderView::SetHeightChangedListener(
+void ContentViewRenderView::SetContentHeightChangedListener(
base::RepeatingClosure callback) {
- DCHECK(height_changed_listener_.is_null() || callback.is_null());
- height_changed_listener_ = std::move(callback);
+ DCHECK(content_height_changed_listener_.is_null() || callback.is_null());
+ content_height_changed_listener_ = std::move(callback);
}
// static
@@ -91,14 +91,21 @@ void ContentViewRenderView::SetCurrentWebContents(
root_container_layer_->AddChild(web_contents_layer_);
}
+void ContentViewRenderView::OnViewportSizeChanged(JNIEnv* env,
+ jint width,
+ jint height) {
+ bool content_height_changed = content_height_ != height;
+ content_height_ = height;
+ if (content_height_changed && !content_height_changed_listener_.is_null())
+ content_height_changed_listener_.Run();
+}
+
void ContentViewRenderView::OnPhysicalBackingSizeChanged(
JNIEnv* env,
const JavaParamRef<jobject>& jweb_contents,
jint width,
jint height,
jboolean for_config_change) {
- bool height_changed = height_ != height;
- height_ = height;
content::WebContents* web_contents =
content::WebContents::FromJavaWebContents(jweb_contents);
gfx::Size size(width, height);
@@ -115,9 +122,6 @@ void ContentViewRenderView::OnPhysicalBackingSizeChanged(
override_deadline = base::TimeDelta();
web_contents->GetNativeView()->OnPhysicalBackingSizeChanged(
size, override_deadline);
-
- if (height_changed && !height_changed_listener_.is_null())
- height_changed_listener_.Run();
}
void ContentViewRenderView::SurfaceCreated(JNIEnv* env) {
diff --git a/chromium/weblayer/browser/content_view_render_view.h b/chromium/weblayer/browser/content_view_render_view.h
index f9c9fdd2668..988e557b56d 100644
--- a/chromium/weblayer/browser/content_view_render_view.h
+++ b/chromium/weblayer/browser/content_view_render_view.h
@@ -40,9 +40,9 @@ class ContentViewRenderView : public content::CompositorClient {
return root_container_layer_;
}
- // Height, in pixels.
- int height() const { return height_; }
- void SetHeightChangedListener(base::RepeatingClosure callback);
+ // Content Height, in pixels.
+ int content_height() const { return content_height_; }
+ void SetContentHeightChangedListener(base::RepeatingClosure callback);
// Methods called from Java via JNI -----------------------------------------
void Destroy(JNIEnv* env);
@@ -55,6 +55,7 @@ class ContentViewRenderView : public content::CompositorClient {
jint width,
jint height,
jboolean for_config_change);
+ void OnViewportSizeChanged(JNIEnv* env, jint width, jint height);
void SurfaceCreated(JNIEnv* env);
void SurfaceDestroyed(JNIEnv* env, jboolean cache_back_buffer);
void SurfaceChanged(JNIEnv* env,
@@ -94,8 +95,8 @@ class ContentViewRenderView : public content::CompositorClient {
scoped_refptr<cc::Layer> root_container_layer_;
scoped_refptr<cc::Layer> web_contents_layer_;
- base::RepeatingClosure height_changed_listener_;
- int height_ = 0;
+ base::RepeatingClosure content_height_changed_listener_;
+ int content_height_ = 0;
};
} // namespace weblayer
diff --git a/chromium/weblayer/browser/download_manager_delegate_impl.cc b/chromium/weblayer/browser/download_manager_delegate_impl.cc
index ff8e7a70a88..2b4926ba8d5 100644
--- a/chromium/weblayer/browser/download_manager_delegate_impl.cc
+++ b/chromium/weblayer/browser/download_manager_delegate_impl.cc
@@ -91,8 +91,7 @@ bool DownloadManagerDelegateImpl::DetermineDownloadTarget(
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
download::DownloadItem::MixedContentStatus::UNKNOWN,
item->GetForcedFilePath(), base::FilePath(),
- std::string() /*mime_type*/, absl::nullopt /*download_schedule*/,
- download::DOWNLOAD_INTERRUPT_REASON_NONE);
+ std::string() /*mime_type*/, download::DOWNLOAD_INTERRUPT_REASON_NONE);
return true;
}
@@ -264,7 +263,6 @@ void DownloadManagerDelegateImpl::OnDownloadPathGenerated(
download::DownloadItem::MixedContentStatus::UNKNOWN,
suggested_path.AddExtension(FILE_PATH_LITERAL(".crdownload")),
base::FilePath(), std::string() /*mime_type*/,
- absl::nullopt /*download_schedule*/,
download::DOWNLOAD_INTERRUPT_REASON_NONE);
}
diff --git a/chromium/weblayer/browser/feature_list_creator.cc b/chromium/weblayer/browser/feature_list_creator.cc
index 70304626019..592ff38a895 100644
--- a/chromium/weblayer/browser/feature_list_creator.cc
+++ b/chromium/weblayer/browser/feature_list_creator.cc
@@ -11,6 +11,7 @@
#include "components/prefs/pref_service.h"
#include "components/variations/service/variations_service.h"
#include "components/variations/variations_crash_keys.h"
+#include "components/variations/variations_switches.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/common/content_switch_dependent_feature_overrides.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -106,10 +107,13 @@ void FeatureListCreator::SetUpFieldTrials() {
std::vector<std::string> variation_ids;
auto feature_list = std::make_unique<base::FeatureList>();
+ const base::CommandLine* command_line =
+ base::CommandLine::ForCurrentProcess();
variations_service_->SetUpFieldTrials(
variation_ids,
- content::GetSwitchDependentFeatureOverrides(
- *base::CommandLine::ForCurrentProcess()),
+ command_line->GetSwitchValueASCII(
+ variations::switches::kForceVariationIds),
+ content::GetSwitchDependentFeatureOverrides(*command_line),
std::move(feature_list), &weblayer_field_trials_);
variations::InitCrashKeys();
#else
diff --git a/chromium/weblayer/browser/java/BUILD.gn b/chromium/weblayer/browser/java/BUILD.gn
index b4a9e6834e6..812e3ad73d9 100644
--- a/chromium/weblayer/browser/java/BUILD.gn
+++ b/chromium/weblayer/browser/java/BUILD.gn
@@ -408,10 +408,7 @@ android_library("test_java") {
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
}
-android_library("junit_test_support") {
- # Platform checks are broken for Robolectric. See https://crbug.com/1071638.
- bypass_platform_checks = true
- testonly = true
+robolectric_library("junit_test_support") {
deps = [
":java",
"//components/payments/content/android:java",
@@ -421,7 +418,6 @@ android_library("junit_test_support") {
"//content/public/android:content_java",
"//mojo/public/java:bindings_java",
"//mojo/public/java:system_java",
- "//third_party/android_deps:robolectric_all_java",
"//third_party/androidx:androidx_annotation_annotation_java",
"//third_party/blink/public/mojom:android_mojo_bindings_java",
"//third_party/mockito:mockito_java",
@@ -433,9 +429,7 @@ android_library("junit_test_support") {
sources = [ "org/chromium/weblayer_private/payments/test_support/WebLayerPaymentRequestBuilder.java" ]
}
-junit_binary("weblayer_junit_tests") {
- # Platform checks are broken for Robolectric. See https://crbug.com/1071638.
- bypass_platform_checks = true
+robolectric_binary("weblayer_junit_tests") {
testonly = true
sources = [ "org/chromium/weblayer_private/payments/WebLayerPaymentRequestServiceTest.java" ]
resources_package = "org.chromium.weblayer_private.test"
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java
index 4927ae672df..ba72036cd82 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java
@@ -7,10 +7,12 @@ package org.chromium.weblayer_private;
import android.app.SearchManager;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.graphics.Rect;
import android.os.RemoteException;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.View;
import androidx.annotation.Nullable;
@@ -26,7 +28,7 @@ import org.chromium.weblayer_private.interfaces.ObjectWrapper;
/**
* A class that handles selection action mode for WebLayer.
*/
-public final class ActionModeCallback implements ActionMode.Callback {
+public final class ActionModeCallback extends ActionMode.Callback2 {
private final ActionModeCallbackHelper mHelper;
// Can be null during init.
private @Nullable ITabClient mTabClient;
@@ -79,8 +81,7 @@ public final class ActionModeCallback implements ActionMode.Callback {
private boolean isWebSearchAvailable() {
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.EXTRA_NEW_SEARCH, true);
- return !PackageManagerUtils.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
- .isEmpty();
+ return PackageManagerUtils.canResolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
}
@Override
@@ -109,4 +110,9 @@ public final class ActionModeCallback implements ActionMode.Callback {
public final void onDestroyActionMode(ActionMode mode) {
mHelper.onDestroyActionMode();
}
+
+ @Override
+ public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
+ mHelper.onGetContentRect(mode, view, outRect);
+ }
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ArCoreVersionUtils.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ArCoreVersionUtils.java
index 365bcbf3efb..bdad3ff26c0 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ArCoreVersionUtils.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ArCoreVersionUtils.java
@@ -15,9 +15,9 @@ import org.chromium.base.annotations.JNINamespace;
@JNINamespace("weblayer")
class ArCoreVersionUtils {
- // Corresponds to V1.22. Must be updated if the arcore version in
+ // Corresponds to V1.32. Must be updated if the arcore version in
// //third_party/arcore-android-sdk-client is rolled.
- private static final int MIN_APK_VERSION = 202940000;
+ private static final int MIN_APK_VERSION = 221020000;
private static final String AR_CORE_PACKAGE = "com.google.ar.core";
private static final String METADATA_KEY_MIN_APK_VERSION = "com.google.ar.core.min_apk_version";
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java
index 8e0b222270b..f959495156c 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java
@@ -7,15 +7,18 @@ package org.chromium.weblayer_private;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
+import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.Settings;
import android.text.TextUtils;
+import android.view.SurfaceControlViewHost;
import android.view.View;
import android.webkit.ValueCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentManager;
import org.chromium.base.ObserverList;
@@ -460,7 +463,7 @@ public class BrowserImpl extends IBrowser.Stub implements View.OnAttachStateChan
}
@Override
- public List getTabs() {
+ public List<TabImpl> getTabs() {
StrictModeWorkaround.apply();
return Arrays.asList(BrowserImplJni.get().getTabs(mNativeBrowser));
}
@@ -472,6 +475,17 @@ public class BrowserImpl extends IBrowser.Stub implements View.OnAttachStateChan
}
@Override
+ public int[] getTabIds() {
+ StrictModeWorkaround.apply();
+ List<TabImpl> tabs = getTabs();
+ int[] ids = new int[tabs.size()];
+ for(int i = 0; i < tabs.size(); i++) {
+ ids[i] = tabs.get(i).getId();
+ }
+ return ids;
+ }
+
+ @Override
public void setClient(IBrowserClient client) {
// This function is called from the client once everything has been setup (meaning all the
// client classes have been created and AIDL interfaces established in both directions).
@@ -728,6 +742,15 @@ public class BrowserImpl extends IBrowser.Stub implements View.OnAttachStateChan
}
}
+ @RequiresApi(Build.VERSION_CODES.R)
+ @Override
+ public void setSurfaceControlViewHost(IObjectWrapper wrappedHost) {
+ // TODO(rayankans): Handle fallback for older devices.
+ SurfaceControlViewHost host =
+ ObjectWrapper.unwrap(wrappedHost, SurfaceControlViewHost.class);
+ host.setView(mViewController.getView(), 0, 0);
+ }
+
@NativeMethods
interface Natives {
long createBrowser(long profile, BrowserImpl caller);
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 f3eb434b15f..b1df391d46c 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java
@@ -4,6 +4,7 @@
package org.chromium.weblayer_private;
+import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.RemoteException;
@@ -188,8 +189,16 @@ public final class BrowserViewController
});
mContentViewRenderView.addView(mBottomSheetContainer);
+ Activity activity = ContextUtils.activityFromContext(context);
+ if (activity == null) {
+ // TODO(rayankans): Remove assumptions about Activity from BottomSheetController.
+ mBottomSheetController = null;
+ mPwaBottomSheetController = null;
+ mBottomSheetObserver = null;
+ return;
+ }
mBottomSheetController = BottomSheetControllerFactory.createBottomSheetController(
- () -> mScrim, (v) -> {}, ContextUtils.activityFromContext(context).getWindow(),
+ () -> mScrim, (v) -> {}, activity.getWindow(),
KeyboardVisibilityDelegate.getInstance(), () -> mBottomSheetContainer,
() -> mContentViewRenderView.getHeight());
BottomSheetControllerFactory.attach(mWindowAndroid, mBottomSheetController);
@@ -235,9 +244,11 @@ public final class BrowserViewController
}
public void destroy() {
- BottomSheetControllerFactory.detach(mBottomSheetController);
- mBottomSheetController.removeObserver(mBottomSheetObserver);
- PwaBottomSheetControllerFactory.detach(mPwaBottomSheetController);
+ if (mBottomSheetController != null) {
+ BottomSheetControllerFactory.detach(mBottomSheetController);
+ mBottomSheetController.removeObserver(mBottomSheetObserver);
+ PwaBottomSheetControllerFactory.detach(mPwaBottomSheetController);
+ }
mWindowAndroid.setModalDialogManager(null);
setActiveTab(null);
if (mOnscreenContentProvider != null) mOnscreenContentProvider.destroy();
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
index dce3faddc7c..f8b8f686bac 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
@@ -872,7 +872,11 @@ public class ContentViewRenderView
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ if (mWebContents == null) return;
updateWebContentsSize();
+ Size viewportSize = getViewportSize();
+ ContentViewRenderViewJni.get().onViewportSizeChanged(
+ mNativeContentViewRenderView, viewportSize.getWidth(), viewportSize.getHeight());
}
/**
@@ -1093,6 +1097,7 @@ public class ContentViewRenderView
void setCurrentWebContents(long nativeContentViewRenderView, WebContents webContents);
void onPhysicalBackingSizeChanged(long nativeContentViewRenderView, WebContents webContents,
int width, int height, boolean forConfigChange);
+ void onViewportSizeChanged(long nativeContentViewRenderView, int width, int height);
void surfaceCreated(long nativeContentViewRenderView);
void surfaceDestroyed(long nativeContentViewRenderView, boolean cacheBackBuffer);
void surfaceChanged(long nativeContentViewRenderView, boolean canBeUsedWithSurfaceControl,
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 5b76ecfde73..3085b7ae541 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ExternalNavigationDelegateImpl.java
@@ -6,12 +6,14 @@ package org.chromium.weblayer_private;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ResolveInfo;
import android.os.RemoteException;
import androidx.annotation.Nullable;
import org.chromium.base.Callback;
import org.chromium.base.Function;
+import org.chromium.base.supplier.Supplier;
import org.chromium.components.embedder_support.util.UrlUtilities;
import org.chromium.components.external_intents.ExternalNavigationDelegate;
import org.chromium.components.external_intents.ExternalNavigationParams;
@@ -23,6 +25,8 @@ import org.chromium.url.Origin;
import org.chromium.weblayer_private.interfaces.APICallException;
import org.chromium.weblayer_private.interfaces.ExternalIntentInIncognitoUserDecision;
+import java.util.List;
+
/**
* WebLayer's implementation of the {@link ExternalNavigationDelegate}.
*/
@@ -149,8 +153,8 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat
public void maybeSetPendingIncognitoUrl(Intent intent) {}
@Override
- public boolean maybeLaunchInstantApp(
- GURL url, GURL referrerUrl, boolean isIncomingRedirect, boolean isSerpReferrer) {
+ public boolean maybeLaunchInstantApp(GURL url, GURL referrerUrl, boolean isIncomingRedirect,
+ boolean isSerpReferrer, Supplier<List<ResolveInfo>> resolveInfoSupplier) {
return false;
}
@@ -176,7 +180,8 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat
}
@Override
- public boolean isIntentForTrustedCallingApp(Intent intent) {
+ public boolean isIntentForTrustedCallingApp(
+ Intent intent, Supplier<List<ResolveInfo>> resolveInfoSupplier) {
return false;
}
@@ -204,7 +209,8 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat
}
@Override
- public boolean maybeSetTargetPackage(Intent intent) {
+ public boolean maybeSetTargetPackage(
+ Intent intent, Supplier<List<ResolveInfo>> resolveInfoSupplier) {
return false;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/FragmentHostingRemoteFragmentImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/FragmentHostingRemoteFragmentImpl.java
index 13f836ffae0..6ac7dc5563e 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/FragmentHostingRemoteFragmentImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/FragmentHostingRemoteFragmentImpl.java
@@ -167,7 +167,9 @@ public abstract class FragmentHostingRemoteFragmentImpl extends RemoteFragmentIm
// within an AppCompatActivity, it will be from the embedder's ClassLoader, so in WebLayer's
// ClassLoader the initialization hasn't occurred. Creating an AppCompatDelegate manually
// here will perform the necessary initialization.
- AppCompatDelegate.create(getActivity(), null);
+ if (getActivity() != null) {
+ AppCompatDelegate.create(getActivity(), null);
+ }
}
@Override
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java
index e4353bc7620..dfe72d7e1fb 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/InterceptNavigationDelegateClientImpl.java
@@ -8,7 +8,6 @@ import android.app.Activity;
import android.os.SystemClock;
import org.chromium.base.ContextUtils;
-import org.chromium.components.external_intents.AuthenticatorNavigationInterceptor;
import org.chromium.components.external_intents.ExternalNavigationHandler;
import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingAsyncActionType;
import org.chromium.components.external_intents.ExternalNavigationHandler.OverrideUrlLoadingResult;
@@ -91,11 +90,6 @@ public class InterceptNavigationDelegateClientImpl implements InterceptNavigatio
}
@Override
- public AuthenticatorNavigationInterceptor createAuthenticatorNavigationInterceptor() {
- return null;
- }
-
- @Override
public boolean isIncognito() {
return mTab.getProfile().isIncognito();
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java
index 5ae639acb1a..d303483b863 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java
@@ -274,6 +274,8 @@ public final class ProfileImpl
long toMillis, @NonNull IObjectWrapper completionCallback) {
StrictModeWorkaround.apply();
checkNotDestroyed();
+ // `toMillis` should be greater than `fromMillis`
+ assert fromMillis < toMillis;
// Handle ContentCapture data clearing.
PlatformContentCaptureController controller =
PlatformContentCaptureController.getInstance();
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 3723120fcf2..5373cad57a7 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
@@ -227,6 +227,7 @@ public final class TabImpl extends ITab.Stub {
@Override
protected void onVerticalScrollDirectionChanged(
boolean directionUp, float currentScrollRatio) {
+ super.onVerticalScrollDirectionChanged(directionUp, currentScrollRatio);
try {
mClient.onScrollNotification(directionUp
? ScrollNotificationType.DIRECTION_CHANGED_UP
@@ -275,11 +276,17 @@ public final class TabImpl extends ITab.Stub {
mWebContentsObserver = new WebContentsObserver() {
@Override
- public void didStartNavigation(NavigationHandle navigationHandle) {
- if (navigationHandle.isInPrimaryMainFrame() && !navigationHandle.isSameDocument()) {
+ public void didStartNavigationInPrimaryMainFrame(NavigationHandle navigationHandle) {
+ if (!navigationHandle.isSameDocument()) {
hideFindInPageUiAndNotifyClient();
}
}
+
+ @Override
+ public void didStartNavigationNoop(NavigationHandle navigationHandle) {
+ if (!navigationHandle.isInPrimaryMainFrame()) return;
+ }
+
@Override
public void viewportFitChanged(@WebContentsObserver.ViewportFitType int value) {
ensureDisplayCutoutController();
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebContentsGestureStateTracker.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebContentsGestureStateTracker.java
index eb9ca9b1ddd..0a1312404bd 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebContentsGestureStateTracker.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebContentsGestureStateTracker.java
@@ -64,7 +64,8 @@ public final class WebContentsGestureStateTracker {
mGestureListener = new GestureStateListener() {
@Override
- public void onFlingStartGesture(int scrollOffsetY, int scrollExtentY) {
+ public void onFlingStartGesture(
+ int scrollOffsetY, int scrollExtentY, boolean isDirectionUp) {
onScrollingStateChanged();
}
@@ -74,7 +75,8 @@ public final class WebContentsGestureStateTracker {
}
@Override
- public void onScrollStarted(int scrollOffsetY, int scrollExtentY) {
+ public void onScrollStarted(
+ int scrollOffsetY, int scrollExtentY, boolean isDirectionUp) {
onScrollingStateChanged();
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java
index b5d8ae6e804..175d9108b82 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerNotificationWrapperBuilder.java
@@ -78,27 +78,27 @@ public final class WebLayerNotificationWrapperBuilder extends NotificationWrappe
* resources. This is useful when {@link Icon} is not available.
*/
private int getFallbackAndroidResource(int appResourceId) {
- if (appResourceId == R.drawable.ic_play_arrow_white_36dp) {
+ if (appResourceId == R.drawable.ic_play_arrow_white_24dp) {
return android.R.drawable.ic_media_play;
}
- if (appResourceId == R.drawable.ic_pause_white_36dp) {
+ if (appResourceId == R.drawable.ic_pause_white_24dp) {
return android.R.drawable.ic_media_pause;
}
- if (appResourceId == R.drawable.ic_stop_white_36dp) {
+ if (appResourceId == R.drawable.ic_stop_white_24dp) {
// There's no ic_media_stop. This standin is at least a square. In practice this
// shouldn't ever come up as stop is only used in (Chrome) cast notifications.
return android.R.drawable.checkbox_off_background;
}
- if (appResourceId == R.drawable.ic_skip_previous_white_36dp) {
+ if (appResourceId == R.drawable.ic_skip_previous_white_24dp) {
return android.R.drawable.ic_media_previous;
}
- if (appResourceId == R.drawable.ic_skip_next_white_36dp) {
+ if (appResourceId == R.drawable.ic_skip_next_white_24dp) {
return android.R.drawable.ic_media_next;
}
- if (appResourceId == R.drawable.ic_fast_forward_white_36dp) {
+ if (appResourceId == R.drawable.ic_fast_forward_white_24dp) {
return android.R.drawable.ic_media_ff;
}
- if (appResourceId == R.drawable.ic_fast_rewind_white_36dp) {
+ if (appResourceId == R.drawable.ic_fast_rewind_white_24dp) {
return android.R.drawable.ic_media_rew;
}
if (appResourceId == R.drawable.audio_playing) {
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl
index ece38bee852..7bd4e537b15 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl
@@ -55,4 +55,10 @@ interface IBrowser {
// Added in 91.
void setChangeVisibilityOnNextDetach(in boolean changeVisibility) = 18;
+
+ // Added in 105.
+ void setSurfaceControlViewHost(in IObjectWrapper host) = 19;
+
+ // Added in 105
+ int[] getTabIds() = 20;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/PRESUBMIT.py b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/PRESUBMIT.py
index 8fa31a20902..e507cad300d 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/PRESUBMIT.py
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/PRESUBMIT.py
@@ -72,6 +72,10 @@ class AidlFile:
def _CompareApiDumpForFiles(input_api, output_api, aidl_files):
if len(aidl_files) == 0:
return []
+ # These tests fail to run on Windows (devil_chromium needs some non-standard
+ # Windows modules) and given the Android dependencies this is reasonable.
+ if input_api.is_windows:
+ return []
repo_root = input_api.change.RepositoryRoot()
build_android_dir = os.path.join(repo_root, 'build', 'android')
@@ -81,7 +85,14 @@ def _CompareApiDumpForFiles(input_api, output_api, aidl_files):
from devil.android.sdk import build_tools
devil_chromium.Initialize()
- aidl_tool_path = build_tools.GetPath('aidl')
+ try:
+ aidl_tool_path = build_tools.GetPath('aidl')
+ except Exception as e:
+ if input_api.no_diffs:
+ # If we are running presubmits with --all or --files and the 'aidl' tool
+ # cannot be found then that probably means that target_os = 'android' is
+ # missing from .gclient and the failure is not interesting.
+ return []
if not os.path.exists(aidl_tool_path):
return [output_api.PresubmitError(
'Android sdk does not contain aidl command ' + aidl_tool_path)]
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 23f8f61a4f2..106483b7538 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
@@ -9,8 +9,6 @@ import androidx.annotation.Nullable;
import org.chromium.components.payments.BrowserPaymentRequest;
import org.chromium.components.payments.JourneyLogger;
import org.chromium.components.payments.PaymentApp;
-import org.chromium.components.payments.PaymentAppFactoryDelegate;
-import org.chromium.components.payments.PaymentAppService;
import org.chromium.components.payments.PaymentAppType;
import org.chromium.components.payments.PaymentRequestService;
import org.chromium.components.payments.PaymentRequestService.Delegate;
@@ -107,13 +105,6 @@ public class WebLayerPaymentRequestService implements BrowserPaymentRequest {
// Implements BrowserPaymentRequest:
@Override
- public void addPaymentAppFactories(
- PaymentAppService service, PaymentAppFactoryDelegate delegate) {
- // There's no WebLayer specific factories.
- }
-
- // Implements BrowserPaymentRequest:
- @Override
@Nullable
public String showOrSkipAppSelector(boolean isShowWaitingForUpdatedDetails, PaymentItem total,
boolean shouldSkipAppSelector) {
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerSiteSettingsDelegate.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerSiteSettingsDelegate.java
index b24a6fe6ba7..efc62c056e3 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerSiteSettingsDelegate.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/settings/WebLayerSiteSettingsDelegate.java
@@ -5,7 +5,7 @@
package org.chromium.weblayer_private.settings;
import android.app.Activity;
-import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
@@ -47,7 +47,7 @@ public class WebLayerSiteSettingsDelegate
}
@Override
- public void getFaviconImageForURL(GURL faviconUrl, Callback<Bitmap> callback) {
+ public void getFaviconImageForURL(GURL faviconUrl, Callback<Drawable> callback) {
// We don't currently support favicons on WebLayer.
callback.onResult(null);
}
@@ -137,4 +137,15 @@ public class WebLayerSiteSettingsDelegate
@Override
public void dismissPrivacySandboxSnackbar() {}
+
+ @Override
+ public boolean canLaunchClearBrowsingDataDialog() {
+ return false;
+ }
+
+ @Override
+ public void launchClearBrowsingDataDialog(Activity currentActivity) {}
+
+ @Override
+ public void onDestroyView() {}
}
diff --git a/chromium/weblayer/browser/overlay_popup_ad_intervention_browsertest.cc b/chromium/weblayer/browser/overlay_popup_ad_intervention_browsertest.cc
index 0424fe82790..4455d2bacbe 100644
--- a/chromium/weblayer/browser/overlay_popup_ad_intervention_browsertest.cc
+++ b/chromium/weblayer/browser/overlay_popup_ad_intervention_browsertest.cc
@@ -134,8 +134,9 @@ class OverlayPopupAdViolationBrowserTestWithoutEnforcement
base::test::ScopedFeatureList feature_list_;
};
+// TODO(https://crbug.com/1344280): Test is flaky.
IN_PROC_BROWSER_TEST_F(OverlayPopupAdViolationBrowserTestWithoutEnforcement,
- OverlayPopupAd_NoAdInterventionTriggered) {
+ DISABLED_OverlayPopupAd_NoAdInterventionTriggered) {
base::HistogramTester histogram_tester;
GURL url = embedded_test_server()->GetURL(
diff --git a/chromium/weblayer/browser/page_load_metrics_browsertest.cc b/chromium/weblayer/browser/page_load_metrics_browsertest.cc
index f6f7dc153fc..060d0a3c796 100644
--- a/chromium/weblayer/browser/page_load_metrics_browsertest.cc
+++ b/chromium/weblayer/browser/page_load_metrics_browsertest.cc
@@ -26,10 +26,22 @@ class PageLoadMetricsObserver
// 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 {
+ // This class is only interested in events for outer-most frame that are
+ // forwarded by PageLoadTracker. So, this class doesn't need observer-level
+ // forwarding.
+ return STOP_OBSERVING;
+ }
+
+ PageLoadMetricsObserver::ObservePolicy OnPrerenderStart(
+ content::NavigationHandle* navigation_handle,
+ const GURL& currently_committed_url) override {
+ // Currently, prerendering is not enabled for WebLayer.
+ //
+ // TODO(https://crbug.com/1267224): If support prerendering, add callbacks
+ // and tests.
return STOP_OBSERVING;
}
diff --git a/chromium/weblayer/browser/page_load_metrics_observer_impl.cc b/chromium/weblayer/browser/page_load_metrics_observer_impl.cc
index fdaeaf80c79..48216ab3f8a 100644
--- a/chromium/weblayer/browser/page_load_metrics_observer_impl.cc
+++ b/chromium/weblayer/browser/page_load_metrics_observer_impl.cc
@@ -18,11 +18,24 @@
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) {
+ // This class is only interested in events for outer-most frame that are
+ // forwarded by PageLoadTracker. So, this class doesn't need observer-level
+ // forwarding.
+ return STOP_OBSERVING;
+}
+
+page_load_metrics::PageLoadMetricsObserver::ObservePolicy
+PageLoadMetricsObserverImpl::OnPrerenderStart(
+ content::NavigationHandle* navigation_handle,
+ const GURL& currently_committed_url) {
+ // Currently, prerendering is not enabled for WebLayer.
+ //
+ // TODO(https://crbug.com/1267224): If support prerendering, add callbacks,
+ // e.g. notification of activation_start.
return STOP_OBSERVING;
}
diff --git a/chromium/weblayer/browser/page_load_metrics_observer_impl.h b/chromium/weblayer/browser/page_load_metrics_observer_impl.h
index c6d94133cd9..b23b030462d 100644
--- a/chromium/weblayer/browser/page_load_metrics_observer_impl.h
+++ b/chromium/weblayer/browser/page_load_metrics_observer_impl.h
@@ -19,6 +19,8 @@ class PageLoadMetricsObserverImpl
ObservePolicy OnFencedFramesStart(
content::NavigationHandle* navigation_handle,
const GURL& currently_committed_url) override;
+ ObservePolicy OnPrerenderStart(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/password_manager_driver_factory.cc b/chromium/weblayer/browser/password_manager_driver_factory.cc
index 814beb62e2b..e74439062f5 100644
--- a/chromium/weblayer/browser/password_manager_driver_factory.cc
+++ b/chromium/weblayer/browser/password_manager_driver_factory.cc
@@ -37,8 +37,7 @@ class PasswordManagerDriverFactory::PasswordManagerDriver
void PasswordFormsParsed(
const std::vector<autofill::FormData>& raw_forms_data) override {}
void PasswordFormsRendered(
- const std::vector<autofill::FormData>& raw_visible_forms_data,
- bool did_stop_loading) override {}
+ const std::vector<autofill::FormData>& raw_visible_forms_data) override {}
void PasswordFormSubmitted(const autofill::FormData& raw_form_data) override {
}
void InformAboutUserInput(const autofill::FormData& raw_form_data) override {
@@ -105,6 +104,9 @@ void PasswordManagerDriverFactory::BindPasswordManagerDriver(
mojo::PendingAssociatedReceiver<autofill::mojom::PasswordManagerDriver>
pending_receiver,
content::RenderFrameHost* render_frame_host) {
+ // TODO(https://crbug.com/1233858): Similarly to the
+ // ContentPasswordManagerDriver implementation. Do not bind the interface when
+ // the RenderFrameHost is in an anonymous iframe.
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
if (!web_contents)
diff --git a/chromium/weblayer/browser/permissions/permission_manager_factory.cc b/chromium/weblayer/browser/permissions/permission_manager_factory.cc
index ef813c2e918..b13d7428e87 100644
--- a/chromium/weblayer/browser/permissions/permission_manager_factory.cc
+++ b/chromium/weblayer/browser/permissions/permission_manager_factory.cc
@@ -126,7 +126,7 @@ permissions::PermissionManager::PermissionContextMap CreatePermissionContexts(
continue;
#endif
ContentSettingsType content_settings_type =
- permissions::PermissionUtil::PermissionTypeToContentSetting(type);
+ permissions::PermissionUtil::PermissionTypeToContentSettingType(type);
if (permission_contexts.find(content_settings_type) ==
permission_contexts.end()) {
permission_contexts[content_settings_type] =
diff --git a/chromium/weblayer/browser/permissions/weblayer_permissions_client.cc b/chromium/weblayer/browser/permissions/weblayer_permissions_client.cc
index e0993278a5f..6cd171c316a 100644
--- a/chromium/weblayer/browser/permissions/weblayer_permissions_client.cc
+++ b/chromium/weblayer/browser/permissions/weblayer_permissions_client.cc
@@ -12,7 +12,6 @@
#include "weblayer/browser/cookie_settings_factory.h"
#include "weblayer/browser/host_content_settings_map_factory.h"
#include "weblayer/browser/permissions/permission_decision_auto_blocker_factory.h"
-#include "weblayer/browser/permissions/permission_manager_factory.h"
#include "weblayer/browser/subresource_filter_profile_context_factory.h"
#if BUILDFLAG(IS_ANDROID)
@@ -63,11 +62,6 @@ WebLayerPermissionsClient::GetPermissionActionsHistory(
return nullptr;
}
-permissions::PermissionManager* WebLayerPermissionsClient::GetPermissionManager(
- content::BrowserContext* browser_context) {
- return PermissionManagerFactory::GetForBrowserContext(browser_context);
-}
-
permissions::ObjectPermissionContextBase*
WebLayerPermissionsClient::GetChooserContext(
content::BrowserContext* browser_context,
diff --git a/chromium/weblayer/browser/permissions/weblayer_permissions_client.h b/chromium/weblayer/browser/permissions/weblayer_permissions_client.h
index a193c0ea981..a772aeb35f4 100644
--- a/chromium/weblayer/browser/permissions/weblayer_permissions_client.h
+++ b/chromium/weblayer/browser/permissions/weblayer_permissions_client.h
@@ -30,8 +30,6 @@ class WebLayerPermissionsClient : public permissions::PermissionsClient {
content::BrowserContext* browser_context) override;
permissions::PermissionDecisionAutoBlocker* GetPermissionDecisionAutoBlocker(
content::BrowserContext* browser_context) override;
- permissions::PermissionManager* GetPermissionManager(
- content::BrowserContext* browser_context) override;
permissions::ObjectPermissionContextBase* GetChooserContext(
content::BrowserContext* browser_context,
ContentSettingsType type) override;
diff --git a/chromium/weblayer/browser/profile_impl.cc b/chromium/weblayer/browser/profile_impl.cc
index 8748a5f3f3c..aa6e5cccdaf 100644
--- a/chromium/weblayer/browser/profile_impl.cc
+++ b/chromium/weblayer/browser/profile_impl.cc
@@ -304,6 +304,8 @@ void ProfileImpl::ClearBrowsingData(
content::BrowsingDataRemover::DATA_TYPE_ATTRIBUTION_REPORTING;
remove_mask |=
content::BrowsingDataRemover::DATA_TYPE_AGGREGATION_SERVICE;
+ remove_mask |= content::BrowsingDataRemover::
+ DATA_TYPE_PRIVATE_AGGREGATION_INTERNAL;
break;
case BrowsingDataType::CACHE:
remove_mask |= content::BrowsingDataRemover::DATA_TYPE_CACHE;
diff --git a/chromium/weblayer/browser/reduce_accept_language_factory.cc b/chromium/weblayer/browser/reduce_accept_language_factory.cc
new file mode 100644
index 00000000000..aa524437203
--- /dev/null
+++ b/chromium/weblayer/browser/reduce_accept_language_factory.cc
@@ -0,0 +1,50 @@
+// 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/reduce_accept_language_factory.h"
+
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/reduce_accept_language/browser/reduce_accept_language_service.h"
+#include "weblayer/browser/browser_context_impl.h"
+#include "weblayer/browser/host_content_settings_map_factory.h"
+
+namespace weblayer {
+
+// static
+reduce_accept_language::ReduceAcceptLanguageService*
+ReduceAcceptLanguageFactory::GetForBrowserContext(
+ content::BrowserContext* context) {
+ return static_cast<reduce_accept_language::ReduceAcceptLanguageService*>(
+ GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+// static
+ReduceAcceptLanguageFactory* ReduceAcceptLanguageFactory::GetInstance() {
+ static base::NoDestructor<ReduceAcceptLanguageFactory> instance;
+ return instance.get();
+}
+
+ReduceAcceptLanguageFactory::ReduceAcceptLanguageFactory()
+ : BrowserContextKeyedServiceFactory(
+ "ReduceAcceptLanguage",
+ BrowserContextDependencyManager::GetInstance()) {
+ DependsOn(HostContentSettingsMapFactory::GetInstance());
+}
+
+ReduceAcceptLanguageFactory::~ReduceAcceptLanguageFactory() = default;
+
+KeyedService* ReduceAcceptLanguageFactory::BuildServiceInstanceFor(
+ content::BrowserContext* context) const {
+ return new reduce_accept_language::ReduceAcceptLanguageService(
+ HostContentSettingsMapFactory::GetForBrowserContext(context),
+ static_cast<BrowserContextImpl*>(context)->pref_service(),
+ context->IsOffTheRecord());
+}
+
+content::BrowserContext* ReduceAcceptLanguageFactory::GetBrowserContextToUse(
+ content::BrowserContext* context) const {
+ return context;
+}
+
+} // namespace weblayer \ No newline at end of file
diff --git a/chromium/weblayer/browser/reduce_accept_language_factory.h b/chromium/weblayer/browser/reduce_accept_language_factory.h
new file mode 100644
index 00000000000..1c8f51f622f
--- /dev/null
+++ b/chromium/weblayer/browser/reduce_accept_language_factory.h
@@ -0,0 +1,42 @@
+// 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_REDUCE_ACCEPT_LANGUAGE_FACTORY_H_
+#define WEBLAYER_BROWSER_REDUCE_ACCEPT_LANGUAGE_FACTORY_H_
+
+#include "base/no_destructor.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+#include "components/reduce_accept_language/browser/reduce_accept_language_service.h"
+#include "content/public/browser/reduce_accept_language_controller_delegate.h"
+
+namespace weblayer {
+
+class ReduceAcceptLanguageFactory : public BrowserContextKeyedServiceFactory {
+ public:
+ static reduce_accept_language::ReduceAcceptLanguageService*
+ GetForBrowserContext(content::BrowserContext* context);
+
+ static ReduceAcceptLanguageFactory* GetInstance();
+
+ // Non-copyable, non-moveable.
+ ReduceAcceptLanguageFactory(const ReduceAcceptLanguageFactory&) = delete;
+ ReduceAcceptLanguageFactory& operator=(const ReduceAcceptLanguageFactory&) =
+ delete;
+
+ private:
+ friend base::NoDestructor<ReduceAcceptLanguageFactory>;
+
+ ReduceAcceptLanguageFactory();
+ ~ReduceAcceptLanguageFactory() override;
+
+ // BrowserContextKeyedServiceFactory methods:
+ KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) const override;
+ content::BrowserContext* GetBrowserContextToUse(
+ content::BrowserContext* context) const override;
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_BROWSER_REDUCE_ACCEPT_LANGUAGE_FACTORY_H_
diff --git a/chromium/weblayer/browser/reduce_accept_language_service_browsertest.cc b/chromium/weblayer/browser/reduce_accept_language_service_browsertest.cc
new file mode 100644
index 00000000000..06084022de4
--- /dev/null
+++ b/chromium/weblayer/browser/reduce_accept_language_service_browsertest.cc
@@ -0,0 +1,92 @@
+// Copyright (c) 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/language/core/browser/language_prefs.h"
+#include "components/language/core/browser/pref_names.h"
+#include "components/prefs/pref_service.h"
+#include "components/reduce_accept_language/browser/reduce_accept_language_service.h"
+#include "components/reduce_accept_language/browser/reduce_accept_language_service_test_util.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+#include "weblayer/browser/browser_context_impl.h"
+#include "weblayer/browser/host_content_settings_map_factory.h"
+#include "weblayer/browser/reduce_accept_language_factory.h"
+#include "weblayer/browser/tab_impl.h"
+#include "weblayer/shell/browser/shell.h"
+#include "weblayer/test/weblayer_browser_test.h"
+#include "weblayer/test/weblayer_browser_test_utils.h"
+
+using reduce_accept_language::test::ReduceAcceptLanguageServiceTester;
+
+namespace weblayer {
+
+class ReduceAcceptLanguageServiceTest : public WebLayerBrowserTest {
+ public:
+ void SetUpOnMainThread() override {
+ WebLayerBrowserTest::SetUpOnMainThread();
+ service_tester_ = std::make_unique<ReduceAcceptLanguageServiceTester>(
+ settings_map(), service(), prefs());
+ language::LanguagePrefs(prefs()).SetUserSelectedLanguagesList(
+ {"en", "ja", "it"});
+ }
+
+ content::WebContents* web_contents() {
+ return static_cast<TabImpl*>(shell()->tab())->web_contents();
+ }
+
+ HostContentSettingsMap* settings_map() {
+ return HostContentSettingsMapFactory::GetForBrowserContext(
+ web_contents()->GetBrowserContext());
+ }
+
+ PrefService* prefs() {
+ return static_cast<BrowserContextImpl*>(web_contents()->GetBrowserContext())
+ ->pref_service();
+ }
+
+ reduce_accept_language::ReduceAcceptLanguageService* service() {
+ return ReduceAcceptLanguageFactory::GetForBrowserContext(
+ web_contents()->GetBrowserContext());
+ }
+
+ ReduceAcceptLanguageServiceTester* tester() { return service_tester_.get(); }
+
+ private:
+ std::unique_ptr<ReduceAcceptLanguageServiceTester> service_tester_;
+};
+
+IN_PROC_BROWSER_TEST_F(ReduceAcceptLanguageServiceTest, GetAcceptLanguageList) {
+ tester()->VerifyFetchAcceptLanguageList({"en", "ja", "it"});
+ reduce_accept_language::ReduceAcceptLanguageService incognito_service(
+ settings_map(), prefs(), true);
+ // Verify incognito mode only has first accept language.
+ EXPECT_EQ(std::vector<std::string>{"en"},
+ incognito_service.GetUserAcceptLanguages());
+}
+
+IN_PROC_BROWSER_TEST_F(ReduceAcceptLanguageServiceTest, PersistLanguageFail) {
+ tester()->VerifyPersistFail(GURL("ws://example.com/"), "Zh-CN");
+}
+
+IN_PROC_BROWSER_TEST_F(ReduceAcceptLanguageServiceTest,
+ PersistLanguageSuccessJavaScriptNotEnabled) {
+ tester()->VerifyPersistSuccessOnJavaScriptDisable(
+ GURL("https://example.com/"), "Zh-CN");
+}
+
+IN_PROC_BROWSER_TEST_F(ReduceAcceptLanguageServiceTest,
+ PersistLanguageSuccess) {
+ tester()->VerifyPersistSuccess(GURL("https://example.com/"), "Zh-CN");
+}
+
+IN_PROC_BROWSER_TEST_F(ReduceAcceptLanguageServiceTest,
+ PersistLanguageMultipleHosts) {
+ tester()->VerifyPersistMultipleHostsSuccess(
+ {GURL("https://example1.com/"), GURL("https://example2.com/"),
+ GURL("http://example.com/")},
+ {"en-US", "es-MX", "zh-CN"});
+}
+
+} // namespace weblayer \ No newline at end of file
diff --git a/chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc b/chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc
index df3e9e863eb..3f27d417f9f 100644
--- a/chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc
+++ b/chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc
@@ -320,15 +320,18 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, DoesNotShowInterstitial_Safe) {
NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_SAFE, false);
}
-IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Malware) {
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
+ DISABLED_ShowsInterstitial_Malware) {
NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_MALWARE, true);
}
-IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Phishing) {
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
+ DISABLED_ShowsInterstitial_Phishing) {
NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_PHISHING, true);
}
-IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, CheckNavigationErrorType) {
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
+ DISABLED_CheckNavigationErrorType) {
auto threat_types = {
safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
safe_browsing::SB_THREAT_TYPE_URL_MALWARE,
@@ -347,16 +350,20 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, CheckNavigationErrorType) {
}
}
-IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Unwanted) {
+// Tests below are disabled due to failures on Android.
+// See crbug.com/1340200.
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
+ DISABLED_ShowsInterstitial_Unwanted) {
NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_UNWANTED, true);
}
-IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Billing) {
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
+ DISABLED_ShowsInterstitial_Billing) {
NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_BILLING, true);
}
IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest,
- ShowsInterstitial_Malware_Subresource) {
+ DISABLED_ShowsInterstitial_Malware_Subresource) {
NavigateWithSubResourceAndThreatType(
safe_browsing::SB_THREAT_TYPE_URL_MALWARE, true);
}
diff --git a/chromium/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc b/chromium/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc
index abb4b8adf4d..82036c1a9ae 100644
--- a/chromium/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc
+++ b/chromium/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.cc
@@ -12,6 +12,7 @@
#include "weblayer/browser/browser_process.h"
#include "weblayer/browser/safe_browsing/client_side_detection_service_factory.h"
#include "weblayer/browser/safe_browsing/safe_browsing_service.h"
+#include "weblayer/browser/verdict_cache_manager_factory.h"
namespace weblayer {
@@ -48,10 +49,11 @@ WebLayerClientSideDetectionHostDelegate::GetSafeBrowsingUIManager() {
return sb_service->GetSafeBrowsingUIManager();
}
-safe_browsing::ClientSideDetectionService*
+base::WeakPtr<safe_browsing::ClientSideDetectionService>
WebLayerClientSideDetectionHostDelegate::GetClientSideDetectionService() {
return ClientSideDetectionServiceFactory::GetForBrowserContext(
- web_contents_->GetBrowserContext());
+ web_contents_->GetBrowserContext())
+ ->GetWeakPtr();
}
void WebLayerClientSideDetectionHostDelegate::AddReferrerChain(
@@ -59,4 +61,10 @@ void WebLayerClientSideDetectionHostDelegate::AddReferrerChain(
GURL current_url,
const content::GlobalRenderFrameHostId& current_outermost_main_frame_id) {}
+raw_ptr<safe_browsing::VerdictCacheManager>
+WebLayerClientSideDetectionHostDelegate::GetCacheManager() {
+ return VerdictCacheManagerFactory::GetForBrowserContext(
+ web_contents_->GetBrowserContext());
+}
+
} // namespace weblayer
diff --git a/chromium/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h b/chromium/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h
index 9bcb2db091b..96f0c962743 100644
--- a/chromium/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h
+++ b/chromium/weblayer/browser/safe_browsing/weblayer_client_side_detection_host_delegate.h
@@ -36,12 +36,13 @@ class WebLayerClientSideDetectionHostDelegate
GetSafeBrowsingDBManager() override;
scoped_refptr<safe_browsing::BaseUIManager> GetSafeBrowsingUIManager()
override;
- safe_browsing::ClientSideDetectionService* GetClientSideDetectionService()
- override;
+ base::WeakPtr<safe_browsing::ClientSideDetectionService>
+ GetClientSideDetectionService() override;
void AddReferrerChain(safe_browsing::ClientPhishingRequest* verdict,
GURL current_url,
const content::GlobalRenderFrameHostId&
current_outermost_main_frame_id) override;
+ raw_ptr<safe_browsing::VerdictCacheManager> GetCacheManager() override;
private:
raw_ptr<content::WebContents> web_contents_;
diff --git a/chromium/weblayer/browser/site_isolation_browsertest.cc b/chromium/weblayer/browser/site_isolation_browsertest.cc
index d88b2f5bc22..e7fd7e8b0b8 100644
--- a/chromium/weblayer/browser/site_isolation_browsertest.cc
+++ b/chromium/weblayer/browser/site_isolation_browsertest.cc
@@ -47,10 +47,10 @@ class SiteIsolationBrowserTest : public WebLayerBrowserTest {
std::vector<std::string> GetSavedIsolatedSites() {
PrefService* prefs =
user_prefs::UserPrefs::Get(GetProfile()->GetBrowserContext());
- auto* list =
- prefs->GetList(site_isolation::prefs::kUserTriggeredIsolatedOrigins);
+ const auto& list = prefs->GetValueList(
+ site_isolation::prefs::kUserTriggeredIsolatedOrigins);
std::vector<std::string> sites;
- for (const base::Value& value : list->GetListDeprecated())
+ for (const base::Value& value : list)
sites.push_back(value.GetString());
return sites;
}
diff --git a/chromium/weblayer/browser/ssl_error_controller_client.cc b/chromium/weblayer/browser/ssl_error_controller_client.cc
index 9e38dbcfc79..a3ac87401da 100644
--- a/chromium/weblayer/browser/ssl_error_controller_client.cc
+++ b/chromium/weblayer/browser/ssl_error_controller_client.cc
@@ -49,7 +49,8 @@ void SSLErrorControllerClient::GoBack() {
void SSLErrorControllerClient::Proceed() {
web_contents_->GetBrowserContext()->GetSSLHostStateDelegate()->AllowCert(
- request_url_.host(), *ssl_info_.cert.get(), cert_error_, web_contents_);
+ request_url_.host(), *ssl_info_.cert.get(), cert_error_,
+ web_contents_->GetPrimaryMainFrame()->GetStoragePartition());
Reload();
}
diff --git a/chromium/weblayer/browser/tab_impl.cc b/chromium/weblayer/browser/tab_impl.cc
index 30a1743caab..bfa7537d8d0 100644
--- a/chromium/weblayer/browser/tab_impl.cc
+++ b/chromium/weblayer/browser/tab_impl.cc
@@ -32,7 +32,6 @@
#include "components/js_injection/browser/js_communication_host.h"
#include "components/js_injection/browser/web_message_host.h"
#include "components/js_injection/browser/web_message_host_factory.h"
-#include "components/metrics/content/content_stability_metrics_provider.h"
#include "components/permissions/permission_manager.h"
#include "components/permissions/permission_request_manager.h"
#include "components/permissions/permission_result.h"
@@ -388,8 +387,6 @@ TabImpl::TabImpl(ProfileImpl* profile,
InitializePageLoadMetricsForWebContents(web_contents_.get());
ukm::InitializeSourceUrlRecorderForWebContents(web_contents_.get());
- metrics::ContentStabilityMetricsProvider::SetupWebContentsObserver(
- web_contents_.get());
#if BUILDFLAG(IS_ANDROID)
javascript_dialogs::TabModalDialogManager::CreateForWebContents(
diff --git a/chromium/weblayer/browser/translate_client_impl.cc b/chromium/weblayer/browser/translate_client_impl.cc
index 99c1b298b9e..625007dbf7c 100644
--- a/chromium/weblayer/browser/translate_client_impl.cc
+++ b/chromium/weblayer/browser/translate_client_impl.cc
@@ -86,8 +86,7 @@ bool TranslateClientImpl::ShowTranslateUI(
translate::TranslateInfoBarDelegate::Create(
step != translate::TRANSLATE_STEP_BEFORE_TRANSLATE,
translate_manager_->GetWeakPtr(),
- infobars::ContentInfoBarManager::FromWebContents(web_contents()),
- web_contents()->GetBrowserContext()->IsOffTheRecord(), step,
+ infobars::ContentInfoBarManager::FromWebContents(web_contents()), step,
source_language, target_language, error_type, triggered_from_menu);
return true;
#else
diff --git a/chromium/weblayer/browser/url_bar/page_info_browsertest.cc b/chromium/weblayer/browser/url_bar/page_info_browsertest.cc
index b5e8fd718b6..ab6368a24ce 100644
--- a/chromium/weblayer/browser/url_bar/page_info_browsertest.cc
+++ b/chromium/weblayer/browser/url_bar/page_info_browsertest.cc
@@ -8,6 +8,8 @@
#include "components/content_settings/core/common/content_settings.h"
#include "components/page_info/android/page_info_client.h"
#include "components/page_info/page_info_delegate.h"
+#include "third_party/blink/public/common/permissions/permission_utils.h"
+#include "url/origin.h"
#include "weblayer/browser/tab_impl.h"
#include "weblayer/browser/url_bar/page_info_delegate_impl.h"
#include "weblayer/public/navigation_controller.h"
@@ -70,7 +72,7 @@ IN_PROC_BROWSER_TEST_F(PageInfoBrowserTest, ContentSettings) {
EXPECT_TRUE(page_info_delegate->GetContentSettings());
}
-IN_PROC_BROWSER_TEST_F(PageInfoBrowserTest, PermissionStatus) {
+IN_PROC_BROWSER_TEST_F(PageInfoBrowserTest, PermissionResult) {
std::unique_ptr<PageInfoDelegate> page_info_delegate =
page_info::GetPageInfoClient()->CreatePageInfoDelegate(GetWebContents());
ASSERT_TRUE(page_info_delegate);
@@ -83,7 +85,8 @@ IN_PROC_BROWSER_TEST_F(PageInfoBrowserTest, PermissionStatus) {
// Check that |page_info_delegate| returns expected ContentSettingsType.
EXPECT_EQ(page_info_delegate
- ->GetPermissionStatus(ContentSettingsType::NOTIFICATIONS, url)
+ ->GetPermissionResult(blink::PermissionType::NOTIFICATIONS,
+ url::Origin::Create(url))
.content_setting,
CONTENT_SETTING_BLOCK);
}
diff --git a/chromium/weblayer/browser/url_bar/page_info_delegate_impl.cc b/chromium/weblayer/browser/url_bar/page_info_delegate_impl.cc
index 49d1050401e..687a31d1181 100644
--- a/chromium/weblayer/browser/url_bar/page_info_delegate_impl.cc
+++ b/chromium/weblayer/browser/url_bar/page_info_delegate_impl.cc
@@ -5,16 +5,17 @@
#include "weblayer/browser/url_bar/page_info_delegate_impl.h"
#include "build/build_config.h"
-#include "components/permissions/permission_manager.h"
#include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h"
#include "components/security_state/content/content_utils.h"
#include "components/subresource_filter/content/browser/subresource_filter_content_settings_manager.h"
#include "components/subresource_filter/content/browser/subresource_filter_profile_context.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/permission_controller.h"
+#include "content/public/browser/permission_result.h"
+#include "url/origin.h"
#include "weblayer/browser/host_content_settings_map_factory.h"
#include "weblayer/browser/page_specific_content_settings_delegate.h"
#include "weblayer/browser/permissions/permission_decision_auto_blocker_factory.h"
-#include "weblayer/browser/permissions/permission_manager_factory.h"
#include "weblayer/browser/stateful_ssl_host_state_delegate_factory.h"
#include "weblayer/browser/subresource_filter_profile_context_factory.h"
@@ -55,11 +56,14 @@ std::u16string PageInfoDelegateImpl::GetWarningDetailText() {
}
#endif
-permissions::PermissionResult PageInfoDelegateImpl::GetPermissionStatus(
- ContentSettingsType type,
- const GURL& site_url) {
- return PermissionManagerFactory::GetForBrowserContext(GetBrowserContext())
- ->GetPermissionStatusForDisplayOnSettingsUI(type, site_url);
+permissions::PermissionResult PageInfoDelegateImpl::GetPermissionResult(
+ blink::PermissionType permission,
+ const url::Origin& origin) {
+ content::PermissionResult permission_result =
+ GetBrowserContext()
+ ->GetPermissionController()
+ ->GetPermissionResultForOriginWithoutContext(permission, origin);
+ return permissions::PermissionUtil::ToPermissionResult(permission_result);
}
#if !BUILDFLAG(IS_ANDROID)
@@ -74,6 +78,11 @@ void PageInfoDelegateImpl::ShowSiteSettings(const GURL& site_url) {
NOTREACHED();
}
+void PageInfoDelegateImpl::ShowCookiesSettings() {
+ // Used for desktop only. Doesn't need implementation for WebLayer.
+ NOTREACHED();
+}
+
void PageInfoDelegateImpl::OpenCookiesDialog() {
// Used for desktop only. Doesn't need implementation for WebLayer.
NOTREACHED();
diff --git a/chromium/weblayer/browser/url_bar/page_info_delegate_impl.h b/chromium/weblayer/browser/url_bar/page_info_delegate_impl.h
index 384cf99c85f..1d666633a8a 100644
--- a/chromium/weblayer/browser/url_bar/page_info_delegate_impl.h
+++ b/chromium/weblayer/browser/url_bar/page_info_delegate_impl.h
@@ -32,13 +32,14 @@ class PageInfoDelegateImpl : public PageInfoDelegate {
void OnUserActionOnPasswordUi(safe_browsing::WarningAction action) override;
std::u16string GetWarningDetailText() override;
#endif
- permissions::PermissionResult GetPermissionStatus(
- ContentSettingsType type,
- const GURL& site_url) override;
+ permissions::PermissionResult GetPermissionResult(
+ blink::PermissionType permission,
+ const url::Origin& origin) override;
#if !BUILDFLAG(IS_ANDROID)
bool CreateInfoBarDelegate() override;
void ShowSiteSettings(const GURL& site_url) override;
+ void ShowCookiesSettings() override;
void OpenCookiesDialog() override;
void OpenCertificateDialog(net::X509Certificate* certificate) override;
void OpenConnectionHelpCenterPage(const ui::Event& event) override;
diff --git a/chromium/weblayer/browser/webapps/webapk_install_scheduler.cc b/chromium/weblayer/browser/webapps/webapk_install_scheduler.cc
index fe275568059..72e6a9ae40d 100644
--- a/chromium/weblayer/browser/webapps/webapk_install_scheduler.cc
+++ b/chromium/weblayer/browser/webapps/webapk_install_scheduler.cc
@@ -91,10 +91,10 @@ void WebApkInstallScheduler::OnGotIconMurmur2HashesBuildProto(
}
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 */,
+ *shortcut_info_.get(), shortcut_info_->manifest_id,
+ 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()));
@@ -123,4 +123,4 @@ bool WebApkInstallScheduler::IsInstallServiceAvailable() {
return WebApkInstallSchedulerBridge::IsInstallServiceAvailable();
}
-} // namespace weblayer \ No newline at end of file
+} // namespace weblayer
diff --git a/chromium/weblayer/browser/webapps/webapk_install_scheduler_browsertest.cc b/chromium/weblayer/browser/webapps/webapk_install_scheduler_browsertest.cc
index 6f563ebbb8e..fc4d1c84d62 100644
--- a/chromium/weblayer/browser/webapps/webapk_install_scheduler_browsertest.cc
+++ b/chromium/weblayer/browser/webapps/webapk_install_scheduler_browsertest.cc
@@ -5,6 +5,7 @@
#include "weblayer/browser/webapps/webapk_install_scheduler.h"
#include "base/files/file_path.h"
+#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "components/webapps/browser/android/shortcut_info.h"
#include "components/webapps/browser/android/webapk/webapk_types.h"
@@ -173,7 +174,7 @@ class WebApkInstallSchedulerTest : public WebLayerBrowserTest {
}
private:
- content::WebContents* web_contents_;
+ raw_ptr<content::WebContents> web_contents_;
net::EmbeddedTestServer test_server_;
diff --git a/chromium/weblayer/browser/webui/net_export_ui.cc b/chromium/weblayer/browser/webui/net_export_ui.cc
index 1ad56cabbfe..f2de43b5d9b 100644
--- a/chromium/weblayer/browser/webui/net_export_ui.cc
+++ b/chromium/weblayer/browser/webui/net_export_ui.cc
@@ -45,26 +45,26 @@ class NetExportMessageHandler
// content::WebUIMessageHandler implementation.
void RegisterMessages() override {
- web_ui()->RegisterDeprecatedMessageCallback(
+ web_ui()->RegisterMessageCallback(
net_log::kEnableNotifyUIWithStateHandler,
base::BindRepeating(&NetExportMessageHandler::OnEnableNotifyUIWithState,
base::Unretained(this)));
- web_ui()->RegisterDeprecatedMessageCallback(
+ web_ui()->RegisterMessageCallback(
net_log::kStartNetLogHandler,
base::BindRepeating(&NetExportMessageHandler::OnStartNetLog,
base::Unretained(this)));
- web_ui()->RegisterDeprecatedMessageCallback(
+ web_ui()->RegisterMessageCallback(
net_log::kStopNetLogHandler,
base::BindRepeating(&NetExportMessageHandler::OnStopNetLog,
base::Unretained(this)));
- web_ui()->RegisterDeprecatedMessageCallback(
+ web_ui()->RegisterMessageCallback(
net_log::kSendNetLogHandler,
base::BindRepeating(&NetExportMessageHandler::OnSendNetLog,
base::Unretained(this)));
}
// Messages
- void OnEnableNotifyUIWithState(const base::ListValue* list) {
+ void OnEnableNotifyUIWithState(const base::Value::List& list) {
AllowJavascript();
if (!state_observation_manager_.IsObserving()) {
state_observation_manager_.Observe(file_writer_.get());
@@ -72,9 +72,7 @@ class NetExportMessageHandler
NotifyUIWithState(file_writer_->GetState());
}
- void OnStartNetLog(const base::ListValue* list) {
- base::Value::ConstListView params = list->GetListDeprecated();
-
+ void OnStartNetLog(const base::Value::List& params) {
// Determine the capture mode.
if (!params.empty() && params[0].is_string()) {
capture_mode_ = net_log::NetExportFileWriter::CaptureModeFromString(
@@ -88,16 +86,18 @@ class NetExportMessageHandler
StartNetLog(base::FilePath());
}
- void OnStopNetLog(const base::ListValue* list) { file_writer_->StopNetLog(); }
+ void OnStopNetLog(const base::Value::List& list) {
+ file_writer_->StopNetLog();
+ }
- void OnSendNetLog(const base::ListValue* list) {
+ void OnSendNetLog(const base::Value::List& list) {
file_writer_->GetFilePathToCompletedLog(
base::BindOnce(&NetExportMessageHandler::SendEmail));
}
// net_log::NetExportFileWriter::StateObserver implementation.
- void OnNewState(const base::DictionaryValue& state) override {
- NotifyUIWithState(state.CreateDeepCopy());
+ void OnNewState(const base::Value::Dict& state) override {
+ NotifyUIWithState(state);
}
private:
@@ -133,8 +133,8 @@ class NetExportMessageHandler
// Fires net-log-info-changed event to update the JavaScript UI in the
// renderer.
- void NotifyUIWithState(std::unique_ptr<base::DictionaryValue> state) {
- FireWebUIListener(net_log::kNetLogInfoChangedEvent, *state);
+ void NotifyUIWithState(const base::Value::Dict& state) {
+ FireWebUIListener(net_log::kNetLogInfoChangedEvent, state);
}
// Cached pointer to SystemNetworkContextManager's NetExportFileWriter.
diff --git a/chromium/weblayer/grit_strings_allowlist.txt b/chromium/weblayer/grit_strings_allowlist.txt
index 3b4dfe4f3a5..f1a512e9e02 100644
--- a/chromium/weblayer/grit_strings_allowlist.txt
+++ b/chromium/weblayer/grit_strings_allowlist.txt
@@ -269,8 +269,8 @@ IDS_SITE_SETTINGS_TYPE_USB_DEVICES
IDS_SITE_SETTINGS_TYPE_USB_DEVICES_MID_SENTENCE
IDS_SITE_SETTINGS_TYPE_VR
IDS_SITE_SETTINGS_TYPE_VR_MID_SENTENCE
-IDS_SITE_SETTINGS_TYPE_WINDOW_PLACEMENT
-IDS_SITE_SETTINGS_TYPE_WINDOW_PLACEMENT_MID_SENTENCE
+IDS_SITE_SETTINGS_TYPE_WINDOW_MANAGEMENT
+IDS_SITE_SETTINGS_TYPE_WINDOW_MANAGEMENT_MID_SENTENCE
IDS_SMS_INFOBAR_BUTTON_OK
IDS_SMS_INFOBAR_STATUS_SMS_RECEIVED
IDS_SMS_INFOBAR_TITLE
diff --git a/chromium/weblayer/public/java/BUILD.gn b/chromium/weblayer/public/java/BUILD.gn
index b5805258831..db36f15aa6c 100644
--- a/chromium/weblayer/public/java/BUILD.gn
+++ b/chromium/weblayer/public/java/BUILD.gn
@@ -173,3 +173,77 @@ process_version("client_version") {
output = _version_constants_java_file
sources = [ "//chrome/VERSION" ]
}
+
+android_aidl("browserfragment_aidl") {
+ import_include = [ "." ]
+ sources = [
+ "org/chromium/browserfragment/interfaces/IBooleanCallback.aidl",
+ "org/chromium/browserfragment/interfaces/IBrowserFragmentDelegate.aidl",
+ "org/chromium/browserfragment/interfaces/IBrowserFragmentDelegateClient.aidl",
+ "org/chromium/browserfragment/interfaces/IBrowserSandboxCallback.aidl",
+ "org/chromium/browserfragment/interfaces/IBrowserSandboxService.aidl",
+ "org/chromium/browserfragment/interfaces/IFragmentParams.aidl",
+ "org/chromium/browserfragment/interfaces/IStringCallback.aidl",
+ "org/chromium/browserfragment/interfaces/ITabCallback.aidl",
+ "org/chromium/browserfragment/interfaces/ITabNavigationControllerProxy.aidl",
+ "org/chromium/browserfragment/interfaces/ITabObserverDelegate.aidl",
+ "org/chromium/browserfragment/interfaces/ITabParams.aidl",
+ "org/chromium/browserfragment/interfaces/ITabProxy.aidl",
+ "org/chromium/browserfragment/interfaces/IWebMessageCallback.aidl",
+ "org/chromium/browserfragment/interfaces/IWebMessageReplyProxy.aidl",
+ ]
+}
+
+android_library("browserfragment_interfaces_java") {
+ deps = [ "//base:base_java" ]
+ srcjar_deps = [ ":browserfragment_aidl" ]
+}
+
+android_library("browserfragment_java") {
+ sources = [
+ "org/chromium/browserfragment/Browser.java",
+ "org/chromium/browserfragment/BrowserFragment.java",
+ "org/chromium/browserfragment/FragmentParams.java",
+ "org/chromium/browserfragment/Tab.java",
+ "org/chromium/browserfragment/TabManager.java",
+ "org/chromium/browserfragment/TabNavigationController.java",
+ "org/chromium/browserfragment/TabObserver.java",
+ "org/chromium/browserfragment/TabObserverDelegate.java",
+ "org/chromium/browserfragment/WebMessageCallback.java",
+ "org/chromium/browserfragment/WebMessageReplyProxy.java",
+ ]
+
+ resources_package = "org.chromium.browserfragment"
+ deps = [
+ ":browserfragment_interfaces_java",
+ "//base:base_java",
+ "//third_party/android_deps:com_google_guava_guava_android_java",
+ "//third_party/android_deps:com_google_guava_listenablefuture_java",
+ "//third_party/androidx:androidx_annotation_annotation_java",
+ "//third_party/androidx:androidx_appcompat_appcompat_java",
+ "//third_party/androidx:androidx_concurrent_concurrent_futures_java",
+ "//third_party/androidx:androidx_fragment_fragment_java",
+ "//third_party/androidx:androidx_lifecycle_lifecycle_viewmodel_java",
+ ]
+
+ proguard_configs = [ "proguard.flags" ]
+}
+
+android_library("browserfragment_sandbox_java") {
+ sources = [
+ # Additional weblayer public files that are for the sandbox.
+ "org/chromium/weblayer/BrowserFragmentDelegate.java",
+ "org/chromium/weblayer/BrowserFragmentTabDelegate.java",
+ "org/chromium/weblayer/BrowserSandboxService.java",
+ "org/chromium/weblayer/TabNavigationControllerProxy.java",
+ "org/chromium/weblayer/TabParams.java",
+ "org/chromium/weblayer/TabProxy.java",
+ "org/chromium/weblayer/WebMessageReplyProxyProxy.java",
+ ]
+ resources_package = "org.chromium.weblayer"
+ deps = [
+ ":browserfragment_interfaces_java",
+ ":java",
+ "//third_party/androidx:androidx_annotation_annotation_java",
+ ]
+}
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/Browser.java b/chromium/weblayer/public/java/org/chromium/browserfragment/Browser.java
new file mode 100644
index 00000000000..6b570c4b63d
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/Browser.java
@@ -0,0 +1,138 @@
+// 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.browserfragment;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.concurrent.futures.CallbackToFutureAdapter;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.chromium.browserfragment.interfaces.IBrowserSandboxCallback;
+import org.chromium.browserfragment.interfaces.IBrowserSandboxService;
+
+/**
+ * Handle to the Browsing Sandbox. Must be created asynchronously.
+ */
+public class Browser {
+ // Use another APK as a placeholder for an actual sandbox, since they are conceptually the
+ // same thing.
+ private static final String BROWSER_SANDBOX_PACKAGE = "org.chromium.browserfragment.sandbox";
+
+ private static final String BROWSER_SANDBOX_ACTION =
+ "org.chromium.weblayer.intent.action.BROWSERSANDBOX";
+
+ private static final String DEFAULT_PROFILE_NAME = "DefaultProfile";
+
+ private static Browser sInstance;
+
+ private IBrowserSandboxService mBrowserSandboxService;
+
+ private static class ConnectionSetup implements ServiceConnection {
+ private CallbackToFutureAdapter.Completer<Browser> mCompleter;
+ private IBrowserSandboxService mBrowserSandboxService;
+ private Context mContext;
+
+ private final IBrowserSandboxCallback mBrowserSandboxCallback =
+ new IBrowserSandboxCallback.Stub() {
+ @Override
+ public void onBrowserProcessInitialized() {
+ sInstance = new Browser(mBrowserSandboxService);
+ mCompleter.set(sInstance);
+ mCompleter = null;
+ }
+ };
+
+ ConnectionSetup(Context context, CallbackToFutureAdapter.Completer<Browser> completer) {
+ mContext = context;
+ mCompleter = completer;
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ mBrowserSandboxService = IBrowserSandboxService.Stub.asInterface(service);
+ try {
+ mBrowserSandboxService.initializeBrowserProcess(mBrowserSandboxCallback);
+ } catch (RemoteException e) {
+ mCompleter.setException(e);
+ mCompleter = null;
+ }
+ }
+
+ // TODO(rayankans): Actually handle failure / disconnection events.
+ @Override
+ public void onServiceDisconnected(ComponentName name) {}
+ }
+
+ private Browser(IBrowserSandboxService service) {
+ mBrowserSandboxService = service;
+ }
+
+ /**
+ * Asynchronously creates a handle to the browsing sandbox after initializing the
+ * browser process.
+ * @param context The application context.
+ */
+ @NonNull
+ public static ListenableFuture<Browser> create(@NonNull Context context) {
+ if (sInstance != null) {
+ return Futures.immediateFuture(sInstance);
+ }
+ return CallbackToFutureAdapter.getFuture(completer -> {
+ ConnectionSetup connectionSetup = new ConnectionSetup(context, completer);
+
+ Intent intent = new Intent(BROWSER_SANDBOX_ACTION);
+ intent.setPackage(BROWSER_SANDBOX_PACKAGE);
+
+ context.bindService(intent, connectionSetup, Context.BIND_AUTO_CREATE);
+
+ // Debug string.
+ return "Browser Sandbox Future";
+ });
+ }
+
+ /**
+ * Creates a new BrowserFragment for displaying web content.
+ */
+ @Nullable
+ public BrowserFragment createFragment() {
+ FragmentParams params =
+ (new FragmentParams.Builder()).setProfileName(DEFAULT_PROFILE_NAME).build();
+ return createFragment(params);
+ }
+
+ /**
+ * Creates a new BrowserFragment for displaying web content.
+ */
+ @Nullable
+ public BrowserFragment createFragment(FragmentParams params) {
+ try {
+ BrowserFragment fragment = new BrowserFragment();
+ fragment.initialize(
+ this, mBrowserSandboxService.createFragmentDelegate(params.getParcelable()));
+ return fragment;
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Enables or disables DevTools remote debugging.
+ */
+ public void setRemoteDebuggingEnabled(boolean enabled) {
+ try {
+ mBrowserSandboxService.setRemoteDebuggingEnabled(enabled);
+ } catch (RemoteException e) {
+ }
+ }
+}
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/BrowserFragment.java b/chromium/weblayer/public/java/org/chromium/browserfragment/BrowserFragment.java
new file mode 100644
index 00000000000..a8f7b8c8265
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/BrowserFragment.java
@@ -0,0 +1,300 @@
+// 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.browserfragment;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.view.LayoutInflater;
+import android.view.SurfaceControlViewHost.SurfacePackage;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatDelegate;
+import androidx.concurrent.futures.CallbackToFutureAdapter;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.ViewModel;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.chromium.browserfragment.interfaces.IBrowserFragmentDelegate;
+import org.chromium.browserfragment.interfaces.IBrowserFragmentDelegateClient;
+
+/**
+ * Fragment for rendering web content.
+ * This is created through `Browser`, since the browsing sandbox must be initialized to render web
+ * content.
+ */
+public class BrowserFragment extends Fragment {
+ private SurfaceView mSurfaceView;
+ private Browser mBrowser;
+ private IBrowserFragmentDelegate mDelegate;
+ private final TabObserverDelegate mTabObserverDelegate = new TabObserverDelegate();
+ private ListenableFuture<TabManager> mFutureTabManager;
+ private CallbackToFutureAdapter.Completer<TabManager> mTabManagerCompleter;
+ private Bundle mInstanceState = new Bundle();
+
+ private final IBrowserFragmentDelegateClient mClient =
+ new IBrowserFragmentDelegateClient.Stub() {
+ @Override
+ public void onSurfacePackageReady(SurfacePackage surfacePackage) {
+ SurfaceView surfaceView = (SurfaceView) BrowserFragment.super.getView();
+ surfaceView.setChildSurfacePackage(surfacePackage);
+ }
+
+ @Override
+ public void onStarted(Bundle instanceState) {
+ mInstanceState = instanceState;
+ mTabManagerCompleter.set(new TabManager(mDelegate));
+ }
+ };
+
+ private SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ IBinder hostToken = ((SurfaceView) getView()).getHostToken();
+ assert hostToken != null;
+ try {
+ mDelegate.attachViewHierarchy(hostToken);
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ resizeSurfaceView(width, height);
+ }
+
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {}
+ };
+
+ /**
+ * This constructor is for the system FragmentManager only. Please use
+ * {@link Browser#createFragment}.
+ */
+ public BrowserFragment() {
+ mFutureTabManager = CallbackToFutureAdapter.getFuture(completer -> {
+ mTabManagerCompleter = completer;
+ // Debug string.
+ return "TabManager Future";
+ });
+ }
+
+ void initialize(Browser browser, IBrowserFragmentDelegate delegate) throws RemoteException {
+ mBrowser = browser;
+ mDelegate = delegate;
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+
+ BrowserViewModel model = getViewModel();
+ if (model.hasSavedState()) {
+ // Load from view model.
+ assert mBrowser == null;
+
+ mBrowser = model.mBrowser;
+ mDelegate = model.mDelegate;
+ } else {
+ // Save to View model.
+ assert mBrowser != null;
+
+ model.mBrowser = mBrowser;
+ model.mDelegate = mDelegate;
+ }
+
+ AppCompatDelegate.create(getActivity(), null);
+
+ try {
+ mDelegate.setClient(mClient);
+ mDelegate.setTabObserverDelegate(mTabObserverDelegate);
+ mDelegate.onAttach();
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ try {
+ mDelegate.onCreate(savedInstanceState);
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ return new BrowserSurfaceView(getActivity(), mSurfaceHolderCallback);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ // We intentionally do not forward the onDestroy call here to avoid destroying/recreating
+ // the WebLayer implementations every time.
+ // onDestroy is called once the ViewModel is cleared because that guarantees that the
+ // Fragment will no longer be used.
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ try {
+ mDelegate.onDetach();
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ try {
+ mDelegate.onStart();
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ try {
+ mDelegate.onStop();
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ try {
+ mDelegate.onResume();
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ try {
+ mDelegate.onPause();
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putAll(mInstanceState);
+ }
+
+ public Browser getBrowser() {
+ return mBrowser;
+ }
+
+ private void resizeSurfaceView(int width, int height) {
+ try {
+ mDelegate.resizeView(width, height);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Returns a ListenableFuture to the TabManager, which becomes available after the
+ * BrowserFragments onStart method finished.
+ */
+ @NonNull
+ public ListenableFuture<TabManager> getTabManager() {
+ return mFutureTabManager;
+ }
+
+ /**
+ * Register a tab observer and returns if successful.
+ *
+ * @param tabObserver The TabObserver.
+ *
+ * @return true if observer was added to the list of observers.
+ */
+ public boolean registerTabObserver(@NonNull TabObserver tabObserver) {
+ return mTabObserverDelegate.registerObserver(tabObserver);
+ }
+
+ /**
+ * Unregister a tab observer and returns if successful.
+ *
+ * @param tabObserver The TabObserver to remove.
+ *
+ * @return true if observer was removed from the list of observers.
+ */
+ public boolean unregisterTabObserver(@NonNull TabObserver tabObserver) {
+ return mTabObserverDelegate.unregisterObserver(tabObserver);
+ }
+
+ private BrowserViewModel getViewModel() {
+ return new ViewModelProvider(this).get(BrowserViewModel.class);
+ }
+
+ /**
+ * A custom SurfaceView that registers a SurfaceHolder.Callback.
+ */
+ private class BrowserSurfaceView extends SurfaceView {
+ private SurfaceHolder.Callback mSurfaceHolderCallback;
+
+ BrowserSurfaceView(Context context, SurfaceHolder.Callback surfaceHolderCallback) {
+ super(context);
+ mSurfaceHolderCallback = surfaceHolderCallback;
+ setZOrderOnTop(true);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ getHolder().addCallback(mSurfaceHolderCallback);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ getHolder().removeCallback(mSurfaceHolderCallback);
+ }
+ }
+
+ /**
+ * This class is an implementation detail and not intended for public use. It may change at any
+ * time in incompatible ways, including being removed.
+ * <p>
+ * This class stores BrowserFragment specific state to a ViewModel so that it can reused if a
+ * new Fragment is created that should share the same state.
+ */
+ public static final class BrowserViewModel extends ViewModel {
+ @Nullable
+ private Browser mBrowser;
+ @Nullable
+ private IBrowserFragmentDelegate mDelegate;
+
+ boolean hasSavedState() {
+ return mBrowser != null;
+ }
+
+ @Override
+ public void onCleared() {
+ if (mDelegate != null) {
+ try {
+ mDelegate.onDestroy();
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ }
+}
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/FragmentParams.java b/chromium/weblayer/public/java/org/chromium/browserfragment/FragmentParams.java
new file mode 100644
index 00000000000..9907fd87099
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/FragmentParams.java
@@ -0,0 +1,79 @@
+// 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.browserfragment;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.chromium.browserfragment.interfaces.IFragmentParams;
+
+/**
+ * Parameters for {@link Browser#createBrowserFragment}.
+ */
+public class FragmentParams {
+ @Nullable
+ private String mProfileName;
+
+ @Nullable
+ private String mPersistenceId;
+
+ private boolean mIsIncognito;
+
+ IFragmentParams getParcelable() {
+ IFragmentParams params = new IFragmentParams();
+ params.profileName = mProfileName;
+ params.persistenceId = mPersistenceId;
+ params.isIncognito = mIsIncognito;
+ return params;
+ }
+
+ /**
+ * A Builder class to help create FragmentParams.
+ */
+ public static final class Builder {
+ private FragmentParams mParams = new FragmentParams();
+
+ public FragmentParams build() {
+ return mParams;
+ }
+
+ /**
+ * Sets the name of the profile. Null or empty string implicitly creates an incognito
+ * profile. If {@code profile} must only contain alphanumeric and underscore characters
+ * since it will be used as a directory name in the file system.
+ *
+ * @param name The name of the profile.
+ */
+ @NonNull
+ public Builder setProfileName(@Nullable String profileName) {
+ mParams.mProfileName = profileName;
+ return this;
+ }
+
+ /**
+ * Sets the persistence id, which uniquely identifies the Browser for saving the set of tabs
+ * and navigations. A value of null does not save/restore any state. A non-null value
+ * results in asynchronously restoring the tabs and navigations. Supplying a non-null value
+ * means the Browser initially has no tabs (until restore is complete).
+ *
+ * @param persistenceId The id for persistence.
+ */
+ @NonNull
+ public Builder setPersistenceId(@Nullable String persistenceId) {
+ mParams.mPersistenceId = persistenceId;
+ return this;
+ }
+
+ /**
+ * Sets whether the profile is incognito.
+ * @param incognito Whether the profile should be incognito.
+ */
+ @NonNull
+ public Builder setIsIncognito(boolean isIncognito) {
+ mParams.mIsIncognito = isIncognito;
+ return this;
+ }
+ }
+}
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/Tab.java b/chromium/weblayer/public/java/org/chromium/browserfragment/Tab.java
new file mode 100644
index 00000000000..c37ed22fadb
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/Tab.java
@@ -0,0 +1,153 @@
+// 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.browserfragment;
+
+import android.os.RemoteException;
+
+import androidx.annotation.NonNull;
+import androidx.concurrent.futures.CallbackToFutureAdapter;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.chromium.browserfragment.interfaces.IStringCallback;
+import org.chromium.browserfragment.interfaces.ITabParams;
+import org.chromium.browserfragment.interfaces.ITabProxy;
+import org.chromium.browserfragment.interfaces.IWebMessageCallback;
+import org.chromium.browserfragment.interfaces.IWebMessageReplyProxy;
+
+import java.util.List;
+
+/**
+ * Tab controls the tab content and state.
+ */
+public class Tab {
+ private ITabProxy mTabProxy;
+ private TabNavigationController mTabNavigationController;
+
+ private String mGuid;
+
+ Tab(@NonNull ITabParams tabParams) {
+ assert tabParams.tabProxy != null;
+ assert tabParams.tabGuid != null;
+ assert tabParams.navigationControllerProxy != null;
+
+ mTabProxy = tabParams.tabProxy;
+ mGuid = tabParams.tabGuid;
+ mTabNavigationController = new TabNavigationController(tabParams.navigationControllerProxy);
+ }
+
+ public String getGuid() {
+ return mGuid;
+ }
+
+ /**
+ * Sets this Tab to active.
+ */
+ public void setActive() {
+ try {
+ mTabProxy.setActive();
+ } catch (RemoteException e) {
+ }
+ }
+
+ /*
+ * Closes this Tab.
+ */
+ public void close() {
+ try {
+ mTabProxy.close();
+ } catch (RemoteException e) {
+ }
+ }
+
+ public ListenableFuture<String> executeScript(
+ @NonNull String script, boolean useSeparateIsolate) {
+ return CallbackToFutureAdapter.getFuture(completer -> {
+ try {
+ mTabProxy.executeScript(script, useSeparateIsolate, new IStringCallback.Stub() {
+ @Override
+ public void onResult(String result) {
+ completer.set(result);
+ }
+ });
+ } catch (RemoteException e) {
+ completer.setException(e);
+ }
+
+ return "Tab.executeScript Future";
+ });
+ }
+
+ /**
+ * Returns the navigation controller for this Tab.
+ *
+ * @return The TabNavigationController.
+ */
+ @NonNull
+ public TabNavigationController getNavigationController() {
+ return mTabNavigationController;
+ }
+
+ /**
+ * Adds a WebMessageCallback and injects a JavaScript object into each frame that the
+ * WebMessageCallback will listen on.
+ *
+ * The injected JavaScript object will be named {@code jsObjectName} in the global scope. This
+ * will inject the JavaScript object in any frame whose origin matches {@code
+ * allowedOriginRules} for every navigation after this call, and the JavaScript object will be
+ * available immediately when the page begins to load.
+ */
+ public void registerWebMessageCallback(
+ WebMessageCallback callback, String jsObjectName, List<String> allowedOrigins) {
+ try {
+ mTabProxy.registerWebMessageCallback(new IWebMessageCallback.Stub() {
+ @Override
+ public void onWebMessageReceived(
+ IWebMessageReplyProxy iReplyProxy, String message) {
+ callback.onWebMessageReceived(new WebMessageReplyProxy(iReplyProxy), message);
+ }
+
+ @Override
+ public void onWebMessageReplyProxyClosed(IWebMessageReplyProxy iReplyProxy) {
+ callback.onWebMessageReplyProxyClosed(new WebMessageReplyProxy(iReplyProxy));
+ }
+
+ @Override
+ public void onWebMessageReplyProxyActiveStateChanged(
+ IWebMessageReplyProxy iReplyProxy) {
+ callback.onWebMessageReplyProxyActiveStateChanged(
+ new WebMessageReplyProxy(iReplyProxy));
+ }
+ }, jsObjectName, allowedOrigins);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Removes the JavaScript object previously registered by way of registerWebMessageCallback.
+ * This impacts future navigations (not any already loaded navigations).
+ *
+ * @param jsObjectName Name of the JavaScript object.
+ */
+ public void unregisterWebMessageCallback(String jsObjectName) {
+ try {
+ mTabProxy.unregisterWebMessageCallback(jsObjectName);
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return mGuid.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof Tab) {
+ return this == obj || mGuid.equals(((Tab) obj).getGuid());
+ }
+ return false;
+ }
+}
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/TabManager.java b/chromium/weblayer/public/java/org/chromium/browserfragment/TabManager.java
new file mode 100644
index 00000000000..5765e5c3723
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/TabManager.java
@@ -0,0 +1,120 @@
+// 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.browserfragment;
+
+import android.os.RemoteException;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.concurrent.futures.CallbackToFutureAdapter;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.chromium.browserfragment.interfaces.IBooleanCallback;
+import org.chromium.browserfragment.interfaces.IBrowserFragmentDelegate;
+import org.chromium.browserfragment.interfaces.ITabCallback;
+import org.chromium.browserfragment.interfaces.ITabParams;
+
+/**
+ * Class for interaction with Browser Tabs.
+ * Calls into BrowserFragmentDelegate which runs on the Binder thread, and requires
+ * finished initialization from onCreate on UIThread.
+ * Access only via ListenableFuture through BrowserFragment.
+ */
+public class TabManager {
+ private IBrowserFragmentDelegate mDelegate;
+
+ private final class RequestNavigationCallback extends IBooleanCallback.Stub {
+ private CallbackToFutureAdapter.Completer<Boolean> mCompleter;
+
+ RequestNavigationCallback(CallbackToFutureAdapter.Completer<Boolean> completer) {
+ mCompleter = completer;
+ }
+
+ @Override
+ public void onResult(boolean didNavigate) {
+ mCompleter.set(didNavigate);
+ }
+ }
+
+ private final class TabCallback extends ITabCallback.Stub {
+ private CallbackToFutureAdapter.Completer<Tab> mCompleter;
+
+ TabCallback(CallbackToFutureAdapter.Completer<Tab> completer) {
+ mCompleter = completer;
+ }
+
+ @Override
+ public void onResult(@Nullable ITabParams tabParams) {
+ if (tabParams != null) {
+ mCompleter.set(new Tab(tabParams));
+ return;
+ }
+ mCompleter.set(null);
+ }
+ };
+
+ TabManager(IBrowserFragmentDelegate delegate) {
+ mDelegate = delegate;
+ }
+
+ /**
+ * Returns a ListenableFuture for the currently active Tab; The tab can be null if no Tab is
+ * active.
+ *
+ * @return ListenableFuture for the active Tab.
+ */
+ @NonNull
+ public ListenableFuture<Tab> getActiveTab() {
+ return CallbackToFutureAdapter.getFuture(completer -> {
+ try {
+ mDelegate.getActiveTab(new TabCallback(completer));
+ } catch (RemoteException e) {
+ completer.setException(e);
+ }
+ // Debug string.
+ return "Active Tab Future";
+ });
+ }
+
+ /**
+ * Creates a new Tab and returns it in a ListenableFuture.
+ *
+ * @return ListenableFuture for the new Tab.
+ */
+ @NonNull
+ public ListenableFuture<Tab> createTab() {
+ return CallbackToFutureAdapter.getFuture(completer -> {
+ try {
+ mDelegate.createTab(new TabCallback(completer));
+ } catch (RemoteException e) {
+ completer.setException(e);
+ }
+ // Debug string.
+ return "Create Tab Future";
+ });
+ }
+
+ /**
+ * Tries to navigate back inside the Browser session and returns a Future with a Boolean
+ * which is true if the back navigation was successful.
+ *
+ * Only recommended to use if no switching of Tabs is used.
+ *
+ * Navigates back inside the currently active tab if possible. If that is not possible,
+ * checks if any Tab was added to the BrowserFragment before the currently active Tab,
+ * if so, the currently active Tab is closed and this Tab is set to active.
+ *
+ * @return ListenableFuture with a Boolean stating if back navigation was successful.
+ */
+ @NonNull
+ public ListenableFuture<Boolean> tryNavigateBack() {
+ return CallbackToFutureAdapter.getFuture(completer -> {
+ mDelegate.tryNavigateBack(new RequestNavigationCallback(completer));
+ // Debug string.
+ return "Did navigate back Future";
+ });
+ }
+}
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/TabNavigationController.java b/chromium/weblayer/public/java/org/chromium/browserfragment/TabNavigationController.java
new file mode 100644
index 00000000000..3e48e55690e
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/TabNavigationController.java
@@ -0,0 +1,103 @@
+// 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.browserfragment;
+
+import android.os.RemoteException;
+
+import androidx.annotation.NonNull;
+import androidx.concurrent.futures.CallbackToFutureAdapter;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.chromium.browserfragment.interfaces.IBooleanCallback;
+import org.chromium.browserfragment.interfaces.ITabNavigationControllerProxy;
+
+/**
+ * TabNavigationController controls the navigation in a Tab.
+ */
+public class TabNavigationController {
+ private final ITabNavigationControllerProxy mTabNavigationControllerProxy;
+
+ private final class RequestNavigationCallback extends IBooleanCallback.Stub {
+ private CallbackToFutureAdapter.Completer<Boolean> mCompleter;
+
+ RequestNavigationCallback(CallbackToFutureAdapter.Completer<Boolean> completer) {
+ mCompleter = completer;
+ }
+
+ @Override
+ public void onResult(boolean possible) {
+ mCompleter.set(possible);
+ }
+ };
+
+ TabNavigationController(ITabNavigationControllerProxy tabNavigationControllerProxy) {
+ mTabNavigationControllerProxy = tabNavigationControllerProxy;
+ }
+
+ /**
+ * Navigates this Tab to the given URI.
+ *
+ * @param uri The destination URI.
+ */
+ public void navigate(@NonNull String uri) {
+ try {
+ mTabNavigationControllerProxy.navigate(uri);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Navigates to the previous navigation.
+ */
+ public void goBack() {
+ try {
+ mTabNavigationControllerProxy.goBack();
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Navigates to the next navigation.
+ */
+ public void goForward() {
+ try {
+ mTabNavigationControllerProxy.goForward();
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Returns true if there is a navigation before the current one.
+ *
+ * @return ListenableFuture with a Boolean stating if there is a navigation before the current
+ * one.
+ */
+ @NonNull
+ public ListenableFuture<Boolean> canGoBack() {
+ return CallbackToFutureAdapter.getFuture(completer -> {
+ mTabNavigationControllerProxy.canGoBack(new RequestNavigationCallback(completer));
+
+ // Debug string.
+ return "Can navigate back Future";
+ });
+ }
+
+ /**
+ * Returns true if there is a navigation after the current one.
+ *
+ * @return ListenableFuture with a Boolean stating if there is a navigation after the current
+ * one.
+ */
+ @NonNull
+ public ListenableFuture<Boolean> canGoForward() {
+ return CallbackToFutureAdapter.getFuture(completer -> {
+ mTabNavigationControllerProxy.canGoForward(new RequestNavigationCallback(completer));
+
+ // Debug string.
+ return "Can navigate forward Future";
+ });
+ }
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/TabObserver.java b/chromium/weblayer/public/java/org/chromium/browserfragment/TabObserver.java
new file mode 100644
index 00000000000..11584a7a5ab
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/TabObserver.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.browserfragment;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * An interface for observing changes to the set of tabs in a BrowserFragment.
+ */
+public abstract class TabObserver {
+ /**
+ * The active tab has changed.
+ *
+ * @param activeTab The newly active tab, null if no tab is active.
+ */
+ public void onActiveTabChanged(@Nullable Tab activeTab) {}
+
+ /**
+ * A tab was added to the BrowserFragment.
+ *
+ * @param tab The tab that was added.
+ */
+ public void onTabAdded(@NonNull Tab tab) {}
+
+ /**
+ * A tab was removed from the BrowserFragment.
+ *
+ * WARNING: this is *not* called when the BrowserFragment is destroyed. See {@link
+ * #onWillDestroyBrowserAndAllTabs} for more.
+ *
+ * @param tab The tab that was removed.
+ */
+ public void onTabRemoved(@NonNull Tab tab) {}
+
+ /**
+ * Called when the BrowserFragment is about to be destroyed. After this
+ * call the BrowserFragment with all Tabs are destroyed and can not be used.
+ */
+ public void onWillDestroyBrowserAndAllTabs() {}
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/TabObserverDelegate.java b/chromium/weblayer/public/java/org/chromium/browserfragment/TabObserverDelegate.java
new file mode 100644
index 00000000000..7614f960401
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/TabObserverDelegate.java
@@ -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.
+
+package org.chromium.browserfragment;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.chromium.base.ObserverList;
+import org.chromium.browserfragment.interfaces.ITabObserverDelegate;
+import org.chromium.browserfragment.interfaces.ITabParams;
+
+/**
+ * TabObserverDelegate notifies TabObservers of Tab-events in weblayer.
+ */
+class TabObserverDelegate extends ITabObserverDelegate.Stub {
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+ private ObserverList<TabObserver> mTabObservers = new ObserverList<TabObserver>();
+
+ /**
+ * Register a TabObserver.
+ *
+ * @return true if the observer was added to the list of observers.
+ */
+ boolean registerObserver(TabObserver tabObserver) {
+ return mTabObservers.addObserver(tabObserver);
+ }
+
+ /**
+ * Unregister a TabObserver.
+ *
+ * @return true if the observer was removed from the list of observers.
+ */
+ boolean unregisterObserver(TabObserver tabObserver) {
+ return mTabObservers.removeObserver(tabObserver);
+ }
+
+ @Override
+ public void notifyActiveTabChanged(@Nullable ITabParams tabParams) {
+ mHandler.post(() -> {
+ Tab tab = null;
+ if (tabParams != null) {
+ tab = new Tab(tabParams);
+ }
+ for (TabObserver observer : mTabObservers) {
+ observer.onActiveTabChanged(tab);
+ }
+ });
+ }
+
+ @Override
+ public void notifyTabAdded(@NonNull ITabParams tabParams) {
+ mHandler.post(() -> {
+ Tab tab = new Tab(tabParams);
+ for (TabObserver observer : mTabObservers) {
+ observer.onTabAdded(tab);
+ }
+ });
+ }
+
+ @Override
+ public void notifyTabRemoved(@NonNull ITabParams tabParams) {
+ mHandler.post(() -> {
+ Tab tab = new Tab(tabParams);
+ for (TabObserver observer : mTabObservers) {
+ observer.onTabRemoved(tab);
+ }
+ });
+ }
+
+ @Override
+ public void notifyWillDestroyBrowserAndAllTabs() {
+ mHandler.post(() -> {
+ for (TabObserver observer : mTabObservers) {
+ observer.onWillDestroyBrowserAndAllTabs();
+ }
+ });
+ }
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/WebMessageCallback.java b/chromium/weblayer/public/java/org/chromium/browserfragment/WebMessageCallback.java
new file mode 100644
index 00000000000..8b3d382173f
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/WebMessageCallback.java
@@ -0,0 +1,45 @@
+// 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.browserfragment;
+
+/**
+ * An interface to receive message events from a JavaScript object of a Tab.
+ *
+ * This callback, the name of the JavaScript object, as well as the origins that are
+ * targeted are set via {@link Tab#registerWebMessageCallback}.
+ */
+public abstract class WebMessageCallback {
+ /**
+ * A WebMessage was received.
+ *
+ * <b>WARNING</b>: It is possible to receive messages from an inactive page. This happens if a
+ * message it sent around the same time the page is put in the back forward cache. As a result
+ * of this, it is possible for this method to be called with a new proxy that is inactive.
+ *
+ * @param replyProxy An object that may be used to post a message back to the page.
+ * @param message The message from the page.
+ */
+ public void onWebMessageReceived(WebMessageReplyProxy replyProxy, String message) {}
+
+ /**
+ * {@link WebMessageReplyProxy} was closed.
+ *
+ * This typically happens when navigating to another page. If the page goes into the back
+ * forward cache, then message channels are left open (and this is not called). In that case
+ * this method will be called either when the page is evicted from the cache or when the user
+ * goes back to it and then navigates away and it doesn't go into the back forward cache again.
+ *
+ * @param replyProxy The proxy that has been closed.
+ */
+ public void onWebMessageReplyProxyClosed(WebMessageReplyProxy replyProxy) {}
+
+ /**
+ * The active state of the reply proxy has changed.
+ * If a channel is active it is not closed and not in the back forward cache.
+ *
+ * @param proxy The proxy that changed state.
+ */
+ public void onWebMessageReplyProxyActiveStateChanged(WebMessageReplyProxy proxy) {}
+}
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/WebMessageReplyProxy.java b/chromium/weblayer/public/java/org/chromium/browserfragment/WebMessageReplyProxy.java
new file mode 100644
index 00000000000..06e9b421e11
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/WebMessageReplyProxy.java
@@ -0,0 +1,33 @@
+// 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.browserfragment;
+
+import android.os.RemoteException;
+
+import org.chromium.browserfragment.interfaces.IWebMessageReplyProxy;
+
+/**
+ * Used to post a message to a page. WebMessageReplyProxy is created when a page posts a message to
+ * the JavaScript object that was created by way of {@link Tab#registerWebMessageCallback}.
+ */
+public class WebMessageReplyProxy {
+ private final IWebMessageReplyProxy mWebMessageReplyProxy;
+
+ WebMessageReplyProxy(IWebMessageReplyProxy webMessageReplyProxy) {
+ mWebMessageReplyProxy = webMessageReplyProxy;
+ }
+
+ /**
+ * Post a message back to the JavaScript object.
+ *
+ * @param message The message to post.
+ */
+ public void postMessage(String message) {
+ try {
+ mWebMessageReplyProxy.postMessage(message);
+ } catch (RemoteException e) {
+ }
+ };
+}
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBooleanCallback.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBooleanCallback.aidl
new file mode 100644
index 00000000000..c1401fdeedc
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBooleanCallback.aidl
@@ -0,0 +1,9 @@
+// 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.browserfragment.interfaces;
+
+oneway interface IBooleanCallback {
+ void onResult(in boolean result) = 1;
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserFragmentDelegate.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserFragmentDelegate.aidl
new file mode 100644
index 00000000000..a3fbccd81c0
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserFragmentDelegate.aidl
@@ -0,0 +1,35 @@
+// 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.browserfragment.interfaces;
+
+import android.os.Bundle;
+import org.chromium.browserfragment.interfaces.IBrowserFragmentDelegateClient;
+import org.chromium.browserfragment.interfaces.IBooleanCallback;
+import org.chromium.browserfragment.interfaces.ITabObserverDelegate;
+import org.chromium.browserfragment.interfaces.ITabProxy;
+import org.chromium.browserfragment.interfaces.ITabCallback;
+
+oneway interface IBrowserFragmentDelegate {
+ void setClient(in IBrowserFragmentDelegateClient client) = 1;
+
+ void attachViewHierarchy(in IBinder hostToken) = 2;
+ void resizeView(in int width, in int height) = 3;
+
+ // Fragment events.
+ void onCreate(in Bundle savedInstanceState) = 4;
+ void onAttach() = 5;
+ void onDestroy() = 6;
+ void onDetach() = 7;
+ void onStart() = 8;
+ void onStop() = 9;
+ void onResume() = 10;
+ void onPause() = 11;
+
+ // Tab operations.
+ void getActiveTab(ITabCallback callback) = 14;
+ void setTabObserverDelegate(ITabObserverDelegate tabObserverDelegate) = 15;
+ void tryNavigateBack(IBooleanCallback callback) = 17;
+ void createTab(ITabCallback callback) = 18;
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserFragmentDelegateClient.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserFragmentDelegateClient.aidl
new file mode 100644
index 00000000000..36afb8d2ce6
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserFragmentDelegateClient.aidl
@@ -0,0 +1,12 @@
+// 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.browserfragment.interfaces;
+
+import android.view.SurfaceControlViewHost.SurfacePackage;
+
+oneway interface IBrowserFragmentDelegateClient {
+ void onSurfacePackageReady(in SurfacePackage surfacePackage) = 1;
+ void onStarted(in Bundle instanceState) = 2;
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserSandboxCallback.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserSandboxCallback.aidl
new file mode 100644
index 00000000000..74a696c14e4
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserSandboxCallback.aidl
@@ -0,0 +1,11 @@
+// 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.browserfragment.interfaces;
+
+import android.view.SurfaceControlViewHost.SurfacePackage;
+
+oneway interface IBrowserSandboxCallback {
+ void onBrowserProcessInitialized() = 1;
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserSandboxService.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserSandboxService.aidl
new file mode 100644
index 00000000000..7731a820df8
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IBrowserSandboxService.aidl
@@ -0,0 +1,17 @@
+// 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.browserfragment.interfaces;
+
+import org.chromium.browserfragment.interfaces.IBrowserFragmentDelegate;
+import org.chromium.browserfragment.interfaces.IBrowserSandboxCallback;
+import org.chromium.browserfragment.interfaces.IFragmentParams;
+
+interface IBrowserSandboxService {
+ void initializeBrowserProcess(in IBrowserSandboxCallback callback) = 1;
+
+ IBrowserFragmentDelegate createFragmentDelegate(in IFragmentParams params) = 2;
+
+ void setRemoteDebuggingEnabled(in boolean enabled) = 3;
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IFragmentParams.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IFragmentParams.aidl
new file mode 100644
index 00000000000..bb5f1669a5f
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IFragmentParams.aidl
@@ -0,0 +1,11 @@
+// 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.browserfragment.interfaces;
+
+parcelable IFragmentParams {
+ String profileName;
+ String persistenceId;
+ boolean isIncognito;
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IStringCallback.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IStringCallback.aidl
new file mode 100644
index 00000000000..d34d38f704b
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IStringCallback.aidl
@@ -0,0 +1,9 @@
+// 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.browserfragment.interfaces;
+
+oneway interface IStringCallback {
+ void onResult(in String result) = 1;
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabCallback.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabCallback.aidl
new file mode 100644
index 00000000000..ee74c6fa74b
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabCallback.aidl
@@ -0,0 +1,11 @@
+// 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.browserfragment.interfaces;
+
+import org.chromium.browserfragment.interfaces.ITabParams;
+
+oneway interface ITabCallback {
+ void onResult(in ITabParams tabParams) = 1;
+}
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabNavigationControllerProxy.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabNavigationControllerProxy.aidl
new file mode 100644
index 00000000000..f79ba9ef32d
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabNavigationControllerProxy.aidl
@@ -0,0 +1,16 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.browserfragment.interfaces;
+
+import org.chromium.browserfragment.interfaces.IBooleanCallback;
+
+oneway interface ITabNavigationControllerProxy {
+ void navigate(in String uri) = 1;
+ void goBack() = 2;
+ void goForward() = 3;
+ void canGoBack(IBooleanCallback callback) = 4;
+ void canGoForward(IBooleanCallback callback) = 5;
+
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabObserverDelegate.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabObserverDelegate.aidl
new file mode 100644
index 00000000000..2a9e9aaa4cf
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabObserverDelegate.aidl
@@ -0,0 +1,14 @@
+// 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.browserfragment.interfaces;
+
+import org.chromium.browserfragment.interfaces.ITabParams;
+
+oneway interface ITabObserverDelegate {
+ void notifyActiveTabChanged(in ITabParams tabParams) = 1;
+ void notifyTabAdded(in ITabParams tabParams) = 2;
+ void notifyTabRemoved(in ITabParams tabParams) = 3;
+ void notifyWillDestroyBrowserAndAllTabs() = 4;
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabParams.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabParams.aidl
new file mode 100644
index 00000000000..8e78cbcea6d
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabParams.aidl
@@ -0,0 +1,14 @@
+// Copyright 2021 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.browserfragment.interfaces;
+
+import org.chromium.browserfragment.interfaces.ITabProxy;
+import org.chromium.browserfragment.interfaces.ITabNavigationControllerProxy;
+
+parcelable ITabParams {
+ ITabProxy tabProxy;
+ String tabGuid;
+ ITabNavigationControllerProxy navigationControllerProxy;
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabProxy.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabProxy.aidl
new file mode 100644
index 00000000000..03bc1c5f8c7
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/ITabProxy.aidl
@@ -0,0 +1,19 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.browserfragment.interfaces;
+
+import org.chromium.browserfragment.interfaces.IStringCallback;
+import org.chromium.browserfragment.interfaces.IWebMessageCallback;
+
+import java.util.List;
+
+oneway interface ITabProxy {
+ void setActive() = 1;
+ void close() = 2;
+ void executeScript(in String script, in boolean useSeparateIsolate, in IStringCallback callback) = 3;
+
+ void registerWebMessageCallback(in IWebMessageCallback callback, in String jsObjectName, in List<String> allowedOrigins) = 4;
+ void unregisterWebMessageCallback(in String jsObjectName) = 5;
+}
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IWebMessageCallback.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IWebMessageCallback.aidl
new file mode 100644
index 00000000000..0ca7a61a1e2
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IWebMessageCallback.aidl
@@ -0,0 +1,13 @@
+// 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.browserfragment.interfaces;
+
+import org.chromium.browserfragment.interfaces.IWebMessageReplyProxy;
+
+oneway interface IWebMessageCallback {
+ void onWebMessageReceived(IWebMessageReplyProxy replyProxy, String message) = 1;
+ void onWebMessageReplyProxyClosed(IWebMessageReplyProxy replyProxy) = 2;
+ void onWebMessageReplyProxyActiveStateChanged(IWebMessageReplyProxy proxy) = 3;
+}
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IWebMessageReplyProxy.aidl b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IWebMessageReplyProxy.aidl
new file mode 100644
index 00000000000..f945f5f15e9
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/IWebMessageReplyProxy.aidl
@@ -0,0 +1,9 @@
+// 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.browserfragment.interfaces;
+
+oneway interface IWebMessageReplyProxy {
+ void postMessage(String message) = 1;
+}
diff --git a/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/OWNERS b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/OWNERS
new file mode 100644
index 00000000000..8f094e0099e
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/browserfragment/interfaces/OWNERS
@@ -0,0 +1,2 @@
+per-file *.aidl=set noparent
+per-file *.aidl=file://ipc/SECURITY_OWNERS
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/Browser.java b/chromium/weblayer/public/java/org/chromium/weblayer/Browser.java
index 10a8f86ea39..51d985203aa 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/Browser.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/Browser.java
@@ -5,6 +5,7 @@
package org.chromium.weblayer;
import android.os.RemoteException;
+import android.view.SurfaceControlViewHost;
import android.view.View;
import android.webkit.ValueCallback;
@@ -90,10 +91,14 @@ public class Browser {
mBrowserRestoreCallbacks = null;
}
- Browser(IBrowser impl, Fragment fragment) {
+ // Constructor for browserfragment to inject the {@code tabListCallback} on startup.
+ Browser(IBrowser impl, Fragment fragment, @Nullable TabListCallback tabListCallback) {
mImpl = impl;
mFragment = fragment;
mTabListCallbacks = new ObserverList<TabListCallback>();
+ if (tabListCallback != null) {
+ mTabListCallbacks.addObserver(tabListCallback);
+ }
mBrowserControlsOffsetCallbacks = new ObserverList<BrowserControlsOffsetCallback>();
mBrowserRestoreCallbacks = new ObserverList<BrowserRestoreCallback>();
@@ -105,6 +110,10 @@ public class Browser {
}
}
+ Browser(IBrowser impl, Fragment fragment) {
+ this(impl, fragment, null);
+ }
+
/**
* Changes the fragment. During configuration changes the fragment may change.
*/
@@ -236,6 +245,21 @@ public class Browser {
}
/**
+ * Returns a List of Tabs as saved in the native Browser.
+ *
+ * @return The Tabs.
+ */
+ @NonNull
+ private int[] getTabIds() {
+ ThreadCheck.ensureOnUiThread();
+ try {
+ return mImpl.getTabIds();
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
* Disposes a Tab. If {@link tab} is the active Tab, no Tab is made active. After this call
* {@link tab} should not be used.
*
@@ -260,6 +284,47 @@ public class Browser {
}
/**
+ * Navigates to the previous navigation across all tabs according to tabs in native Browser.
+ */
+ void tryNavigateBack(@NonNull Callback<Boolean> callback) {
+ Tab activeTab = getActiveTab();
+ if (activeTab == null) {
+ callback.onResult(false);
+ return;
+ }
+ if (activeTab.dismissTransientUi()) {
+ callback.onResult(true);
+ return;
+ }
+ NavigationController controller = activeTab.getNavigationController();
+ if (controller.canGoBack()) {
+ controller.goBack();
+ callback.onResult(true);
+ return;
+ }
+ int[] tabIds = getTabIds();
+ if (tabIds.length > 1) {
+ Tab previousTab = null;
+ int activeTabId = activeTab.getId();
+ int prevId = -1;
+ for (int id : tabIds) {
+ if (id == activeTabId) {
+ previousTab = Tab.getTabById(prevId);
+ break;
+ }
+ prevId = id;
+ }
+ if (previousTab != null) {
+ activeTab.dispatchBeforeUnloadAndClose();
+ setActiveTab(previousTab);
+ callback.onResult(true);
+ return;
+ }
+ }
+ callback.onResult(false);
+ }
+
+ /**
* Adds a TabListCallback.
*
* @param callback The TabListCallback.
@@ -591,6 +656,25 @@ public class Browser {
}
}
+ /**
+ * Attaches the top-level view to the SurfaceControlViewHost.
+ * @param host The SurfaceControlViewHost created from the host app's SurfaceView.
+ *
+ * @since 105
+ */
+ void setSurfaceControlViewHost(SurfaceControlViewHost host) {
+ ThreadCheck.ensureOnUiThread();
+
+ if (WebLayer.getSupportedMajorVersionInternal() < 105) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ mImpl.setSurfaceControlViewHost(ObjectWrapper.wrap(host));
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
private final class BrowserClientImpl extends IBrowserClient.Stub {
@Override
public void onActiveTabChanged(int activeTabId) {
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java b/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java
index a120cc2429d..bfb6a447c5e 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java
@@ -46,6 +46,8 @@ public final class BrowserFragment extends RemoteFragment {
// Nonnull between onCreate() and onDestroy().
private Browser mBrowser;
+ private boolean mIgnoreViewModel;
+
/**
* This constructor is for the system FragmentManager only. Please use
* {@link WebLayer#createBrowserFragment}.
@@ -74,7 +76,7 @@ public final class BrowserFragment extends RemoteFragment {
throw new RuntimeException("BrowserFragment was created without arguments.");
}
// If there is saved state, then it should be used and this method should not be called.
- assert !(new ViewModelProvider(this)).get(BrowserViewModel.class).hasSavedState();
+ assert !getViewModel().hasSavedState();
try {
mWebLayer = WebLayer.loadSync(appContext);
} catch (Exception e) {
@@ -96,30 +98,53 @@ public final class BrowserFragment extends RemoteFragment {
@Override
public void onAttach(Context context) {
ThreadCheck.ensureOnUiThread();
- BrowserViewModel browserViewModel = new ViewModelProvider(this).get(BrowserViewModel.class);
+ BrowserViewModel browserViewModel = getViewModel();
if (browserViewModel.hasSavedState()) {
configureFromViewModel(browserViewModel);
}
super.onAttach(context);
}
+ // Method for browserfragment to inject the {@code tabListCallback} on startup of the weblayer
+ // browser.
+ void onCreate(Bundle savedInstanceState, @Nullable TabListCallback tabListCallback) {
+ onCreateInternal(savedInstanceState, tabListCallback);
+
+ // Set |mForwardCreateDestroyEvents| to true so subsequent `onCreate` calls from the host
+ // process don't recreate the internal objects.
+ mForwardCreateDestroyEvents = false;
+ }
+
@Override
public void onCreate(Bundle savedInstanceState) {
+ onCreateInternal(savedInstanceState, null);
+ }
+
+ private void onCreateInternal(
+ Bundle savedInstanceState, @Nullable TabListCallback tabListCallback) {
super.onCreate(savedInstanceState);
if (mBrowser != null) {
// If mBrowser is non-null, it means mBrowser came from a ViewModel.
return;
}
try {
- mBrowser = new Browser(mImpl.getBrowser(), this);
+ mBrowser = new Browser(mImpl.getBrowser(), this, tabListCallback);
} catch (RemoteException e) {
throw new APICallException(e);
}
if (useViewModel()) {
- saveToViewModel(new ViewModelProvider(this).get(BrowserViewModel.class));
+ saveToViewModel(getViewModel());
}
}
+ void onDestroy(boolean force) {
+ if (force) {
+ mForwardCreateDestroyEvents = true;
+ }
+
+ onDestroy();
+ }
+
@Override
@SuppressWarnings("ReferenceEquality")
public void onDestroy() {
@@ -163,10 +188,23 @@ public final class BrowserFragment extends RemoteFragment {
}
private boolean useViewModel() {
+ if (mIgnoreViewModel) {
+ return false;
+ }
Bundle args = getArguments();
return args == null ? false : args.getBoolean(BrowserFragmentArgs.USE_VIEW_MODEL, false);
}
+ private BrowserViewModel getViewModel() {
+ return mIgnoreViewModel ? new BrowserViewModel()
+ : new ViewModelProvider(this).get(BrowserViewModel.class);
+ }
+
+ // TODO(rayankans): Remove ViewModel from this class.
+ void ignoreViewModel() {
+ mIgnoreViewModel = true;
+ }
+
/**
* This class is an implementation detail and not intended for public use. It may change at any
* time in incompatible ways, including being removed.
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragmentDelegate.java b/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragmentDelegate.java
new file mode 100644
index 00000000000..8d36ec11e18
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragmentDelegate.java
@@ -0,0 +1,189 @@
+// 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;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.view.SurfaceControlViewHost;
+import android.view.WindowManager;
+
+import org.chromium.browserfragment.interfaces.IBooleanCallback;
+import org.chromium.browserfragment.interfaces.IBrowserFragmentDelegate;
+import org.chromium.browserfragment.interfaces.IBrowserFragmentDelegateClient;
+import org.chromium.browserfragment.interfaces.IFragmentParams;
+import org.chromium.browserfragment.interfaces.ITabCallback;
+import org.chromium.browserfragment.interfaces.ITabObserverDelegate;
+import org.chromium.browserfragment.interfaces.ITabParams;
+
+/**
+ * This class acts as a proxy between the embedding app's BrowserFragment and
+ * the WebLayer implementation.
+ */
+class BrowserFragmentDelegate extends IBrowserFragmentDelegate.Stub {
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+ private Context mContext;
+ private WebLayer mWebLayer;
+
+ // TODO(rayankans): Create an event handler instead of using the weblayer fragment directly.
+ private BrowserFragment mFragment;
+
+ private BrowserFragmentTabDelegate mTabDelegate;
+
+ private IBrowserFragmentDelegateClient mClient;
+ private SurfaceControlViewHost mSurfaceControlViewHost;
+
+ BrowserFragmentDelegate(Context context, WebLayer webLayer, IFragmentParams params) {
+ mContext = context;
+ mWebLayer = webLayer;
+ mTabDelegate = new BrowserFragmentTabDelegate();
+
+ BrowserFragmentCreateParams createParams = (new BrowserFragmentCreateParams.Builder())
+ .setProfileName(params.profileName)
+ .setPersistenceId(params.persistenceId)
+ .setIsIncognito(params.isIncognito)
+ .build();
+ mHandler.post(() -> {
+ mFragment = (BrowserFragment) WebLayer.createBrowserFragmentWithParams(createParams);
+ mFragment.ignoreViewModel();
+ });
+ }
+
+ @Override
+ public void setClient(IBrowserFragmentDelegateClient client) {
+ mClient = client;
+ }
+
+ @Override
+ public void attachViewHierarchy(IBinder hostToken) {
+ mHandler.post(() -> attachViewHierarchyOnUi(hostToken));
+ }
+
+ private void attachViewHierarchyOnUi(IBinder hostToken) {
+ WindowManager window = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+
+ assert mSurfaceControlViewHost == null;
+ mSurfaceControlViewHost =
+ new SurfaceControlViewHost(mContext, window.getDefaultDisplay(), hostToken);
+
+ mFragment.getBrowser().setSurfaceControlViewHost(mSurfaceControlViewHost);
+ try {
+ mClient.onSurfacePackageReady(mSurfaceControlViewHost.getSurfacePackage());
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void resizeView(int width, int height) {
+ mHandler.post(() -> {
+ if (mSurfaceControlViewHost != null) {
+ mSurfaceControlViewHost.relayout(width, height);
+ }
+ });
+ }
+
+ @Override
+ public void getActiveTab(ITabCallback tabCallback) {
+ mHandler.post(() -> {
+ Tab activeTab = mFragment.getBrowser().getActiveTab();
+ try {
+ if (activeTab != null) {
+ ITabParams tabParams = TabParams.buildParcelable(activeTab);
+ tabCallback.onResult(tabParams);
+ } else {
+ tabCallback.onResult(null);
+ }
+ } catch (RemoteException e) {
+ }
+ });
+ }
+
+ @Override
+ public void onAttach() {
+ mHandler.post(() -> mFragment.onAttach(mContext));
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ mHandler.post(() -> mFragment.onCreate(savedInstanceState, mTabDelegate));
+ }
+
+ @Override
+ public void onDestroy() {
+ mHandler.post(() -> mFragment.onDestroy(/* force= */ true));
+ }
+
+ @Override
+ public void onDetach() {
+ mHandler.post(() -> {
+ mFragment.onDetach();
+ mSurfaceControlViewHost.release();
+ mSurfaceControlViewHost = null;
+ });
+ }
+
+ @Override
+ public void onStart() {
+ mHandler.post(() -> {
+ mFragment.onStart();
+
+ // Retrieve the instance state.
+ Bundle instanceState = new Bundle();
+ mFragment.onSaveInstanceState(instanceState);
+
+ try {
+ mClient.onStarted(instanceState);
+ } catch (RemoteException e) {
+ }
+ });
+ }
+
+ @Override
+ public void onStop() {
+ mHandler.post(() -> mFragment.onStop());
+ }
+
+ @Override
+ public void onResume() {
+ mHandler.post(() -> mFragment.onResume());
+ }
+
+ @Override
+ public void onPause() {
+ mHandler.post(() -> mFragment.onPause());
+ }
+
+ @Override
+ public void setTabObserverDelegate(ITabObserverDelegate tabObserverDelegate) {
+ mTabDelegate.setObserver(tabObserverDelegate);
+ }
+
+ @Override
+ public void tryNavigateBack(IBooleanCallback callback) {
+ mHandler.post(() -> {
+ mFragment.getBrowser().tryNavigateBack(didNavigate -> {
+ try {
+ callback.onResult(didNavigate);
+ } catch (RemoteException e) {
+ }
+ });
+ });
+ }
+
+ @Override
+ public void createTab(ITabCallback callback) {
+ mHandler.post(() -> {
+ Tab newTab = mFragment.getBrowser().createTab();
+ try {
+ callback.onResult(TabParams.buildParcelable(newTab));
+ } catch (RemoteException e) {
+ }
+ });
+ }
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragmentTabDelegate.java b/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragmentTabDelegate.java
new file mode 100644
index 00000000000..dd937f06efe
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragmentTabDelegate.java
@@ -0,0 +1,86 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.weblayer;
+
+import android.os.RemoteException;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.chromium.browserfragment.interfaces.ITabObserverDelegate;
+import org.chromium.browserfragment.interfaces.ITabParams;
+
+/**
+ * This class acts as a proxy between the Tab events happening in
+ * weblayer and the TabManager in browserfragment.
+ */
+class BrowserFragmentTabDelegate extends TabListCallback {
+ private ITabObserverDelegate mTabObserver;
+
+ private final NewTabCallback mNewTabCallback = new NewTabCallback() {
+ @Override
+ public void onNewTab(@NonNull Tab tab, @NewTabType int type) {
+ // Set foreground tabs and tabs in new windows by default to active.
+ switch (type) {
+ case NewTabType.FOREGROUND_TAB:
+ case NewTabType.NEW_WINDOW:
+ tab.getBrowser().setActiveTab(tab);
+ break;
+ }
+ }
+ };
+
+ void setObserver(ITabObserverDelegate observer) {
+ mTabObserver = observer;
+ }
+
+ @Override
+ public void onActiveTabChanged(@Nullable Tab tab) {
+ maybeRunOnTabObserver(observer -> {
+ ITabParams tabParams = null;
+ if (tab != null) {
+ tabParams = TabParams.buildParcelable(tab);
+ }
+ observer.notifyActiveTabChanged(tabParams);
+ });
+ }
+
+ @Override
+ public void onTabAdded(@NonNull Tab tab) {
+ // This is a requirement to open new tabs.
+ tab.setNewTabCallback(mNewTabCallback);
+
+ maybeRunOnTabObserver(observer -> {
+ ITabParams tabParams = TabParams.buildParcelable(tab);
+ observer.notifyTabAdded(tabParams);
+ });
+ }
+
+ @Override
+ public void onTabRemoved(@NonNull Tab tab) {
+ maybeRunOnTabObserver(observer -> {
+ ITabParams tabParams = TabParams.buildParcelable(tab);
+ observer.notifyTabRemoved(tabParams);
+ });
+ }
+
+ @Override
+ public void onWillDestroyBrowserAndAllTabs() {
+ maybeRunOnTabObserver(observer -> observer.notifyWillDestroyBrowserAndAllTabs());
+ }
+
+ private interface OnTabObserverCallback {
+ void run(ITabObserverDelegate tabObserver) throws RemoteException;
+ }
+
+ private void maybeRunOnTabObserver(OnTabObserverCallback callback) {
+ if (mTabObserver != null) {
+ try {
+ callback.run(mTabObserver);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/BrowserSandboxService.java b/chromium/weblayer/public/java/org/chromium/weblayer/BrowserSandboxService.java
new file mode 100644
index 00000000000..25a64ea3509
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/BrowserSandboxService.java
@@ -0,0 +1,64 @@
+// 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;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+
+import org.chromium.browserfragment.interfaces.IBrowserFragmentDelegate;
+import org.chromium.browserfragment.interfaces.IBrowserSandboxCallback;
+import org.chromium.browserfragment.interfaces.IBrowserSandboxService;
+import org.chromium.browserfragment.interfaces.IFragmentParams;
+
+/**
+ * Service running the browser process for a BrowserFragment outside of the hosting
+ * application's process.
+ */
+public class BrowserSandboxService extends Service {
+ private final Context mContext = this;
+
+ private final IBrowserSandboxService.Stub mBinder = new IBrowserSandboxService.Stub() {
+ private WebLayer mWebLayer;
+
+ @Override
+ public void initializeBrowserProcess(IBrowserSandboxCallback callback) {
+ new Handler(Looper.getMainLooper()).post(() -> {
+ WebLayer.loadAsync(mContext, (webLayer) -> onWebLayerReady(webLayer, callback));
+ });
+ }
+
+ private void onWebLayerReady(WebLayer webLayer, IBrowserSandboxCallback callback) {
+ mWebLayer = webLayer;
+ try {
+ callback.onBrowserProcessInitialized();
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public IBrowserFragmentDelegate createFragmentDelegate(IFragmentParams params) {
+ assert mWebLayer != null;
+
+ return new BrowserFragmentDelegate(mContext, mWebLayer, params);
+ }
+
+ @Override
+ public void setRemoteDebuggingEnabled(boolean enabled) {
+ assert mWebLayer != null;
+ mWebLayer.setRemoteDebuggingEnabled(enabled);
+ }
+
+ };
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/RemoteFragment.java b/chromium/weblayer/public/java/org/chromium/weblayer/RemoteFragment.java
index eb89893dbb4..948a4287d5b 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/RemoteFragment.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/RemoteFragment.java
@@ -68,6 +68,11 @@ abstract class RemoteFragment extends Fragment {
// Whetner saveToViewModel() was called. In other words, state was saved to ViewModelImpl.
private boolean mSavedStateToViewModel;
+ // Whether to forward the onCreate and onDestroy events to the remote fragment.
+ // TODO(rayankans): Remove this hack once BrowserFragmentDelegate is merged with
+ // BrowserFragment.
+ protected boolean mForwardCreateDestroyEvents = true;
+
private static final class IRemoteFragmentClientImpl extends IRemoteFragmentClient.Stub {
private RemoteFragment mRemoteFragment;
// Used to track when destroy is being called because a ViewModel is being destroyed. When
@@ -339,6 +344,9 @@ abstract class RemoteFragment extends Fragment {
super.onCreate(savedInstanceState);
return;
}
+ if (!mForwardCreateDestroyEvents) {
+ return;
+ }
try {
mRemoteFragment.handleOnCreate(ObjectWrapper.wrap(savedInstanceState));
} catch (RemoteException e) {
@@ -447,6 +455,11 @@ abstract class RemoteFragment extends Fragment {
return;
}
ThreadCheck.ensureOnUiThread();
+
+ if (!mForwardCreateDestroyEvents) {
+ return;
+ }
+
try {
mRemoteFragment.handleOnDestroy();
// The other side does the clean up automatically in handleOnDestroy()
@@ -471,7 +484,11 @@ abstract class RemoteFragment extends Fragment {
}
private void superOnCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ // TODO(rayankans): Remove calls into the base Fragment class.
+ try {
+ super.onCreate(savedInstanceState);
+ } catch (NullPointerException e) {
+ }
}
private void superOnAttach(Context context) {
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/Tab.java b/chromium/weblayer/public/java/org/chromium/weblayer/Tab.java
index c3d37fd73bf..ac81926e330 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/Tab.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/Tab.java
@@ -57,6 +57,8 @@ public class Tab {
private @Nullable ActionModeCallback mActionModeCallback;
// Id from the remote side.
private final int mId;
+ // Guid from the remote side.
+ private final String mGuid;
// Constructor for test mocking.
protected Tab() {
@@ -67,6 +69,7 @@ public class Tab {
mCallbacks = null;
mScrollOffsetCallbacks = null;
mId = 0;
+ mGuid = "";
}
Tab(ITab impl, Browser browser) {
@@ -74,6 +77,7 @@ public class Tab {
mBrowser = browser;
try {
mId = impl.getId();
+ mGuid = impl.getGuid();
mImpl.setClient(new TabClientImpl());
} catch (RemoteException e) {
throw new APICallException(e);
@@ -308,7 +312,6 @@ public class Tab {
@NonNull
public NavigationController getNavigationController() {
- ThreadCheck.ensureOnUiThread();
throwIfDestroyed();
return mNavigationController;
}
@@ -414,13 +417,7 @@ public class Tab {
*/
@NonNull
public String getGuid() {
- ThreadCheck.ensureOnUiThread();
- throwIfDestroyed();
- try {
- return mImpl.getGuid();
- } catch (RemoteException e) {
- throw new APICallException(e);
- }
+ return mGuid;
}
/**
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/TabNavigationControllerProxy.java b/chromium/weblayer/public/java/org/chromium/weblayer/TabNavigationControllerProxy.java
new file mode 100644
index 00000000000..fd2407e7c7e
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/TabNavigationControllerProxy.java
@@ -0,0 +1,62 @@
+// 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;
+
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+
+import org.chromium.browserfragment.interfaces.IBooleanCallback;
+import org.chromium.browserfragment.interfaces.ITabNavigationControllerProxy;
+
+class TabNavigationControllerProxy extends ITabNavigationControllerProxy.Stub {
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+ private final NavigationController mNavigationController;
+
+ TabNavigationControllerProxy(NavigationController navigationController) {
+ mNavigationController = navigationController;
+ }
+
+ @Override
+ public void navigate(String uri) {
+ mHandler.post(() -> {
+ NavigateParams.Builder navigateParamsBuilder =
+ new NavigateParams.Builder().disableIntentProcessing();
+ mNavigationController.navigate(Uri.parse(uri), navigateParamsBuilder.build());
+ });
+ }
+
+ @Override
+ public void goBack() {
+ mHandler.post(() -> { mNavigationController.goBack(); });
+ }
+
+ @Override
+ public void goForward() {
+ mHandler.post(() -> { mNavigationController.goForward(); });
+ }
+
+ @Override
+ public void canGoBack(IBooleanCallback callback) {
+ mHandler.post(() -> {
+ try {
+ callback.onResult(mNavigationController.canGoBack());
+ } catch (RemoteException e) {
+ }
+ });
+ }
+
+ @Override
+ public void canGoForward(IBooleanCallback callback) {
+ mHandler.post(() -> {
+ try {
+ callback.onResult(mNavigationController.canGoForward());
+ } catch (RemoteException e) {
+ }
+ });
+ }
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/TabParams.java b/chromium/weblayer/public/java/org/chromium/weblayer/TabParams.java
new file mode 100644
index 00000000000..a647844d660
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/TabParams.java
@@ -0,0 +1,24 @@
+// 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;
+
+import androidx.annotation.NonNull;
+
+import org.chromium.browserfragment.interfaces.ITabParams;
+
+/**
+ * Parameters for {@link Tab}.
+ */
+class TabParams {
+ static ITabParams buildParcelable(@NonNull Tab tab) {
+ ITabParams parcel = new ITabParams();
+ parcel.tabProxy = new TabProxy(tab);
+ parcel.tabGuid = tab.getGuid();
+ parcel.navigationControllerProxy =
+ new TabNavigationControllerProxy(tab.getNavigationController());
+
+ return parcel;
+ }
+} \ No newline at end of file
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/TabProxy.java b/chromium/weblayer/public/java/org/chromium/weblayer/TabProxy.java
new file mode 100644
index 00000000000..ea78b72e446
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/TabProxy.java
@@ -0,0 +1,119 @@
+// 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;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+
+import org.chromium.browserfragment.interfaces.IStringCallback;
+import org.chromium.browserfragment.interfaces.ITabProxy;
+import org.chromium.browserfragment.interfaces.IWebMessageCallback;
+
+import java.util.List;
+
+/**
+ * This class acts as a proxy between a Tab object in the embedding app
+ * and the Tab implementation in WebLayer.
+ */
+class TabProxy extends ITabProxy.Stub {
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+ private int mTabId;
+ private String mGuid;
+
+ TabProxy(Tab tab) {
+ mTabId = tab.getId();
+ mGuid = tab.getGuid();
+ }
+
+ void invalidate() {
+ mTabId = -1;
+ mGuid = null;
+ }
+
+ boolean isValid() {
+ return mGuid != null;
+ }
+
+ private Tab getTab() {
+ Tab tab = Tab.getTabById(mTabId);
+ if (tab == null) {
+ // TODO(swestphal): Raise exception.
+ }
+ return tab;
+ }
+
+ @Override
+ public void setActive() {
+ mHandler.post(() -> {
+ Tab tab = getTab();
+ tab.getBrowser().setActiveTab(tab);
+ });
+ }
+
+ @Override
+ public void close() {
+ mHandler.post(() -> {
+ getTab().dispatchBeforeUnloadAndClose();
+ invalidate();
+ });
+ }
+
+ @Override
+ public void executeScript(String script, boolean useSeparateIsolate, IStringCallback callback) {
+ mHandler.post(() -> {
+ // TODO(rayankans): Verify the tab's origin is 1P.
+ getTab().executeScript(script, useSeparateIsolate, (String result) -> {
+ try {
+ callback.onResult(result);
+ } catch (RemoteException e) {
+ }
+ });
+ });
+ }
+
+ @Override
+ public void registerWebMessageCallback(
+ IWebMessageCallback callback, String jsObjectName, List<String> allowedOrigins) {
+ mHandler.post(() -> {
+ getTab().registerWebMessageCallback(new WebMessageCallback() {
+ @Override
+ public void onWebMessageReceived(
+ WebMessageReplyProxy replyProxy, WebMessage message) {
+ try {
+ callback.onWebMessageReceived(
+ new WebMessageReplyProxyProxy(replyProxy), message.getContents());
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void onWebMessageReplyProxyClosed(WebMessageReplyProxy replyProxy) {
+ try {
+ callback.onWebMessageReplyProxyClosed(
+ new WebMessageReplyProxyProxy(replyProxy));
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void onWebMessageReplyProxyActiveStateChanged(
+ WebMessageReplyProxy replyProxy) {
+ try {
+ callback.onWebMessageReplyProxyActiveStateChanged(
+ new WebMessageReplyProxyProxy(replyProxy));
+ } catch (RemoteException e) {
+ }
+ }
+ }, jsObjectName, allowedOrigins);
+ });
+ }
+
+ @Override
+ public void unregisterWebMessageCallback(String jsObjectName) {
+ mHandler.post(() -> { getTab().unregisterWebMessageCallback(jsObjectName); });
+ }
+}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/WebMessageReplyProxyProxy.java b/chromium/weblayer/public/java/org/chromium/weblayer/WebMessageReplyProxyProxy.java
new file mode 100644
index 00000000000..1ad7c1f9a32
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/WebMessageReplyProxyProxy.java
@@ -0,0 +1,29 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.weblayer;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import org.chromium.browserfragment.interfaces.IWebMessageReplyProxy;
+
+/**
+ * This class act as a proxy between browserfragment and the {@link WebMessageReplyProxy} in
+ * weblayer.
+ */
+class WebMessageReplyProxyProxy extends IWebMessageReplyProxy.Stub {
+ private Handler mHandler = new Handler(Looper.getMainLooper());
+
+ private final WebMessageReplyProxy mWebMessageReplyProxy;
+
+ WebMessageReplyProxyProxy(WebMessageReplyProxy webMessageReplyProxy) {
+ mWebMessageReplyProxy = webMessageReplyProxy;
+ }
+
+ @Override
+ public void postMessage(String message) {
+ mHandler.post(() -> { mWebMessageReplyProxy.postMessage(new WebMessage(message)); });
+ }
+}
diff --git a/chromium/weblayer/renderer/content_renderer_client_impl.cc b/chromium/weblayer/renderer/content_renderer_client_impl.cc
index 5046b828aaf..65149ff6f72 100644
--- a/chromium/weblayer/renderer/content_renderer_client_impl.cc
+++ b/chromium/weblayer/renderer/content_renderer_client_impl.cc
@@ -172,7 +172,8 @@ void ContentRendererClientImpl::RenderFrameCreated(
}
}
-void ContentRendererClientImpl::WebViewCreated(blink::WebView* web_view) {
+void ContentRendererClientImpl::WebViewCreated(blink::WebView* web_view,
+ bool was_created_by_renderer) {
new prerender::NoStatePrefetchClient(web_view);
}
diff --git a/chromium/weblayer/renderer/content_renderer_client_impl.h b/chromium/weblayer/renderer/content_renderer_client_impl.h
index c5318ec73e4..d4ed15bf2cb 100644
--- a/chromium/weblayer/renderer/content_renderer_client_impl.h
+++ b/chromium/weblayer/renderer/content_renderer_client_impl.h
@@ -36,7 +36,8 @@ class ContentRendererClientImpl : public content::ContentRendererClient {
// content::ContentRendererClient:
void RenderThreadStarted() override;
void RenderFrameCreated(content::RenderFrame* render_frame) override;
- void WebViewCreated(blink::WebView* web_view) override;
+ void WebViewCreated(blink::WebView* web_view,
+ bool was_created_by_renderer) override;
SkBitmap* GetSadPluginBitmap() override;
SkBitmap* GetSadWebViewBitmap() override;
void PrepareErrorPage(content::RenderFrame* render_frame,
diff --git a/chromium/weblayer/renderer/error_page_helper.cc b/chromium/weblayer/renderer/error_page_helper.cc
index 6eb924db516..dc8b9454555 100644
--- a/chromium/weblayer/renderer/error_page_helper.cc
+++ b/chromium/weblayer/renderer/error_page_helper.cc
@@ -57,9 +57,9 @@ void ErrorPageHelper::DisableErrorPageHelperForNextError() {
ErrorPageHelper::ErrorPageHelper(content::RenderFrame* render_frame)
: RenderFrameObserver(render_frame),
RenderFrameObserverTracker<ErrorPageHelper>(render_frame) {
- render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
- base::BindRepeating(&ErrorPageHelper::BindErrorPageHelper,
- weak_factory_.GetWeakPtr()));
+ render_frame->GetAssociatedInterfaceRegistry()
+ ->AddInterface<mojom::ErrorPageHelper>(base::BindRepeating(
+ &ErrorPageHelper::BindErrorPageHelper, weak_factory_.GetWeakPtr()));
}
ErrorPageHelper::~ErrorPageHelper() = default;
diff --git a/chromium/weblayer/renderer/weblayer_render_thread_observer.cc b/chromium/weblayer/renderer/weblayer_render_thread_observer.cc
index 913c304be54..3d8a589d31a 100644
--- a/chromium/weblayer/renderer/weblayer_render_thread_observer.cc
+++ b/chromium/weblayer/renderer/weblayer_render_thread_observer.cc
@@ -14,7 +14,8 @@ WebLayerRenderThreadObserver::~WebLayerRenderThreadObserver() = default;
void WebLayerRenderThreadObserver::RegisterMojoInterfaces(
blink::AssociatedInterfaceRegistry* associated_interfaces) {
- associated_interfaces->AddInterface(base::BindRepeating(
+ associated_interfaces->AddInterface<
+ mojom::RendererConfiguration>(base::BindRepeating(
&WebLayerRenderThreadObserver::OnRendererConfigurationAssociatedRequest,
base::Unretained(this)));
}
diff --git a/chromium/weblayer/shell/android/BUILD.gn b/chromium/weblayer/shell/android/BUILD.gn
index 74362f16869..de9a8db0e75 100644
--- a/chromium/weblayer/shell/android/BUILD.gn
+++ b/chromium/weblayer/shell/android/BUILD.gn
@@ -106,6 +106,26 @@ weblayer_shell_apk_helper("weblayer_shell_system_webview") {
apk_name = "WebLayerShellSystemWebView"
}
+generate_wrapper("run_browserfragment_shell") {
+ testonly = true
+ wrapper_script = "$root_out_dir/bin/run_browserfragment_shell"
+ executable = "//weblayer/tools/run_weblayer_shell.py"
+ executable_args = [
+ "--shell-apk-path",
+ "@WrappedPath(apks/BFShell.apk)",
+ "--support-apk-path",
+ "@WrappedPath(apks/BFSandbox.apk)",
+ "--support-apk-path",
+ "@WrappedPath(apks/WebLayerSupport.apk)",
+ ]
+
+ deps = [
+ ":browser_sandbox_apk",
+ ":browserfragment_shell_apk",
+ ":weblayer_support_apk",
+ ]
+}
+
generate_wrapper("run_weblayer_shell") {
testonly = true
wrapper_script = "$root_out_dir/bin/run_weblayer_shell"
@@ -304,3 +324,82 @@ script_test("weblayer_shell_wpt") {
"//third_party/blink/tools:wpt_tests_android_isolate",
]
}
+
+# TODO(rayankans): Update `run_weblayer_shell` to also deploy the browserfragment shell with a
+# browser sandbox APK.
+
+browserfragment_shell_manifest =
+ "$target_gen_dir/browserfragment_shell_manifest/AndroidManifest.xml"
+
+jinja_template("browserfragment_shell_manifest") {
+ input = "browserfragment_shell_apk/AndroidManifest.xml"
+ output = browserfragment_shell_manifest
+}
+
+android_resources("browserfragment_shell_resources") {
+ sources = [
+ "browserfragment_shell_apk/res/layout/main.xml",
+ "browserfragment_shell_apk/res/values/styles.xml",
+ ]
+}
+
+android_library("browserfragment_shell_java") {
+ testonly = true
+ resources_package = "org.chromium.browserfragment.shell"
+
+ sources = [ "browserfragment_shell_apk/src/org/chromium/browserfragment/shell/BrowserFragmentShellActivity.java" ]
+
+ deps = [
+ ":browserfragment_shell_resources",
+ "//base:base_java",
+ "//third_party/android_deps:com_google_guava_guava_android_java",
+ "//third_party/androidx:androidx_appcompat_appcompat_java",
+ "//third_party/androidx:androidx_fragment_fragment_java",
+ "//weblayer/public/java:browserfragment_java",
+ ]
+}
+
+android_apk("browserfragment_shell_apk") {
+ testonly = true
+
+ # Test runner does not support having "additional apks" that are incremental.
+ never_incremental = true
+
+ deps = [
+ ":browserfragment_shell_java",
+ ":browserfragment_shell_manifest",
+ ]
+
+ apk_name = "BFShell"
+ android_manifest = browserfragment_shell_manifest
+ min_sdk_version = default_min_sdk_version
+ target_sdk_version = 28
+ android_manifest_dep = ":browserfragment_shell_manifest"
+}
+
+browser_sandbox_manifest =
+ "$target_gen_dir/browser_sandbox_manifest/AndroidManifest.xml"
+
+jinja_template("browser_sandbox_manifest") {
+ input = "browser_sandbox_apk/AndroidManifest.xml"
+ output = browser_sandbox_manifest
+}
+
+android_apk("browser_sandbox_apk") {
+ testonly = true
+
+ # Test runner does not support having "additional apks" that are incremental.
+ never_incremental = true
+
+ deps = [
+ ":browser_sandbox_manifest",
+ "//weblayer/public/java:browserfragment_sandbox_java",
+ ]
+
+ apk_name = "BFSandbox"
+ android_manifest = browser_sandbox_manifest
+ min_sdk_version = default_min_sdk_version
+ target_sdk_version = 28
+ android_manifest_dep = ":browser_sandbox_manifest"
+ shared_resources = true
+}
diff --git a/chromium/weblayer/shell/android/browser_sandbox_apk/AndroidManifest.xml b/chromium/weblayer/shell/android/browser_sandbox_apk/AndroidManifest.xml
new file mode 100644
index 00000000000..f258fe5d3dd
--- /dev/null
+++ b/chromium/weblayer/shell/android/browser_sandbox_apk/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright 2022 The Chromium Authors. All rights reserved.
+
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.chromium.browserfragment.sandbox">
+
+ <application android:label="BF sandbox">
+
+ <service android:name="org.chromium.weblayer.BrowserSandboxService"
+ android:exported="true" >
+ <intent-filter>
+ <action android:name="org.chromium.weblayer.intent.action.BROWSERSANDBOX" />
+ </intent-filter>
+ </service>
+
+ <!-- TODO(rayankans): Make this a template. -->
+ <meta-data android:name="org.chromium.weblayer.WebLayerPackage"
+ android:value="org.chromium.weblayer.support"/>
+
+ </application>
+</manifest>
diff --git a/chromium/weblayer/shell/android/browserfragment_shell_apk/AndroidManifest.xml b/chromium/weblayer/shell/android/browserfragment_shell_apk/AndroidManifest.xml
new file mode 100644
index 00000000000..fee9e739e42
--- /dev/null
+++ b/chromium/weblayer/shell/android/browserfragment_shell_apk/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright 2022 The Chromium Authors. All rights reserved.
+
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="org.chromium.browserfragment.shell">
+
+ <application android:label="BF shell"
+ android:supportsRtl="true">
+ <activity android:name="BrowserFragmentShellActivity"
+ android:launchMode="singleTask"
+ android:theme="@style/ShellTheme"
+ android:windowSoftInputMode="adjustResize"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/chromium/weblayer/shell/android/browserfragment_shell_apk/res/layout/main.xml b/chromium/weblayer/shell/android/browserfragment_shell_apk/res/layout/main.xml
new file mode 100644
index 00000000000..7361030f06f
--- /dev/null
+++ b/chromium/weblayer/shell/android/browserfragment_shell_apk/res/layout/main.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2022 The Chromium Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file. -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <Button
+ android:id="@+id/create_tab"
+ android:text="Create and Preload Tab"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <Button
+ android:id="@+id/navigate_tab"
+ android:text="Open Tab"
+ android:enabled="false"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+ <androidx.fragment.app.FragmentContainerView
+ android:id="@+id/fragment_container_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</LinearLayout>
+
diff --git a/chromium/weblayer/shell/android/browserfragment_shell_apk/res/values/styles.xml b/chromium/weblayer/shell/android/browserfragment_shell_apk/res/values/styles.xml
new file mode 100644
index 00000000000..1577b6d4ad8
--- /dev/null
+++ b/chromium/weblayer/shell/android/browserfragment_shell_apk/res/values/styles.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools">
+ <style name="ShellTheme" parent="Theme.AppCompat.DayNight.NoActionBar"/>
+</resources> \ No newline at end of file
diff --git a/chromium/weblayer/shell/android/browserfragment_shell_apk/src/org/chromium/browserfragment/shell/BrowserFragmentShellActivity.java b/chromium/weblayer/shell/android/browserfragment_shell_apk/src/org/chromium/browserfragment/shell/BrowserFragmentShellActivity.java
new file mode 100644
index 00000000000..30b89504e89
--- /dev/null
+++ b/chromium/weblayer/shell/android/browserfragment_shell_apk/src/org/chromium/browserfragment/shell/BrowserFragmentShellActivity.java
@@ -0,0 +1,200 @@
+// 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.browserfragment.shell;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.chromium.base.Log;
+import org.chromium.browserfragment.Browser;
+import org.chromium.browserfragment.BrowserFragment;
+import org.chromium.browserfragment.FragmentParams;
+import org.chromium.browserfragment.Tab;
+import org.chromium.browserfragment.TabManager;
+import org.chromium.browserfragment.TabObserver;
+import org.chromium.browserfragment.WebMessageCallback;
+import org.chromium.browserfragment.WebMessageReplyProxy;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Activity for managing the Demo Shell.
+ */
+public class BrowserFragmentShellActivity extends AppCompatActivity {
+ private static final String TAG = "BrowserFragmentShell";
+
+ private static final String BROWSER_FRAGMENT_TAG = "BROWSER_FRAGMENT_TAG";
+
+ private Context mContext;
+
+ private TabManager mTabManager;
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main);
+
+ mContext = getApplicationContext();
+
+ ListenableFuture<Browser> browserFuture = Browser.create(mContext);
+ Futures.addCallback(browserFuture, new FutureCallback<Browser>() {
+ @Override
+ public void onSuccess(Browser browser) {
+ onBrowserReady(browser, savedInstanceState);
+ }
+
+ @Override
+ public void onFailure(Throwable thrown) {}
+ }, mContext.getMainExecutor());
+
+ final Button createTabButton = findViewById(R.id.create_tab);
+ final Button navigateButton = findViewById(R.id.navigate_tab);
+
+ createTabButton.setOnClickListener((View v) -> {
+ if (mTabManager != null) {
+ ListenableFuture<Tab> newTabFuture = mTabManager.createTab();
+ Futures.addCallback(newTabFuture, new FutureCallback<Tab>() {
+ @Override
+ public void onSuccess(Tab newTab) {
+ navigateButton.setEnabled(true);
+ newTab.getNavigationController().navigate("https://google.com");
+ // TODO(swestphal): Call this in a Tab-loaded-callback instead.
+ navigateButton.setOnClickListener((View v) -> {
+ navigateButton.setEnabled(false);
+ newTab.setActive();
+ });
+ }
+ @Override
+ public void onFailure(Throwable thrown) {}
+ }, mContext.getMainExecutor());
+ }
+ });
+ }
+
+ private void onBrowserReady(Browser browser, Bundle savedInstanceState) {
+ browser.setRemoteDebuggingEnabled(true);
+
+ BrowserFragment fragment = getOrCreateBrowserFragment(browser, savedInstanceState);
+
+ fragment.registerTabObserver(new TabObserver() {
+ @Override
+ public void onActiveTabChanged(@Nullable Tab activeTab) {
+ Log.i(TAG, "received 'onActiveTabChanged'-event");
+ }
+
+ @Override
+ public void onTabAdded(@NonNull Tab tab) {
+ Log.i(TAG, "received 'onTabAdded'-event");
+ }
+
+ @Override
+ public void onTabRemoved(@NonNull Tab tab) {
+ Log.i(TAG, "received 'onTabRemoved'-event");
+ }
+
+ @Override
+ public void onWillDestroyBrowserAndAllTabs() {
+ Log.i(TAG, "received 'onWillDestroyBrowserAndAllTabs'-event");
+ }
+ });
+ ListenableFuture<TabManager> tabManagerFuture = fragment.getTabManager();
+ AsyncFunction<TabManager, Tab> getActiveTabTask = tabManager -> {
+ mTabManager = tabManager;
+ return tabManager.getActiveTab();
+ };
+ ListenableFuture<Tab> activeTabFuture = Futures.transformAsync(
+ tabManagerFuture, getActiveTabTask, mContext.getMainExecutor());
+
+ Futures.addCallback(activeTabFuture, new FutureCallback<Tab>() {
+ @Override
+ public void onSuccess(Tab activeTab) {
+ if (savedInstanceState == null) {
+ // TODO(rayankans): Expose Tab URL to avoid relying on |savedInstanceState|.
+ activeTab.getNavigationController().navigate("https://google.com");
+
+ activeTab.registerWebMessageCallback(new WebMessageCallback() {
+ @Override
+ public void onWebMessageReceived(
+ WebMessageReplyProxy replyProxy, String message) {
+ Log.i(TAG, "received WebMessage: " + message);
+ replyProxy.postMessage("Bouncing answer from browser: " + message);
+ }
+
+ @Override
+ public void onWebMessageReplyProxyClosed(WebMessageReplyProxy replyProxy) {}
+
+ @Override
+ public void onWebMessageReplyProxyActiveStateChanged(
+ WebMessageReplyProxy proxy) {}
+ }, "x", Arrays.asList("*"));
+ }
+ }
+ @Override
+ public void onFailure(Throwable thrown) {}
+ }, mContext.getMainExecutor());
+ }
+
+ private BrowserFragment getOrCreateBrowserFragment(Browser browser, Bundle savedInstanceState) {
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ if (savedInstanceState != null) {
+ List<Fragment> fragments = fragmentManager.getFragments();
+ if (fragments.size() > 1) {
+ throw new IllegalStateException("More than one fragment added, shouldn't happen");
+ }
+ if (fragments.size() == 1) {
+ return (BrowserFragment) fragments.get(0);
+ }
+ }
+
+ FragmentParams params =
+ (new FragmentParams.Builder()).setProfileName("DefaultProfile").build();
+ BrowserFragment fragment = browser.createFragment(params);
+
+ fragmentManager.beginTransaction()
+ .setReorderingAllowed(true)
+ .add(R.id.fragment_container_view, fragment, BROWSER_FRAGMENT_TAG)
+ .commit();
+
+ return fragment;
+ }
+
+ @Override
+ public void onBackPressed() {
+ BrowserFragment fragment = (BrowserFragment) getSupportFragmentManager().findFragmentByTag(
+ BROWSER_FRAGMENT_TAG);
+ if (fragment == null) {
+ super.onBackPressed();
+ return;
+ }
+ ListenableFuture<Boolean> tryNavigateBackFuture = mTabManager.tryNavigateBack();
+ Futures.addCallback(tryNavigateBackFuture, new FutureCallback<Boolean>() {
+ @Override
+ public void onSuccess(Boolean didNavigate) {
+ if (!didNavigate) {
+ BrowserFragmentShellActivity.super.onBackPressed();
+ }
+ }
+ @Override
+ public void onFailure(Throwable thrown) {
+ BrowserFragmentShellActivity.super.onBackPressed();
+ }
+ }, mContext.getMainExecutor());
+ }
+}
diff --git a/chromium/weblayer/shell/android/shell_apk/DEPS b/chromium/weblayer/shell/android/shell_apk/DEPS
index 941c524071c..976d31890b3 100644
--- a/chromium/weblayer/shell/android/shell_apk/DEPS
+++ b/chromium/weblayer/shell/android/shell_apk/DEPS
@@ -6,5 +6,6 @@ include_rules = [
# possible, as it can be confusing since the ClassLoader of the client will be
# different from the implementation. Only simple utility classes are allowed.
"+base/android/java/src/org/chromium/base/IntentUtils.java",
+ "+base/android/java/src/org/chromium/base/Log.java",
"+base/android/java/src/org/chromium/base/compat/ApiHelperForR.java",
]
diff --git a/chromium/weblayer/test/BUILD.gn b/chromium/weblayer/test/BUILD.gn
index 8f8ca44d65d..03c93c2856e 100644
--- a/chromium/weblayer/test/BUILD.gn
+++ b/chromium/weblayer/test/BUILD.gn
@@ -116,6 +116,7 @@ test("weblayer_browsertests") {
"//components/favicon/content",
"//components/heavy_ad_intervention",
"//components/infobars/content",
+ "//components/language/core/browser",
"//components/network_session_configurator/common",
"//components/network_time",
"//components/no_state_prefetch/browser",
@@ -126,6 +127,8 @@ test("weblayer_browsertests") {
"//components/permissions",
"//components/permissions:test_support",
"//components/prefs",
+ "//components/reduce_accept_language/browser:browser",
+ "//components/reduce_accept_language/browser:test_support",
"//components/security_interstitials/content:security_interstitial_page",
"//components/sessions:test_support",
"//components/signin/core/browser",
@@ -183,6 +186,7 @@ test("weblayer_browsertests") {
"../browser/popup_blocker_browsertest.cc",
"../browser/prefetch_browsertest.cc",
"../browser/profile_browsertest.cc",
+ "../browser/reduce_accept_language_service_browsertest.cc",
"../browser/site_isolation_browsertest.cc",
"../browser/ssl_browsertest.cc",
"../browser/subresource_filter_browsertest.cc",
@@ -217,6 +221,7 @@ test("weblayer_browsertests") {
"../browser/android/metrics/metrics_test_helper.h",
"../browser/android/metrics/ukm_browsertest.cc",
"../browser/autofill_browsertest.cc",
+ "../browser/browser_controls_navigation_state_handler_browsertest.cc",
"../browser/safe_browsing/client_side_detection_service_browsertest.cc",
"../browser/safe_browsing/client_side_detection_service_factory_browsertest.cc",
"../browser/safe_browsing/safe_browsing_browsertest.cc",
diff --git a/chromium/weblayer/tools/run_weblayer_shell.py b/chromium/weblayer/tools/run_weblayer_shell.py
index 41391b2152b..05fc96a0eaf 100755
--- a/chromium/weblayer/tools/run_weblayer_shell.py
+++ b/chromium/weblayer/tools/run_weblayer_shell.py
@@ -73,6 +73,12 @@ def main():
'launch']
launch_cmd.extend(args.remaining_args)
subprocess.call(launch_cmd)
+ elif (os.path.basename(args.shell_apk_path) == "BFShell.apk"):
+ launch_cmd = [os.path.join(os.path.dirname(args.shell_apk_path),
+ os.pardir, 'bin', 'browserfragment_shell_apk'),
+ 'launch']
+ launch_cmd.extend(args.remaining_args)
+ subprocess.call(launch_cmd)
else:
device.adb.Shell('monkey -p org.chromium.weblayer.shell 1')