blob: 532c8144c413ebc141c45f8ebfb809bcbb50bedf [file] [log] [blame]
// 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/components/web_app_shortcut.h"
#include "base/i18n/file_util_icu.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "build/build_config.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/common/chrome_constants.h"
#include "content/public/browser/browser_thread.h"
using content::BrowserThread;
namespace {
void DeleteShortcutInfoOnUIThread(
std::unique_ptr<web_app::ShortcutInfo> shortcut_info,
base::OnceClosure callback) {
shortcut_info.reset();
if (callback)
std::move(callback).Run();
}
} // namespace
namespace web_app {
ShortcutInfo::ShortcutInfo() {}
ShortcutInfo::~ShortcutInfo() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
ShortcutLocations::ShortcutLocations()
: on_desktop(false),
applications_menu_location(APP_MENU_LOCATION_NONE),
in_quick_launch_bar(false) {}
std::string GenerateApplicationNameFromInfo(const ShortcutInfo& shortcut_info) {
// TODO(loyso): Remove this empty()/non-empty difference.
if (shortcut_info.extension_id.empty())
return GenerateApplicationNameFromURL(shortcut_info.url);
return GenerateApplicationNameFromAppId(shortcut_info.extension_id);
}
base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path,
const std::string& extension_id,
const GURL& url) {
DCHECK(!profile_path.empty());
base::FilePath app_data_dir(profile_path.Append(chrome::kWebAppDirname));
if (!extension_id.empty()) {
return app_data_dir.AppendASCII(
GenerateApplicationNameFromAppId(extension_id));
}
std::string host(url.host());
std::string scheme(url.has_scheme() ? url.scheme() : "http");
std::string port(url.has_port() ? url.port() : "80");
std::string scheme_port(scheme + "_" + port);
#if defined(OS_WIN)
base::FilePath::StringType host_path(base::UTF8ToUTF16(host));
base::FilePath::StringType scheme_port_path(base::UTF8ToUTF16(scheme_port));
#elif defined(OS_POSIX)
base::FilePath::StringType host_path(host);
base::FilePath::StringType scheme_port_path(scheme_port);
#endif
return app_data_dir.Append(host_path).Append(scheme_port_path);
}
namespace internals {
void PostShortcutIOTask(base::OnceCallback<void(const ShortcutInfo&)> task,
std::unique_ptr<ShortcutInfo> shortcut_info) {
PostShortcutIOTaskAndReply(std::move(task), std::move(shortcut_info),
base::OnceClosure());
}
void PostShortcutIOTaskAndReply(
base::OnceCallback<void(const ShortcutInfo&)> task,
std::unique_ptr<ShortcutInfo> shortcut_info,
base::OnceClosure reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Ownership of |shortcut_info| moves to the Reply, which is guaranteed to
// outlive the const reference.
const web_app::ShortcutInfo& shortcut_info_ref = *shortcut_info;
GetShortcutIOTaskRunner()->PostTaskAndReply(
FROM_HERE,
base::BindOnce(std::move(task), base::ConstRef(shortcut_info_ref)),
base::BindOnce(&DeleteShortcutInfoOnUIThread, std::move(shortcut_info),
std::move(reply)));
}
scoped_refptr<base::TaskRunner> GetShortcutIOTaskRunner() {
constexpr base::TaskTraits traits = {
base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN};
#if defined(OS_WIN)
return base::CreateCOMSTATaskRunnerWithTraits(
traits, base::SingleThreadTaskRunnerThreadMode::SHARED);
#else
return base::CreateTaskRunnerWithTraits(traits);
#endif
}
base::FilePath GetSanitizedFileName(const base::string16& name) {
#if defined(OS_WIN)
base::string16 file_name = name;
#else
std::string file_name = base::UTF16ToUTF8(name);
#endif
base::i18n::ReplaceIllegalCharactersInPath(&file_name, '_');
return base::FilePath(file_name);
}
base::FilePath GetShortcutDataDir(const web_app::ShortcutInfo& shortcut_info) {
return web_app::GetWebAppDataDirectory(shortcut_info.profile_path,
shortcut_info.extension_id,
shortcut_info.url);
}
} // namespace internals
} // namespace web_app