Commit 858f8a1e authored by Alexey Baskakov's avatar Alexey Baskakov Committed by Commit Bot

WebApp: Download icons for Web App installation.

- Use WebAppIconDownloader in WebAppDataRetriever.
- Extract InstallFinalizer interface:
  WebAppInstallFinalizer is a BMO implementation.
  BookmarkAppInstallFinalizer will use extensions and CrxInstaller.

Bug: 901226
Change-Id: Ie865bfd4facfc6f890ab92d5d6451a37a34979ea
Reviewed-on: https://chromium-review.googlesource.com/c/1343410Reviewed-by: default avatarcalamity <calamity@chromium.org>
Commit-Queue: Alexey Baskakov <loyso@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609958}
parent 13dbadb1
...@@ -23,6 +23,8 @@ source_set("web_applications") { ...@@ -23,6 +23,8 @@ source_set("web_applications") {
"web_app_database.h", "web_app_database.h",
"web_app_database_factory.cc", "web_app_database_factory.cc",
"web_app_database_factory.h", "web_app_database_factory.h",
"web_app_install_finalizer.cc",
"web_app_install_finalizer.h",
"web_app_install_manager.cc", "web_app_install_manager.cc",
"web_app_install_manager.h", "web_app_install_manager.h",
"web_app_registrar.cc", "web_app_registrar.cc",
...@@ -52,6 +54,8 @@ source_set("web_applications_test_support") { ...@@ -52,6 +54,8 @@ source_set("web_applications_test_support") {
sources = [ sources = [
"test/test_data_retriever.cc", "test/test_data_retriever.cc",
"test/test_data_retriever.h", "test/test_data_retriever.h",
"test/test_install_finalizer.cc",
"test/test_install_finalizer.h",
"test/test_system_web_app_manager.cc", "test/test_system_web_app_manager.cc",
"test/test_system_web_app_manager.h", "test/test_system_web_app_manager.h",
"test/test_web_app_database.cc", "test/test_web_app_database.cc",
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
source_set("components") { source_set("components") {
sources = [ sources = [
"install_finalizer.h",
"install_manager.h", "install_manager.h",
"pending_app_manager.cc", "pending_app_manager.cc",
"pending_app_manager.h", "pending_app_manager.h",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// 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_COMPONENTS_INSTALL_FINALIZER_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_INSTALL_FINALIZER_H_
#include <memory>
#include "base/callback_forward.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
struct WebApplicationInfo;
namespace web_app {
enum class InstallResultCode;
// An abstract finalizer for the installation process, represents the last step.
// Takes WebApplicationInfo as input, writes data to disk (e.g icons, shortcuts)
// and registers an app.
class InstallFinalizer {
public:
using InstallFinalizedCallback =
base::OnceCallback<void(const AppId& app_id, InstallResultCode code)>;
virtual void FinalizeInstall(std::unique_ptr<WebApplicationInfo> web_app_info,
InstallFinalizedCallback callback) = 0;
virtual ~InstallFinalizer() = default;
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_INSTALL_FINALIZER_H_
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/installable/installable_data.h" #include "chrome/browser/installable/installable_data.h"
#include "chrome/browser/installable/installable_manager.h" #include "chrome/browser/installable/installable_manager.h"
#include "chrome/browser/web_applications/components/web_app_icon_downloader.h"
#include "chrome/browser/web_applications/components/web_app_icon_generator.h" #include "chrome/browser/web_applications/components/web_app_icon_generator.h"
#include "chrome/browser/web_applications/components/web_app_install_utils.h"
#include "chrome/common/chrome_render_frame.mojom.h" #include "chrome/common/chrome_render_frame.mojom.h"
#include "chrome/common/web_application_info.h" #include "chrome/common/web_application_info.h"
#include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_entry.h"
...@@ -28,29 +28,6 @@ ...@@ -28,29 +28,6 @@
namespace web_app { namespace web_app {
namespace {
char GetLetterForIcon(const GURL& app_url) {
char icon_letter = ' ';
std::string domain_and_registry(
net::registry_controlled_domains::GetDomainAndRegistry(
app_url,
net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
// TODO(crbug.com/867311): Decode the app URL or the domain before retrieving
// the first character, otherwise we generate an icon with "x" if the domain
// or app URL starts with a UTF-8 character.
if (!domain_and_registry.empty()) {
icon_letter = domain_and_registry[0];
} else if (app_url.has_host()) {
icon_letter = app_url.host_piece()[0];
}
DCHECK(icon_letter >= '!' && icon_letter <= '~');
return icon_letter;
}
} // namespace
WebAppDataRetriever::WebAppDataRetriever() = default; WebAppDataRetriever::WebAppDataRetriever() = default;
WebAppDataRetriever::~WebAppDataRetriever() = default; WebAppDataRetriever::~WebAppDataRetriever() = default;
...@@ -110,25 +87,23 @@ void WebAppDataRetriever::CheckInstallabilityAndRetrieveManifest( ...@@ -110,25 +87,23 @@ void WebAppDataRetriever::CheckInstallabilityAndRetrieveManifest(
weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback))); weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback)));
} }
void WebAppDataRetriever::GetIcons(const GURL& app_url, void WebAppDataRetriever::GetIcons(content::WebContents* web_contents,
const std::vector<GURL>& icon_urls, const std::vector<GURL>& icon_urls,
bool skip_page_fav_icons,
GetIconsCallback callback) { GetIconsCallback callback) {
// TODO(crbug.com/864904): Download icons using |icon_urls|. DCHECK(!icon_urls.empty());
const char icon_letter = GetLetterForIcon(app_url);
const std::set<int> sizes_to_generate = SizesToGenerate();
std::vector<WebApplicationInfo::IconInfo> icons;
for (int size : sizes_to_generate) {
WebApplicationInfo::IconInfo icon_info;
icon_info.width = size;
icon_info.height = size;
icon_info.data = GenerateBitmap(size, SK_ColorDKGRAY, icon_letter);
icons.push_back(icon_info);
}
base::ThreadTaskRunnerHandle::Get()->PostTask( // TODO(loyso): Refactor WebAppIconDownloader: crbug.com/907296.
FROM_HERE, base::BindOnce(std::move(callback), std::move(icons))); icon_downloader_ = std::make_unique<WebAppIconDownloader>(
web_contents, icon_urls,
"Extensions.BookmarkApp.Icon.HttpStatusCodeClassOnCreate",
base::BindOnce(&WebAppDataRetriever::OnIconsDownloaded,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
if (skip_page_fav_icons)
icon_downloader_->SkipPageFavicons();
icon_downloader_->Start();
} }
void WebAppDataRetriever::OnGetWebApplicationInfo( void WebAppDataRetriever::OnGetWebApplicationInfo(
...@@ -169,4 +144,18 @@ void WebAppDataRetriever::OnDidPerformInstallableCheck( ...@@ -169,4 +144,18 @@ void WebAppDataRetriever::OnDidPerformInstallableCheck(
std::move(callback).Run(*data.manifest, is_installable); std::move(callback).Run(*data.manifest, is_installable);
} }
void WebAppDataRetriever::OnIconsDownloaded(GetIconsCallback callback,
bool success,
const IconsMap& icons_map) {
// |icons_map| is owned by |icon_downloader_|. Take a copy before destroying
// the downloader. Return empty |result_map| if the tab has navigated away
// during the icon download.
IconsMap result_map;
if (success)
result_map = icons_map;
icon_downloader_.reset();
std::move(callback).Run(std::move(result_map));
}
} // namespace web_app } // namespace web_app
...@@ -5,13 +5,17 @@ ...@@ -5,13 +5,17 @@
#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_DATA_RETRIEVER_H_ #ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_DATA_RETRIEVER_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_DATA_RETRIEVER_H_ #define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_DATA_RETRIEVER_H_
#include <map>
#include <memory> #include <memory>
#include <vector>
#include "base/callback.h" #include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chrome/browser/web_applications/components/web_app_install_utils.h"
#include "chrome/common/chrome_render_frame.mojom.h" #include "chrome/common/chrome_render_frame.mojom.h"
class GURL;
struct InstallableData; struct InstallableData;
struct WebApplicationInfo; struct WebApplicationInfo;
...@@ -25,6 +29,8 @@ class WebContents; ...@@ -25,6 +29,8 @@ class WebContents;
namespace web_app { namespace web_app {
class WebAppIconDownloader;
// Class used by BookmarkAppInstallationTask to retrieve the necessary // Class used by BookmarkAppInstallationTask to retrieve the necessary
// information to install an app. Should only be called from the UI thread. // information to install an app. Should only be called from the UI thread.
class WebAppDataRetriever { class WebAppDataRetriever {
...@@ -35,9 +41,8 @@ class WebAppDataRetriever { ...@@ -35,9 +41,8 @@ class WebAppDataRetriever {
// |is_installable| is false if installability check failed. // |is_installable| is false if installability check failed.
using CheckInstallabilityCallback = using CheckInstallabilityCallback =
base::OnceCallback<void(const blink::Manifest&, bool is_installable)>; base::OnceCallback<void(const blink::Manifest&, bool is_installable)>;
// Returns empty vector if error. // Returns empty map if error.
using GetIconsCallback = using GetIconsCallback = base::OnceCallback<void(IconsMap)>;
base::OnceCallback<void(std::vector<WebApplicationInfo::IconInfo>)>;
WebAppDataRetriever(); WebAppDataRetriever();
virtual ~WebAppDataRetriever(); virtual ~WebAppDataRetriever();
...@@ -52,11 +57,11 @@ class WebAppDataRetriever { ...@@ -52,11 +57,11 @@ class WebAppDataRetriever {
content::WebContents* web_contents, content::WebContents* web_contents,
CheckInstallabilityCallback callback); CheckInstallabilityCallback callback);
// Downloads icons from |icon_urls|. If icons are missing for certain required // Downloads icons from |icon_urls|. Runs |callback| with a map of
// sizes, generates them based on |app_url|. Runs |callback| with a vector of // the retrieved icons.
// the retrieved and generated icons. virtual void GetIcons(content::WebContents* web_contents,
virtual void GetIcons(const GURL& app_url,
const std::vector<GURL>& icon_urls, const std::vector<GURL>& icon_urls,
bool skip_page_fav_icons,
GetIconsCallback callback); GetIconsCallback callback);
private: private:
...@@ -70,9 +75,15 @@ class WebAppDataRetriever { ...@@ -70,9 +75,15 @@ class WebAppDataRetriever {
void OnDidPerformInstallableCheck(CheckInstallabilityCallback callback, void OnDidPerformInstallableCheck(CheckInstallabilityCallback callback,
const InstallableData& data); const InstallableData& data);
void OnIconsDownloaded(GetIconsCallback callback,
bool success,
const IconsMap& icons_map);
// Saved callback from GetWebApplicationInfo(). // Saved callback from GetWebApplicationInfo().
GetWebApplicationInfoCallback get_web_app_info_callback_; GetWebApplicationInfoCallback get_web_app_info_callback_;
std::unique_ptr<WebAppIconDownloader> icon_downloader_;
base::WeakPtrFactory<WebAppDataRetriever> weak_ptr_factory_{this}; base::WeakPtrFactory<WebAppDataRetriever> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(WebAppDataRetriever); DISALLOW_COPY_AND_ASSIGN(WebAppDataRetriever);
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "chrome/browser/installable/fake_installable_manager.h" #include "chrome/browser/installable/fake_installable_manager.h"
#include "chrome/browser/installable/installable_data.h" #include "chrome/browser/installable/installable_data.h"
#include "chrome/browser/installable/installable_manager.h" #include "chrome/browser/installable/installable_manager.h"
#include "chrome/browser/web_applications/components/web_app_icon_generator.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_entry.h"
...@@ -36,11 +35,6 @@ const char kFooUrl2[] = "https://foo.example/bar"; ...@@ -36,11 +35,6 @@ const char kFooUrl2[] = "https://foo.example/bar";
const char kFooTitle[] = "Foo Title"; const char kFooTitle[] = "Foo Title";
const char kBarUrl[] = "https://bar.example"; const char kBarUrl[] = "https://bar.example";
constexpr int kIconSizesToGenerate[] = {
icon_size::k32, icon_size::k64, icon_size::k48,
icon_size::k96, icon_size::k128, icon_size::k256,
};
} // namespace } // namespace
class FakeChromeRenderFrame class FakeChromeRenderFrame
...@@ -279,32 +273,6 @@ TEST_F(WebAppDataRetrieverTest, GetWebApplicationInfo_FrameNavigated) { ...@@ -279,32 +273,6 @@ TEST_F(WebAppDataRetrieverTest, GetWebApplicationInfo_FrameNavigated) {
EXPECT_EQ(nullptr, web_app_info()); EXPECT_EQ(nullptr, web_app_info());
} }
TEST_F(WebAppDataRetrieverTest, GetIcons_NoIconsProvided) {
base::RunLoop run_loop;
WebAppDataRetriever retriever;
retriever.GetIcons(
GURL(kFooUrl), std::vector<GURL>(),
base::BindOnce(&WebAppDataRetrieverTest::GetIconsCallback,
base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run();
// Make sure that icons have been generated for all sizes.
for (int size : kIconSizesToGenerate) {
int generated_icons_for_size =
std::count_if(icons().begin(), icons().end(),
[&size](const WebApplicationInfo::IconInfo& icon) {
return icon.width == size && icon.height == size;
});
EXPECT_EQ(1, generated_icons_for_size);
}
for (const auto& icon : icons()) {
EXPECT_FALSE(icon.data.drawsNothing());
// Since all icons are generated, they should have an empty url.
EXPECT_TRUE(icon.url.is_empty());
}
}
TEST_F(WebAppDataRetrieverTest, CheckInstallabilityAndRetrieveManifest) { TEST_F(WebAppDataRetrieverTest, CheckInstallabilityAndRetrieveManifest) {
const GURL manifest_start_url = GURL("https://example.com/start"); const GURL manifest_start_url = GURL("https://example.com/start");
const std::string manifest_short_name = "Short Name from Manifest"; const std::string manifest_short_name = "Short Name from Manifest";
......
...@@ -95,7 +95,7 @@ void WebAppIconDownloader::FetchIcons(const std::vector<GURL>& urls) { ...@@ -95,7 +95,7 @@ void WebAppIconDownloader::FetchIcons(const std::vector<GURL>& urls) {
// callback. // callback.
if (in_progress_requests_.empty() && !need_favicon_urls_) { if (in_progress_requests_.empty() && !need_favicon_urls_) {
base::MessageLoopCurrent::Get()->task_runner()->PostTask( base::MessageLoopCurrent::Get()->task_runner()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback_), true, favicon_map_)); FROM_HERE, base::BindOnce(std::move(callback_), true, icons_map_));
} }
} }
...@@ -116,11 +116,11 @@ void WebAppIconDownloader::DidDownloadFavicon( ...@@ -116,11 +116,11 @@ void WebAppIconDownloader::DidDownloadFavicon(
http_status_code / 100, 5); http_status_code / 100, 5);
} }
favicon_map_[image_url] = bitmaps; icons_map_[image_url] = bitmaps;
// Once all requests have been resolved, perform post-download tasks. // Once all requests have been resolved, perform post-download tasks.
if (in_progress_requests_.empty() && !need_favicon_urls_) if (in_progress_requests_.empty() && !need_favicon_urls_)
std::move(callback_).Run(true, favicon_map_); std::move(callback_).Run(true, icons_map_);
} }
// content::WebContentsObserver overrides: // content::WebContentsObserver overrides:
...@@ -132,8 +132,8 @@ void WebAppIconDownloader::DidFinishNavigation( ...@@ -132,8 +132,8 @@ void WebAppIconDownloader::DidFinishNavigation(
// Clear all pending requests. // Clear all pending requests.
in_progress_requests_.clear(); in_progress_requests_.clear();
favicon_map_.clear(); icons_map_.clear();
std::move(callback_).Run(false, favicon_map_); std::move(callback_).Run(false, icons_map_);
} }
void WebAppIconDownloader::DidUpdateFaviconURL( void WebAppIconDownloader::DidUpdateFaviconURL(
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chrome/browser/web_applications/components/web_app_install_utils.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
class SkBitmap; class SkBitmap;
...@@ -36,12 +37,9 @@ namespace web_app { ...@@ -36,12 +37,9 @@ namespace web_app {
// icons) for a tab. // icons) for a tab.
class WebAppIconDownloader : public content::WebContentsObserver { class WebAppIconDownloader : public content::WebContentsObserver {
public: public:
typedef std::map<GURL, std::vector<SkBitmap> > FaviconMap; using WebAppIconDownloaderCallback =
typedef base::OnceCallback<void( base::OnceCallback<void(bool success, const IconsMap& icons_map)>;
bool, /* success */
/* A map of icon urls to the bitmaps provided by that url. */
const FaviconMap&)>
WebAppIconDownloaderCallback;
// |extra_favicon_urls| allows callers to provide icon urls that aren't // |extra_favicon_urls| allows callers to provide icon urls that aren't
// provided by the renderer (e.g touch icons on non-android environments). // provided by the renderer (e.g touch icons on non-android environments).
// |https_status_code_class_histogram_name| optionally specifies a histogram // |https_status_code_class_histogram_name| optionally specifies a histogram
...@@ -100,7 +98,7 @@ class WebAppIconDownloader : public content::WebContentsObserver { ...@@ -100,7 +98,7 @@ class WebAppIconDownloader : public content::WebContentsObserver {
std::vector<GURL> extra_favicon_urls_; std::vector<GURL> extra_favicon_urls_;
// The icons which were downloaded. Populated by FetchIcons(). // The icons which were downloaded. Populated by FetchIcons().
FaviconMap favicon_map_; IconsMap icons_map_;
// Request ids of in-progress requests. // Request ids of in-progress requests.
std::set<int> in_progress_requests_; std::set<int> in_progress_requests_;
......
...@@ -73,13 +73,12 @@ class TestWebAppIconDownloader : public WebAppIconDownloader { ...@@ -73,13 +73,12 @@ class TestWebAppIconDownloader : public WebAppIconDownloader {
size_t pending_requests() const { return in_progress_requests_.size(); } size_t pending_requests() const { return in_progress_requests_.size(); }
void DownloadsComplete(bool success, void DownloadsComplete(bool success, const IconsMap& map) {
const WebAppIconDownloader::FaviconMap& map) {
downloads_succeeded_ = success; downloads_succeeded_ = success;
favicon_map_ = map; favicon_map_ = map;
} }
WebAppIconDownloader::FaviconMap favicon_map() const { return favicon_map_; } IconsMap favicon_map() const { return favicon_map_; }
void CompleteImageDownload( void CompleteImageDownload(
int id, int id,
...@@ -102,7 +101,7 @@ class TestWebAppIconDownloader : public WebAppIconDownloader { ...@@ -102,7 +101,7 @@ class TestWebAppIconDownloader : public WebAppIconDownloader {
private: private:
std::vector<content::FaviconURL> initial_favicon_urls_; std::vector<content::FaviconURL> initial_favicon_urls_;
WebAppIconDownloader::FaviconMap favicon_map_; IconsMap favicon_map_;
int id_counter_; int id_counter_;
base::Optional<bool> downloads_succeeded_; base::Optional<bool> downloads_succeeded_;
......
...@@ -108,6 +108,10 @@ void GenerateIcons(std::set<int> generate_sizes, ...@@ -108,6 +108,10 @@ void GenerateIcons(std::set<int> generate_sizes,
net::registry_controlled_domains::GetDomainAndRegistry( net::registry_controlled_domains::GetDomainAndRegistry(
app_url, app_url,
net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)); net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
// TODO(crbug.com/867311): Decode the app URL or the domain before retrieving
// the first character, otherwise we generate an icon with "x" if the domain
// or app URL starts with a UTF-8 character.
if (!domain_and_registry.empty()) { if (!domain_and_registry.empty()) {
icon_letter = domain_and_registry[0]; icon_letter = domain_and_registry[0];
} else if (app_url.has_host()) { } else if (app_url.has_host()) {
......
...@@ -14,7 +14,7 @@ namespace web_app { ...@@ -14,7 +14,7 @@ namespace web_app {
namespace { namespace {
void ReplaceWebAppIcons(std::map<int, web_app::BitmapAndSource> bitmap_map, void ReplaceWebAppIcons(std::map<int, BitmapAndSource> bitmap_map,
WebApplicationInfo* web_app_info) { WebApplicationInfo* web_app_info) {
web_app_info->icons.clear(); web_app_info->icons.clear();
...@@ -113,10 +113,10 @@ void MergeInstallableDataIcon(const InstallableData& data, ...@@ -113,10 +113,10 @@ void MergeInstallableDataIcon(const InstallableData& data,
} }
std::vector<BitmapAndSource> FilterSquareIcons( std::vector<BitmapAndSource> FilterSquareIcons(
const std::map<GURL, std::vector<SkBitmap>>& bitmaps, const IconsMap& icons_map,
const WebApplicationInfo& web_app_info) { const WebApplicationInfo& web_app_info) {
std::vector<BitmapAndSource> downloaded_icons; std::vector<BitmapAndSource> downloaded_icons;
for (const std::pair<GURL, std::vector<SkBitmap>>& url_bitmap : bitmaps) { for (const std::pair<GURL, std::vector<SkBitmap>>& url_bitmap : icons_map) {
for (const SkBitmap& bitmap : url_bitmap.second) { for (const SkBitmap& bitmap : url_bitmap.second) {
if (bitmap.empty() || bitmap.width() != bitmap.height()) if (bitmap.empty() || bitmap.width() != bitmap.height())
continue; continue;
......
...@@ -29,6 +29,9 @@ enum class ForInstallableSite { ...@@ -29,6 +29,9 @@ enum class ForInstallableSite {
kUnknown, kUnknown,
}; };
// A map of icon urls to the bitmaps provided by that url.
using IconsMap = std::map<GURL, std::vector<SkBitmap>>;
// Update the given WebApplicationInfo with information from the manifest. // Update the given WebApplicationInfo with information from the manifest.
void UpdateWebAppInfoFromManifest(const blink::Manifest& manifest, void UpdateWebAppInfoFromManifest(const blink::Manifest& manifest,
WebApplicationInfo* web_app_info, WebApplicationInfo* web_app_info,
...@@ -49,10 +52,10 @@ std::vector<GURL> GetValidIconUrlsToDownload( ...@@ -49,10 +52,10 @@ std::vector<GURL> GetValidIconUrlsToDownload(
void MergeInstallableDataIcon(const InstallableData& data, void MergeInstallableDataIcon(const InstallableData& data,
WebApplicationInfo* web_app_info); WebApplicationInfo* web_app_info);
// Get a list of non-empty square icons from downloaded |bitmaps| and // Get a list of non-empty square icons from downloaded |icons_map| and
// |web_app_info| (merged together). // |web_app_info| (merged together).
std::vector<BitmapAndSource> FilterSquareIcons( std::vector<BitmapAndSource> FilterSquareIcons(
const std::map<GURL, std::vector<SkBitmap>>& bitmaps, const IconsMap& icons_map,
const WebApplicationInfo& web_app_info); const WebApplicationInfo& web_app_info);
// Ensure that the necessary-sized icons are available by resizing larger // Ensure that the necessary-sized icons are available by resizing larger
......
...@@ -23,12 +23,17 @@ void TestDataRetriever::GetWebApplicationInfo( ...@@ -23,12 +23,17 @@ void TestDataRetriever::GetWebApplicationInfo(
FROM_HERE, base::BindOnce(std::move(callback), std::move(web_app_info_))); FROM_HERE, base::BindOnce(std::move(callback), std::move(web_app_info_)));
} }
void TestDataRetriever::GetIcons(const GURL& app_url, void TestDataRetriever::GetIcons(content::WebContents* web_contents,
const std::vector<GURL>& icon_urls, const std::vector<GURL>& icon_urls,
bool skip_page_fav_icons,
GetIconsCallback callback) { GetIconsCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask( base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), FROM_HERE, base::BindOnce(std::move(callback), std::move(icons_map_)));
std::vector<WebApplicationInfo::IconInfo>())); icons_map_.clear();
}
void TestDataRetriever::SetIcons(IconsMap icons_map) {
icons_map_ = std::move(icons_map);
} }
} // namespace web_app } // namespace web_app
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/web_applications/components/web_app_data_retriever.h" #include "chrome/browser/web_applications/components/web_app_data_retriever.h"
#include "chrome/browser/web_applications/components/web_app_install_utils.h"
struct WebApplicationInfo; struct WebApplicationInfo;
...@@ -21,15 +22,20 @@ class TestDataRetriever : public WebAppDataRetriever { ...@@ -21,15 +22,20 @@ class TestDataRetriever : public WebAppDataRetriever {
explicit TestDataRetriever(std::unique_ptr<WebApplicationInfo> web_app_info); explicit TestDataRetriever(std::unique_ptr<WebApplicationInfo> web_app_info);
~TestDataRetriever() override; ~TestDataRetriever() override;
// WebAppDataRetriever:
void GetWebApplicationInfo(content::WebContents* web_contents, void GetWebApplicationInfo(content::WebContents* web_contents,
GetWebApplicationInfoCallback callback) override; GetWebApplicationInfoCallback callback) override;
void GetIcons(content::WebContents* web_contents,
void GetIcons(const GURL& app_url,
const std::vector<GURL>& icon_urls, const std::vector<GURL>& icon_urls,
bool skip_page_fav_icons,
GetIconsCallback callback) override; GetIconsCallback callback) override;
// Set icons to respond on |GetIcons|.
void SetIcons(IconsMap icons_map);
private: private:
std::unique_ptr<WebApplicationInfo> web_app_info_; std::unique_ptr<WebApplicationInfo> web_app_info_;
IconsMap icons_map_;
DISALLOW_COPY_AND_ASSIGN(TestDataRetriever); DISALLOW_COPY_AND_ASSIGN(TestDataRetriever);
}; };
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <utility>
#include "chrome/browser/web_applications/test/test_install_finalizer.h"
#include "base/callback.h"
#include "chrome/browser/web_applications/components/web_app_constants.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/common/web_application_info.h"
namespace web_app {
TestInstallFinalizer::TestInstallFinalizer() {}
TestInstallFinalizer::~TestInstallFinalizer() = default;
void TestInstallFinalizer::FinalizeInstall(
std::unique_ptr<WebApplicationInfo> web_app_info,
InstallFinalizedCallback callback) {
const AppId app_id = GenerateAppIdFromURL(web_app_info->app_url);
web_app_info_ = std::move(web_app_info);
std::move(callback).Run(app_id, InstallResultCode::kSuccess);
}
} // namespace web_app
// Copyright 2018 The Chromium Authors. All rights reserved.
// 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_TEST_TEST_INSTALL_FINALIZER_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_TEST_TEST_INSTALL_FINALIZER_H_
#include <memory>
#include "base/macros.h"
#include "chrome/browser/web_applications/components/install_finalizer.h"
struct WebApplicationInfo;
namespace web_app {
class TestInstallFinalizer final : public InstallFinalizer {
public:
TestInstallFinalizer();
~TestInstallFinalizer() override;
// InstallFinalizer:
void FinalizeInstall(std::unique_ptr<WebApplicationInfo> web_app_info,
InstallFinalizedCallback callback) override;
std::unique_ptr<WebApplicationInfo> web_app_info() {
return std::move(web_app_info_);
}
private:
std::unique_ptr<WebApplicationInfo> web_app_info_;
DISALLOW_COPY_AND_ASSIGN(TestInstallFinalizer);
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_TEST_TEST_INSTALL_FINALIZER_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <utility>
#include "chrome/browser/web_applications/web_app_install_finalizer.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.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/web_app.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/common/web_application_info.h"
namespace web_app {
WebAppInstallFinalizer::WebAppInstallFinalizer(WebAppRegistrar* registrar)
: registrar_(registrar) {}
WebAppInstallFinalizer::~WebAppInstallFinalizer() = default;
void WebAppInstallFinalizer::FinalizeInstall(
std::unique_ptr<WebApplicationInfo> web_app_info,
InstallFinalizedCallback callback) {
const AppId app_id = GenerateAppIdFromURL(web_app_info->app_url);
auto web_app = std::make_unique<WebApp>(app_id);
web_app->SetName(base::UTF16ToUTF8(web_app_info->title));
web_app->SetDescription(base::UTF16ToUTF8(web_app_info->description));
web_app->SetLaunchUrl(web_app_info->app_url);
web_app->SetScope(web_app_info->scope);
web_app->SetThemeColor(web_app_info->theme_color);
// TODO(loyso): Add web_app_info->icons into web_app. Save them on disk.
registrar_->RegisterApp(std::move(web_app));
std::move(callback).Run(app_id, InstallResultCode::kSuccess);
}
} // namespace web_app
// Copyright 2018 The Chromium Authors. All rights reserved.
// 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_WEB_APP_INSTALL_FINALIZER_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_INSTALL_FINALIZER_H_
#include <memory>
#include "base/macros.h"
#include "chrome/browser/web_applications/components/install_finalizer.h"
struct WebApplicationInfo;
namespace web_app {
class WebAppRegistrar;
class WebAppInstallFinalizer final : public InstallFinalizer {
public:
explicit WebAppInstallFinalizer(WebAppRegistrar* registrar);
~WebAppInstallFinalizer() override;
// InstallFinalizer:
void FinalizeInstall(std::unique_ptr<WebApplicationInfo> web_app_info,
InstallFinalizedCallback callback) override;
private:
WebAppRegistrar* registrar_;
DISALLOW_COPY_AND_ASSIGN(WebAppInstallFinalizer);
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_INSTALL_FINALIZER_H_
...@@ -8,26 +8,24 @@ ...@@ -8,26 +8,24 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/strings/utf_string_conversions.h" #include "chrome/browser/web_applications/components/install_finalizer.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_data_retriever.h" #include "chrome/browser/web_applications/components/web_app_data_retriever.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/components/web_app_icon_generator.h"
#include "chrome/browser/web_applications/components/web_app_install_utils.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_utils.h" #include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/common/web_application_info.h" #include "chrome/common/web_application_info.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "third_party/blink/public/common/manifest/manifest.h"
namespace web_app { namespace web_app {
WebAppInstallManager::WebAppInstallManager(Profile* profile, WebAppInstallManager::WebAppInstallManager(
WebAppRegistrar* registrar) Profile* profile,
: profile_(profile), std::unique_ptr<InstallFinalizer> install_finalizer)
registrar_(registrar), : data_retriever_(std::make_unique<WebAppDataRetriever>()),
data_retriever_(std::make_unique<WebAppDataRetriever>()) { install_finalizer_(std::move(install_finalizer)) {
DCHECK(AllowWebAppInstallation(profile_)); DCHECK(AllowWebAppInstallation(profile));
} }
WebAppInstallManager::~WebAppInstallManager() = default; WebAppInstallManager::~WebAppInstallManager() = default;
...@@ -64,6 +62,11 @@ void WebAppInstallManager::SetDataRetrieverForTesting( ...@@ -64,6 +62,11 @@ void WebAppInstallManager::SetDataRetrieverForTesting(
data_retriever_ = std::move(data_retriever); data_retriever_ = std::move(data_retriever);
} }
void WebAppInstallManager::SetInstallFinalizerForTesting(
std::unique_ptr<InstallFinalizer> install_finalizer) {
install_finalizer_ = std::move(install_finalizer);
}
void WebAppInstallManager::CallInstallCallback(const AppId& app_id, void WebAppInstallManager::CallInstallCallback(const AppId& app_id,
InstallResultCode code) { InstallResultCode code) {
Observe(nullptr); Observe(nullptr);
...@@ -119,26 +122,49 @@ void WebAppInstallManager::OnDidPerformInstallableCheck( ...@@ -119,26 +122,49 @@ void WebAppInstallManager::OnDidPerformInstallableCheck(
is_installable && !force_shortcut_app ? ForInstallableSite::kYes is_installable && !force_shortcut_app ? ForInstallableSite::kYes
: ForInstallableSite::kNo; : ForInstallableSite::kNo;
// TODO(loyso): Implement installation logic from BookmarkAppHelper: // TODO(loyso): Implement UpdateShareTargetInPrefs installation logic.
// - UpdateShareTargetInPrefs.
// - WebAppIconDownloader.
// etc
UpdateWebAppInfoFromManifest(manifest, web_app_info.get(), UpdateWebAppInfoFromManifest(manifest, web_app_info.get(),
for_installable_site); for_installable_site);
const AppId app_id = GenerateAppIdFromURL(web_app_info->app_url); std::vector<GURL> icon_urls;
auto web_app = std::make_unique<WebApp>(app_id); for (auto& icon_info : web_app_info->icons) {
if (icon_info.url.is_valid())
icon_urls.push_back(icon_info.url);
}
// If the manifest specified icons, don't use the page icons.
const bool skip_page_fav_icons = !manifest.icons.empty();
data_retriever_->GetIcons(
web_contents(), icon_urls, skip_page_fav_icons,
base::BindOnce(&WebAppInstallManager::OnIconsRetrieved,
weak_ptr_factory_.GetWeakPtr(), std::move(web_app_info)));
}
void WebAppInstallManager::OnIconsRetrieved(
std::unique_ptr<WebApplicationInfo> web_app_info,
IconsMap icons_map) {
// If interrupted, install_callback_ is already invoked or may invoke later.
if (InstallInterrupted())
return;
DCHECK(web_app_info);
web_app->SetName(base::UTF16ToUTF8(web_app_info->title)); std::vector<BitmapAndSource> downloaded_icons =
web_app->SetDescription(base::UTF16ToUTF8(web_app_info->description)); FilterSquareIcons(icons_map, *web_app_info);
web_app->SetLaunchUrl(web_app_info->app_url); ResizeDownloadedIconsGenerateMissing(std::move(downloaded_icons),
web_app->SetScope(web_app_info->scope); web_app_info.get());
web_app->SetThemeColor(web_app_info->theme_color);
registrar_->RegisterApp(std::move(web_app)); install_finalizer_->FinalizeInstall(
std::move(web_app_info),
base::BindOnce(&WebAppInstallManager::OnInstallFinalized,
weak_ptr_factory_.GetWeakPtr()));
}
CallInstallCallback(app_id, InstallResultCode::kSuccess); void WebAppInstallManager::OnInstallFinalized(const AppId& app_id,
InstallResultCode code) {
CallInstallCallback(app_id, code);
} }
} // namespace web_app } // namespace web_app
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chrome/browser/web_applications/components/install_manager.h" #include "chrome/browser/web_applications/components/install_manager.h"
#include "chrome/browser/web_applications/components/web_app_install_utils.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
class Profile; class Profile;
...@@ -25,13 +26,14 @@ class WebContents; ...@@ -25,13 +26,14 @@ class WebContents;
namespace web_app { namespace web_app {
class InstallFinalizer;
class WebAppDataRetriever; class WebAppDataRetriever;
class WebAppRegistrar;
class WebAppInstallManager final : public InstallManager, class WebAppInstallManager final : public InstallManager,
content::WebContentsObserver { content::WebContentsObserver {
public: public:
WebAppInstallManager(Profile* profile, WebAppRegistrar* registrar); WebAppInstallManager(Profile* profile,
std::unique_ptr<InstallFinalizer> install_finalizer);
~WebAppInstallManager() override; ~WebAppInstallManager() override;
// InstallManager: // InstallManager:
...@@ -45,6 +47,8 @@ class WebAppInstallManager final : public InstallManager, ...@@ -45,6 +47,8 @@ class WebAppInstallManager final : public InstallManager,
void SetDataRetrieverForTesting( void SetDataRetrieverForTesting(
std::unique_ptr<WebAppDataRetriever> data_retriever); std::unique_ptr<WebAppDataRetriever> data_retriever);
void SetInstallFinalizerForTesting(
std::unique_ptr<InstallFinalizer> install_finalizer);
private: private:
void CallInstallCallback(const AppId& app_id, InstallResultCode code); void CallInstallCallback(const AppId& app_id, InstallResultCode code);
...@@ -61,13 +65,15 @@ class WebAppInstallManager final : public InstallManager, ...@@ -61,13 +65,15 @@ class WebAppInstallManager final : public InstallManager,
bool force_shortcut_app, bool force_shortcut_app,
const blink::Manifest& manifest, const blink::Manifest& manifest,
bool is_installable); bool is_installable);
void OnIconsRetrieved(std::unique_ptr<WebApplicationInfo> web_app_info,
IconsMap icons_map);
void OnInstallFinalized(const AppId& app_id, InstallResultCode code);
// Saved callback: // Saved callback:
OnceInstallCallback install_callback_; OnceInstallCallback install_callback_;
Profile* profile_;
WebAppRegistrar* registrar_;
std::unique_ptr<WebAppDataRetriever> data_retriever_; std::unique_ptr<WebAppDataRetriever> data_retriever_;
std::unique_ptr<InstallFinalizer> install_finalizer_;
base::WeakPtrFactory<WebAppInstallManager> weak_ptr_factory_{this}; base::WeakPtrFactory<WebAppInstallManager> weak_ptr_factory_{this};
......
...@@ -16,10 +16,13 @@ ...@@ -16,10 +16,13 @@
#include "chrome/browser/installable/installable_manager.h" #include "chrome/browser/installable/installable_manager.h"
#include "chrome/browser/ssl/security_state_tab_helper.h" #include "chrome/browser/ssl/security_state_tab_helper.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_icon_generator.h"
#include "chrome/browser/web_applications/test/test_data_retriever.h" #include "chrome/browser/web_applications/test/test_data_retriever.h"
#include "chrome/browser/web_applications/test/test_install_finalizer.h"
#include "chrome/browser/web_applications/test/test_web_app_database.h" #include "chrome/browser/web_applications/test/test_web_app_database.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.h"
#include "chrome/browser/web_applications/web_app_install_finalizer.h"
#include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_utils.h" #include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
...@@ -36,8 +39,11 @@ class WebAppInstallManagerTest : public WebAppTest { ...@@ -36,8 +39,11 @@ class WebAppInstallManagerTest : public WebAppTest {
database_ = std::make_unique<TestWebAppDatabase>(); database_ = std::make_unique<TestWebAppDatabase>();
registrar_ = std::make_unique<WebAppRegistrar>(database_.get()); registrar_ = std::make_unique<WebAppRegistrar>(database_.get());
install_manager_ =
std::make_unique<WebAppInstallManager>(profile(), registrar_.get()); auto install_finalizer =
std::make_unique<WebAppInstallFinalizer>(registrar_.get());
install_manager_ = std::make_unique<WebAppInstallManager>(
profile(), std::move(install_finalizer));
} }
void CreateRendererAppInfo(const GURL& url, void CreateRendererAppInfo(const GURL& url,
...@@ -53,8 +59,10 @@ class WebAppInstallManagerTest : public WebAppTest { ...@@ -53,8 +59,10 @@ class WebAppInstallManagerTest : public WebAppTest {
web_app_info->scope = scope; web_app_info->scope = scope;
web_app_info->theme_color = theme_color; web_app_info->theme_color = theme_color;
install_manager_->SetDataRetrieverForTesting( auto data_retriever =
std::make_unique<TestDataRetriever>(std::move(web_app_info))); std::make_unique<TestDataRetriever>(std::move(web_app_info));
data_retriever_ = data_retriever.get();
install_manager_->SetDataRetrieverForTesting(std::move(data_retriever));
} }
void CreateRendererAppInfo(const GURL& url, void CreateRendererAppInfo(const GURL& url,
...@@ -74,10 +82,42 @@ class WebAppInstallManagerTest : public WebAppTest { ...@@ -74,10 +82,42 @@ class WebAppInstallManagerTest : public WebAppTest {
return base::NullableString16(base::UTF8ToUTF16(str), false); return base::NullableString16(base::UTF8ToUTF16(str), false);
} }
void SetInstallFinalizerForTesting() {
auto install_finalizer = std::make_unique<TestInstallFinalizer>();
install_finalizer_ = install_finalizer.get();
install_manager_->SetInstallFinalizerForTesting(
std::move(install_finalizer));
}
void SetIconsMapToRetrieve(IconsMap icons_map) {
CHECK(data_retriever_);
data_retriever_->SetIcons(std::move(icons_map));
}
AppId InstallWebApp() {
AppId app_id;
base::RunLoop run_loop;
const bool force_shortcut_app = false;
install_manager_->InstallWebApp(
web_contents(), force_shortcut_app,
base::BindLambdaForTesting(
[&](const AppId& installed_app_id, InstallResultCode code) {
EXPECT_EQ(InstallResultCode::kSuccess, code);
app_id = installed_app_id;
run_loop.Quit();
}));
run_loop.Run();
return app_id;
}
protected: protected:
std::unique_ptr<TestWebAppDatabase> database_; std::unique_ptr<TestWebAppDatabase> database_;
std::unique_ptr<WebAppRegistrar> registrar_; std::unique_ptr<WebAppRegistrar> registrar_;
std::unique_ptr<WebAppInstallManager> install_manager_; std::unique_ptr<WebAppInstallManager> install_manager_;
// Owned by install_manager_:
TestDataRetriever* data_retriever_ = nullptr;
TestInstallFinalizer* install_finalizer_ = nullptr;
}; };
TEST_F(WebAppInstallManagerTest, InstallFromWebContents) { TEST_F(WebAppInstallManagerTest, InstallFromWebContents) {
...@@ -175,7 +215,6 @@ TEST_F(WebAppInstallManagerTest, WebContentsDestroyed) { ...@@ -175,7 +215,6 @@ TEST_F(WebAppInstallManagerTest, WebContentsDestroyed) {
EXPECT_TRUE(callback_called); EXPECT_TRUE(callback_called);
} }
// TODO(loyso): Convert more tests from bookmark_app_helper_unittest.cc
TEST_F(WebAppInstallManagerTest, InstallableCheck) { TEST_F(WebAppInstallManagerTest, InstallableCheck) {
const std::string renderer_description = "RendererDescription"; const std::string renderer_description = "RendererDescription";
CreateRendererAppInfo(GURL("https://renderer.com/path"), "RendererName", CreateRendererAppInfo(GURL("https://renderer.com/path"), "RendererName",
...@@ -188,6 +227,7 @@ TEST_F(WebAppInstallManagerTest, InstallableCheck) { ...@@ -188,6 +227,7 @@ TEST_F(WebAppInstallManagerTest, InstallableCheck) {
const GURL manifest_scope = GURL("https://example.com/scope"); const GURL manifest_scope = GURL("https://example.com/scope");
const base::Optional<SkColor> manifest_theme_color = 0xAABBCCDD; const base::Optional<SkColor> manifest_theme_color = 0xAABBCCDD;
{
auto manifest = std::make_unique<blink::Manifest>(); auto manifest = std::make_unique<blink::Manifest>();
manifest->short_name = ToNullableUTF16("Short Name from Manifest"); manifest->short_name = ToNullableUTF16("Short Name from Manifest");
manifest->name = ToNullableUTF16(manifest_name); manifest->name = ToNullableUTF16(manifest_name);
...@@ -198,6 +238,7 @@ TEST_F(WebAppInstallManagerTest, InstallableCheck) { ...@@ -198,6 +238,7 @@ TEST_F(WebAppInstallManagerTest, InstallableCheck) {
FakeInstallableManager::CreateForWebContentsWithManifest( FakeInstallableManager::CreateForWebContentsWithManifest(
web_contents(), NO_ERROR_DETECTED, GURL("https://example.com/manifest"), web_contents(), NO_ERROR_DETECTED, GURL("https://example.com/manifest"),
std::move(manifest)); std::move(manifest));
}
base::RunLoop run_loop; base::RunLoop run_loop;
bool callback_called = false; bool callback_called = false;
...@@ -228,4 +269,42 @@ TEST_F(WebAppInstallManagerTest, InstallableCheck) { ...@@ -228,4 +269,42 @@ TEST_F(WebAppInstallManagerTest, InstallableCheck) {
EXPECT_EQ(manifest_theme_color, web_app->theme_color()); EXPECT_EQ(manifest_theme_color, web_app->theme_color());
} }
TEST_F(WebAppInstallManagerTest, GetIcons_NoIconsProvided) {
CreateRendererAppInfo(GURL("https://example.com/path"), "Name",
"Description");
CreateDefaultInstallableManager();
SetInstallFinalizerForTesting();
IconsMap icons_map;
SetIconsMapToRetrieve(std::move(icons_map));
InstallWebApp();
std::unique_ptr<WebApplicationInfo> info = install_finalizer_->web_app_info();
constexpr int kIconSizesToGenerate[] = {
icon_size::k32, icon_size::k64, icon_size::k48,
icon_size::k96, icon_size::k128, icon_size::k256,
};
// Make sure that icons have been generated for all sizes.
for (int size : kIconSizesToGenerate) {
int generated_icons_for_size =
std::count_if(info->icons.begin(), info->icons.end(),
[&size](const WebApplicationInfo::IconInfo& icon) {
return icon.width == size && icon.height == size;
});
EXPECT_EQ(1, generated_icons_for_size);
}
for (const auto& icon : info->icons) {
EXPECT_FALSE(icon.data.drawsNothing());
// Since all icons are generated, they should have an empty url.
EXPECT_TRUE(icon.url.is_empty());
}
}
// TODO(loyso): Convert more tests from bookmark_app_helper_unittest.cc
} // namespace web_app } // namespace web_app
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/browser/web_applications/system_web_app_manager.h"
#include "chrome/browser/web_applications/web_app_database.h" #include "chrome/browser/web_applications/web_app_database.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_install_finalizer.h"
#include "chrome/browser/web_applications/web_app_install_manager.h" #include "chrome/browser/web_applications/web_app_install_manager.h"
#include "chrome/browser/web_applications/web_app_provider_factory.h" #include "chrome/browser/web_applications/web_app_provider_factory.h"
#include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/browser/web_applications/web_app_registrar.h"
...@@ -61,8 +62,11 @@ void WebAppProvider::CreateWebAppsSubsystems(Profile* profile) { ...@@ -61,8 +62,11 @@ void WebAppProvider::CreateWebAppsSubsystems(Profile* profile) {
database_factory_ = std::make_unique<WebAppDatabaseFactory>(profile); database_factory_ = std::make_unique<WebAppDatabaseFactory>(profile);
database_ = std::make_unique<WebAppDatabase>(database_factory_.get()); database_ = std::make_unique<WebAppDatabase>(database_factory_.get());
registrar_ = std::make_unique<WebAppRegistrar>(database_.get()); registrar_ = std::make_unique<WebAppRegistrar>(database_.get());
install_manager_ =
std::make_unique<WebAppInstallManager>(profile, registrar_.get()); auto install_finalizer =
std::make_unique<WebAppInstallFinalizer>(registrar_.get());
install_manager_ = std::make_unique<WebAppInstallManager>(
profile, std::move(install_finalizer));
registrar_->Init(base::DoNothing()); registrar_->Init(base::DoNothing());
} }
......
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