Commit 52ee0f60 authored by Giovanni Ortuño Urquidi's avatar Giovanni Ortuño Urquidi Committed by Commit Bot

desktop-pwas: Add option to skip shortcut creation in PendingAppManager

WebAppPolicyManager would like to skip shortcut creation because there
is a separate policy to create them. So we add that option to AppInfo
and plumb it all the way down to BookmarkAppHelper

Bug: 876175
Change-Id: I09f460efe7c3809856bde77ebe4570de6ae8845e
Reviewed-on: https://chromium-review.googlesource.com/1186220
Commit-Queue: Giovanni Ortuño Urquidi <ortuno@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585788}
parent dff0ce2c
...@@ -603,6 +603,7 @@ void BookmarkAppHelper::FinishInstallation(const Extension* extension) { ...@@ -603,6 +603,7 @@ void BookmarkAppHelper::FinishInstallation(const Extension* extension) {
// On Mac, shortcuts are automatically created for hosted apps when they are // On Mac, shortcuts are automatically created for hosted apps when they are
// installed, so there is no need to create them again. // installed, so there is no need to create them again.
#if !defined(OS_MACOSX) #if !defined(OS_MACOSX)
if (create_shortcuts_) {
#if !defined(OS_CHROMEOS) #if !defined(OS_CHROMEOS)
web_app::ShortcutLocations creation_locations; web_app::ShortcutLocations creation_locations;
#if defined(OS_LINUX) || defined(OS_WIN) #if defined(OS_LINUX) || defined(OS_WIN)
...@@ -613,6 +614,7 @@ void BookmarkAppHelper::FinishInstallation(const Extension* extension) { ...@@ -613,6 +614,7 @@ void BookmarkAppHelper::FinishInstallation(const Extension* extension) {
creation_locations.applications_menu_location = creation_locations.applications_menu_location =
web_app::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS; web_app::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS;
creation_locations.in_quick_launch_bar = false; creation_locations.in_quick_launch_bar = false;
web_app::CreateShortcuts(web_app::SHORTCUT_CREATION_BY_USER, web_app::CreateShortcuts(web_app::SHORTCUT_CREATION_BY_USER,
creation_locations, current_profile, extension); creation_locations, current_profile, extension);
#else #else
...@@ -622,6 +624,7 @@ void BookmarkAppHelper::FinishInstallation(const Extension* extension) { ...@@ -622,6 +624,7 @@ void BookmarkAppHelper::FinishInstallation(const Extension* extension) {
extension->id()); extension->id());
} }
#endif // !defined(OS_CHROMEOS) #endif // !defined(OS_CHROMEOS)
}
// Reparent the tab into an app window immediately when opening as a window. // Reparent the tab into an app window immediately when opening as a window.
if (!silent_install && if (!silent_install &&
......
...@@ -96,6 +96,11 @@ class BookmarkAppHelper : public content::NotificationObserver { ...@@ -96,6 +96,11 @@ class BookmarkAppHelper : public content::NotificationObserver {
// If called, the installed extension will be considered default installed. // If called, the installed extension will be considered default installed.
void set_is_default_app() { is_default_app_ = true; } void set_is_default_app() { is_default_app_ = true; }
// If called, desktop shortcuts will not be created.
void set_skip_shortcut_creation() { create_shortcuts_ = false; }
bool create_shortcuts() const { return create_shortcuts_; }
protected: protected:
// Protected methods for testing. // Protected methods for testing.
...@@ -155,6 +160,8 @@ class BookmarkAppHelper : public content::NotificationObserver { ...@@ -155,6 +160,8 @@ class BookmarkAppHelper : public content::NotificationObserver {
bool is_default_app_ = false; bool is_default_app_ = false;
bool create_shortcuts_ = true;
// The mechanism via which the app creation was triggered. // The mechanism via which the app creation was triggered.
WebappInstallSource install_source_; WebappInstallSource install_source_;
......
...@@ -82,7 +82,9 @@ void WebAppPolicyManager::RefreshPolicyInstalledApps() { ...@@ -82,7 +82,9 @@ void WebAppPolicyManager::RefreshPolicyInstalledApps() {
else else
container = PendingAppManager::LaunchContainer::kTab; container = PendingAppManager::LaunchContainer::kTab;
apps_to_install.emplace_back(GURL(url.GetString()), container); // There is a separate policy to create shortcuts/pin apps to shelf.
apps_to_install.emplace_back(GURL(url.GetString()), container,
false /* create_shortcuts */);
} }
pending_app_manager_->InstallApps(std::move(apps_to_install), pending_app_manager_->InstallApps(std::move(apps_to_install),
base::DoNothing()); base::DoNothing());
......
...@@ -102,9 +102,11 @@ TEST_F(WebAppPolicyManagerTest, TwoForceInstalledApps) { ...@@ -102,9 +102,11 @@ TEST_F(WebAppPolicyManagerTest, TwoForceInstalledApps) {
std::vector<PendingAppManager::AppInfo> expected_apps_to_install; std::vector<PendingAppManager::AppInfo> expected_apps_to_install;
expected_apps_to_install.emplace_back( expected_apps_to_install.emplace_back(
GURL(kUrl1), PendingAppManager::LaunchContainer::kWindow); GURL(kUrl1), PendingAppManager::LaunchContainer::kWindow,
false /* create_shortcuts */);
expected_apps_to_install.emplace_back( expected_apps_to_install.emplace_back(
GURL(kUrl2), PendingAppManager::LaunchContainer::kTab); GURL(kUrl2), PendingAppManager::LaunchContainer::kTab,
false /* create_shortcuts */);
EXPECT_EQ(apps_to_install, expected_apps_to_install); EXPECT_EQ(apps_to_install, expected_apps_to_install);
} }
......
...@@ -9,8 +9,12 @@ ...@@ -9,8 +9,12 @@
namespace web_app { namespace web_app {
PendingAppManager::AppInfo::AppInfo(GURL url, LaunchContainer launch_container) PendingAppManager::AppInfo::AppInfo(GURL url,
: url(std::move(url)), launch_container(launch_container) {} LaunchContainer launch_container,
bool create_shortcuts)
: url(std::move(url)),
launch_container(launch_container),
create_shortcuts(create_shortcuts) {}
PendingAppManager::AppInfo::AppInfo(PendingAppManager::AppInfo&& other) = PendingAppManager::AppInfo::AppInfo(PendingAppManager::AppInfo&& other) =
default; default;
...@@ -19,15 +23,16 @@ PendingAppManager::AppInfo::~AppInfo() = default; ...@@ -19,15 +23,16 @@ PendingAppManager::AppInfo::~AppInfo() = default;
std::unique_ptr<PendingAppManager::AppInfo> PendingAppManager::AppInfo::Clone() std::unique_ptr<PendingAppManager::AppInfo> PendingAppManager::AppInfo::Clone()
const { const {
auto other = std::make_unique<AppInfo>(url, launch_container); auto other =
std::make_unique<AppInfo>(url, launch_container, create_shortcuts);
DCHECK_EQ(*this, *other); DCHECK_EQ(*this, *other);
return other; return other;
} }
bool PendingAppManager::AppInfo::operator==( bool PendingAppManager::AppInfo::operator==(
const PendingAppManager::AppInfo& other) const { const PendingAppManager::AppInfo& other) const {
return std::tie(url, launch_container) == return std::tie(url, launch_container, create_shortcuts) ==
std::tie(other.url, other.launch_container); std::tie(other.url, other.launch_container, other.create_shortcuts);
} }
PendingAppManager::PendingAppManager() = default; PendingAppManager::PendingAppManager() = default;
...@@ -37,7 +42,8 @@ PendingAppManager::~PendingAppManager() = default; ...@@ -37,7 +42,8 @@ PendingAppManager::~PendingAppManager() = default;
std::ostream& operator<<(std::ostream& out, std::ostream& operator<<(std::ostream& out,
const PendingAppManager::AppInfo& app_info) { const PendingAppManager::AppInfo& app_info) {
return out << "url: " << app_info.url << "\n launch_container: " return out << "url: " << app_info.url << "\n launch_container: "
<< static_cast<int32_t>(app_info.launch_container); << static_cast<int32_t>(app_info.launch_container)
<< "\n create_shortcuts: " << app_info.create_shortcuts;
} }
} // namespace web_app } // namespace web_app
...@@ -36,7 +36,9 @@ class PendingAppManager { ...@@ -36,7 +36,9 @@ class PendingAppManager {
}; };
struct AppInfo { struct AppInfo {
AppInfo(GURL url, LaunchContainer launch_container); AppInfo(GURL url,
LaunchContainer launch_container,
bool create_shortcuts = true);
AppInfo(AppInfo&& other); AppInfo(AppInfo&& other);
~AppInfo(); ~AppInfo();
...@@ -44,8 +46,9 @@ class PendingAppManager { ...@@ -44,8 +46,9 @@ class PendingAppManager {
bool operator==(const AppInfo& other) const; bool operator==(const AppInfo& other) const;
GURL url; const GURL url;
LaunchContainer launch_container; const LaunchContainer launch_container;
const bool create_shortcuts;
DISALLOW_COPY_AND_ASSIGN(AppInfo); DISALLOW_COPY_AND_ASSIGN(AppInfo);
}; };
......
...@@ -104,6 +104,10 @@ void BookmarkAppInstallationTask::OnGetWebApplicationInfo( ...@@ -104,6 +104,10 @@ void BookmarkAppInstallationTask::OnGetWebApplicationInfo(
// is plumbed through this class. // is plumbed through this class.
helper_ = helper_factory_.Run(profile_, *web_app_info, web_contents, helper_ = helper_factory_.Run(profile_, *web_app_info, web_contents,
WebappInstallSource::MENU_BROWSER_TAB); WebappInstallSource::MENU_BROWSER_TAB);
if (!app_info_.create_shortcuts)
helper_->set_skip_shortcut_creation();
helper_->Create(base::Bind(&BookmarkAppInstallationTask::OnInstalled, helper_->Create(base::Bind(&BookmarkAppInstallationTask::OnInstalled,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(),
base::Passed(&result_callback))); base::Passed(&result_callback)));
......
...@@ -55,6 +55,13 @@ class TestBookmarkAppHelper : public BookmarkAppHelper { ...@@ -55,6 +55,13 @@ class TestBookmarkAppHelper : public BookmarkAppHelper {
: BookmarkAppHelper(profile, web_app_info, contents, install_source) {} : BookmarkAppHelper(profile, web_app_info, contents, install_source) {}
~TestBookmarkAppHelper() override {} ~TestBookmarkAppHelper() override {}
void CompleteInstallation() {
CompleteInstallableCheck();
content::RunAllTasksUntilIdle();
CompleteIconDownload();
content::RunAllTasksUntilIdle();
}
void CompleteInstallableCheck() { void CompleteInstallableCheck() {
blink::Manifest manifest; blink::Manifest manifest;
InstallableData data = { InstallableData data = {
...@@ -78,6 +85,37 @@ class TestBookmarkAppHelper : public BookmarkAppHelper { ...@@ -78,6 +85,37 @@ class TestBookmarkAppHelper : public BookmarkAppHelper {
DISALLOW_COPY_AND_ASSIGN(TestBookmarkAppHelper); DISALLOW_COPY_AND_ASSIGN(TestBookmarkAppHelper);
}; };
// All BookmarkAppDataRetriever operations are async, so this class posts tasks
// when running callbacks to simulate async behavior in tests as well.
class TestDataRetriever : public BookmarkAppDataRetriever {
public:
explicit TestDataRetriever(std::unique_ptr<WebApplicationInfo> web_app_info)
: web_app_info_(std::move(web_app_info)) {}
~TestDataRetriever() override = default;
void GetWebApplicationInfo(content::WebContents* web_contents,
GetWebApplicationInfoCallback callback) override {
DCHECK(web_contents);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), std::move(web_app_info_)));
}
void GetIcons(const GURL& app_url,
const std::vector<GURL>& icon_urls,
GetIconsCallback callback) override {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback),
std::vector<WebApplicationInfo::IconInfo>()));
}
private:
std::unique_ptr<WebApplicationInfo> web_app_info_;
DISALLOW_COPY_AND_ASSIGN(TestDataRetriever);
};
class BookmarkAppInstallationTaskTest : public ChromeRenderViewHostTestHarness { class BookmarkAppInstallationTaskTest : public ChromeRenderViewHostTestHarness {
public: public:
BookmarkAppInstallationTaskTest() = default; BookmarkAppInstallationTaskTest() = default;
...@@ -100,6 +138,16 @@ class BookmarkAppInstallationTaskTest : public ChromeRenderViewHostTestHarness { ...@@ -100,6 +138,16 @@ class BookmarkAppInstallationTaskTest : public ChromeRenderViewHostTestHarness {
} }
protected: protected:
void SetTestingFactories(BookmarkAppInstallationTask* task,
const GURL& app_url) {
WebApplicationInfo info;
info.app_url = app_url;
info.title = base::UTF8ToUTF16(kWebAppTitle);
task->SetDataRetrieverForTesting(std::make_unique<TestDataRetriever>(
std::make_unique<WebApplicationInfo>(std::move(info))));
task->SetBookmarkAppHelperFactoryForTesting(helper_factory());
}
BookmarkAppInstallationTask::BookmarkAppHelperFactory helper_factory() { BookmarkAppInstallationTask::BookmarkAppHelperFactory helper_factory() {
return base::BindRepeating( return base::BindRepeating(
&BookmarkAppInstallationTaskTest::CreateTestBookmarkAppHelper, &BookmarkAppInstallationTaskTest::CreateTestBookmarkAppHelper,
...@@ -135,37 +183,6 @@ class BookmarkAppInstallationTaskTest : public ChromeRenderViewHostTestHarness { ...@@ -135,37 +183,6 @@ class BookmarkAppInstallationTaskTest : public ChromeRenderViewHostTestHarness {
DISALLOW_COPY_AND_ASSIGN(BookmarkAppInstallationTaskTest); DISALLOW_COPY_AND_ASSIGN(BookmarkAppInstallationTaskTest);
}; };
// All BookmarkAppDataRetriever operations are async, so this class posts tasks
// when running callbacks to simulate async behavior in tests as well.
class TestDataRetriever : public BookmarkAppDataRetriever {
public:
explicit TestDataRetriever(std::unique_ptr<WebApplicationInfo> web_app_info)
: web_app_info_(std::move(web_app_info)) {}
~TestDataRetriever() override = default;
void GetWebApplicationInfo(content::WebContents* web_contents,
GetWebApplicationInfoCallback callback) override {
DCHECK(web_contents);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), std::move(web_app_info_)));
}
void GetIcons(const GURL& app_url,
const std::vector<GURL>& icon_urls,
GetIconsCallback callback) override {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback),
std::vector<WebApplicationInfo::IconInfo>()));
}
private:
std::unique_ptr<WebApplicationInfo> web_app_info_;
DISALLOW_COPY_AND_ASSIGN(TestDataRetriever);
};
class TestInstaller : public BookmarkAppInstaller { class TestInstaller : public BookmarkAppInstaller {
public: public:
explicit TestInstaller(Profile* profile, bool succeeds) explicit TestInstaller(Profile* profile, bool succeeds)
...@@ -285,12 +302,7 @@ TEST_F(BookmarkAppInstallationTaskTest, ...@@ -285,12 +302,7 @@ TEST_F(BookmarkAppInstallationTaskTest,
web_app::PendingAppManager::AppInfo( web_app::PendingAppManager::AppInfo(
app_url, web_app::PendingAppManager::LaunchContainer::kWindow)); app_url, web_app::PendingAppManager::LaunchContainer::kWindow));
WebApplicationInfo info; SetTestingFactories(task.get(), app_url);
info.app_url = app_url;
info.title = base::UTF8ToUTF16(kWebAppTitle);
task->SetDataRetrieverForTesting(std::make_unique<TestDataRetriever>(
std::make_unique<WebApplicationInfo>(std::move(info))));
task->SetBookmarkAppHelperFactoryForTesting(helper_factory());
task->InstallWebAppOrShortcutFromWebContents( task->InstallWebAppOrShortcutFromWebContents(
web_contents(), web_contents(),
...@@ -316,12 +328,7 @@ TEST_F(BookmarkAppInstallationTaskTest, ...@@ -316,12 +328,7 @@ TEST_F(BookmarkAppInstallationTaskTest,
web_app::PendingAppManager::AppInfo( web_app::PendingAppManager::AppInfo(
app_url, web_app::PendingAppManager::LaunchContainer::kWindow)); app_url, web_app::PendingAppManager::LaunchContainer::kWindow));
WebApplicationInfo info; SetTestingFactories(task.get(), app_url);
info.app_url = app_url;
info.title = base::UTF8ToUTF16(kWebAppTitle);
task->SetDataRetrieverForTesting(std::make_unique<TestDataRetriever>(
std::make_unique<WebApplicationInfo>(std::move(info))));
task->SetBookmarkAppHelperFactoryForTesting(helper_factory());
task->InstallWebAppOrShortcutFromWebContents( task->InstallWebAppOrShortcutFromWebContents(
web_contents(), web_contents(),
...@@ -338,4 +345,29 @@ TEST_F(BookmarkAppInstallationTaskTest, ...@@ -338,4 +345,29 @@ TEST_F(BookmarkAppInstallationTaskTest,
EXPECT_FALSE(app_installed()); EXPECT_FALSE(app_installed());
} }
TEST_F(BookmarkAppInstallationTaskTest,
WebAppOrShortcutFromContents_NoShortcuts) {
const GURL app_url(kWebAppUrl);
web_app::PendingAppManager::AppInfo app_info(
app_url, web_app::PendingAppManager::LaunchContainer::kWindow,
false /* create_shortcuts */);
auto task = std::make_unique<BookmarkAppInstallationTask>(
profile(), std::move(app_info));
SetTestingFactories(task.get(), app_url);
task->InstallWebAppOrShortcutFromWebContents(
web_contents(),
base::BindOnce(&BookmarkAppInstallationTaskTest::OnInstallationTaskResult,
base::Unretained(this), base::DoNothing().Once()));
content::RunAllTasksUntilIdle();
test_helper().CompleteInstallation();
EXPECT_TRUE(app_installed());
EXPECT_FALSE(test_helper().create_shortcuts());
}
} // namespace extensions } // namespace extensions
...@@ -26,13 +26,18 @@ IN_PROC_BROWSER_TEST_F(PendingBookmarkAppManagerBrowserTest, InstallSucceeds) { ...@@ -26,13 +26,18 @@ IN_PROC_BROWSER_TEST_F(PendingBookmarkAppManagerBrowserTest, InstallSucceeds) {
ASSERT_TRUE(embedded_test_server()->Start()); ASSERT_TRUE(embedded_test_server()->Start());
base::RunLoop run_loop; base::RunLoop run_loop;
std::string app_id; std::string app_id;
web_app::PendingAppManager::AppInfo app_info(
embedded_test_server()->GetURL("/banners/manifest_test_page.html"),
web_app::PendingAppManager::LaunchContainer::kWindow);
web_app::WebAppProvider::Get(browser()->profile()) web_app::WebAppProvider::Get(browser()->profile())
->pending_app_manager() ->pending_app_manager()
.Install(web_app::PendingAppManager::AppInfo( .Install(web_app::PendingAppManager::AppInfo(
embedded_test_server()->GetURL( embedded_test_server()->GetURL(
"/banners/manifest_test_page.html"), "/banners/manifest_test_page.html"),
web_app::PendingAppManager::LaunchContainer::kWindow), web_app::PendingAppManager::LaunchContainer::kWindow,
false /* create_shortcuts */), // Avoid creating real
// shortcuts in tests.
base::BindLambdaForTesting( base::BindLambdaForTesting(
[&run_loop, &app_id](const GURL& provided_url, [&run_loop, &app_id](const GURL& provided_url,
const std::string& id) { const std::string& id) {
......
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