1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/web_applications/web_app.h"
8 #include "base/bind_helpers.h"
9 #include "base/file_util.h"
10 #include "base/i18n/file_util_icu.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/threading/thread.h"
14 #include "chrome/common/chrome_constants.h"
15 #include "chrome/common/chrome_version_info.h"
16 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
17 #include "chrome/common/url_constants.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "extensions/common/constants.h"
20 #include "extensions/common/extension.h"
22 using content::BrowserThread
;
26 #if defined(TOOLKIT_VIEWS)
27 // Predicator for sorting images from largest to smallest.
28 bool IconPrecedes(const WebApplicationInfo::IconInfo
& left
,
29 const WebApplicationInfo::IconInfo
& right
) {
30 return left
.width
< right
.width
;
34 void DeleteShortcutsOnFileThread(
35 const ShellIntegration::ShortcutInfo
& shortcut_info
) {
36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
38 base::FilePath shortcut_data_dir
= web_app::GetWebAppDataDirectory(
39 shortcut_info
.profile_path
, shortcut_info
.extension_id
, GURL());
40 return web_app::internals::DeletePlatformShortcuts(
41 shortcut_data_dir
, shortcut_info
);
44 void UpdateShortcutsOnFileThread(
45 const base::string16
& old_app_title
,
46 const ShellIntegration::ShortcutInfo
& shortcut_info
) {
47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
49 base::FilePath shortcut_data_dir
= web_app::GetWebAppDataDirectory(
50 shortcut_info
.profile_path
, shortcut_info
.extension_id
, GURL());
51 return web_app::internals::UpdatePlatformShortcuts(
52 shortcut_data_dir
, old_app_title
, shortcut_info
);
59 // The following string is used to build the directory name for
60 // shortcuts to chrome applications (the kind which are installed
61 // from a CRX). Application shortcuts to URLs use the {host}_{path}
62 // for the name of this directory. Hosts can't include an underscore.
63 // By starting this string with an underscore, we ensure that there
64 // are no naming conflicts.
65 static const char* kCrxAppPrefix
= "_crx_";
69 base::FilePath
GetSanitizedFileName(const base::string16
& name
) {
71 base::string16 file_name
= name
;
73 std::string file_name
= base::UTF16ToUTF8(name
);
75 file_util::ReplaceIllegalCharactersInPath(&file_name
, '_');
76 return base::FilePath(file_name
);
79 } // namespace internals
81 base::FilePath
GetWebAppDataDirectory(const base::FilePath
& profile_path
,
82 const std::string
& extension_id
,
84 DCHECK(!profile_path
.empty());
85 base::FilePath
app_data_dir(profile_path
.Append(chrome::kWebAppDirname
));
87 if (!extension_id
.empty()) {
88 return app_data_dir
.AppendASCII(
89 GenerateApplicationNameFromExtensionId(extension_id
));
92 std::string
host(url
.host());
93 std::string
scheme(url
.has_scheme() ? url
.scheme() : "http");
94 std::string
port(url
.has_port() ? url
.port() : "80");
95 std::string
scheme_port(scheme
+ "_" + port
);
98 base::FilePath::StringType
host_path(base::UTF8ToUTF16(host
));
99 base::FilePath::StringType
scheme_port_path(base::UTF8ToUTF16(scheme_port
));
100 #elif defined(OS_POSIX)
101 base::FilePath::StringType
host_path(host
);
102 base::FilePath::StringType
scheme_port_path(scheme_port
);
105 return app_data_dir
.Append(host_path
).Append(scheme_port_path
);
108 base::FilePath
GetWebAppDataDirectory(const base::FilePath
& profile_path
,
109 const extensions::Extension
& extension
) {
110 return GetWebAppDataDirectory(
113 GURL(extensions::AppLaunchInfo::GetLaunchWebURL(&extension
)));
116 std::string
GenerateApplicationNameFromInfo(
117 const ShellIntegration::ShortcutInfo
& shortcut_info
) {
118 if (!shortcut_info
.extension_id
.empty()) {
119 return web_app::GenerateApplicationNameFromExtensionId(
120 shortcut_info
.extension_id
);
122 return web_app::GenerateApplicationNameFromURL(
127 std::string
GenerateApplicationNameFromURL(const GURL
& url
) {
129 t
.append(url
.host());
131 t
.append(url
.path());
135 std::string
GenerateApplicationNameFromExtensionId(const std::string
& id
) {
136 std::string
t(web_app::kCrxAppPrefix
);
141 std::string
GetExtensionIdFromApplicationName(const std::string
& app_name
) {
142 std::string
prefix(kCrxAppPrefix
);
143 if (app_name
.substr(0, prefix
.length()) != prefix
)
144 return std::string();
145 return app_name
.substr(prefix
.length());
148 void CreateShortcuts(
149 const ShellIntegration::ShortcutInfo
& shortcut_info
,
150 const ShellIntegration::ShortcutLocations
& creation_locations
,
151 ShortcutCreationReason creation_reason
) {
152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
154 BrowserThread::PostTask(
157 base::Bind(base::IgnoreResult(&CreateShortcutsOnFileThread
),
158 shortcut_info
, creation_locations
, creation_reason
));
161 void DeleteAllShortcuts(const ShellIntegration::ShortcutInfo
& shortcut_info
) {
162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
164 BrowserThread::PostTask(
167 base::Bind(&DeleteShortcutsOnFileThread
, shortcut_info
));
170 void UpdateAllShortcuts(const base::string16
& old_app_title
,
171 const ShellIntegration::ShortcutInfo
& shortcut_info
) {
172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
174 BrowserThread::PostTask(
177 base::Bind(&UpdateShortcutsOnFileThread
, old_app_title
, shortcut_info
));
180 bool CreateShortcutsOnFileThread(
181 const ShellIntegration::ShortcutInfo
& shortcut_info
,
182 const ShellIntegration::ShortcutLocations
& creation_locations
,
183 ShortcutCreationReason creation_reason
) {
184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
186 base::FilePath shortcut_data_dir
= GetWebAppDataDirectory(
187 shortcut_info
.profile_path
, shortcut_info
.extension_id
,
189 return internals::CreatePlatformShortcuts(shortcut_data_dir
, shortcut_info
,
194 bool IsValidUrl(const GURL
& url
) {
195 static const char* const kValidUrlSchemes
[] = {
196 content::kFileScheme
,
197 content::kFileSystemScheme
,
199 content::kHttpScheme
,
200 content::kHttpsScheme
,
201 extensions::kExtensionScheme
,
204 for (size_t i
= 0; i
< arraysize(kValidUrlSchemes
); ++i
) {
205 if (url
.SchemeIs(kValidUrlSchemes
[i
]))
212 #if defined(TOOLKIT_VIEWS)
213 void GetIconsInfo(const WebApplicationInfo
& app_info
,
214 IconInfoList
* icons
) {
218 for (size_t i
= 0; i
< app_info
.icons
.size(); ++i
) {
219 // We only take square shaped icons (i.e. width == height).
220 if (app_info
.icons
[i
].width
== app_info
.icons
[i
].height
) {
221 icons
->push_back(app_info
.icons
[i
]);
225 std::sort(icons
->begin(), icons
->end(), &IconPrecedes
);
229 #if defined(OS_LINUX)
230 std::string
GetWMClassFromAppName(std::string app_name
) {
231 file_util::ReplaceIllegalCharactersInPath(&app_name
, '_');
232 base::TrimString(app_name
, "_", &app_name
);
237 } // namespace web_app