Commit fd3894ec authored by Alexey Baskakov's avatar Alexey Baskakov Committed by Commit Bot

WebApp: Introduce WebApp, WebAppRegistrar and InstallManager entities.

Introduce DesktopPWAsWithoutExtensions command line switch.

A WebApp represents single web app.
WebApp objects are owned by WebAppRegistrar.

WebAppRegistrar is a root entity which is able to add/remove new apps.
Later WebAppRegistrar will be able:
- to iterate over all the registered apps.
- to iterate over various subsets of all registered apps (shortcut apps)
- to survive the browser (and ChromeOS) relaunch (persistence)

InstallManager is an abstract manager to plumb 3-dot menu user installation.
We will evolve its WebAppInstallManager implementation
into comprehensive install manager later.

--enable-features=DesktopPWAsWithoutExtensions will enable off-extensions
implementation for Desktop PWAs.

Bug: 891172, 871116
Change-Id: Iebcbd93cf08eec0f11c7c22dce57ded81a2a2e94
Reviewed-on: https://chromium-review.googlesource.com/c/1275468Reviewed-by: default avatarBen Wells <benwells@chromium.org>
Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Commit-Queue: Alexey Baskakov <loyso@chromium.org>
Cr-Commit-Position: refs/heads/master@{#599887}
parent 5826ca3c
...@@ -3970,6 +3970,9 @@ jumbo_split_static_library("browser") { ...@@ -3970,6 +3970,9 @@ jumbo_split_static_library("browser") {
"//chrome/browser/extensions", "//chrome/browser/extensions",
"//chrome/browser/web_applications", "//chrome/browser/web_applications",
# TODO(loyso): Erase these. crbug.com/877898.
"//chrome/browser/web_applications:web_applications_on_extensions",
"//chrome/browser/web_applications/bookmark_apps", "//chrome/browser/web_applications/bookmark_apps",
"//chrome/browser/web_applications/components", "//chrome/browser/web_applications/components",
"//chrome/browser/web_applications/extensions", "//chrome/browser/web_applications/extensions",
...@@ -3978,6 +3981,7 @@ jumbo_split_static_library("browser") { ...@@ -3978,6 +3981,7 @@ jumbo_split_static_library("browser") {
"//apps", "//apps",
"//chrome/browser/sync_file_system/drive_backend:sync_file_system_drive_proto", "//chrome/browser/sync_file_system/drive_backend:sync_file_system_drive_proto",
"//chrome/browser/web_applications", "//chrome/browser/web_applications",
"//chrome/browser/web_applications:web_applications_on_extensions",
"//chrome/browser/web_applications/bookmark_apps", "//chrome/browser/web_applications/bookmark_apps",
"//chrome/browser/web_applications/components", "//chrome/browser/web_applications/components",
"//chrome/browser/web_applications/extensions", "//chrome/browser/web_applications/extensions",
......
...@@ -69,7 +69,7 @@ source_set("chromeos") { ...@@ -69,7 +69,7 @@ source_set("chromeos") {
"//chrome/browser/extensions", "//chrome/browser/extensions",
"//chrome/browser/resource_coordinator:tab_metrics_event_proto", "//chrome/browser/resource_coordinator:tab_metrics_event_proto",
"//chrome/browser/ssl:proto", "//chrome/browser/ssl:proto",
"//chrome/browser/web_applications", "//chrome/browser/web_applications:web_applications_on_extensions",
"//chrome/browser/web_applications/bookmark_apps", "//chrome/browser/web_applications/bookmark_apps",
"//chrome/browser/web_applications/components", "//chrome/browser/web_applications/components",
"//chrome/common", "//chrome/common",
......
...@@ -1258,6 +1258,10 @@ jumbo_split_static_library("ui") { ...@@ -1258,6 +1258,10 @@ jumbo_split_static_library("ui") {
if (enable_extensions) { if (enable_extensions) {
deps += [ deps += [
"//chrome/browser/web_applications",
# TODO(loyso): Erase these. crbug.com/877898.
"//chrome/browser/web_applications:web_applications_on_extensions",
"//chrome/browser/web_applications/components", "//chrome/browser/web_applications/components",
"//chrome/browser/web_applications/extensions", "//chrome/browser/web_applications/extensions",
] ]
......
...@@ -99,9 +99,9 @@ ...@@ -99,9 +99,9 @@
#if BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/api/commands/command_service.h" #include "chrome/browser/extensions/api/commands/command_service.h"
#include "chrome/browser/extensions/api/extension_action/extension_action_api.h" #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/ui/extensions/settings_api_bubble_helpers.h" #include "chrome/browser/ui/extensions/settings_api_bubble_helpers.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/common/extensions/extension_metrics.h" #include "chrome/common/extensions/extension_metrics.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry.h"
...@@ -1256,15 +1256,13 @@ bool CanViewSource(const Browser* browser) { ...@@ -1256,15 +1256,13 @@ bool CanViewSource(const Browser* browser) {
void CreateBookmarkAppFromCurrentWebContents(Browser* browser, void CreateBookmarkAppFromCurrentWebContents(Browser* browser,
bool force_shortcut_app) { bool force_shortcut_app) {
base::RecordAction(UserMetricsAction("CreateHostedApp")); base::RecordAction(UserMetricsAction("CreateHostedApp"));
extensions::TabHelper::FromWebContents( web_app::WebAppProvider::InstallWebApp(
browser->tab_strip_model()->GetActiveWebContents()) browser->tab_strip_model()->GetActiveWebContents(), force_shortcut_app);
->CreateHostedAppFromWebContents(force_shortcut_app);
} }
bool CanCreateBookmarkApp(const Browser* browser) { bool CanCreateBookmarkApp(const Browser* browser) {
return extensions::TabHelper::FromWebContents( return web_app::WebAppProvider::CanInstallWebApp(
browser->tab_strip_model()->GetActiveWebContents()) browser->tab_strip_model()->GetActiveWebContents());
->CanCreateBookmarkApp();
} }
#endif // BUILDFLAG(ENABLE_EXTENSIONS) #endif // BUILDFLAG(ENABLE_EXTENSIONS)
......
...@@ -7,6 +7,71 @@ group("web_app_group") { ...@@ -7,6 +7,71 @@ group("web_app_group") {
} }
source_set("web_applications") { source_set("web_applications") {
sources = [
"web_app.cc",
"web_app.h",
"web_app_install_manager.cc",
"web_app_install_manager.h",
"web_app_registrar.cc",
"web_app_registrar.h",
"web_app_utils.cc",
"web_app_utils.h",
]
deps = [
":web_app_group",
"//chrome/browser/web_applications/components",
"//chrome/common",
"//content/public/browser",
"//skia",
]
}
source_set("web_applications_test_support") {
testonly = true
sources = [
"test/test_data_retriever.cc",
"test/test_data_retriever.h",
"test/web_app_test.cc",
"test/web_app_test.h",
]
deps = [
":web_app_group",
":web_applications",
"//chrome/browser/web_applications/components",
"//chrome/test:test_support",
"//testing/gtest",
]
}
source_set("web_applications_unit_tests") {
testonly = true
sources = [
"web_app_install_manager_unittest.cc",
"web_app_registrar_unittest.cc",
]
deps = [
":web_app_group",
":web_applications",
":web_applications_test_support",
"//base/test:test_support",
"//chrome/browser",
"//chrome/browser/web_applications/components",
"//chrome/common",
"//chrome/test:test_support",
"//content/public/browser",
"//content/test:test_support",
"//skia",
]
}
# TODO(loyso): Erase this and move WebAppProvider into web_applications set.
# crbug.com/877898
source_set("web_applications_on_extensions") {
sources = [ sources = [
"web_app_provider.cc", "web_app_provider.cc",
"web_app_provider.h", "web_app_provider.h",
...@@ -16,6 +81,7 @@ source_set("web_applications") { ...@@ -16,6 +81,7 @@ source_set("web_applications") {
deps = [ deps = [
":web_app_group", ":web_app_group",
":web_applications",
"//chrome/browser/web_applications/bookmark_apps", "//chrome/browser/web_applications/bookmark_apps",
"//chrome/browser/web_applications/components", "//chrome/browser/web_applications/components",
"//chrome/browser/web_applications/extensions", "//chrome/browser/web_applications/extensions",
...@@ -30,6 +96,7 @@ source_set("unit_tests") { ...@@ -30,6 +96,7 @@ source_set("unit_tests") {
deps = [ deps = [
":web_app_group", ":web_app_group",
":web_applications_unit_tests",
"//chrome/browser/web_applications/bookmark_apps:unit_tests", "//chrome/browser/web_applications/bookmark_apps:unit_tests",
"//chrome/browser/web_applications/components:unit_tests", "//chrome/browser/web_applications/components:unit_tests",
"//chrome/browser/web_applications/extensions:unit_tests", "//chrome/browser/web_applications/extensions:unit_tests",
......
...@@ -8,6 +8,8 @@ assert(enable_extensions) ...@@ -8,6 +8,8 @@ assert(enable_extensions)
source_set("bookmark_apps") { source_set("bookmark_apps") {
sources = [ sources = [
"bookmark_app_install_manager.cc",
"bookmark_app_install_manager.h",
"external_web_apps.cc", "external_web_apps.cc",
"external_web_apps.h", "external_web_apps.h",
"policy/web_app_policy_constants.cc", "policy/web_app_policy_constants.cc",
...@@ -44,7 +46,7 @@ source_set("unit_tests") { ...@@ -44,7 +46,7 @@ source_set("unit_tests") {
"//base", "//base",
"//chrome/browser", "//chrome/browser",
"//chrome/browser/web_applications:web_app_group", "//chrome/browser/web_applications:web_app_group",
"//chrome/browser/web_applications:web_applications", "//chrome/browser/web_applications:web_applications_on_extensions",
"//chrome/browser/web_applications/components", "//chrome/browser/web_applications/components",
"//chrome/browser/web_applications/components:test_support", "//chrome/browser/web_applications/components:test_support",
"//chrome/browser/web_applications/extensions", "//chrome/browser/web_applications/extensions",
......
// 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 "chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/web_contents.h"
namespace extensions {
BookmarkAppInstallManager::BookmarkAppInstallManager() = default;
BookmarkAppInstallManager::~BookmarkAppInstallManager() = default;
bool BookmarkAppInstallManager::CanInstallWebApp(
const content::WebContents* web_contents) {
return extensions::TabHelper::FromWebContents(web_contents)
->CanCreateBookmarkApp();
}
void BookmarkAppInstallManager::InstallWebApp(
content::WebContents* web_contents,
bool force_shortcut_app) {
extensions::TabHelper::FromWebContents(web_contents)
->CreateHostedAppFromWebContents(force_shortcut_app);
}
} // namespace extensions
// 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_BOOKMARK_APPS_BOOKMARK_APP_INSTALL_MANAGER_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_BOOKMARK_APPS_BOOKMARK_APP_INSTALL_MANAGER_H_
#include "base/macros.h"
#include "chrome/browser/web_applications/components/install_manager.h"
namespace extensions {
class BookmarkAppInstallManager final : public web_app::InstallManager {
public:
BookmarkAppInstallManager();
~BookmarkAppInstallManager() override;
// InstallManager interface implementation.
bool CanInstallWebApp(const content::WebContents* web_contents) override;
void InstallWebApp(content::WebContents* web_contents,
bool force_shortcut_app) override;
private:
DISALLOW_COPY_AND_ASSIGN(BookmarkAppInstallManager);
};
} // namespace extensions
#endif // CHROME_BROWSER_WEB_APPLICATIONS_BOOKMARK_APPS_BOOKMARK_APP_INSTALL_MANAGER_H_
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
source_set("components") { source_set("components") {
sources = [ sources = [
"install_manager.h",
"install_result_code.h", "install_result_code.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_MANAGER_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_INSTALL_MANAGER_H_
namespace content {
class WebContents;
}
namespace web_app {
class InstallManager {
public:
// Returns true if a web app can be installed for a given |web_contents|.
virtual bool CanInstallWebApp(const content::WebContents* web_contents) = 0;
// Starts a web app installation process for a given |web_contents|.
virtual void InstallWebApp(content::WebContents* web_contents,
bool force_shortcut_app) = 0;
virtual ~InstallManager() = default;
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_INSTALL_MANAGER_H_
...@@ -19,6 +19,7 @@ enum class InstallResultCode { ...@@ -19,6 +19,7 @@ enum class InstallResultCode {
kAlreadyInstalled, kAlreadyInstalled,
// Catch-all failure category. More-specific failure categories are below. // Catch-all failure category. More-specific failure categories are below.
kFailedUnknownReason, kFailedUnknownReason,
kGetWebApplicationInfoFailed,
kPreviouslyUninstalled, kPreviouslyUninstalled,
}; };
......
...@@ -42,9 +42,6 @@ source_set("unit_tests") { ...@@ -42,9 +42,6 @@ source_set("unit_tests") {
testonly = true testonly = true
sources = [ sources = [
# TODO(loyso): Extract it into web_applications_test_support set.
"../test/test_data_retriever.cc",
"../test/test_data_retriever.h",
"bookmark_app_installation_task_unittest.cc", "bookmark_app_installation_task_unittest.cc",
"bookmark_app_installer_unittest.cc", "bookmark_app_installer_unittest.cc",
"pending_bookmark_app_manager_unittest.cc", "pending_bookmark_app_manager_unittest.cc",
...@@ -55,6 +52,7 @@ source_set("unit_tests") { ...@@ -55,6 +52,7 @@ source_set("unit_tests") {
":extensions", ":extensions",
"//chrome/browser", "//chrome/browser",
"//chrome/browser/web_applications:web_app_group", "//chrome/browser/web_applications:web_app_group",
"//chrome/browser/web_applications:web_applications_test_support",
"//chrome/browser/web_applications/components", "//chrome/browser/web_applications/components",
"//chrome/common", "//chrome/common",
"//chrome/test:test_support", "//chrome/test:test_support",
...@@ -82,8 +80,8 @@ source_set("browser_tests") { ...@@ -82,8 +80,8 @@ source_set("browser_tests") {
"//base/test:test_support", "//base/test:test_support",
"//chrome/browser", "//chrome/browser",
"//chrome/browser/ui", "//chrome/browser/ui",
"//chrome/browser/web_applications",
"//chrome/browser/web_applications:web_app_group", "//chrome/browser/web_applications:web_app_group",
"//chrome/browser/web_applications:web_applications_on_extensions",
"//chrome/browser/web_applications/components", "//chrome/browser/web_applications/components",
"//chrome/test:test_support_ui", "//chrome/test:test_support_ui",
"//extensions/browser", "//extensions/browser",
......
// 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 "chrome/browser/web_applications/test/web_app_test.h"
namespace web_app {
WebAppTest::WebAppTest() = default;
WebAppTest::~WebAppTest() = default;
} // namespace web_app
// Copyright (c) 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_WEB_APP_TEST_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_TEST_WEB_APP_TEST_H_
#include "base/macros.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
namespace web_app {
class WebAppTest : public ChromeRenderViewHostTestHarness {
public:
WebAppTest();
~WebAppTest() override;
private:
DISALLOW_COPY_AND_ASSIGN(WebAppTest);
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_TEST_WEB_APP_TEST_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 "chrome/browser/web_applications/web_app.h"
namespace web_app {
WebApp::WebApp(const AppId& app_id) : app_id_(app_id) {}
WebApp::~WebApp() = default;
void WebApp::SetName(const std::string& name) {
name_ = name;
}
void WebApp::SetDescription(const std::string& description) {
description_ = description;
}
void WebApp::SetLaunchUrl(const std::string& launch_url) {
launch_url_ = launch_url;
}
} // 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_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_H_
#include <string>
#include "base/macros.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
namespace web_app {
class WebApp {
public:
explicit WebApp(const AppId& app_id);
~WebApp();
const AppId& app_id() const { return app_id_; }
const std::string& name() const { return name_; }
const std::string& description() const { return description_; }
const std::string& launch_url() const { return launch_url_; }
void SetName(const std::string& name);
void SetDescription(const std::string& description);
void SetLaunchUrl(const std::string& launch_url);
private:
const AppId app_id_;
std::string name_;
std::string description_;
std::string launch_url_;
DISALLOW_COPY_AND_ASSIGN(WebApp);
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_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 "chrome/browser/web_applications/web_app_install_manager.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/web_applications/components/install_result_code.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/web_app.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/common/web_application_info.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
namespace web_app {
WebAppInstallManager::WebAppInstallManager(Profile* profile,
WebAppRegistrar* registrar)
: profile_(profile),
registrar_(registrar),
data_retriever_(std::make_unique<WebAppDataRetriever>()) {
DCHECK(AllowWebAppInstallation(profile_));
}
WebAppInstallManager::~WebAppInstallManager() = default;
bool WebAppInstallManager::CanInstallWebApp(
const content::WebContents* web_contents) {
return IsValidWebAppUrl(web_contents->GetURL());
}
void WebAppInstallManager::InstallWebApp(content::WebContents* web_contents,
bool force_shortcut_app) {
// TODO(loyso): Use force_shortcut_app flag during installation.
InstallFromWebContents(web_contents, base::DoNothing());
}
void WebAppInstallManager::SetDataRetrieverForTesting(
std::unique_ptr<WebAppDataRetriever> data_retriever) {
data_retriever_ = std::move(data_retriever);
}
void WebAppInstallManager::InstallWebAppForTesting(
content::WebContents* web_contents,
OnceInstallCallback callback) {
InstallFromWebContents(web_contents, std::move(callback));
}
void WebAppInstallManager::InstallFromWebContents(
content::WebContents* web_contents,
OnceInstallCallback install_callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
data_retriever_->GetWebApplicationInfo(
web_contents,
base::BindOnce(&WebAppInstallManager::OnGetWebApplicationInfo,
weak_ptr_factory_.GetWeakPtr(),
std::move(install_callback)));
}
void WebAppInstallManager::OnGetWebApplicationInfo(
OnceInstallCallback install_callback,
std::unique_ptr<WebApplicationInfo> web_app_info) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (!web_app_info) {
std::move(install_callback)
.Run(AppId(), InstallResultCode::kGetWebApplicationInfoFailed);
return;
}
// TODO(loyso): Implement installation logic from BookmarkAppHelper:
// - InstallableManager to get InstallableData.
// - UpdateWebAppInfoFromManifest.
// - UpdateShareTargetInPrefs.
// - WebAppIconDownloader.
// etc
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.spec());
registrar_->RegisterApp(std::move(web_app));
std::move(install_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_MANAGER_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_INSTALL_MANAGER_H_
#include "base/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/web_applications/components/install_manager.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
class Profile;
struct WebApplicationInfo;
namespace web_app {
enum class InstallResultCode;
class WebAppDataRetriever;
class WebAppRegistrar;
class WebAppInstallManager final : public InstallManager {
public:
WebAppInstallManager(Profile* profile, WebAppRegistrar* registrar);
~WebAppInstallManager() override;
using OnceInstallCallback =
base::OnceCallback<void(const AppId& app_id, InstallResultCode code)>;
// InstallManager interface implementation.
bool CanInstallWebApp(const content::WebContents* web_contents) override;
void InstallWebApp(content::WebContents* web_contents,
bool force_shortcut_app) override;
void SetDataRetrieverForTesting(
std::unique_ptr<WebAppDataRetriever> data_retriever);
void InstallWebAppForTesting(content::WebContents* web_contents,
OnceInstallCallback callback);
private:
void InstallFromWebContents(content::WebContents* web_contents,
OnceInstallCallback callback);
void OnGetWebApplicationInfo(
OnceInstallCallback install_callback,
std::unique_ptr<WebApplicationInfo> web_app_info);
Profile* profile_;
WebAppRegistrar* registrar_;
std::unique_ptr<WebAppDataRetriever> data_retriever_;
base::WeakPtrFactory<WebAppInstallManager> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(WebAppInstallManager);
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_INSTALL_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.
#include "chrome/browser/web_applications/web_app_install_manager.h"
#include "base/callback.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
#include "chrome/browser/web_applications/components/install_result_code.h"
#include "chrome/browser/web_applications/test/test_data_retriever.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/browser/web_applications/web_app_utils.h"
#include "chrome/test/base/testing_profile.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace web_app {
class WebAppInstallManagerTest : public WebAppTest {};
TEST_F(WebAppInstallManagerTest, InstallFromWebContents) {
EXPECT_EQ(true, AllowWebAppInstallation(profile()));
auto registrar = std::make_unique<WebAppRegistrar>();
auto manager =
std::make_unique<WebAppInstallManager>(profile(), registrar.get());
auto web_app_info = std::make_unique<WebApplicationInfo>();
const GURL url = GURL("https://example.com/path");
const std::string name = "Name";
const std::string description = "Description";
const AppId app_id = GenerateAppIdFromURL(url);
web_app_info->app_url = url;
web_app_info->title = base::UTF8ToUTF16(name);
web_app_info->description = base::UTF8ToUTF16(description);
manager->SetDataRetrieverForTesting(
std::make_unique<TestDataRetriever>(std::move(web_app_info)));
base::RunLoop run_loop;
bool callback_called = false;
manager->InstallWebAppForTesting(
web_contents(),
base::BindLambdaForTesting(
[&](const AppId& installed_app_id, InstallResultCode code) {
EXPECT_EQ(InstallResultCode::kSuccess, code);
EXPECT_EQ(app_id, installed_app_id);
callback_called = true;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, run_loop.QuitClosure());
}));
run_loop.Run();
EXPECT_TRUE(callback_called);
WebApp* web_app = registrar->GetAppById(app_id);
EXPECT_NE(nullptr, web_app);
EXPECT_EQ(app_id, web_app->app_id());
EXPECT_EQ(name, web_app->name());
EXPECT_EQ(description, web_app->description());
EXPECT_EQ(url.spec(), web_app->launch_url());
}
TEST_F(WebAppInstallManagerTest, GetWebApplicationInfoFailed) {
auto registrar = std::make_unique<WebAppRegistrar>();
auto manager =
std::make_unique<WebAppInstallManager>(profile(), registrar.get());
manager->SetDataRetrieverForTesting(std::make_unique<TestDataRetriever>(
std::unique_ptr<WebApplicationInfo>()));
base::RunLoop run_loop;
bool callback_called = false;
manager->InstallWebAppForTesting(
web_contents(),
base::BindLambdaForTesting(
[&](const AppId& installed_app_id, InstallResultCode code) {
EXPECT_EQ(InstallResultCode::kGetWebApplicationInfoFailed, code);
EXPECT_EQ(AppId(), installed_app_id);
callback_called = true;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, run_loop.QuitClosure());
}));
run_loop.Run();
EXPECT_TRUE(callback_called);
}
} // namespace web_app
...@@ -7,16 +7,25 @@ ...@@ -7,16 +7,25 @@
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/feature_list.h"
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/web_applications/bookmark_apps/bookmark_app_install_manager.h"
#include "chrome/browser/web_applications/bookmark_apps/external_web_apps.h" #include "chrome/browser/web_applications/bookmark_apps/external_web_apps.h"
#include "chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager.h" #include "chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager.h"
#include "chrome/browser/web_applications/bookmark_apps/system_web_app_manager.h" #include "chrome/browser/web_applications/bookmark_apps/system_web_app_manager.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/extensions/pending_bookmark_app_manager.h" #include "chrome/browser/web_applications/extensions/pending_bookmark_app_manager.h"
#include "chrome/browser/web_applications/extensions/web_app_extension_ids_map.h" #include "chrome/browser/web_applications/extensions/web_app_extension_ids_map.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_utils.h"
#include "chrome/common/chrome_features.h"
#include "content/public/browser/notification_source.h" #include "content/public/browser/notification_source.h"
#include "content/public/browser/web_contents.h"
namespace web_app { namespace web_app {
...@@ -25,9 +34,39 @@ WebAppProvider* WebAppProvider::Get(Profile* profile) { ...@@ -25,9 +34,39 @@ WebAppProvider* WebAppProvider::Get(Profile* profile) {
return WebAppProviderFactory::GetForProfile(profile); return WebAppProviderFactory::GetForProfile(profile);
} }
WebAppProvider::WebAppProvider(Profile* profile) // static
: pending_app_manager_( WebAppProvider* WebAppProvider::GetForWebContents(
std::make_unique<extensions::PendingBookmarkAppManager>(profile)) { const content::WebContents* web_contents) {
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
DCHECK(profile);
return WebAppProvider::Get(profile);
}
WebAppProvider::WebAppProvider(Profile* profile) {
if (base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions))
CreateWebAppsSubsystems(profile);
else
CreateBookmarkAppsSubsystems(profile);
}
WebAppProvider::~WebAppProvider() = default;
void WebAppProvider::CreateWebAppsSubsystems(Profile* profile) {
if (!AllowWebAppInstallation(profile))
return;
registrar_ = std::make_unique<WebAppRegistrar>();
install_manager_ =
std::make_unique<WebAppInstallManager>(profile, registrar_.get());
}
void WebAppProvider::CreateBookmarkAppsSubsystems(Profile* profile) {
install_manager_ = std::make_unique<extensions::BookmarkAppInstallManager>();
pending_app_manager_ =
std::make_unique<extensions::PendingBookmarkAppManager>(profile);
if (WebAppPolicyManager::ShouldEnableForProfile(profile)) { if (WebAppPolicyManager::ShouldEnableForProfile(profile)) {
web_app_policy_manager_ = std::make_unique<WebAppPolicyManager>( web_app_policy_manager_ = std::make_unique<WebAppPolicyManager>(
profile, pending_app_manager_.get()); profile, pending_app_manager_.get());
...@@ -44,8 +83,6 @@ WebAppProvider::WebAppProvider(Profile* profile) ...@@ -44,8 +83,6 @@ WebAppProvider::WebAppProvider(Profile* profile)
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
} }
WebAppProvider::~WebAppProvider() = default;
// static // static
void WebAppProvider::RegisterProfilePrefs( void WebAppProvider::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) { user_prefs::PrefRegistrySyncable* registry) {
...@@ -53,12 +90,38 @@ void WebAppProvider::RegisterProfilePrefs( ...@@ -53,12 +90,38 @@ void WebAppProvider::RegisterProfilePrefs(
WebAppPolicyManager::RegisterProfilePrefs(registry); WebAppPolicyManager::RegisterProfilePrefs(registry);
} }
// static
bool WebAppProvider::CanInstallWebApp(
const content::WebContents* web_contents) {
auto* provider = WebAppProvider::GetForWebContents(web_contents);
if (!provider || !provider->install_manager_)
return false;
return provider->install_manager_->CanInstallWebApp(web_contents);
}
// static
void WebAppProvider::InstallWebApp(content::WebContents* web_contents,
bool force_shortcut_app) {
auto* provider = WebAppProvider::GetForWebContents(web_contents);
if (!provider || !provider->install_manager_)
return;
provider->install_manager_->InstallWebApp(web_contents, force_shortcut_app);
}
void WebAppProvider::Reset() { void WebAppProvider::Reset() {
// TODO(loyso): Make it independent to the order of destruction via using two
// end-to-end passes:
// 1) Do Reset() for each subsystem to nullify pointers (detach subsystems).
// 2) Destroy subsystems.
// PendingAppManager is used by WebAppPolicyManager and therefore should be // PendingAppManager is used by WebAppPolicyManager and therefore should be
// deleted after it. // deleted after it.
web_app_policy_manager_.reset(); web_app_policy_manager_.reset();
system_web_app_manager_.reset(); system_web_app_manager_.reset();
pending_app_manager_.reset(); pending_app_manager_.reset();
install_manager_.reset();
registrar_.reset();
} }
void WebAppProvider::Observe(int type, void WebAppProvider::Observe(int type,
......
...@@ -17,13 +17,24 @@ ...@@ -17,13 +17,24 @@
class Profile; class Profile;
namespace content {
class WebContents;
}
namespace user_prefs { namespace user_prefs {
class PrefRegistrySyncable; class PrefRegistrySyncable;
} }
namespace web_app { namespace web_app {
// Forward declarations of generalized interfaces.
class PendingAppManager; class PendingAppManager;
class InstallManager;
// Forward declarations for new extension-independent subsystems.
class WebAppRegistrar;
// Forward declarations for legacy extension-based subsystems.
class WebAppPolicyManager; class WebAppPolicyManager;
class SystemWebAppManager; class SystemWebAppManager;
...@@ -34,6 +45,8 @@ class WebAppProvider : public KeyedService, ...@@ -34,6 +45,8 @@ class WebAppProvider : public KeyedService,
public content::NotificationObserver { public content::NotificationObserver {
public: public:
static WebAppProvider* Get(Profile* profile); static WebAppProvider* Get(Profile* profile);
static WebAppProvider* GetForWebContents(
const content::WebContents* web_contents);
explicit WebAppProvider(Profile* profile); explicit WebAppProvider(Profile* profile);
...@@ -45,6 +58,13 @@ class WebAppProvider : public KeyedService, ...@@ -45,6 +58,13 @@ class WebAppProvider : public KeyedService,
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// Returns true if a bookmark can be installed for a given |web_contents|.
static bool CanInstallWebApp(const content::WebContents* web_contents);
// Starts a bookmark installation process for a given |web_contents|.
static void InstallWebApp(content::WebContents* web_contents,
bool force_shortcut_app);
void Reset(); void Reset();
// content::NotificationObserver // content::NotificationObserver
...@@ -53,10 +73,22 @@ class WebAppProvider : public KeyedService, ...@@ -53,10 +73,22 @@ class WebAppProvider : public KeyedService,
const content::NotificationDetails& details) override; const content::NotificationDetails& details) override;
private: private:
// Create extension-independent subsystems.
void CreateWebAppsSubsystems(Profile* profile);
// ... or create legacy extension-based subsystems.
void CreateBookmarkAppsSubsystems(Profile* profile);
void OnScanForExternalWebApps( void OnScanForExternalWebApps(
std::vector<web_app::PendingAppManager::AppInfo>); std::vector<web_app::PendingAppManager::AppInfo>);
// New extension-independent subsystems:
std::unique_ptr<WebAppRegistrar> registrar_;
// New generalized subsystems:
std::unique_ptr<InstallManager> install_manager_;
std::unique_ptr<PendingAppManager> pending_app_manager_; std::unique_ptr<PendingAppManager> pending_app_manager_;
// Legacy extension-based subsystems:
std::unique_ptr<WebAppPolicyManager> web_app_policy_manager_; std::unique_ptr<WebAppPolicyManager> web_app_policy_manager_;
std::unique_ptr<SystemWebAppManager> system_web_app_manager_; std::unique_ptr<SystemWebAppManager> system_web_app_manager_;
......
// 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 "chrome/browser/web_applications/web_app_registrar.h"
#include "base/logging.h"
#include "chrome/browser/web_applications/web_app.h"
namespace web_app {
WebAppRegistrar::WebAppRegistrar() {}
WebAppRegistrar::~WebAppRegistrar() = default;
void WebAppRegistrar::RegisterApp(std::unique_ptr<WebApp> web_app) {
const auto app_id = web_app->app_id();
DCHECK(!app_id.empty());
DCHECK(!GetAppById(app_id));
registry_.emplace(std::make_pair(app_id, std::move(web_app)));
}
std::unique_ptr<WebApp> WebAppRegistrar::UnregisterApp(const AppId& app_id) {
DCHECK(!app_id.empty());
auto kv = registry_.find(app_id);
DCHECK(kv != registry_.end());
auto web_app = std::move(kv->second);
registry_.erase(kv);
return web_app;
}
WebApp* WebAppRegistrar::GetAppById(const AppId& app_id) {
auto kv = registry_.find(app_id);
return kv == registry_.end() ? nullptr : kv->second.get();
}
} // 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_REGISTRAR_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_REGISTRAR_H_
#include <map>
#include <memory>
#include "base/macros.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
namespace web_app {
class WebApp;
class WebAppRegistrar {
public:
WebAppRegistrar();
~WebAppRegistrar();
void RegisterApp(std::unique_ptr<WebApp> web_app);
std::unique_ptr<WebApp> UnregisterApp(const AppId& app_id);
WebApp* GetAppById(const AppId& app_id);
private:
std::map<AppId, std::unique_ptr<WebApp>> registry_;
DISALLOW_COPY_AND_ASSIGN(WebAppRegistrar);
};
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_REGISTRAR_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 "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace web_app {
TEST(WebAppRegistrar, CreateRegisterUnregister) {
auto registrar = std::make_unique<WebAppRegistrar>();
EXPECT_EQ(nullptr, registrar->GetAppById(AppId()));
const GURL launch_url = GURL("https://example.com/path");
const AppId app_id = GenerateAppIdFromURL(launch_url);
const std::string name = "Name";
const std::string description = "Description";
const GURL launch_url2 = GURL("https://example.com/path2");
const AppId app_id2 = GenerateAppIdFromURL(launch_url2);
auto web_app = std::make_unique<WebApp>(app_id);
auto web_app2 = std::make_unique<WebApp>(app_id2);
web_app->SetName(name);
web_app->SetDescription(description);
web_app->SetLaunchUrl(launch_url.spec());
EXPECT_EQ(nullptr, registrar->GetAppById(app_id));
EXPECT_EQ(nullptr, registrar->GetAppById(app_id2));
registrar->RegisterApp(std::move(web_app));
WebApp* app = registrar->GetAppById(app_id);
EXPECT_EQ(app_id, app->app_id());
EXPECT_EQ(name, app->name());
EXPECT_EQ(description, app->description());
EXPECT_EQ(launch_url.spec(), app->launch_url());
EXPECT_EQ(nullptr, registrar->GetAppById(app_id2));
registrar->RegisterApp(std::move(web_app2));
WebApp* app2 = registrar->GetAppById(app_id2);
EXPECT_EQ(app_id2, app2->app_id());
registrar->UnregisterApp(app_id);
EXPECT_EQ(nullptr, registrar->GetAppById(app_id));
// Check that app2 is still registered.
app2 = registrar->GetAppById(app_id2);
EXPECT_EQ(app_id2, app2->app_id());
registrar->UnregisterApp(app_id2);
EXPECT_EQ(nullptr, registrar->GetAppById(app_id2));
}
TEST(WebAppRegistrar, DestroyRegistrarOwningRegisteredApps) {
auto registrar = std::make_unique<WebAppRegistrar>();
const AppId app_id = GenerateAppIdFromURL(GURL("https://example.com/path"));
const AppId app_id2 = GenerateAppIdFromURL(GURL("https://example.com/path2"));
auto web_app = std::make_unique<WebApp>(app_id);
registrar->RegisterApp(std::move(web_app));
auto web_app2 = std::make_unique<WebApp>(app_id2);
registrar->RegisterApp(std::move(web_app2));
registrar.reset();
}
} // 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.
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/browser/profiles/profile.h"
namespace web_app {
bool AllowWebAppInstallation(Profile* profile) {
return !profile->IsGuestSession() && !profile->IsOffTheRecord() &&
!profile->IsSystemProfile();
}
} // 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_UTILS_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_UTILS_H_
class Profile;
namespace web_app {
bool AllowWebAppInstallation(Profile* profile);
} // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_UTILS_H_
...@@ -216,6 +216,11 @@ const base::Feature kDesktopPWAsLinkCapturing{ ...@@ -216,6 +216,11 @@ const base::Feature kDesktopPWAsLinkCapturing{
const base::Feature kDesktopPWAsStayInWindow{"DesktopPWAsStayInWindow", const base::Feature kDesktopPWAsStayInWindow{"DesktopPWAsStayInWindow",
base::FEATURE_ENABLED_BY_DEFAULT}; base::FEATURE_ENABLED_BY_DEFAULT};
// Enables or disables new Desktop PWAs implementation that does not use
// extensions.
const base::Feature kDesktopPWAsWithoutExtensions{
"DesktopPWAsWithoutExtensions", base::FEATURE_DISABLED_BY_DEFAULT};
// Disables downloads of unsafe file types over HTTP. // Disables downloads of unsafe file types over HTTP.
const base::Feature kDisallowUnsafeHttpDownloads{ const base::Feature kDisallowUnsafeHttpDownloads{
"DisallowUnsafeHttpDownloads", base::FEATURE_DISABLED_BY_DEFAULT}; "DisallowUnsafeHttpDownloads", base::FEATURE_DISABLED_BY_DEFAULT};
......
...@@ -133,6 +133,9 @@ extern const base::Feature kDesktopPWAsLinkCapturing; ...@@ -133,6 +133,9 @@ extern const base::Feature kDesktopPWAsLinkCapturing;
COMPONENT_EXPORT(CHROME_FEATURES) COMPONENT_EXPORT(CHROME_FEATURES)
extern const base::Feature kDesktopPWAsStayInWindow; extern const base::Feature kDesktopPWAsStayInWindow;
COMPONENT_EXPORT(CHROME_FEATURES)
extern const base::Feature kDesktopPWAsWithoutExtensions;
COMPONENT_EXPORT(CHROME_FEATURES) COMPONENT_EXPORT(CHROME_FEATURES)
extern const base::Feature kDisallowUnsafeHttpDownloads; extern const base::Feature kDisallowUnsafeHttpDownloads;
COMPONENT_EXPORT(CHROME_FEATURES) COMPONENT_EXPORT(CHROME_FEATURES)
......
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