Commit 5129bd56 authored by Robert Woods's avatar Robert Woods Committed by Commit Bot

WebApps: Add file handling support to BMO on CrOS.

In this CL:
- Save FileHandlers to WebAppDatabase
- Implement GetAllFileHandlers in WebAppFileHandlerManager

Bug: 938103
Change-Id: I64a2115dc800b8216f7899d9f83ae19586b45db7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1958297
Commit-Queue: Robert Woods <robertwoods@google.com>
Reviewed-by: default avatarAlexey Baskakov <loyso@chromium.org>
Cr-Commit-Position: refs/heads/master@{#727279}
parent 46babd96
...@@ -61,6 +61,7 @@ class FileHandlerManager : public AppRegistrarObserver { ...@@ -61,6 +61,7 @@ class FileHandlerManager : public AppRegistrarObserver {
protected: protected:
Profile* profile() const { return profile_; } Profile* profile() const { return profile_; }
AppRegistrar* registrar() { return registrar_; }
// Indicates whether file handlers have been registered for an app. // Indicates whether file handlers have been registered for an app.
bool AreFileHandlersEnabled(const AppId& app_id) const; bool AreFileHandlersEnabled(const AppId& app_id) const;
......
...@@ -18,6 +18,22 @@ message WebAppIconInfoProto { ...@@ -18,6 +18,22 @@ message WebAppIconInfoProto {
optional string url = 2; optional string url = 2;
} }
// A mapping between a MIME type and a set of file extensions for a file handler
// "accept" entry. See chrome/browser/web_applications/web_app.h for details.
message WebAppFileHandlerAcceptProto {
required string mimetype = 1;
repeated string file_extensions = 2;
}
// A file handler "action" associated with a set of "accept" entries, each of
// which specifies a MIME type and corresponding set of file extensions that the
// handler can handle. See chrome/browser/web_applications/web_app.h for
// details.
message WebAppFileHandlerProto {
required string action = 1;
repeated WebAppFileHandlerAcceptProto accept = 2;
}
// A set to track simultaneous installs and uninstalls from multiple install // A set to track simultaneous installs and uninstalls from multiple install
// sources. // sources.
message SourcesProto { message SourcesProto {
...@@ -64,4 +80,6 @@ message WebAppProto { ...@@ -64,4 +80,6 @@ message WebAppProto {
repeated WebAppIconInfoProto icon_infos = 10; repeated WebAppIconInfoProto icon_infos = 10;
// A list of icon sizes we successfully downloaded to store on disk. // A list of icon sizes we successfully downloaded to store on disk.
repeated int32 downloaded_icon_sizes = 11; repeated int32 downloaded_icon_sizes = 11;
// A list of file handlers.
repeated WebAppFileHandlerProto file_handlers = 12;
} }
...@@ -156,6 +156,10 @@ void WebApp::SetDownloadedIconSizes(std::vector<SquareSizePx> sizes) { ...@@ -156,6 +156,10 @@ void WebApp::SetDownloadedIconSizes(std::vector<SquareSizePx> sizes) {
downloaded_icon_sizes_ = std::move(sizes); downloaded_icon_sizes_ = std::move(sizes);
} }
void WebApp::SetFileHandlers(FileHandlers file_handlers) {
file_handlers_ = std::move(file_handlers);
}
void WebApp::SetSyncData(SyncData sync_data) { void WebApp::SetSyncData(SyncData sync_data) {
sync_data_ = std::move(sync_data); sync_data_ = std::move(sync_data);
} }
...@@ -168,11 +172,40 @@ WebApp::SyncData::SyncData(const SyncData& sync_data) = default; ...@@ -168,11 +172,40 @@ WebApp::SyncData::SyncData(const SyncData& sync_data) = default;
WebApp::SyncData& WebApp::SyncData::operator=(SyncData&& sync_data) = default; WebApp::SyncData& WebApp::SyncData::operator=(SyncData&& sync_data) = default;
WebApp::FileHandlerAccept::FileHandlerAccept() = default;
WebApp::FileHandlerAccept::~FileHandlerAccept() = default;
WebApp::FileHandlerAccept::FileHandlerAccept(
const FileHandlerAccept& file_handler_accept) = default;
WebApp::FileHandlerAccept& WebApp::FileHandlerAccept::operator=(
FileHandlerAccept&& file_handler_accept) = default;
WebApp::FileHandler::FileHandler() = default;
WebApp::FileHandler::~FileHandler() = default;
WebApp::FileHandler::FileHandler(const FileHandler& file_handler) = default;
WebApp::FileHandler& WebApp::FileHandler::operator=(
FileHandler&& file_handler) = default;
std::ostream& operator<<(std::ostream& out, const WebApp::SyncData& sync_data) { std::ostream& operator<<(std::ostream& out, const WebApp::SyncData& sync_data) {
return out << "theme_color: " << ColorToString(sync_data.theme_color) return out << "theme_color: " << ColorToString(sync_data.theme_color)
<< " name: " << sync_data.name; << " name: " << sync_data.name;
} }
std::ostream& operator<<(std::ostream& out,
const WebApp::FileHandlerAccept& file_handler_accept) {
out << "mimetype: " << file_handler_accept.mimetype << " file_extensions:";
for (const auto& file_extension : file_handler_accept.file_extensions)
out << " " << file_extension;
return out;
}
std::ostream& operator<<(std::ostream& out,
const WebApp::FileHandler& file_handler) {
out << "action: " << file_handler.action;
for (const auto& accept_entry : file_handler.accept)
out << " accept: " << accept_entry;
return out;
}
std::ostream& operator<<(std::ostream& out, const WebApp& app) { std::ostream& operator<<(std::ostream& out, const WebApp& app) {
const std::string display_mode = const std::string display_mode =
blink::DisplayModeToString(app.display_mode_); blink::DisplayModeToString(app.display_mode_);
...@@ -197,16 +230,42 @@ std::ostream& operator<<(std::ostream& out, const WebApp& app) { ...@@ -197,16 +230,42 @@ std::ostream& operator<<(std::ostream& out, const WebApp& app) {
out << " icon_url: " << icon << std::endl; out << " icon_url: " << icon << std::endl;
for (SquareSizePx size : app.downloaded_icon_sizes_) for (SquareSizePx size : app.downloaded_icon_sizes_)
out << " icon_size_on_disk: " << size << std::endl; out << " icon_size_on_disk: " << size << std::endl;
for (const WebApp::FileHandler& file_handler : app.file_handlers_)
out << " file_handler: " << file_handler << std::endl;
return out; return out;
} }
bool operator==(const WebApp::FileHandlerAccept& file_handler_accept1,
const WebApp::FileHandlerAccept& file_handler_accept2) {
return std::tie(file_handler_accept1.mimetype,
file_handler_accept1.file_extensions) ==
std::tie(file_handler_accept2.mimetype,
file_handler_accept2.file_extensions);
}
bool operator==(const WebApp::FileHandler& file_handler1,
const WebApp::FileHandler& file_handler2) {
return std::tie(file_handler1.action, file_handler1.accept) ==
std::tie(file_handler2.action, file_handler2.accept);
}
bool operator==(const WebApp::SyncData& sync_data1, bool operator==(const WebApp::SyncData& sync_data1,
const WebApp::SyncData& sync_data2) { const WebApp::SyncData& sync_data2) {
return std::tie(sync_data1.name, sync_data1.theme_color) == return std::tie(sync_data1.name, sync_data1.theme_color) ==
std::tie(sync_data2.name, sync_data2.theme_color); std::tie(sync_data2.name, sync_data2.theme_color);
} }
bool operator!=(const WebApp::FileHandlerAccept& file_handler_accept1,
const WebApp::FileHandlerAccept& file_handler_accept2) {
return !(file_handler_accept1 == file_handler_accept2);
}
bool operator!=(const WebApp::FileHandler& file_handler1,
const WebApp::FileHandler& file_handler2) {
return !(file_handler1 == file_handler2);
}
bool operator!=(const WebApp::SyncData& sync_data1, bool operator!=(const WebApp::SyncData& sync_data1,
const WebApp::SyncData& sync_data2) { const WebApp::SyncData& sync_data2) {
return !(sync_data1 == sync_data2); return !(sync_data1 == sync_data2);
...@@ -218,13 +277,13 @@ bool operator==(const WebApp& app1, const WebApp& app2) { ...@@ -218,13 +277,13 @@ bool operator==(const WebApp& app1, const WebApp& app2) {
app1.icon_infos_, app1.downloaded_icon_sizes_, app1.icon_infos_, app1.downloaded_icon_sizes_,
app1.display_mode_, app1.user_display_mode_, app1.display_mode_, app1.user_display_mode_,
app1.is_locally_installed_, app1.is_in_sync_install_, app1.is_locally_installed_, app1.is_in_sync_install_,
app1.sync_data_) == app1.file_handlers_, app1.sync_data_) ==
std::tie(app2.app_id_, app2.sources_, app2.name_, app2.launch_url_, std::tie(app2.app_id_, app2.sources_, app2.name_, app2.launch_url_,
app2.description_, app2.scope_, app2.theme_color_, app2.description_, app2.scope_, app2.theme_color_,
app2.icon_infos_, app2.downloaded_icon_sizes_, app2.icon_infos_, app2.downloaded_icon_sizes_,
app2.display_mode_, app2.user_display_mode_, app2.display_mode_, app2.user_display_mode_,
app2.is_locally_installed_, app2.is_in_sync_install_, app2.is_locally_installed_, app2.is_in_sync_install_,
app2.sync_data_); app2.file_handlers_, app2.sync_data_);
} }
bool operator!=(const WebApp& app1, const WebApp& app2) { bool operator!=(const WebApp& app1, const WebApp& app2) {
......
...@@ -7,9 +7,11 @@ ...@@ -7,9 +7,11 @@
#include <bitset> #include <bitset>
#include <iosfwd> #include <iosfwd>
#include <set>
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/containers/flat_set.h"
#include "base/optional.h" #include "base/optional.h"
#include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_constants.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/components/web_app_helpers.h"
...@@ -70,6 +72,41 @@ class WebApp { ...@@ -70,6 +72,41 @@ class WebApp {
return downloaded_icon_sizes_; return downloaded_icon_sizes_;
} }
// Represents a single file handler "accept" entry, mapping a MIME type to a
// set of file extensions that can be handled by the handler.
struct FileHandlerAccept {
FileHandlerAccept();
~FileHandlerAccept();
// Copyable and move-assignable to support Copy-on-Write with Commit.
FileHandlerAccept(const FileHandlerAccept& file_handler_accept);
FileHandlerAccept& operator=(FileHandlerAccept&& file_handler_accept);
// A MIME type that can be handled by the file handler.
std::string mimetype;
// A set of one or more file extensions that can be handled by the file
// handler, corresponding to the MIME type.
base::flat_set<std::string> file_extensions;
};
// Represents a single entry in the "file_handlers" field of the web
// application manifest.
struct FileHandler {
FileHandler();
~FileHandler();
// Copyable and move-assignable to support Copy-on-Write with Commit.
FileHandler(const FileHandler& file_handler);
FileHandler& operator=(FileHandler&& file_handler);
// The URL that will be navigated to when dispatching on a file with a
// matching MIME type or file extension.
GURL action;
// A collection of MIME type to file extensions mappings that the handler
// will match on.
std::vector<FileHandlerAccept> accept;
};
using FileHandlers = std::vector<FileHandler>;
const FileHandlers& file_handlers() const { return file_handlers_; }
// While local |name| and |theme_color| may vary from device to device, the // While local |name| and |theme_color| may vary from device to device, the
// synced copies of these fields are replicated to all devices. The synced // synced copies of these fields are replicated to all devices. The synced
// copies are read by a device to generate a placeholder icon (if needed). Any // copies are read by a device to generate a placeholder icon (if needed). Any
...@@ -113,6 +150,7 @@ class WebApp { ...@@ -113,6 +150,7 @@ class WebApp {
void SetIsInSyncInstall(bool is_in_sync_install); void SetIsInSyncInstall(bool is_in_sync_install);
void SetIconInfos(std::vector<WebApplicationIconInfo> icon_infos); void SetIconInfos(std::vector<WebApplicationIconInfo> icon_infos);
void SetDownloadedIconSizes(std::vector<SquareSizePx> sizes); void SetDownloadedIconSizes(std::vector<SquareSizePx> sizes);
void SetFileHandlers(FileHandlers file_handlers);
void SetSyncData(SyncData sync_data); void SetSyncData(SyncData sync_data);
...@@ -142,12 +180,17 @@ class WebApp { ...@@ -142,12 +180,17 @@ class WebApp {
bool is_in_sync_install_ = false; bool is_in_sync_install_ = false;
std::vector<WebApplicationIconInfo> icon_infos_; std::vector<WebApplicationIconInfo> icon_infos_;
std::vector<SquareSizePx> downloaded_icon_sizes_; std::vector<SquareSizePx> downloaded_icon_sizes_;
FileHandlers file_handlers_;
SyncData sync_data_; SyncData sync_data_;
}; };
// For logging and debug purposes. // For logging and debug purposes.
std::ostream& operator<<(std::ostream& out, const WebApp::SyncData& sync_data); std::ostream& operator<<(std::ostream& out, const WebApp::SyncData& sync_data);
std::ostream& operator<<(std::ostream& out,
const WebApp::FileHandlerAccept& file_handler_accept);
std::ostream& operator<<(std::ostream& out,
const WebApp::FileHandler& file_handler);
std::ostream& operator<<(std::ostream& out, const WebApp& app); std::ostream& operator<<(std::ostream& out, const WebApp& app);
bool operator==(const WebApp::SyncData& sync_data1, bool operator==(const WebApp::SyncData& sync_data1,
...@@ -155,6 +198,16 @@ bool operator==(const WebApp::SyncData& sync_data1, ...@@ -155,6 +198,16 @@ bool operator==(const WebApp::SyncData& sync_data1,
bool operator!=(const WebApp::SyncData& sync_data1, bool operator!=(const WebApp::SyncData& sync_data1,
const WebApp::SyncData& sync_data2); const WebApp::SyncData& sync_data2);
bool operator==(const WebApp::FileHandlerAccept& file_handler_accept1,
const WebApp::FileHandlerAccept& file_handler_accept2);
bool operator!=(const WebApp::FileHandlerAccept& file_handler_accept1,
const WebApp::FileHandlerAccept& file_handler_accept2);
bool operator==(const WebApp::FileHandler& file_handler1,
const WebApp::FileHandler& file_handler2);
bool operator!=(const WebApp::FileHandler& file_handler1,
const WebApp::FileHandler& file_handler2);
bool operator==(const WebApp& app1, const WebApp& app2); bool operator==(const WebApp& app1, const WebApp& app2);
bool operator!=(const WebApp& app1, const WebApp& app2); bool operator!=(const WebApp& app1, const WebApp& app2);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/stl_util.h"
#include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_database_factory.h" #include "chrome/browser/web_applications/web_app_database_factory.h"
#include "chrome/browser/web_applications/web_app_registry_update.h" #include "chrome/browser/web_applications/web_app_registry_update.h"
...@@ -133,6 +134,21 @@ std::unique_ptr<WebAppProto> WebAppDatabase::CreateWebAppProto( ...@@ -133,6 +134,21 @@ std::unique_ptr<WebAppProto> WebAppDatabase::CreateWebAppProto(
for (SquareSizePx size : web_app.downloaded_icon_sizes()) for (SquareSizePx size : web_app.downloaded_icon_sizes())
local_data->add_downloaded_icon_sizes(size); local_data->add_downloaded_icon_sizes(size);
for (const auto& file_handler : web_app.file_handlers()) {
WebAppFileHandlerProto* file_handler_proto =
local_data->add_file_handlers();
file_handler_proto->set_action(file_handler.action.spec());
for (const auto& accept_entry : file_handler.accept) {
WebAppFileHandlerAcceptProto* accept_entry_proto =
file_handler_proto->add_accept();
accept_entry_proto->set_mimetype(accept_entry.mimetype);
for (const auto& file_extension : accept_entry.file_extensions)
accept_entry_proto->add_file_extensions(file_extension);
}
}
return local_data; return local_data;
} }
...@@ -252,6 +268,35 @@ std::unique_ptr<WebApp> WebAppDatabase::CreateWebApp( ...@@ -252,6 +268,35 @@ std::unique_ptr<WebApp> WebAppDatabase::CreateWebApp(
icon_sizes_on_disk.push_back(size); icon_sizes_on_disk.push_back(size);
web_app->SetDownloadedIconSizes(std::move(icon_sizes_on_disk)); web_app->SetDownloadedIconSizes(std::move(icon_sizes_on_disk));
WebApp::FileHandlers file_handlers;
for (const auto& file_handler_proto : local_data.file_handlers()) {
WebApp::FileHandler file_handler;
file_handler.action = GURL(file_handler_proto.action());
if (file_handler.action.is_empty() || !file_handler.action.is_valid()) {
DLOG(ERROR) << "WebApp FileHandler proto action parse error";
return nullptr;
}
for (const auto& accept_entry_proto : file_handler_proto.accept()) {
WebApp::FileHandlerAccept accept_entry;
accept_entry.mimetype = accept_entry_proto.mimetype();
for (const auto& file_extension : accept_entry_proto.file_extensions()) {
if (base::Contains(accept_entry.file_extensions, file_extension)) {
// We intentionally don't return a nullptr here; instead, duplicate
// entries are absorbed.
DLOG(ERROR) << "WebApp::FileHandlerAccept parsing encountered "
<< "duplicate file extension";
}
accept_entry.file_extensions.insert(file_extension);
}
file_handler.accept.push_back(std::move(accept_entry));
}
file_handlers.push_back(std::move(file_handler));
}
web_app->SetFileHandlers(std::move(file_handlers));
return web_app; return web_app;
} }
......
...@@ -36,6 +36,34 @@ class WebAppDatabaseTest : public WebAppTest { ...@@ -36,6 +36,34 @@ class WebAppDatabaseTest : public WebAppTest {
test_registry_controller_->SetUp(profile()); test_registry_controller_->SetUp(profile());
} }
static WebApp::FileHandlers CreateFileHandlers(int suffix) {
WebApp::FileHandlers file_handlers;
for (unsigned int i = 0; i < 5; ++i) {
std::string suffix_str =
base::NumberToString(suffix) + base::NumberToString(i);
WebApp::FileHandlerAccept file_handler_accept1;
file_handler_accept1.mimetype = "application/" + suffix_str + "+foo";
file_handler_accept1.file_extensions.insert("." + suffix_str + "a");
file_handler_accept1.file_extensions.insert("." + suffix_str + "b");
WebApp::FileHandlerAccept file_handler_accept2;
file_handler_accept2.mimetype = "application/" + suffix_str + "+bar";
file_handler_accept2.file_extensions.insert("." + suffix_str + "a");
file_handler_accept2.file_extensions.insert("." + suffix_str + "b");
WebApp::FileHandler file_handler;
file_handler.action = GURL("https://example.com/open-" + suffix_str);
file_handler.accept.push_back(std::move(file_handler_accept1));
file_handler.accept.push_back(std::move(file_handler_accept2));
file_handlers.push_back(std::move(file_handler));
}
return file_handlers;
}
static std::unique_ptr<WebApp> CreateWebApp(const std::string& base_url, static std::unique_ptr<WebApp> CreateWebApp(const std::string& base_url,
int suffix) { int suffix) {
const auto launch_url = base_url + base::NumberToString(suffix); const auto launch_url = base_url + base::NumberToString(suffix);
...@@ -86,6 +114,8 @@ class WebAppDatabaseTest : public WebAppTest { ...@@ -86,6 +114,8 @@ class WebAppDatabaseTest : public WebAppTest {
app->SetIconInfos({std::move(icon)}); app->SetIconInfos({std::move(icon)});
app->SetDownloadedIconSizes({size}); app->SetDownloadedIconSizes({size});
app->SetFileHandlers(CreateFileHandlers(suffix));
WebApp::SyncData sync_data; WebApp::SyncData sync_data;
sync_data.name = "Sync" + name; sync_data.name = "Sync" + name;
sync_data.theme_color = synced_theme_color; sync_data.theme_color = synced_theme_color;
...@@ -278,6 +308,7 @@ TEST_F(WebAppDatabaseTest, WebAppWithoutOptionalFields) { ...@@ -278,6 +308,7 @@ TEST_F(WebAppDatabaseTest, WebAppWithoutOptionalFields) {
EXPECT_FALSE(app->is_in_sync_install()); EXPECT_FALSE(app->is_in_sync_install());
EXPECT_TRUE(app->sync_data().name.empty()); EXPECT_TRUE(app->sync_data().name.empty());
EXPECT_FALSE(app->sync_data().theme_color.has_value()); EXPECT_FALSE(app->sync_data().theme_color.has_value());
EXPECT_TRUE(app->file_handlers().empty());
controller().RegisterApp(std::move(app)); controller().RegisterApp(std::move(app));
Registry registry = database_factory().ReadRegistry(); Registry registry = database_factory().ReadRegistry();
...@@ -308,6 +339,7 @@ TEST_F(WebAppDatabaseTest, WebAppWithoutOptionalFields) { ...@@ -308,6 +339,7 @@ TEST_F(WebAppDatabaseTest, WebAppWithoutOptionalFields) {
EXPECT_FALSE(app_copy->is_in_sync_install()); EXPECT_FALSE(app_copy->is_in_sync_install());
EXPECT_TRUE(app_copy->sync_data().name.empty()); EXPECT_TRUE(app_copy->sync_data().name.empty());
EXPECT_FALSE(app_copy->sync_data().theme_color.has_value()); EXPECT_FALSE(app_copy->sync_data().theme_color.has_value());
EXPECT_TRUE(app_copy->file_handlers().empty());
} }
TEST_F(WebAppDatabaseTest, WebAppWithManyIcons) { TEST_F(WebAppDatabaseTest, WebAppWithManyIcons) {
...@@ -345,4 +377,42 @@ TEST_F(WebAppDatabaseTest, WebAppWithManyIcons) { ...@@ -345,4 +377,42 @@ TEST_F(WebAppDatabaseTest, WebAppWithManyIcons) {
} }
} }
TEST_F(WebAppDatabaseTest, WebAppWithFileHandlersRoundTrip) {
controller().Init();
const std::string base_url = "https://example.com/path";
auto app = CreateWebApp(base_url, 0);
auto app_id = app->app_id();
WebApp::FileHandlers file_handlers;
WebApp::FileHandler file_handler1;
file_handler1.action = GURL("https://example.com/path/csv");
WebApp::FileHandlerAccept accept_csv;
accept_csv.mimetype = "text/csv";
accept_csv.file_extensions.insert(".csv");
accept_csv.file_extensions.insert(".txt");
file_handler1.accept.push_back(std::move(accept_csv));
file_handlers.push_back(std::move(file_handler1));
WebApp::FileHandler file_handler2;
file_handler2.action = GURL("https://example.com/path/svg");
WebApp::FileHandlerAccept accept_xml;
accept_xml.mimetype = "text/xml";
accept_xml.file_extensions.insert(".xml");
file_handler2.accept.push_back(std::move(accept_xml));
WebApp::FileHandlerAccept accept_svg;
accept_svg.mimetype = "text/xml+svg";
accept_svg.file_extensions.insert(".svg");
file_handler2.accept.push_back(std::move(accept_svg));
file_handlers.push_back(std::move(file_handler2));
app->SetFileHandlers(std::move(file_handlers));
controller().RegisterApp(std::move(app));
Registry registry = database_factory().ReadRegistry();
EXPECT_TRUE(IsRegistryEqual(mutable_registrar().registry(), registry));
}
} // namespace web_app } // namespace web_app
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/web_applications/web_app_file_handler_manager.h" #include "chrome/browser/web_applications/web_app_file_handler_manager.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "base/logging.h" #include "base/logging.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -16,8 +18,42 @@ WebAppFileHandlerManager::~WebAppFileHandlerManager() = default; ...@@ -16,8 +18,42 @@ WebAppFileHandlerManager::~WebAppFileHandlerManager() = default;
const std::vector<apps::FileHandlerInfo>* const std::vector<apps::FileHandlerInfo>*
WebAppFileHandlerManager::GetAllFileHandlers(const AppId& app_id) { WebAppFileHandlerManager::GetAllFileHandlers(const AppId& app_id) {
NOTIMPLEMENTED(); // Return cached FileHandlerInfo if present.
return nullptr; auto it = file_handler_infos_.find(app_id);
if (it != file_handler_infos_.end())
return &it->second;
// TODO(crbug.com/938103): Implement explicit safe downcast from AppRegistrar
// to WebAppRegistrar rather than using static_cast.
WebAppRegistrar* web_registrar = static_cast<WebAppRegistrar*>(registrar());
const WebApp* web_app = web_registrar->GetAppById(app_id);
const std::vector<WebApp::FileHandler>& file_handlers =
web_app->file_handlers();
std::vector<apps::FileHandlerInfo> file_handler_infos;
for (const auto& file_handler : file_handlers) {
apps::FileHandlerInfo info;
info.id = file_handler.action.spec();
info.include_directories = false;
info.verb = apps::file_handler_verbs::kOpenWith;
for (const auto& accept_entry : file_handler.accept) {
info.types.insert(accept_entry.mimetype);
info.extensions.insert(accept_entry.file_extensions.begin(),
accept_entry.file_extensions.end());
}
file_handler_infos.push_back(std::move(info));
}
// The transformed data is stored in a map so that we can give a pointer to
// the data to web_file_tasks, as they don't want the call to GetFileHandlers
// to involve a copy.
std::vector<apps::FileHandlerInfo>& apps_file_handler_infos =
file_handler_infos_[app_id];
apps_file_handler_infos = std::move(file_handler_infos);
return &apps_file_handler_infos;
} }
} // namespace web_app } // namespace web_app
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_FILE_HANDLER_MANAGER_H_ #ifndef CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_FILE_HANDLER_MANAGER_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_FILE_HANDLER_MANAGER_H_ #define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_FILE_HANDLER_MANAGER_H_
#include <map>
#include <vector> #include <vector>
#include "chrome/browser/web_applications/components/file_handler_manager.h" #include "chrome/browser/web_applications/components/file_handler_manager.h"
...@@ -23,6 +24,15 @@ class WebAppFileHandlerManager : public FileHandlerManager { ...@@ -23,6 +24,15 @@ class WebAppFileHandlerManager : public FileHandlerManager {
protected: protected:
const std::vector<apps::FileHandlerInfo>* GetAllFileHandlers( const std::vector<apps::FileHandlerInfo>* GetAllFileHandlers(
const AppId& app_id) override; const AppId& app_id) override;
private:
using FileHandlerInfos = std::map<AppId, std::vector<apps::FileHandlerInfo>>;
// TODO(crbug.com/938103): At the moment, we have two equivalent
// representations of these data held in memory: here, and in WebApp. If
// GetAllFileHandlers can be modified to return a copy rather than a
// reference, there would be no need to cache here.
FileHandlerInfos file_handler_infos_;
}; };
} // namespace web_app } // namespace web_app
......
...@@ -95,6 +95,29 @@ std::vector<SquareSizePx> GetSquareSizePxs( ...@@ -95,6 +95,29 @@ std::vector<SquareSizePx> GetSquareSizePxs(
return sizes; return sizes;
} }
void SetWebAppFileHandlers(
const std::vector<blink::Manifest::FileHandler>& file_handlers,
WebApp* web_app) {
WebApp::FileHandlers web_app_file_handlers;
for (const auto& file_handler : file_handlers) {
WebApp::FileHandler web_app_file_handler;
web_app_file_handler.action = file_handler.action;
// Convert from string16 to string in the accept map.
for (const auto& pair : file_handler.accept) {
WebApp::FileHandlerAccept accept_entry;
accept_entry.mimetype = base::UTF16ToUTF8(pair.first);
for (const auto& file_extension : pair.second)
accept_entry.file_extensions.insert(base::UTF16ToUTF8(file_extension));
web_app_file_handler.accept.push_back(std::move(accept_entry));
}
web_app_file_handlers.push_back(std::move(web_app_file_handler));
}
web_app->SetFileHandlers(std::move(web_app_file_handlers));
}
} // namespace } // namespace
WebAppInstallFinalizer::WebAppInstallFinalizer(Profile* profile, WebAppInstallFinalizer::WebAppInstallFinalizer(Profile* profile,
...@@ -171,6 +194,8 @@ void WebAppInstallFinalizer::FinalizeInstall( ...@@ -171,6 +194,8 @@ void WebAppInstallFinalizer::FinalizeInstall(
web_app->SetIconInfos(web_app_info.icon_infos); web_app->SetIconInfos(web_app_info.icon_infos);
web_app->SetDownloadedIconSizes(GetSquareSizePxs(web_app_info.icon_bitmaps)); web_app->SetDownloadedIconSizes(GetSquareSizePxs(web_app_info.icon_bitmaps));
SetWebAppFileHandlers(web_app_info.file_handlers, web_app.get());
icon_manager_->WriteData( icon_manager_->WriteData(
std::move(app_id), web_app_info.icon_bitmaps, std::move(app_id), web_app_info.icon_bitmaps,
base::BindOnce(&WebAppInstallFinalizer::OnIconsDataWritten, base::BindOnce(&WebAppInstallFinalizer::OnIconsDataWritten,
......
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