Commit 3cece5c7 authored by Eric Willigers's avatar Eric Willigers Committed by Commit Bot

Desktop PWAs: Detect share target changes in ManifestUpdateTask

WebApplicationInfo now uses apps::ShareTarget, for
easy detection of changes.


Note that ShareTarget is only implemented for web apps,
not bookmark apps.


Bug: 1127213
Change-Id: Iadba1cd798cc5f87c58c1af9ec1a12a66d3b60c9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2437994Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Reviewed-by: default avatarAlexey Baskakov <loyso@chromium.org>
Commit-Queue: Marc Treib <treib@chromium.org>
Auto-Submit: Eric Willigers <ericwilligers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812571}
parent 1d18f0b4
...@@ -2104,6 +2104,7 @@ static_library("browser") { ...@@ -2104,6 +2104,7 @@ static_library("browser") {
"//components/security_state/content", "//components/security_state/content",
"//components/security_state/core", "//components/security_state/core",
"//components/send_tab_to_self", "//components/send_tab_to_self",
"//components/services/app_service/public/cpp:intents",
"//components/services/heap_profiling", "//components/services/heap_profiling",
"//components/services/language_detection/public/cpp", "//components/services/language_detection/public/cpp",
"//components/services/language_detection/public/mojom", "//components/services/language_detection/public/mojom",
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
class GURL; class GURL;
class Profile; class Profile;
namespace apps {
struct ShareTarget;
}
namespace base { namespace base {
class Time; class Time;
} }
...@@ -92,6 +95,8 @@ class AppRegistrar { ...@@ -92,6 +95,8 @@ class AppRegistrar {
virtual const GURL& GetAppStartUrl(const AppId& app_id) const = 0; virtual const GURL& GetAppStartUrl(const AppId& app_id) const = 0;
virtual const std::string* GetAppLaunchQueryParams( virtual const std::string* GetAppLaunchQueryParams(
const AppId& app_id) const = 0; const AppId& app_id) const = 0;
virtual const apps::ShareTarget* GetAppShareTarget(
const AppId& app_id) const = 0;
// Returns the start_url with launch_query_params appended to the end if any. // Returns the start_url with launch_query_params appended to the end if any.
GURL GetAppLaunchUrl(const AppId& app_id) const; GURL GetAppLaunchUrl(const AppId& app_id) const;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "chrome/browser/web_applications/components/web_app_icon_generator.h" #include "chrome/browser/web_applications/components/web_app_icon_generator.h"
#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_features.h"
#include "chrome/common/web_application_info.h" #include "chrome/common/web_application_info.h"
#include "components/services/app_service/public/cpp/share_target.h"
#include "third_party/blink/public/common/manifest/manifest.h" #include "third_party/blink/public/common/manifest/manifest.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
...@@ -125,6 +126,65 @@ UpdateShortcutsMenuItemInfosFromManifest( ...@@ -125,6 +126,65 @@ UpdateShortcutsMenuItemInfosFromManifest(
return web_app_shortcut_infos; return web_app_shortcut_infos;
} }
apps::ShareTarget::Method ToAppsShareTargetMethod(
blink::Manifest::ShareTarget::Method method) {
switch (method) {
case blink::Manifest::ShareTarget::Method::kGet:
return apps::ShareTarget::Method::kGet;
case blink::Manifest::ShareTarget::Method::kPost:
return apps::ShareTarget::Method::kPost;
}
NOTREACHED();
}
apps::ShareTarget::Enctype ToAppsShareTargetEnctype(
blink::Manifest::ShareTarget::Enctype enctype) {
switch (enctype) {
case blink::Manifest::ShareTarget::Enctype::kFormUrlEncoded:
return apps::ShareTarget::Enctype::kFormUrlEncoded;
case blink::Manifest::ShareTarget::Enctype::kMultipartFormData:
return apps::ShareTarget::Enctype::kMultipartFormData;
}
NOTREACHED();
}
base::Optional<apps::ShareTarget> ToWebAppShareTarget(
const base::Optional<blink::Manifest::ShareTarget>& share_target) {
if (!share_target) {
return base::nullopt;
}
apps::ShareTarget apps_share_target;
apps_share_target.action = share_target->action;
apps_share_target.method = ToAppsShareTargetMethod(share_target->method);
apps_share_target.enctype = ToAppsShareTargetEnctype(share_target->enctype);
if (share_target->params.title.has_value()) {
apps_share_target.params.title =
base::UTF16ToUTF8(*share_target->params.title);
}
if (share_target->params.text.has_value()) {
apps_share_target.params.text =
base::UTF16ToUTF8(*share_target->params.text);
}
if (share_target->params.url.has_value()) {
apps_share_target.params.url = base::UTF16ToUTF8(*share_target->params.url);
}
for (const auto& file_filter : share_target->params.files) {
apps::ShareTarget::Files apps_share_target_files;
apps_share_target_files.name = base::UTF16ToUTF8(file_filter.name);
for (const auto& file_type : file_filter.accept) {
apps_share_target_files.accept.push_back(base::UTF16ToUTF8(file_type));
}
apps_share_target.params.files.push_back(
std::move(apps_share_target_files));
}
return std::move(apps_share_target);
}
} // namespace } // namespace
void UpdateWebAppInfoFromManifest(const blink::Manifest& manifest, void UpdateWebAppInfoFromManifest(const blink::Manifest& manifest,
...@@ -211,7 +271,7 @@ void UpdateWebAppInfoFromManifest(const blink::Manifest& manifest, ...@@ -211,7 +271,7 @@ void UpdateWebAppInfoFromManifest(const blink::Manifest& manifest,
web_app_info->file_handlers = manifest.file_handlers; web_app_info->file_handlers = manifest.file_handlers;
web_app_info->share_target = manifest.share_target; web_app_info->share_target = ToWebAppShareTarget(manifest.share_target);
web_app_info->protocol_handlers = manifest.protocol_handlers; web_app_info->protocol_handlers = manifest.protocol_handlers;
......
...@@ -203,6 +203,79 @@ TEST(WebAppInstallUtils, UpdateWebAppInfoFromManifest_MaskableIcon) { ...@@ -203,6 +203,79 @@ TEST(WebAppInstallUtils, UpdateWebAppInfoFromManifest_MaskableIcon) {
EXPECT_EQ(2, purpose_to_count[IconPurpose::MASKABLE]); EXPECT_EQ(2, purpose_to_count[IconPurpose::MASKABLE]);
} }
TEST(WebAppInstallUtils, UpdateWebAppInfoFromManifest_ShareTarget) {
blink::Manifest manifest;
WebApplicationInfo web_app_info;
{
blink::Manifest::ShareTarget share_target;
share_target.action = GURL("http://example.com/share1");
share_target.method = blink::Manifest::ShareTarget::Method::kPost;
share_target.enctype =
blink::Manifest::ShareTarget::Enctype::kMultipartFormData;
share_target.params.title = base::ASCIIToUTF16("kTitle");
share_target.params.text = base::ASCIIToUTF16("kText");
blink::Manifest::FileFilter file_filter;
file_filter.name = base::ASCIIToUTF16("kImages");
file_filter.accept.push_back(base::ASCIIToUTF16(".png"));
file_filter.accept.push_back(base::ASCIIToUTF16("image/png"));
share_target.params.files.push_back(std::move(file_filter));
manifest.share_target = std::move(share_target);
}
UpdateWebAppInfoFromManifest(manifest, &web_app_info);
{
EXPECT_TRUE(web_app_info.share_target.has_value());
const auto& share_target = *web_app_info.share_target;
EXPECT_EQ(share_target.action, GURL("http://example.com/share1"));
EXPECT_EQ(share_target.method, apps::ShareTarget::Method::kPost);
EXPECT_EQ(share_target.enctype,
apps::ShareTarget::Enctype::kMultipartFormData);
EXPECT_EQ(share_target.params.title, "kTitle");
EXPECT_EQ(share_target.params.text, "kText");
EXPECT_TRUE(share_target.params.url.empty());
EXPECT_EQ(share_target.params.files.size(), 1U);
EXPECT_EQ(share_target.params.files[0].name, "kImages");
EXPECT_EQ(share_target.params.files[0].accept.size(), 2U);
EXPECT_EQ(share_target.params.files[0].accept[0], ".png");
EXPECT_EQ(share_target.params.files[0].accept[1], "image/png");
}
{
blink::Manifest::ShareTarget share_target;
share_target.action = GURL("http://example.com/share2");
share_target.method = blink::Manifest::ShareTarget::Method::kGet;
share_target.enctype =
blink::Manifest::ShareTarget::Enctype::kFormUrlEncoded;
share_target.params.text = base::ASCIIToUTF16("kText");
share_target.params.url = base::ASCIIToUTF16("kUrl");
manifest.share_target = std::move(share_target);
}
UpdateWebAppInfoFromManifest(manifest, &web_app_info);
{
EXPECT_TRUE(web_app_info.share_target.has_value());
const auto& share_target = *web_app_info.share_target;
EXPECT_EQ(share_target.action, GURL("http://example.com/share2"));
EXPECT_EQ(share_target.method, apps::ShareTarget::Method::kGet);
EXPECT_EQ(share_target.enctype,
apps::ShareTarget::Enctype::kFormUrlEncoded);
EXPECT_TRUE(share_target.params.title.empty());
EXPECT_EQ(share_target.params.text, "kText");
EXPECT_EQ(share_target.params.url, "kUrl");
EXPECT_TRUE(share_target.params.files.empty());
}
manifest.share_target = base::nullopt;
UpdateWebAppInfoFromManifest(manifest, &web_app_info);
EXPECT_FALSE(web_app_info.share_target.has_value());
}
// Tests that WebAppInfo is correctly updated when Manifest contains Shortcuts. // Tests that WebAppInfo is correctly updated when Manifest contains Shortcuts.
TEST_F(WebAppInstallUtilsWithShortcutsMenu, TEST_F(WebAppInstallUtilsWithShortcutsMenu,
UpdateWebAppInfoFromManifestWithShortcuts) { UpdateWebAppInfoFromManifestWithShortcuts) {
...@@ -638,87 +711,4 @@ TEST_F(WebAppInstallUtilsWithShortcutsMenu, ...@@ -638,87 +711,4 @@ TEST_F(WebAppInstallUtilsWithShortcutsMenu,
} }
} }
TEST(WebAppInstallUtils, UpdateShareTargetFromManifest) {
const base::string16 kTitle = base::ASCIIToUTF16("kTitle");
const base::string16 kText = base::ASCIIToUTF16("kText");
const base::string16 kUrl = base::ASCIIToUTF16("kUrl");
const base::string16 kImages = base::ASCIIToUTF16("kImages");
const base::string16 kExtension = base::ASCIIToUTF16(".png");
const base::string16 kContentType = base::ASCIIToUTF16("image/png");
WebApplicationInfo web_app_info;
blink::Manifest manifest;
manifest.start_url = AppUrl();
manifest.scope = AppUrl().GetWithoutFilename();
manifest.short_name = base::ASCIIToUTF16(kAppShortName);
{
blink::Manifest::ShareTarget share_target;
share_target.action = GURL("http://example.com/share1");
share_target.method = blink::Manifest::ShareTarget::Method::kPost;
share_target.enctype =
blink::Manifest::ShareTarget::Enctype::kMultipartFormData;
share_target.params.title = kTitle;
share_target.params.text = kText;
blink::Manifest::FileFilter file_filter;
file_filter.name = kImages;
file_filter.accept.push_back(kExtension);
file_filter.accept.push_back(kContentType);
share_target.params.files.push_back(std::move(file_filter));
manifest.share_target = std::move(share_target);
}
UpdateWebAppInfoFromManifest(manifest, &web_app_info);
{
EXPECT_TRUE(web_app_info.share_target.has_value());
auto share_target = *web_app_info.share_target;
EXPECT_EQ(share_target.action, GURL("http://example.com/share1"));
EXPECT_EQ(share_target.method, blink::Manifest::ShareTarget::Method::kPost);
EXPECT_EQ(share_target.enctype,
blink::Manifest::ShareTarget::Enctype::kMultipartFormData);
EXPECT_EQ(share_target.params.title, kTitle);
EXPECT_EQ(share_target.params.text, kText);
EXPECT_FALSE(share_target.params.url.has_value());
EXPECT_EQ(share_target.params.files.size(), 1U);
EXPECT_EQ(share_target.params.files[0].name, kImages);
EXPECT_EQ(share_target.params.files[0].accept.size(), 2U);
EXPECT_EQ(share_target.params.files[0].accept[0], kExtension);
EXPECT_EQ(share_target.params.files[0].accept[1], kContentType);
}
{
blink::Manifest::ShareTarget share_target;
share_target.action = GURL("http://example.com/share2");
share_target.method = blink::Manifest::ShareTarget::Method::kGet;
share_target.enctype =
blink::Manifest::ShareTarget::Enctype::kFormUrlEncoded;
share_target.params.text = kText;
share_target.params.url = kUrl;
manifest.share_target = std::move(share_target);
}
UpdateWebAppInfoFromManifest(manifest, &web_app_info);
{
EXPECT_TRUE(web_app_info.share_target.has_value());
auto share_target = *web_app_info.share_target;
EXPECT_EQ(share_target.action, GURL("http://example.com/share2"));
EXPECT_EQ(share_target.method, blink::Manifest::ShareTarget::Method::kGet);
EXPECT_EQ(share_target.enctype,
blink::Manifest::ShareTarget::Enctype::kFormUrlEncoded);
EXPECT_FALSE(share_target.params.title.has_value());
EXPECT_EQ(share_target.params.text, kText);
EXPECT_EQ(share_target.params.url, kUrl);
EXPECT_TRUE(share_target.params.files.empty());
}
manifest.share_target = base::nullopt;
UpdateWebAppInfoFromManifest(manifest, &web_app_info);
EXPECT_FALSE(web_app_info.share_target.has_value());
}
} // namespace web_app } // namespace web_app
...@@ -155,6 +155,12 @@ const std::string* BookmarkAppRegistrar::GetAppLaunchQueryParams( ...@@ -155,6 +155,12 @@ const std::string* BookmarkAppRegistrar::GetAppLaunchQueryParams(
return nullptr; return nullptr;
} }
// Only implemented for WebApp. Bookmark apps are going away.
const apps::ShareTarget* BookmarkAppRegistrar::GetAppShareTarget(
const web_app::AppId& app_id) const {
return nullptr;
}
base::Optional<GURL> BookmarkAppRegistrar::GetAppScopeInternal( base::Optional<GURL> BookmarkAppRegistrar::GetAppScopeInternal(
const web_app::AppId& app_id) const { const web_app::AppId& app_id) const {
const Extension* extension = GetBookmarkAppDchecked(app_id); const Extension* extension = GetBookmarkAppDchecked(app_id);
......
...@@ -48,6 +48,8 @@ class BookmarkAppRegistrar : public web_app::AppRegistrar, ...@@ -48,6 +48,8 @@ class BookmarkAppRegistrar : public web_app::AppRegistrar,
const GURL& GetAppStartUrl(const web_app::AppId& app_id) const override; const GURL& GetAppStartUrl(const web_app::AppId& app_id) const override;
const std::string* GetAppLaunchQueryParams( const std::string* GetAppLaunchQueryParams(
const web_app::AppId& app_id) const override; const web_app::AppId& app_id) const override;
const apps::ShareTarget* GetAppShareTarget(
const web_app::AppId& app_id) const override;
base::Optional<GURL> GetAppScopeInternal( base::Optional<GURL> GetAppScopeInternal(
const web_app::AppId& app_id) const override; const web_app::AppId& app_id) const override;
web_app::DisplayMode GetAppDisplayMode( web_app::DisplayMode GetAppDisplayMode(
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include "chrome/browser/web_applications/test/test_system_web_app_installation.h" #include "chrome/browser/web_applications/test/test_system_web_app_installation.h"
#include "chrome/browser/web_applications/test/web_app_install_observer.h" #include "chrome/browser/web_applications/test/web_app_install_observer.h"
#include "chrome/browser/web_applications/test/web_app_test.h" #include "chrome/browser/web_applications/test/web_app_test.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_features.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h" #include "chrome/test/base/ui_test_utils.h"
...@@ -1213,6 +1215,127 @@ IN_PROC_BROWSER_TEST_P(ManifestUpdateManagerWebAppsBrowserTest, ...@@ -1213,6 +1215,127 @@ IN_PROC_BROWSER_TEST_P(ManifestUpdateManagerWebAppsBrowserTest,
SK_ColorRED); SK_ColorRED);
} }
IN_PROC_BROWSER_TEST_P(ManifestUpdateManagerWebAppsBrowserTest,
CheckFindsAddedShareTarget) {
constexpr char kManifestTemplate[] = R"(
{
"name": "Test app name",
"start_url": ".",
"scope": "/",
"display": "minimal-ui",
"icons": $1
}
)";
constexpr char kShareTargetManifestTemplate[] = R"(
{
"name": "Test app name",
"start_url": ".",
"scope": "/",
"display": "minimal-ui",
"share_target": {
"action": "/web_share_target/share.html",
"method": "GET",
"params": {
"url": "link"
}
},
"icons": $1
}
)";
OverrideManifest(kManifestTemplate, {kInstallableIconList});
AppId app_id = InstallWebApp();
OverrideManifest(kShareTargetManifestTemplate, {kInstallableIconList});
EXPECT_EQ(GetResultAfterPageLoad(GetAppURL(), &app_id),
ManifestUpdateResult::kAppUpdated);
histogram_tester_.ExpectBucketCount(kUpdateHistogramName,
ManifestUpdateResult::kAppUpdated, 1);
const WebApp* web_app =
GetProvider().registrar().AsWebAppRegistrar()->GetAppById(app_id);
EXPECT_TRUE(web_app->share_target().has_value());
EXPECT_EQ(web_app->share_target()->method, apps::ShareTarget::Method::kGet);
}
IN_PROC_BROWSER_TEST_P(ManifestUpdateManagerWebAppsBrowserTest,
CheckFindsShareTargetChange) {
constexpr char kShareTargetManifestTemplate[] = R"(
{
"name": "Test app name",
"start_url": ".",
"scope": "/",
"display": "minimal-ui",
"share_target": {
"action": "/web_share_target/share.html",
"method": "$1",
"params": {
"url": "link"
}
},
"icons": $2
}
)";
OverrideManifest(kShareTargetManifestTemplate, {"GET", kInstallableIconList});
AppId app_id = InstallWebApp();
OverrideManifest(kShareTargetManifestTemplate,
{"POST", kInstallableIconList});
EXPECT_EQ(GetResultAfterPageLoad(GetAppURL(), &app_id),
ManifestUpdateResult::kAppUpdated);
histogram_tester_.ExpectBucketCount(kUpdateHistogramName,
ManifestUpdateResult::kAppUpdated, 1);
const WebApp* web_app =
GetProvider().registrar().AsWebAppRegistrar()->GetAppById(app_id);
EXPECT_TRUE(web_app->share_target().has_value());
EXPECT_EQ(web_app->share_target()->method, apps::ShareTarget::Method::kPost);
}
IN_PROC_BROWSER_TEST_P(ManifestUpdateManagerWebAppsBrowserTest,
CheckFindsDeletedShareTarget) {
constexpr char kShareTargetManifestTemplate[] = R"(
{
"name": "Test app name",
"start_url": ".",
"scope": "/",
"display": "minimal-ui",
"share_target": {
"action": "/web_share_target/share.html",
"method": "GET",
"params": {
"url": "link"
}
},
"icons": $1
}
)";
constexpr char kManifestTemplate[] = R"(
{
"name": "Test app name",
"start_url": ".",
"scope": "/",
"display": "minimal-ui",
"icons": $1
}
)";
OverrideManifest(kShareTargetManifestTemplate, {kInstallableIconList});
AppId app_id = InstallWebApp();
OverrideManifest(kManifestTemplate, {kInstallableIconList});
EXPECT_EQ(GetResultAfterPageLoad(GetAppURL(), &app_id),
ManifestUpdateResult::kAppUpdated);
histogram_tester_.ExpectBucketCount(kUpdateHistogramName,
ManifestUpdateResult::kAppUpdated, 1);
const WebApp* web_app =
GetProvider().registrar().AsWebAppRegistrar()->GetAppById(app_id);
EXPECT_FALSE(web_app->share_target().has_value());
}
class ManifestUpdateManagerBrowserTestWithShortcutsMenu class ManifestUpdateManagerBrowserTestWithShortcutsMenu
: public ManifestUpdateManagerBrowserTest { : public ManifestUpdateManagerBrowserTest {
public: public:
......
...@@ -177,6 +177,17 @@ bool ManifestUpdateTask::IsUpdateNeededForManifest() const { ...@@ -177,6 +177,17 @@ bool ManifestUpdateTask::IsUpdateNeededForManifest() const {
return true; return true;
} }
const apps::ShareTarget* app_share_target =
registrar_.GetAppShareTarget(app_id_);
if (app_share_target) {
if (!web_application_info_->share_target ||
*web_application_info_->share_target != *app_share_target) {
return true;
}
} else if (web_application_info_->share_target) {
return true;
}
// TODO(crbug.com/926083): Check more manifest fields. // TODO(crbug.com/926083): Check more manifest fields.
return false; return false;
} }
......
...@@ -117,6 +117,11 @@ const std::string* TestAppRegistrar::GetAppLaunchQueryParams( ...@@ -117,6 +117,11 @@ const std::string* TestAppRegistrar::GetAppLaunchQueryParams(
return nullptr; return nullptr;
} }
const apps::ShareTarget* TestAppRegistrar::GetAppShareTarget(
const AppId& app_id) const {
return nullptr;
}
base::Optional<GURL> TestAppRegistrar::GetAppScopeInternal( base::Optional<GURL> TestAppRegistrar::GetAppScopeInternal(
const AppId& app_id) const { const AppId& app_id) const {
const auto& result = installed_apps_.find(app_id); const auto& result = installed_apps_.find(app_id);
......
...@@ -62,6 +62,8 @@ class TestAppRegistrar : public AppRegistrar { ...@@ -62,6 +62,8 @@ class TestAppRegistrar : public AppRegistrar {
const GURL& GetAppStartUrl(const AppId& app_id) const override; const GURL& GetAppStartUrl(const AppId& app_id) const override;
const std::string* GetAppLaunchQueryParams( const std::string* GetAppLaunchQueryParams(
const AppId& app_id) const override; const AppId& app_id) const override;
const apps::ShareTarget* GetAppShareTarget(
const AppId& app_id) const override;
base::Optional<GURL> GetAppScopeInternal(const AppId& app_id) const override; base::Optional<GURL> GetAppScopeInternal(const AppId& app_id) const override;
DisplayMode GetAppDisplayMode(const AppId& app_id) const override; DisplayMode GetAppDisplayMode(const AppId& app_id) const override;
DisplayMode GetAppUserDisplayMode(const AppId& app_id) const override; DisplayMode GetAppUserDisplayMode(const AppId& app_id) const override;
......
...@@ -47,28 +47,6 @@ std::vector<std::vector<SquareSizePx>> GetDownloadedShortcutsMenuIconsSizes( ...@@ -47,28 +47,6 @@ std::vector<std::vector<SquareSizePx>> GetDownloadedShortcutsMenuIconsSizes(
return shortcuts_menu_icons_sizes; return shortcuts_menu_icons_sizes;
} }
apps::ShareTarget::Method ToAppsShareTargetMethod(
blink::Manifest::ShareTarget::Method method) {
switch (method) {
case blink::Manifest::ShareTarget::Method::kGet:
return apps::ShareTarget::Method::kGet;
case blink::Manifest::ShareTarget::Method::kPost:
return apps::ShareTarget::Method::kPost;
}
NOTREACHED();
}
apps::ShareTarget::Enctype ToAppsShareTargetEnctype(
blink::Manifest::ShareTarget::Enctype enctype) {
switch (enctype) {
case blink::Manifest::ShareTarget::Enctype::kFormUrlEncoded:
return apps::ShareTarget::Enctype::kFormUrlEncoded;
case blink::Manifest::ShareTarget::Enctype::kMultipartFormData:
return apps::ShareTarget::Enctype::kMultipartFormData;
}
NOTREACHED();
}
void SetWebAppFileHandlers( void SetWebAppFileHandlers(
const std::vector<blink::Manifest::FileHandler>& manifest_file_handlers, const std::vector<blink::Manifest::FileHandler>& manifest_file_handlers,
WebApp& web_app) { WebApp& web_app) {
...@@ -93,45 +71,6 @@ void SetWebAppFileHandlers( ...@@ -93,45 +71,6 @@ void SetWebAppFileHandlers(
web_app.SetFileHandlers(std::move(web_app_file_handlers)); web_app.SetFileHandlers(std::move(web_app_file_handlers));
} }
void SetWebAppShareTarget(
const base::Optional<blink::Manifest::ShareTarget>& share_target,
WebApp& web_app) {
if (!share_target) {
web_app.SetShareTarget(base::nullopt);
return;
}
apps::ShareTarget apps_share_target;
apps_share_target.action = share_target->action;
apps_share_target.method = ToAppsShareTargetMethod(share_target->method);
apps_share_target.enctype = ToAppsShareTargetEnctype(share_target->enctype);
if (share_target->params.title.has_value()) {
apps_share_target.params.title =
base::UTF16ToUTF8(*share_target->params.title);
}
if (share_target->params.text.has_value()) {
apps_share_target.params.text =
base::UTF16ToUTF8(*share_target->params.text);
}
if (share_target->params.url.has_value()) {
apps_share_target.params.url = base::UTF16ToUTF8(*share_target->params.url);
}
for (const auto& file_filter : share_target->params.files) {
apps::ShareTarget::Files apps_share_target_files;
apps_share_target_files.name = base::UTF16ToUTF8(file_filter.name);
for (const auto& file_type : file_filter.accept) {
apps_share_target_files.accept.push_back(base::UTF16ToUTF8(file_type));
}
apps_share_target.params.files.push_back(
std::move(apps_share_target_files));
}
web_app.SetShareTarget(std::move(apps_share_target));
}
void SetWebAppProtocolHandlers( void SetWebAppProtocolHandlers(
const std::vector<blink::Manifest::ProtocolHandler>& protocol_handlers, const std::vector<blink::Manifest::ProtocolHandler>& protocol_handlers,
WebApp& web_app) { WebApp& web_app) {
...@@ -188,7 +127,7 @@ void SetWebAppManifestFields(const WebApplicationInfo& web_app_info, ...@@ -188,7 +127,7 @@ void SetWebAppManifestFields(const WebApplicationInfo& web_app_info,
web_app_info.shortcuts_menu_icons_bitmaps)); web_app_info.shortcuts_menu_icons_bitmaps));
SetWebAppFileHandlers(web_app_info.file_handlers, web_app); SetWebAppFileHandlers(web_app_info.file_handlers, web_app);
SetWebAppShareTarget(web_app_info.share_target, web_app); web_app.SetShareTarget(web_app_info.share_target);
SetWebAppProtocolHandlers(web_app_info.protocol_handlers, web_app); SetWebAppProtocolHandlers(web_app_info.protocol_handlers, web_app);
if (base::FeatureList::IsEnabled(features::kDesktopPWAsRunOnOsLogin) && if (base::FeatureList::IsEnabled(features::kDesktopPWAsRunOnOsLogin) &&
......
...@@ -20,6 +20,34 @@ ...@@ -20,6 +20,34 @@
namespace web_app { namespace web_app {
TEST(WebAppInstallationUtils, SetWebAppManifestFields_Summary) {
WebApplicationInfo web_app_info;
web_app_info.start_url = GURL("https://www.chromium.org/index.html");
web_app_info.scope = web_app_info.start_url.GetWithoutFilename();
web_app_info.title = base::ASCIIToUTF16("App Name");
web_app_info.description = base::ASCIIToUTF16("App Description");
web_app_info.theme_color = SK_ColorCYAN;
web_app_info.background_color = SK_ColorMAGENTA;
const AppId app_id = GenerateAppIdFromURL(web_app_info.start_url);
auto web_app = std::make_unique<WebApp>(app_id);
SetWebAppManifestFields(web_app_info, *web_app);
EXPECT_EQ(web_app->scope(), GURL("https://www.chromium.org/"));
EXPECT_EQ(web_app->name(), "App Name");
EXPECT_EQ(web_app->description(), "App Description");
EXPECT_TRUE(web_app->theme_color().has_value());
EXPECT_EQ(*web_app->theme_color(), SK_ColorCYAN);
EXPECT_TRUE(web_app->background_color().has_value());
EXPECT_EQ(*web_app->background_color(), SK_ColorMAGENTA);
web_app_info.theme_color = base::nullopt;
web_app_info.background_color = base::nullopt;
SetWebAppManifestFields(web_app_info, *web_app);
EXPECT_FALSE(web_app->theme_color().has_value());
EXPECT_FALSE(web_app->background_color().has_value());
}
TEST(WebAppInstallationUtils, SetWebAppManifestFields_ShareTarget) { TEST(WebAppInstallationUtils, SetWebAppManifestFields_ShareTarget) {
WebApplicationInfo web_app_info; WebApplicationInfo web_app_info;
web_app_info.start_url = GURL("https://www.chromium.org/index.html"); web_app_info.start_url = GURL("https://www.chromium.org/index.html");
...@@ -30,20 +58,18 @@ TEST(WebAppInstallationUtils, SetWebAppManifestFields_ShareTarget) { ...@@ -30,20 +58,18 @@ TEST(WebAppInstallationUtils, SetWebAppManifestFields_ShareTarget) {
auto web_app = std::make_unique<WebApp>(app_id); auto web_app = std::make_unique<WebApp>(app_id);
{ {
blink::Manifest::ShareTarget share_target; apps::ShareTarget share_target;
share_target.action = GURL("http://example.com/share1"); share_target.action = GURL("http://example.com/share1");
share_target.method = blink::Manifest::ShareTarget::Method::kPost; share_target.method = apps::ShareTarget::Method::kPost;
share_target.enctype = share_target.enctype = apps::ShareTarget::Enctype::kMultipartFormData;
blink::Manifest::ShareTarget::Enctype::kMultipartFormData; share_target.params.title = "kTitle";
share_target.params.title = base::ASCIIToUTF16("kTitle"); share_target.params.text = "kText";
share_target.params.text = base::ASCIIToUTF16("kText");
apps::ShareTarget::Files file_filter;
blink::Manifest::FileFilter file_filter; file_filter.name = "kImages";
file_filter.name = base::ASCIIToUTF16("kImages"); file_filter.accept.push_back(".png");
file_filter.accept.push_back(base::ASCIIToUTF16(".png")); file_filter.accept.push_back("image/png");
file_filter.accept.push_back(base::ASCIIToUTF16("image/png"));
share_target.params.files.push_back(std::move(file_filter)); share_target.params.files.push_back(std::move(file_filter));
web_app_info.share_target = std::move(share_target); web_app_info.share_target = std::move(share_target);
} }
...@@ -67,13 +93,12 @@ TEST(WebAppInstallationUtils, SetWebAppManifestFields_ShareTarget) { ...@@ -67,13 +93,12 @@ TEST(WebAppInstallationUtils, SetWebAppManifestFields_ShareTarget) {
} }
{ {
blink::Manifest::ShareTarget share_target; apps::ShareTarget share_target;
share_target.action = GURL("http://example.com/share2"); share_target.action = GURL("http://example.com/share2");
share_target.method = blink::Manifest::ShareTarget::Method::kGet; share_target.method = apps::ShareTarget::Method::kGet;
share_target.enctype = share_target.enctype = apps::ShareTarget::Enctype::kFormUrlEncoded;
blink::Manifest::ShareTarget::Enctype::kFormUrlEncoded; share_target.params.text = "kText";
share_target.params.text = base::ASCIIToUTF16("kText"); share_target.params.url = "kUrl";
share_target.params.url = base::ASCIIToUTF16("kUrl");
web_app_info.share_target = std::move(share_target); web_app_info.share_target = std::move(share_target);
} }
......
...@@ -98,6 +98,14 @@ const std::string* WebAppRegistrar::GetAppLaunchQueryParams( ...@@ -98,6 +98,14 @@ const std::string* WebAppRegistrar::GetAppLaunchQueryParams(
return web_app ? web_app->launch_query_params() : nullptr; return web_app ? web_app->launch_query_params() : nullptr;
} }
const apps::ShareTarget* WebAppRegistrar::GetAppShareTarget(
const AppId& app_id) const {
auto* web_app = GetAppById(app_id);
return (web_app && web_app->share_target().has_value())
? &web_app->share_target().value()
: nullptr;
}
base::Optional<GURL> WebAppRegistrar::GetAppScopeInternal( base::Optional<GURL> WebAppRegistrar::GetAppScopeInternal(
const AppId& app_id) const { const AppId& app_id) const {
auto* web_app = GetAppById(app_id); auto* web_app = GetAppById(app_id);
......
...@@ -51,6 +51,8 @@ class WebAppRegistrar : public AppRegistrar, public ProfileManagerObserver { ...@@ -51,6 +51,8 @@ class WebAppRegistrar : public AppRegistrar, public ProfileManagerObserver {
const GURL& GetAppStartUrl(const AppId& app_id) const override; const GURL& GetAppStartUrl(const AppId& app_id) const override;
const std::string* GetAppLaunchQueryParams( const std::string* GetAppLaunchQueryParams(
const AppId& app_id) const override; const AppId& app_id) const override;
const apps::ShareTarget* GetAppShareTarget(
const AppId& app_id) const override;
base::Optional<GURL> GetAppScopeInternal(const AppId& app_id) const override; base::Optional<GURL> GetAppScopeInternal(const AppId& app_id) const override;
DisplayMode GetAppDisplayMode(const AppId& app_id) const override; DisplayMode GetAppDisplayMode(const AppId& app_id) const override;
DisplayMode GetAppUserDisplayMode(const AppId& app_id) const override; DisplayMode GetAppUserDisplayMode(const AppId& app_id) const override;
......
...@@ -198,6 +198,7 @@ static_library("common") { ...@@ -198,6 +198,7 @@ static_library("common") {
"//components/prefs", "//components/prefs",
"//components/safe_browsing:buildflags", "//components/safe_browsing:buildflags",
"//components/safe_browsing/core/web_ui:constants", "//components/safe_browsing/core/web_ui:constants",
"//components/services/app_service/public/cpp:app_share_target",
"//components/services/heap_profiling/public/cpp", "//components/services/heap_profiling/public/cpp",
"//components/strings", "//components/strings",
"//components/translate/content/common", "//components/translate/content/common",
......
...@@ -39,7 +39,7 @@ include_rules = [ ...@@ -39,7 +39,7 @@ include_rules = [
"+components/safe_browsing/buildflags.h", "+components/safe_browsing/buildflags.h",
"+components/safe_browsing/core/proto/csd.pb.h", "+components/safe_browsing/core/proto/csd.pb.h",
"+components/safe_browsing/core/web_ui/constants.h", "+components/safe_browsing/core/web_ui/constants.h",
"+components/services/app_service/public", "+components/services/app_service/public/cpp/share_target.h",
"+components/strings/grit/components_strings.h", "+components/strings/grit/components_strings.h",
"+components/translate/core/common", "+components/translate/core/common",
"+components/url_formatter", "+components/url_formatter",
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/containers/flat_set.h" #include "base/containers/flat_set.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "components/services/app_service/public/cpp/share_target.h"
#include "third_party/blink/public/common/manifest/manifest.h" #include "third_party/blink/public/common/manifest/manifest.h"
#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
...@@ -161,7 +162,7 @@ struct WebApplicationInfo { ...@@ -161,7 +162,7 @@ struct WebApplicationInfo {
std::vector<blink::Manifest::FileHandler> file_handlers; std::vector<blink::Manifest::FileHandler> file_handlers;
// File types the app accepts as a Web Share Target. // File types the app accepts as a Web Share Target.
base::Optional<blink::Manifest::ShareTarget> share_target; base::Optional<apps::ShareTarget> share_target;
// Additional search terms that users can use to find the app. // Additional search terms that users can use to find the app.
std::vector<std::string> additional_search_terms; std::vector<std::string> additional_search_terms;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment