Store tab_strip scope_patterns field in web_app_database
Bug: 1381374
Change-Id: If803e582bc1b57154fd279a8846005fff41983fe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4530101
Reviewed-by: Ben Kelly <[email protected]>
Reviewed-by: Alan Cutter <[email protected]>
Commit-Queue: Ben Kelly <[email protected]>
Auto-Submit: Louise Brett <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1144751}
diff --git a/chrome/browser/web_applications/DEPS b/chrome/browser/web_applications/DEPS
index 242c13f..b15f1b0 100644
--- a/chrome/browser/web_applications/DEPS
+++ b/chrome/browser/web_applications/DEPS
@@ -9,5 +9,6 @@
"+mojo/public/cpp/bindings",
"+services/network/public/cpp",
"+third_party/blink/public/common",
+ "+third_party/liburlpattern",
"+url",
}
diff --git a/chrome/browser/web_applications/proto/BUILD.gn b/chrome/browser/web_applications/proto/BUILD.gn
index f3d25488..dcb3712 100644
--- a/chrome/browser/web_applications/proto/BUILD.gn
+++ b/chrome/browser/web_applications/proto/BUILD.gn
@@ -13,6 +13,7 @@
"web_app_share_target.proto",
"web_app_tab_strip.proto",
"web_app_translations.proto",
+ "web_app_url_pattern.proto",
]
link_deps = [
"//chrome/browser/ash/system_web_apps/types/proto",
diff --git a/chrome/browser/web_applications/proto/web_app_tab_strip.proto b/chrome/browser/web_applications/proto/web_app_tab_strip.proto
index 55d20bf..ee7aef5a 100644
--- a/chrome/browser/web_applications/proto/web_app_tab_strip.proto
+++ b/chrome/browser/web_applications/proto/web_app_tab_strip.proto
@@ -5,6 +5,7 @@
syntax = "proto2";
import "content/browser/background_fetch/background_fetch.proto";
+import "chrome/browser/web_applications/proto/web_app_url_pattern.proto";
option optimize_for = LITE_RUNTIME;
@@ -12,6 +13,7 @@
message HomeTabParams {
repeated content.proto.ImageResource icons = 1;
+ repeated UrlPattern scope_patterns = 2;
}
message NewTabButtonParams {
diff --git a/chrome/browser/web_applications/proto/web_app_url_pattern.proto b/chrome/browser/web_applications/proto/web_app_url_pattern.proto
new file mode 100644
index 0000000..0c9c771
--- /dev/null
+++ b/chrome/browser/web_applications/proto/web_app_url_pattern.proto
@@ -0,0 +1,39 @@
+// 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package web_app.proto;
+
+// Proto represtenting a UrlPattern. This should be kept up to date with
+// third_party/blink/public/common/url_pattern.h
+message UrlPattern {
+ repeated UrlPatternPart pathname = 1;
+}
+
+message UrlPatternPart {
+ enum PartType {
+ UNKNOWN_PART_TYPE = 0;
+ FULL_WILDCARD = 1;
+ SEGMENT_WILDCARD = 2;
+ FIXED = 3;
+ }
+ optional PartType part_type = 1;
+
+ optional string name = 2;
+ optional string prefix = 3;
+ optional string value = 4;
+ optional string suffix = 5;
+
+ enum Modifier {
+ UNKNOWN_MODIFIER = 0;
+ ZERO_OR_MORE = 1;
+ OPTIONAL = 2;
+ ONE_OR_MORE = 3;
+ NONE = 4;
+ }
+ optional Modifier modifier = 6;
+}
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.cc b/chrome/browser/web_applications/test/web_app_test_utils.cc
index 3cffcd9..8620373 100644
--- a/chrome/browser/web_applications/test/web_app_test_utils.cc
+++ b/chrome/browser/web_applications/test/web_app_test_utils.cc
@@ -71,7 +71,9 @@
#include "third_party/blink/public/common/permissions_policy/permissions_policy.h"
#include "third_party/blink/public/common/permissions_policy/policy_helper_public.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
+#include "third_party/blink/public/common/url_pattern.h"
#include "third_party/blink/public/mojom/manifest/capture_links.mojom-shared.h"
+#include "third_party/liburlpattern/pattern.h"
#include "third_party/skia/include/core/SkColor.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -383,6 +385,42 @@
return icons;
}
+std::vector<blink::UrlPattern> CreateRandomScopePatterns(RandomHelper& random) {
+ std::vector<blink::UrlPattern> scope_patterns;
+
+ for (int i = random.next_uint(4) + 1; i >= 0; --i) {
+ blink::UrlPattern url_pattern;
+
+ for (int j = random.next_uint(4) + 1; j >= 0; --j) {
+ liburlpattern::Part part;
+
+ std::vector<liburlpattern::PartType> part_types = {
+ liburlpattern::PartType::kFixed,
+ liburlpattern::PartType::kFullWildcard,
+ liburlpattern::PartType::kSegmentWildcard};
+ std::vector<liburlpattern::Modifier> modifiers = {
+ liburlpattern::Modifier::kZeroOrMore,
+ liburlpattern::Modifier::kOptional,
+ liburlpattern::Modifier::kOneOrMore, liburlpattern::Modifier::kNone};
+ part.type = part_types[random.next_uint(part_types.size())];
+ part.value = "value" + base::NumberToString(j);
+ if (part.type == liburlpattern::PartType::kFullWildcard ||
+ part.type == liburlpattern::PartType::kSegmentWildcard) {
+ part.prefix = "prefix" + base::NumberToString(j);
+ part.name = "name" + base::NumberToString(j);
+ part.suffix = "suffix" + base::NumberToString(j);
+ }
+
+ part.modifier = modifiers[random.next_uint(modifiers.size())];
+
+ url_pattern.pathname.push_back(std::move(part));
+ }
+
+ scope_patterns.push_back(std::move(url_pattern));
+ }
+ return scope_patterns;
+}
+
proto::WebAppOsIntegrationState GenerateRandomWebAppOsIntegrationState(
RandomHelper& random,
WebApp& app) {
@@ -828,6 +866,9 @@
if (random.next_bool()) {
home_tab_params.icons = CreateRandomHomeTabIcons(random);
}
+ if (random.next_bool()) {
+ home_tab_params.scope_patterns = CreateRandomScopePatterns(random);
+ }
tab_strip.home_tab = std::move(home_tab_params);
} else {
tab_strip.home_tab =
diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h
index d7a0a51..fbc1eab 100644
--- a/chrome/browser/web_applications/web_app.h
+++ b/chrome/browser/web_applications/web_app.h
@@ -566,6 +566,8 @@
// like is_placeholder and install URLs.
ExternalConfigMap management_to_external_config_map_;
+ // TODO(crbug.com/1381374): Add to AsDebugValue() and
+ // GetManifestDataChanges().
absl::optional<blink::Manifest::TabStrip> tab_strip_;
// Only used on Mac.
diff --git a/chrome/browser/web_applications/web_app_database.cc b/chrome/browser/web_applications/web_app_database.cc
index 803630c..41a79c4 100644
--- a/chrome/browser/web_applications/web_app_database.cc
+++ b/chrome/browser/web_applications/web_app_database.cc
@@ -21,6 +21,7 @@
#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
#include "chrome/browser/web_applications/os_integration/web_app_file_handler_manager.h"
#include "chrome/browser/web_applications/proto/web_app.pb.h"
+#include "chrome/browser/web_applications/proto/web_app_url_pattern.pb.h"
#include "chrome/browser/web_applications/user_display_mode.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_chromeos_data.h"
@@ -44,8 +45,10 @@
#include "third_party/blink/public/common/manifest/manifest.h"
#include "third_party/blink/public/common/permissions_policy/origin_with_possible_wildcards.h"
#include "third_party/blink/public/common/permissions_policy/policy_helper_public.h"
+#include "third_party/blink/public/common/url_pattern.h"
#include "third_party/blink/public/mojom/manifest/capture_links.mojom.h"
#include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
+#include "third_party/blink/public/mojom/url_pattern.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -303,16 +306,6 @@
}
}
-TabStrip::Visibility ProtoToTabStripVisibility(
- proto::TabStrip::Visibility visibility) {
- switch (visibility) {
- case proto::TabStrip_Visibility_AUTO:
- return TabStrip::Visibility::kAuto;
- case proto::TabStrip_Visibility_ABSENT:
- return TabStrip::Visibility::kAbsent;
- }
-}
-
std::string FilePathToProto(const base::FilePath& path) {
base::Pickle pickle;
path.WriteToPickle(&pickle);
@@ -772,12 +765,21 @@
} else {
auto* mutable_home_tab_params =
mutable_tab_strip->mutable_home_tab_params();
- absl::optional<std::vector<blink::Manifest::ImageResource>> icons =
+
+ const absl::optional<std::vector<blink::Manifest::ImageResource>>& icons =
absl::get<blink::Manifest::HomeTabParams>(tab_strip.home_tab).icons;
for (const auto& image_resource : *icons) {
*(mutable_home_tab_params->add_icons()) =
AppImageResourceToProto(image_resource);
}
+
+ const std::vector<blink::UrlPattern>& scope_patterns =
+ absl::get<blink::Manifest::HomeTabParams>(tab_strip.home_tab)
+ .scope_patterns;
+ for (const auto& pattern : scope_patterns) {
+ *(mutable_home_tab_params->add_scope_patterns()) =
+ ToUrlPatternProto(pattern);
+ }
}
if (absl::holds_alternative<TabStrip::Visibility>(
@@ -1478,33 +1480,7 @@
web_app->SetWebAppManagementExternalConfigMap(management_to_external_config);
if (local_data.has_tab_strip()) {
- TabStrip tab_strip;
- if (local_data.tab_strip().has_home_tab_visibility()) {
- tab_strip.home_tab = ProtoToTabStripVisibility(
- local_data.tab_strip().home_tab_visibility());
- } else {
- absl::optional<std::vector<blink::Manifest::ImageResource>> icons =
- ParseAppImageResource(
- "WebApp", local_data.tab_strip().home_tab_params().icons());
- blink::Manifest::HomeTabParams home_tab_params;
- if (!icons->empty()) {
- home_tab_params.icons = std::move(*icons);
- }
- tab_strip.home_tab = std::move(home_tab_params);
- }
-
- if (local_data.tab_strip().has_new_tab_button_visibility()) {
- tab_strip.new_tab_button = ProtoToTabStripVisibility(
- local_data.tab_strip().new_tab_button_visibility());
- } else {
- blink::Manifest::NewTabButtonParams new_tab_button_params;
- if (local_data.tab_strip().new_tab_button_params().has_url()) {
- new_tab_button_params.url =
- GURL(local_data.tab_strip().new_tab_button_params().url());
- }
- tab_strip.new_tab_button = new_tab_button_params;
- }
- web_app->SetTabStrip(std::move(tab_strip));
+ web_app->SetTabStrip(ProtoToTabStrip(local_data.tab_strip()));
}
if (local_data.has_current_os_integration_states()) {
diff --git a/chrome/browser/web_applications/web_app_proto_utils.cc b/chrome/browser/web_applications/web_app_proto_utils.cc
index 4cb6695..7cd03d57 100644
--- a/chrome/browser/web_applications/web_app_proto_utils.cc
+++ b/chrome/browser/web_applications/web_app_proto_utils.cc
@@ -5,10 +5,12 @@
#include "chrome/browser/web_applications/web_app_proto_utils.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
+#include "chrome/browser/web_applications/proto/web_app_url_pattern.pb.h"
#include "chrome/browser/web_applications/user_display_mode.h"
#include "components/services/app_service/public/cpp/icon_info.h"
#include "third_party/blink/public/common/manifest/manifest.h"
#include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
+#include "third_party/liburlpattern/pattern.h"
#include "ui/gfx/geometry/size.h"
namespace web_app {
@@ -56,6 +58,75 @@
}
}
+proto::UrlPatternPart::Modifier UrlPatternModifierToProto(
+ liburlpattern::Modifier modifier) {
+ switch (modifier) {
+ case liburlpattern::Modifier::kZeroOrMore:
+ return proto::UrlPatternPart_Modifier_ZERO_OR_MORE;
+ case liburlpattern::Modifier::kOptional:
+ return proto::UrlPatternPart_Modifier_OPTIONAL;
+ case liburlpattern::Modifier::kOneOrMore:
+ return proto::UrlPatternPart_Modifier_ONE_OR_MORE;
+ case liburlpattern::Modifier::kNone:
+ return proto::UrlPatternPart_Modifier_NONE;
+ }
+}
+
+absl::optional<liburlpattern::Modifier> ProtoToUrlPatternModifier(
+ proto::UrlPatternPart::Modifier modifier) {
+ switch (modifier) {
+ case proto::UrlPatternPart_Modifier_UNKNOWN_MODIFIER:
+ return absl::nullopt;
+ case proto::UrlPatternPart_Modifier_ZERO_OR_MORE:
+ return liburlpattern::Modifier::kZeroOrMore;
+ case proto::UrlPatternPart_Modifier_OPTIONAL:
+ return liburlpattern::Modifier::kOptional;
+ case proto::UrlPatternPart_Modifier_ONE_OR_MORE:
+ return liburlpattern::Modifier::kOneOrMore;
+ case proto::UrlPatternPart_Modifier_NONE:
+ return liburlpattern::Modifier::kNone;
+ }
+}
+
+proto::UrlPatternPart::PartType UrlPatternPartTypeToProto(
+ liburlpattern::PartType part_type) {
+ switch (part_type) {
+ case liburlpattern::PartType::kRegex:
+ NOTREACHED();
+ [[fallthrough]];
+ case liburlpattern::PartType::kFullWildcard:
+ return proto::UrlPatternPart_PartType_FULL_WILDCARD;
+ case liburlpattern::PartType::kSegmentWildcard:
+ return proto::UrlPatternPart_PartType_SEGMENT_WILDCARD;
+ case liburlpattern::PartType::kFixed:
+ return proto::UrlPatternPart_PartType_FIXED;
+ }
+}
+
+absl::optional<liburlpattern::PartType> ProtoToUrlPatternPartType(
+ proto::UrlPatternPart::PartType part_type) {
+ switch (part_type) {
+ case proto::UrlPatternPart_PartType_UNKNOWN_PART_TYPE:
+ return absl::nullopt;
+ case proto::UrlPatternPart_PartType_FULL_WILDCARD:
+ return liburlpattern::PartType::kFullWildcard;
+ case proto::UrlPatternPart_PartType_SEGMENT_WILDCARD:
+ return liburlpattern::PartType::kSegmentWildcard;
+ case proto::UrlPatternPart_PartType_FIXED:
+ return liburlpattern::PartType::kFixed;
+ }
+}
+
+TabStrip::Visibility ProtoToTabStripVisibility(
+ proto::TabStrip::Visibility visibility) {
+ switch (visibility) {
+ case proto::TabStrip_Visibility_AUTO:
+ return TabStrip::Visibility::kAuto;
+ case proto::TabStrip_Visibility_ABSENT:
+ return TabStrip::Visibility::kAbsent;
+ }
+}
+
} // namespace
absl::optional<std::vector<apps::IconInfo>> ParseAppIconInfos(
@@ -297,4 +368,118 @@
}
}
+absl::optional<blink::UrlPattern> ToUrlPattern(
+ const proto::UrlPattern& proto_url_pattern) {
+ blink::UrlPattern url_pattern;
+
+ for (const proto::UrlPatternPart& proto_part : proto_url_pattern.pathname()) {
+ liburlpattern::Part part;
+
+ if (!proto_part.has_part_type()) {
+ DLOG(ERROR) << "WebApp UrlPattern Part has missing type";
+ continue;
+ }
+ absl::optional<liburlpattern::PartType> opt_part_type =
+ ProtoToUrlPatternPartType(proto_part.part_type());
+ if (!opt_part_type.has_value()) {
+ return absl::nullopt;
+ }
+ part.type = opt_part_type.value();
+
+ if (!proto_part.has_value()) {
+ DLOG(ERROR) << "WebApp UrlPattern Part has missing value";
+ continue;
+ }
+ part.value = proto_part.value();
+
+ if (!proto_part.has_modifier()) {
+ DLOG(ERROR) << "WebApp UrlPattern Part has missing type";
+ continue;
+ }
+
+ absl::optional<liburlpattern::Modifier> opt_modifier =
+ ProtoToUrlPatternModifier(proto_part.modifier());
+ if (!opt_modifier.has_value()) {
+ return absl::nullopt;
+ }
+ part.modifier = opt_modifier.value();
+
+ if (proto_part.has_name()) {
+ part.name = proto_part.name();
+ }
+
+ if (proto_part.has_prefix()) {
+ part.prefix = proto_part.prefix();
+ }
+
+ if (proto_part.has_suffix()) {
+ part.suffix = proto_part.suffix();
+ }
+
+ url_pattern.pathname.push_back(std::move(part));
+ }
+ return url_pattern;
+}
+
+proto::UrlPattern ToUrlPatternProto(const blink::UrlPattern& url_pattern) {
+ proto::UrlPattern url_pattern_proto;
+ for (const auto& part : url_pattern.pathname) {
+ proto::UrlPatternPart* url_pattern_part_proto =
+ url_pattern_proto.add_pathname();
+
+ url_pattern_part_proto->set_name(part.name);
+ url_pattern_part_proto->set_prefix(part.prefix);
+ url_pattern_part_proto->set_value(part.value);
+ url_pattern_part_proto->set_suffix(part.suffix);
+
+ url_pattern_part_proto->set_part_type(UrlPatternPartTypeToProto(part.type));
+ url_pattern_part_proto->set_modifier(
+ UrlPatternModifierToProto(part.modifier));
+ }
+ return url_pattern_proto;
+}
+
+absl::optional<TabStrip> ProtoToTabStrip(proto::TabStrip tab_strip_proto) {
+ TabStrip tab_strip;
+ if (tab_strip_proto.has_home_tab_visibility()) {
+ tab_strip.home_tab =
+ ProtoToTabStripVisibility(tab_strip_proto.home_tab_visibility());
+ } else {
+ absl::optional<std::vector<blink::Manifest::ImageResource>> icons =
+ ParseAppImageResource("WebApp",
+ tab_strip_proto.home_tab_params().icons());
+ blink::Manifest::HomeTabParams home_tab_params;
+ if (!icons->empty()) {
+ home_tab_params.icons = std::move(*icons);
+ }
+
+ std::vector<blink::UrlPattern> scope_patterns;
+ for (const proto::UrlPattern& proto_url_pattern :
+ tab_strip_proto.home_tab_params().scope_patterns()) {
+ absl::optional<blink::UrlPattern> url_pattern =
+ ToUrlPattern(proto_url_pattern);
+ if (!url_pattern) {
+ return absl::nullopt;
+ }
+ scope_patterns.push_back(url_pattern.value());
+ }
+ home_tab_params.scope_patterns = std::move(scope_patterns);
+
+ tab_strip.home_tab = std::move(home_tab_params);
+ }
+
+ if (tab_strip_proto.has_new_tab_button_visibility()) {
+ tab_strip.new_tab_button =
+ ProtoToTabStripVisibility(tab_strip_proto.new_tab_button_visibility());
+ } else {
+ blink::Manifest::NewTabButtonParams new_tab_button_params;
+ if (tab_strip_proto.new_tab_button_params().has_url()) {
+ new_tab_button_params.url =
+ GURL(tab_strip_proto.new_tab_button_params().url());
+ }
+ tab_strip.new_tab_button = new_tab_button_params;
+ }
+ return tab_strip;
+}
+
} // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_proto_utils.h b/chrome/browser/web_applications/web_app_proto_utils.h
index a07227e..70f01aa 100644
--- a/chrome/browser/web_applications/web_app_proto_utils.h
+++ b/chrome/browser/web_applications/web_app_proto_utils.h
@@ -8,10 +8,13 @@
#include <vector>
#include "chrome/browser/web_applications/proto/web_app.pb.h"
+#include "chrome/browser/web_applications/proto/web_app_tab_strip.pb.h"
+#include "chrome/browser/web_applications/proto/web_app_url_pattern.pb.h"
#include "chrome/browser/web_applications/web_app.h"
#include "components/sync/protocol/web_app_specifics.pb.h"
#include "content/browser/background_fetch/background_fetch.pb.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/public/common/url_pattern.h"
namespace apps {
struct IconInfo;
@@ -56,6 +59,13 @@
WebAppProto::RunOnOsLoginMode ToWebAppProtoRunOnOsLoginMode(
RunOnOsLoginMode mode);
+absl::optional<blink::UrlPattern> ToUrlPattern(
+ const proto::UrlPattern& proto_url_pattern);
+
+proto::UrlPattern ToUrlPatternProto(const blink::UrlPattern& url_pattern);
+
+absl::optional<TabStrip> ProtoToTabStrip(proto::TabStrip tab_strip_proto);
+
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_PROTO_UTILS_H_