web_app.cc revision 868fa2fe829687343ffae624259930155e16dbd8
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/web_applications/web_app.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/file_util_icu.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/chrome_version_info.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "grit/chromium_strings.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_VIEWS)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Predicator for sorting images from largest to smallest.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IconPrecedes(const WebApplicationInfo::IconInfo& left,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const WebApplicationInfo::IconInfo& right) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return left.width < right.width;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeleteShortcutsOnFileThread(
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ShellIntegration::ShortcutInfo& shortcut_info) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath shortcut_data_dir = web_app::GetWebAppDataDirectory(
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcut_info.profile_path, shortcut_info.extension_id, GURL());
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return web_app::internals::DeletePlatformShortcuts(
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcut_data_dir, shortcut_info);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UpdateShortcutsOnFileThread(
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const string16& old_app_title,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ShellIntegration::ShortcutInfo& shortcut_info) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath shortcut_data_dir = web_app::GetWebAppDataDirectory(
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcut_info.profile_path, shortcut_info.extension_id, GURL());
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return web_app::internals::UpdatePlatformShortcuts(
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      shortcut_data_dir, old_app_title, shortcut_info);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace web_app {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following string is used to build the directory name for
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shortcuts to chrome applications (the kind which are installed
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from a CRX).  Application shortcuts to URLs use the {host}_{path}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the name of this directory.  Hosts can't include an underscore.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// By starting this string with an underscore, we ensure that there
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are no naming conflicts.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kCrxAppPrefix = "_crx_";
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internals {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetSanitizedFileName(const string16& name) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 file_name = name;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string file_name = UTF16ToUTF8(name);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::ReplaceIllegalCharactersInPath(&file_name, '_');
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::FilePath(file_name);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internals
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const std::string& extension_id,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const GURL& url) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!profile_path.empty());
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath app_data_dir(profile_path.Append(chrome::kWebAppDirname));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension_id.empty()) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return app_data_dir.AppendASCII(
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GenerateApplicationNameFromExtensionId(extension_id));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string host(url.host());
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string scheme(url.has_scheme() ? url.scheme() : "http");
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string port(url.has_port() ? url.port() : "80");
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string scheme_port(scheme + "_" + port);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType host_path(UTF8ToUTF16(host));
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType scheme_port_path(UTF8ToUTF16(scheme_port));
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType host_path(host);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType scheme_port_path(scheme_port);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return app_data_dir.Append(host_path).Append(scheme_port_path);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path,
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const extensions::Extension& extension) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetWebAppDataDirectory(
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      profile_path,
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      extension.id(),
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GURL(extensions::AppLaunchInfo::GetLaunchWebURL(&extension)));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromInfo(
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ShellIntegration::ShortcutInfo& shortcut_info) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!shortcut_info.extension_id.empty()) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return web_app::GenerateApplicationNameFromExtensionId(
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        shortcut_info.extension_id);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return web_app::GenerateApplicationNameFromURL(
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        shortcut_info.url);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromURL(const GURL& url) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string t;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t.append(url.host());
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t.append("_");
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t.append(url.path());
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return t;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromExtensionId(const std::string& id) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string t(web_app::kCrxAppPrefix);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t.append(id);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return t;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetExtensionIdFromApplicationName(const std::string& app_name) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string prefix(kCrxAppPrefix);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (app_name.substr(0, prefix.length()) != prefix)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::string();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return app_name.substr(prefix.length());
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CreateShortcuts(
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ShellIntegration::ShortcutInfo& shortcut_info,
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ShellIntegration::ShortcutLocations& creation_locations) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::FILE,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(base::IgnoreResult(&CreateShortcutsOnFileThread),
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 shortcut_info, creation_locations));
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeleteAllShortcuts(const ShellIntegration::ShortcutInfo& shortcut_info) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::FILE,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DeleteShortcutsOnFileThread, shortcut_info));
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void UpdateAllShortcuts(const string16& old_app_title,
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                        const ShellIntegration::ShortcutInfo& shortcut_info) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::FILE,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&UpdateShortcutsOnFileThread, old_app_title, shortcut_info));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreateShortcutsOnFileThread(
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ShellIntegration::ShortcutInfo& shortcut_info,
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ShellIntegration::ShortcutLocations& creation_locations) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath shortcut_data_dir = GetWebAppDataDirectory(
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcut_info.profile_path, shortcut_info.extension_id,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcut_info.url);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return internals::CreatePlatformShortcuts(shortcut_data_dir, shortcut_info,
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            creation_locations);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValidUrl(const GURL& url) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kValidUrlSchemes[] = {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::kFileScheme,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::kFileSystemScheme,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::kFtpScheme,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::kHttpScheme,
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::kHttpsScheme,
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::kExtensionScheme,
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kValidUrlSchemes); ++i) {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (url.SchemeIs(kValidUrlSchemes[i]))
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_VIEWS)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetIconsInfo(const WebApplicationInfo& app_info,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  IconInfoList* icons) {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(icons);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icons->clear();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < app_info.icons.size(); ++i) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We only take square shaped icons (i.e. width == height).
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (app_info.icons[i].width == app_info.icons[i].height) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icons->push_back(app_info.icons[i]);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(icons->begin(), icons->end(), &IconPrecedes);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetWMClassFromAppName(std::string app_name) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::ReplaceIllegalCharactersInPath(&app_name, '_');
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TrimString(app_name, "_", &app_name);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return app_name;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)string16 GetAppShortcutsSubdirName() {
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (channel == chrome::VersionInfo::CHANNEL_CANARY)
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_APP_SHORTCUTS_SUBDIR_NAME_CANARY);
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_APP_SHORTCUTS_SUBDIR_NAME);
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace web_app
244