Skip to content

Commit

Permalink
Persist scope_extensions to web app database
Browse files Browse the repository at this point in the history
These changes persist the 'scope_extensions' info in the web app
manifest to the web app database after it is parsed by the manifest
parser. This feature will allow progressive web apps to extend their
scope.

Design Doc: https://docs.google.com/document/d/1-idhx8heajbPYl3cdXFVCjpIuf96cRa_DrRk6147ELI/edit?usp=sharing

Prototype CL: https://chromium-review.googlesource.com/c/chromium/src/+/4034807

Chrome Status: https://chromestatus.com/feature/5746537956114432

Bug: 1250011

Change-Id: Ie2e013f039c33a41bd9db451095e343f44e01e80
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4198368
Reviewed-by: Alan Cutter <alancutter@chromium.org>
Commit-Queue: Alan Cutter <alancutter@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1104812}
  • Loading branch information
LuHuangMSFT authored and Chromium LUCI CQ committed Feb 14, 2023
1 parent 6d05f33 commit ef9a1cf
Show file tree
Hide file tree
Showing 14 changed files with 302 additions and 38 deletions.
2 changes: 2 additions & 0 deletions chrome/browser/web_applications/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ source_set("web_applications") {
"preinstalled_web_apps/preinstalled_web_app_definition_utils.h",
"preinstalled_web_apps/preinstalled_web_apps.cc",
"preinstalled_web_apps/preinstalled_web_apps.h",
"scope_extension_info.cc",
"scope_extension_info.h",
"user_display_mode.cc",
"user_display_mode.h",
"user_uninstalled_preinstalled_web_app_prefs.cc",
Expand Down
8 changes: 8 additions & 0 deletions chrome/browser/web_applications/proto/web_app.proto
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ message WebAppUrlHandlerProto {
required bool has_origin_wildcard = 2;
}

message WebAppScopeExtensionProto {
required string origin = 1;
required bool has_origin_wildcard = 2;
}

// A set to track simultaneous installs and uninstalls from multiple install
// sources. This should stay in sync with |WebAppManagement| in
// chrome/browser/web_applications/web_app_constants.h
Expand Down Expand Up @@ -397,4 +402,7 @@ message WebAppProto {
// If present, signals that this app is an Isolated Web App, and contains
// IWA-specific information like bundle location.
optional IsolationDataProto isolation_data = 60;

// Contains web origins that are part of the app's extended scope.
repeated WebAppScopeExtensionProto scope_extensions = 61;
}
42 changes: 42 additions & 0 deletions chrome/browser/web_applications/scope_extension_info.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <tuple>

#include "chrome/browser/web_applications/scope_extension_info.h"

namespace web_app {

ScopeExtensionInfo::ScopeExtensionInfo(const url::Origin& origin,
bool has_origin_wildcard)
: origin(origin), has_origin_wildcard(has_origin_wildcard) {}

base::Value ScopeExtensionInfo::AsDebugValue() const {
base::Value root(base::Value::Type::DICT);
root.SetStringKey("origin", origin.GetDebugString());
root.SetBoolKey("has_origin_wildcard", has_origin_wildcard);
return root;
}

bool operator==(const ScopeExtensionInfo& scope_extension1,
const ScopeExtensionInfo& scope_extension2) {
return scope_extension1.origin == scope_extension2.origin &&
scope_extension1.has_origin_wildcard ==
scope_extension2.has_origin_wildcard;
}

bool operator!=(const ScopeExtensionInfo& scope_extension1,
const ScopeExtensionInfo& scope_extension2) {
return !(scope_extension1 == scope_extension2);
}

bool operator<(const ScopeExtensionInfo& scope_extension1,
const ScopeExtensionInfo& scope_extension2) {
return std::tie(scope_extension1.origin,
scope_extension1.has_origin_wildcard) <
std::tie(scope_extension2.origin,
scope_extension2.has_origin_wildcard);
}

} // namespace web_app
50 changes: 50 additions & 0 deletions chrome/browser/web_applications/scope_extension_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_WEB_APPLICATIONS_SCOPE_EXTENSION_INFO_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_SCOPE_EXTENSION_INFO_H_

#include "base/values.h"
#include "url/origin.h"

namespace web_app {

// Contains information about a web app's scope extension information derived
// from its web app manifest.
struct ScopeExtensionInfo {
ScopeExtensionInfo() = default;
ScopeExtensionInfo(const url::Origin& origin, bool has_origin_wildcard);

// Copyable to support web_app::WebApp being copyable as it has a
// ScopeExtensions member variable.
ScopeExtensionInfo(const ScopeExtensionInfo&) = default;
ScopeExtensionInfo& operator=(const ScopeExtensionInfo&) = default;
// Movable to support being contained in std::vector, which requires value
// types to be copyable or movable.
ScopeExtensionInfo(ScopeExtensionInfo&&) = default;
ScopeExtensionInfo& operator=(ScopeExtensionInfo&&) = default;

~ScopeExtensionInfo() = default;

base::Value AsDebugValue() const;

url::Origin origin;

bool has_origin_wildcard = false;
};

bool operator==(const ScopeExtensionInfo& scope_extension1,
const ScopeExtensionInfo& scope_extension2);

bool operator!=(const ScopeExtensionInfo& scope_extension1,
const ScopeExtensionInfo& scope_extension2);

// Allow ScopeExtensionInfo to be used as a key in STL (for example, a std::set
// or std::map).
bool operator<(const ScopeExtensionInfo& scope_extension1,
const ScopeExtensionInfo& scope_extension2);

} // namespace web_app

#endif // CHROME_BROWSER_WEB_APPLICATIONS_SCOPE_EXTENSION_INFO_H_
21 changes: 21 additions & 0 deletions chrome/browser/web_applications/test/web_app_test_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,25 @@ std::vector<apps::UrlHandlerInfo> CreateRandomUrlHandlers(uint32_t suffix) {
return url_handlers;
}

std::vector<ScopeExtensionInfo> CreateRandomScopeExtensions(
uint32_t suffix,
RandomHelper& random) {
std::vector<ScopeExtensionInfo> scope_extensions;

for (unsigned int i = 0; i < 3; ++i) {
std::string suffix_str =
base::NumberToString(suffix) + base::NumberToString(i);

ScopeExtensionInfo scope_extension;
scope_extension.origin =
url::Origin::Create(GURL("https://app-" + suffix_str + ".com/"));
scope_extension.has_origin_wildcard = random.next_bool();
scope_extensions.push_back(std::move(scope_extension));
}

return scope_extensions;
}

std::vector<WebAppShortcutsMenuItemInfo> CreateRandomShortcutsMenuItemInfos(
const GURL& scope,
RandomHelper& random) {
Expand Down Expand Up @@ -566,6 +585,8 @@ std::unique_ptr<WebApp> CreateRandomWebApp(const GURL& base_url,
app->SetShareTarget(CreateRandomShareTarget(random.next_uint()));
app->SetProtocolHandlers(CreateRandomProtocolHandlers(random.next_uint()));
app->SetUrlHandlers(CreateRandomUrlHandlers(random.next_uint()));
app->SetScopeExtensions(
CreateRandomScopeExtensions(random.next_uint(), random));
if (random.next_bool()) {
app->SetLockScreenStartUrl(scope.Resolve(
"lock_screen_start_url" + base::NumberToString(random.next_uint())));
Expand Down
8 changes: 8 additions & 0 deletions chrome/browser/web_applications/web_app.cc
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,11 @@ void WebApp::SetUrlHandlers(apps::UrlHandlers url_handlers) {
url_handlers_ = std::move(url_handlers);
}

void WebApp::SetScopeExtensions(
std::vector<ScopeExtensionInfo> scope_extensions) {
scope_extensions_ = std::move(scope_extensions);
}

void WebApp::SetLockScreenStartUrl(const GURL& lock_screen_start_url) {
DCHECK(lock_screen_start_url.is_empty() || lock_screen_start_url.is_valid());
lock_screen_start_url_ = lock_screen_start_url;
Expand Down Expand Up @@ -727,6 +732,7 @@ bool WebApp::operator==(const WebApp& other) const {
app.allowed_launch_protocols_,
app.disallowed_launch_protocols_,
app.url_handlers_,
app.scope_extensions_,
app.lock_screen_start_url_,
app.note_taking_new_note_url_,
app.last_badging_time_,
Expand Down Expand Up @@ -990,6 +996,8 @@ base::Value WebApp::AsDebugValueWithOnlyPlatformAgnosticFields() const {

root.Set("url_handlers", ConvertDebugValueList(url_handlers_));

root.Set("scope_extensions", ConvertDebugValueList(scope_extensions_));

root.Set("user_display_mode",
user_display_mode_.has_value()
? ConvertUserDisplayModeToString(*user_display_mode_)
Expand Down
6 changes: 6 additions & 0 deletions chrome/browser/web_applications/web_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ class WebApp {

const apps::UrlHandlers& url_handlers() const { return url_handlers_; }

const std::vector<ScopeExtensionInfo>& scope_extensions() const {
return scope_extensions_;
}

RunOnOsLoginMode run_on_os_login_mode() const {
return run_on_os_login_mode_;
}
Expand Down Expand Up @@ -378,6 +382,7 @@ class WebApp {
void SetDisallowedLaunchProtocols(
base::flat_set<std::string> disallowed_launch_protocols);
void SetUrlHandlers(apps::UrlHandlers url_handlers);
void SetScopeExtensions(std::vector<ScopeExtensionInfo> scope_extensions);
void SetLockScreenStartUrl(const GURL& lock_screen_start_url);
void SetNoteTakingNewNoteUrl(const GURL& note_taking_new_note_url);
void SetLastBadgingTime(const base::Time& time);
Expand Down Expand Up @@ -481,6 +486,7 @@ class WebApp {
base::flat_set<std::string> disallowed_launch_protocols_;
// TODO(crbug.com/1072058): No longer aiming to ship, remove.
apps::UrlHandlers url_handlers_;
std::vector<ScopeExtensionInfo> scope_extensions_;
GURL lock_screen_start_url_;
GURL note_taking_new_note_url_;
base::Time last_badging_time_;
Expand Down
27 changes: 27 additions & 0 deletions chrome/browser/web_applications/web_app_database.cc
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,14 @@ std::unique_ptr<WebAppProto> WebAppDatabase::CreateWebAppProto(
url_handler_proto->set_has_origin_wildcard(url_handler.has_origin_wildcard);
}

for (const auto& scope_extension : web_app.scope_extensions()) {
WebAppScopeExtensionProto* scope_extension_proto =
local_data->add_scope_extensions();
scope_extension_proto->set_origin(scope_extension.origin.Serialize());
scope_extension_proto->set_has_origin_wildcard(
scope_extension.has_origin_wildcard);
}

if (web_app.lock_screen_start_url().is_valid()) {
local_data->set_lock_screen_start_url(
web_app.lock_screen_start_url().spec());
Expand Down Expand Up @@ -1273,6 +1281,25 @@ std::unique_ptr<WebApp> WebAppDatabase::CreateWebApp(
}
web_app->SetUrlHandlers(std::move(url_handlers));

std::vector<ScopeExtensionInfo> scope_extensions;
for (const auto& scope_extension_proto : local_data.scope_extensions()) {
ScopeExtensionInfo scope_extension;

url::Origin origin =
url::Origin::Create(GURL(scope_extension_proto.origin()));
if (origin.opaque()) {
DLOG(ERROR) << "WebApp ScopeExtension proto url parse error: "
<< origin.GetDebugString();
return nullptr;
}
scope_extension.origin = std::move(origin);
scope_extension.has_origin_wildcard =
scope_extension_proto.has_origin_wildcard();

scope_extensions.push_back(std::move(scope_extension));
}
web_app->SetScopeExtensions(std::move(scope_extensions));

if (local_data.has_lock_screen_start_url()) {
web_app->SetLockScreenStartUrl(GURL(local_data.lock_screen_start_url()));
}
Expand Down
3 changes: 3 additions & 0 deletions chrome/browser/web_applications/web_app_database_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "base/time/time.h"
#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
#include "chrome/browser/web_applications/proto/web_app.pb.h"
#include "chrome/browser/web_applications/scope_extension_info.h"
#include "chrome/browser/web_applications/test/fake_web_app_database_factory.h"
#include "chrome/browser/web_applications/test/fake_web_app_provider.h"
#include "chrome/browser/web_applications/test/web_app_test.h"
Expand Down Expand Up @@ -378,6 +379,7 @@ TEST_F(WebAppDatabaseTest, WebAppWithoutOptionalFields) {
EXPECT_TRUE(app->allowed_launch_protocols().empty());
EXPECT_TRUE(app->disallowed_launch_protocols().empty());
EXPECT_TRUE(app->url_handlers().empty());
EXPECT_TRUE(app->scope_extensions().empty());
EXPECT_TRUE(app->last_badging_time().is_null());
EXPECT_TRUE(app->last_launch_time().is_null());
EXPECT_TRUE(app->install_time().is_null());
Expand Down Expand Up @@ -449,6 +451,7 @@ TEST_F(WebAppDatabaseTest, WebAppWithoutOptionalFields) {
EXPECT_TRUE(app_copy->allowed_launch_protocols().empty());
EXPECT_TRUE(app_copy->disallowed_launch_protocols().empty());
EXPECT_TRUE(app_copy->url_handlers().empty());
EXPECT_TRUE(app_copy->scope_extensions().empty());
EXPECT_TRUE(app_copy->shortcuts_menu_item_infos().empty());
EXPECT_TRUE(app_copy->downloaded_shortcuts_menu_icons_sizes().empty());
EXPECT_EQ(app_copy->run_on_os_login_mode(), RunOnOsLoginMode::kNotRun);
Expand Down
5 changes: 5 additions & 0 deletions chrome/browser/web_applications/web_app_install_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "base/values.h"
#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
#include "chrome/browser/web_applications/scope_extension_info.h"
#include "components/services/app_service/public/cpp/file_handler.h"
#include "components/services/app_service/public/cpp/icon_info.h"
#include "components/services/app_service/public/cpp/protocol_handler_info.h"
Expand Down Expand Up @@ -295,6 +296,10 @@ struct WebAppInstallInfo {
// information.
apps::UrlHandlers url_handlers;

// The app intends to have an extended scope containing URLs described by this
// information.
std::vector<web_app::ScopeExtensionInfo> scope_extensions;

// URL within scope to launch on the lock screen for a "show on lock screen"
// action. Valid iff this is considered a lock-screen-capable app.
GURL lock_screen_start_url;
Expand Down
17 changes: 17 additions & 0 deletions chrome/browser/web_applications/web_app_install_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "chrome/browser/web_applications/os_integration/os_integration_manager.h"
#include "chrome/browser/web_applications/os_integration/web_app_file_handler_manager.h"
#include "chrome/browser/web_applications/policy/pre_redirection_url_observer.h"
#include "chrome/browser/web_applications/scope_extension_info.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_chromeos_data.h"
#include "chrome/browser/web_applications/web_app_constants.h"
Expand Down Expand Up @@ -308,6 +309,18 @@ apps::UrlHandlers ToWebAppUrlHandlers(
return apps_url_handlers;
}

std::vector<ScopeExtensionInfo> ToWebAppScopeExtensions(
const std::vector<blink::mojom::ManifestScopeExtensionPtr>&
scope_extensions) {
std::vector<ScopeExtensionInfo> apps_scope_extensions;
for (const auto& scope_extension : scope_extensions) {
DCHECK(scope_extension);
apps_scope_extensions.emplace_back(scope_extension->origin,
scope_extension->has_origin_wildcard);
}
return apps_scope_extensions;
}

std::vector<apps::ProtocolHandlerInfo> ToWebAppProtocolHandlers(
const std::vector<blink::mojom::ManifestProtocolHandlerPtr>&
manifest_protocol_handlers) {
Expand Down Expand Up @@ -669,6 +682,9 @@ void UpdateWebAppInfoFromManifest(const blink::mojom::Manifest& manifest,

web_app_info->url_handlers = ToWebAppUrlHandlers(manifest.url_handlers);

web_app_info->scope_extensions =
ToWebAppScopeExtensions(manifest.scope_extensions);

GURL inferred_scope = web_app_info->scope.is_valid() ? web_app_info->scope
: web_app_info->start_url.is_valid()
? web_app_info->start_url.GetWithoutFilename()
Expand Down Expand Up @@ -1178,6 +1194,7 @@ void SetWebAppManifestFields(const WebAppInstallInfo& web_app_info,
web_app.SetShareTarget(web_app_info.share_target);
web_app.SetProtocolHandlers(web_app_info.protocol_handlers);
web_app.SetUrlHandlers(web_app_info.url_handlers);
web_app.SetScopeExtensions(web_app_info.scope_extensions);

if (base::FeatureList::IsEnabled(features::kWebLockScreenApi))
web_app.SetLockScreenStartUrl(web_app_info.lock_screen_start_url);
Expand Down

0 comments on commit ef9a1cf

Please sign in to comment.