Skip to content

Commit

Permalink
iwa: Use correct StoragePartition in a controlled frame
Browse files Browse the repository at this point in the history
This adds ExtensionsBrowserClient::GetWebViewStoragePartitionConfig,
which is used by WebViewGuest to check which StoragePartition should be
used by a webview or a controlled frame. This allows IWAs and Chrome
Apps to separate their StoragePartition assignment logic.

Bug: 1311065
Change-Id: I1bea478ca340d9b8c97c873de5da2217ef8e1b6e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4241880
Reviewed-by: Chase Phillips <cmp@chromium.org>
Commit-Queue: Robbie McElrath <rmcelrath@chromium.org>
Reviewed-by: Ovidio Ruiz-Henríquez <odejesush@chromium.org>
Reviewed-by: Kevin McNee <mcnee@chromium.org>
Reviewed-by: David Bertoni <dbertoni@chromium.org>
Reviewed-by: Zelin Liu <zelin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1106663}
  • Loading branch information
robbiemc authored and Chromium LUCI CQ committed Feb 17, 2023
1 parent 18a1a7d commit f01dda1
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 29 deletions.
21 changes: 21 additions & 0 deletions chrome/browser/extensions/chrome_extensions_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
#include "chrome/browser/usb/usb_chooser_context.h"
#include "chrome/browser/usb/usb_chooser_context_factory.h"
#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
#include "chrome/common/channel_info.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
Expand All @@ -73,6 +74,7 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/common/content_switches.h"
#include "extensions/browser/api/content_settings/content_settings_service.h"
#include "extensions/browser/api/core_extensions_browser_api_provider.h"
Expand Down Expand Up @@ -893,4 +895,23 @@ void ChromeExtensionsBrowserClient::AddAPIActionOrEventToActivityLog(
AddActionToExtensionActivityLog(browser_context, action);
}

content::StoragePartitionConfig
ChromeExtensionsBrowserClient::GetWebViewStoragePartitionConfig(
content::BrowserContext* browser_context,
content::SiteInstance* owner_site_instance,
const std::string& partition_name,
bool in_memory) {
const GURL& owner_site_url = owner_site_instance->GetSiteURL();
if (owner_site_url.SchemeIs(chrome::kIsolatedAppScheme)) {
base::expected<web_app::IsolatedWebAppUrlInfo, std::string> url_info =
web_app::IsolatedWebAppUrlInfo::Create(owner_site_url);
DCHECK(url_info.has_value()) << url_info.error();
return url_info->GetStoragePartitionConfigForControlledFrame(
browser_context, partition_name, in_memory);
}

return ExtensionsBrowserClient::GetWebViewStoragePartitionConfig(
browser_context, owner_site_instance, partition_name, in_memory);
}

} // namespace extensions
5 changes: 5 additions & 0 deletions chrome/browser/extensions/chrome_extensions_browser_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,11 @@ class ChromeExtensionsBrowserClient : public ExtensionsBrowserClient {
const GURL& url,
const std::u16string& url_title,
int call_type) override;
content::StoragePartitionConfig GetWebViewStoragePartitionConfig(
content::BrowserContext* browser_context,
content::SiteInstance* owner_site_instance,
const std::string& partition_name,
bool in_memory) override;

private:
friend struct base::LazyInstanceTraitsBase<ChromeExtensionsBrowserClient>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,28 @@ const web_package::SignedWebBundleId& IsolatedWebAppUrlInfo::web_bundle_id()
content::StoragePartitionConfig IsolatedWebAppUrlInfo::storage_partition_config(
content::BrowserContext* browser_context) const {
DCHECK(browser_context != nullptr);
return content::StoragePartitionConfig::Create(browser_context,
partition_domain(),
/*partition_name=*/"",
/*in_memory=*/false);
}

content::StoragePartitionConfig
IsolatedWebAppUrlInfo::GetStoragePartitionConfigForControlledFrame(
content::BrowserContext* browser_context,
const std::string& partition_name,
bool in_memory) const {
DCHECK(browser_context);
DCHECK(!partition_name.empty() || in_memory);
return content::StoragePartitionConfig::Create(
browser_context, partition_domain(), partition_name, in_memory);
}

std::string IsolatedWebAppUrlInfo::partition_domain() const {
constexpr char kIsolatedWebAppPartitionPrefix[] = "iwa-";
// We add a prefix to `partition_domain` to avoid potential name conflicts
// with Chrome Apps, which use their id/hostname as `partition_domain`.
return content::StoragePartitionConfig::Create(
browser_context,
/*partition_domain=*/kIsolatedWebAppPartitionPrefix + origin().host(),
/*partition_name=*/"",
/*in_memory=*/false);
return kIsolatedWebAppPartitionPrefix + origin().host();
}

} // namespace web_app
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,19 @@ class IsolatedWebAppUrlInfo {
content::StoragePartitionConfig storage_partition_config(
content::BrowserContext* browser_context) const;

// Returns the StoragePartitionConfig that should be used by a controlled
// frame within the IWA represented by this object.
content::StoragePartitionConfig GetStoragePartitionConfigForControlledFrame(
content::BrowserContext* browser_context,
const std::string& partition_name,
bool in_memory) const;

private:
explicit IsolatedWebAppUrlInfo(
const web_package::SignedWebBundleId& web_bundle_id);

std::string partition_domain() const;

url::Origin origin_;
AppId app_id_;
web_package::SignedWebBundleId web_bundle_id_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,24 @@ TEST_F(IsolatedWebAppUrlInfoTest, WebBundleIdIsCorrect) {
Eq("aerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic"));
}

TEST_F(IsolatedWebAppUrlInfoTest, GetStoragePartitionConfigForControlledFrame) {
content::BrowserTaskEnvironment task_environment;
TestingProfile testing_profile;

base::expected<IsolatedWebAppUrlInfo, std::string> url_info =
IsolatedWebAppUrlInfo::Create(GURL(kValidIsolatedWebAppUrl));
content::StoragePartitionConfig iwa_config =
url_info->storage_partition_config(&testing_profile);
content::StoragePartitionConfig frame_config =
url_info->GetStoragePartitionConfigForControlledFrame(
&testing_profile, "name", /*in_memory=*/false);

EXPECT_THAT(frame_config.partition_domain(),
Eq(iwa_config.partition_domain()));
EXPECT_THAT(frame_config.partition_name(), Eq("name"));
EXPECT_FALSE(frame_config.in_memory());
}

TEST_F(IsolatedWebAppUrlInfoTest, StoragePartitionConfigUsesOrigin) {
content::BrowserTaskEnvironment task_environment;
TestingProfile testing_profile;
Expand Down
36 changes: 36 additions & 0 deletions extensions/browser/extensions_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
#include "components/update_client/update_client.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/storage_partition_config.h"
#include "extensions/browser/extension_api_frame_id_map.h"
#include "extensions/browser/extension_error.h"
#include "extensions/browser/updater/scoped_extension_updater_keep_alive.h"
#include "extensions/common/constants.h"
#include "extensions/common/permissions/permission_set.h"
#include "url/gurl.h"

namespace extensions {

Expand Down Expand Up @@ -197,4 +202,35 @@ void ExtensionsBrowserClient::AddDOMActionToActivityLog(
const std::u16string& url_title,
int call_type) {}

content::StoragePartitionConfig
ExtensionsBrowserClient::GetWebViewStoragePartitionConfig(
content::BrowserContext* browser_context,
content::SiteInstance* owner_site_instance,
const std::string& partition_name,
bool in_memory) {
const GURL& owner_site_url = owner_site_instance->GetSiteURL();
auto partition_config = content::StoragePartitionConfig::Create(
browser_context, owner_site_url.host(), partition_name, in_memory);

if (owner_site_url.SchemeIs(extensions::kExtensionScheme)) {
const auto& owner_config = owner_site_instance->GetStoragePartitionConfig();
#if DCHECK_IS_ON()
if (browser_context->IsOffTheRecord()) {
DCHECK(owner_config.in_memory());
}
#endif
if (!owner_config.is_default()) {
partition_config.set_fallback_to_partition_domain_for_blob_urls(
owner_config.in_memory()
? content::StoragePartitionConfig::FallbackMode::
kFallbackPartitionInMemory
: content::StoragePartitionConfig::FallbackMode::
kFallbackPartitionOnDisk);
DCHECK_EQ(owner_config,
partition_config.GetFallbackForBlobUrls().value());
}
}
return partition_config;
}

} // namespace extensions
12 changes: 11 additions & 1 deletion extensions/browser/extensions_browser_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "content/public/browser/bluetooth_chooser.h"
#include "content/public/browser/storage_partition_config.h"
#include "extensions/browser/extension_event_histogram_value.h"
#include "extensions/browser/extension_prefs_observer.h"
#include "extensions/browser/extensions_browser_api_provider.h"
Expand All @@ -41,6 +40,8 @@ class FilePath;
namespace content {
class BrowserContext;
class RenderFrameHost;
class SiteInstance;
class StoragePartitionConfig;
class WebContents;
} // namespace content

Expand Down Expand Up @@ -493,6 +494,15 @@ class ExtensionsBrowserClient {
const std::u16string& url_title,
int call_type);

// Returns the StoragePartitionConfig that should be used for a <webview> or
// <controlledframe> with the given |partition_name| that is owned by a frame
// within |owner_site_instance|.
virtual content::StoragePartitionConfig GetWebViewStoragePartitionConfig(
content::BrowserContext* browser_context,
content::SiteInstance* owner_site_instance,
const std::string& partition_name,
bool in_memory);

private:
std::vector<std::unique_ptr<ExtensionsBrowserAPIProvider>> providers_;
};
Expand Down
31 changes: 8 additions & 23 deletions extensions/browser/guest_view/web_view/web_view_guest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,10 @@ int WebViewGuest::GetOrGenerateRulesRegistryID(int embedder_process_id,
void WebViewGuest::CreateWebContents(std::unique_ptr<GuestViewBase> owned_this,
const base::Value::Dict& create_params,
WebContentsCreatedCallback callback) {
RenderFrameHost* owner_render_frame_host =
owner_web_contents()->GetPrimaryMainFrame();
RenderProcessHost* owner_render_process_host =
owner_web_contents()->GetPrimaryMainFrame()->GetProcess();
owner_render_frame_host->GetProcess();
DCHECK_EQ(browser_context(), owner_render_process_host->GetBrowserContext());

std::string storage_partition_id;
Expand All @@ -325,28 +327,11 @@ void WebViewGuest::CreateWebContents(std::unique_ptr<GuestViewBase> owned_this,
std::move(callback).Run(std::move(owned_this), nullptr);
return;
}
std::string partition_domain = GetOwnerSiteURL().host();
auto partition_config = content::StoragePartitionConfig::Create(
browser_context(), partition_domain, storage_partition_id,
!persist_storage /* in_memory */);

if (GetOwnerSiteURL().SchemeIs(extensions::kExtensionScheme)) {
auto owner_config =
extensions::util::GetStoragePartitionConfigForExtensionId(
GetOwnerSiteURL().host(), browser_context());
if (browser_context()->IsOffTheRecord()) {
DCHECK(owner_config.in_memory());
}
if (!owner_config.is_default()) {
partition_config.set_fallback_to_partition_domain_for_blob_urls(
owner_config.in_memory()
? content::StoragePartitionConfig::FallbackMode::
kFallbackPartitionInMemory
: content::StoragePartitionConfig::FallbackMode::
kFallbackPartitionOnDisk);
DCHECK(owner_config == partition_config.GetFallbackForBlobUrls().value());
}
}

content::StoragePartitionConfig partition_config =
ExtensionsBrowserClient::Get()->GetWebViewStoragePartitionConfig(
browser_context(), owner_render_frame_host->GetSiteInstance(),
storage_partition_id, /*in_memory=*/!persist_storage);

// If we already have a webview tag in the same app using the same storage
// partition, we should use the same SiteInstance so the existing tag and
Expand Down

0 comments on commit f01dda1

Please sign in to comment.