web_app.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_VIEWS)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Predicator for sorting images from largest to smallest.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IconPrecedes(const WebApplicationInfo::IconInfo& left,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const WebApplicationInfo::IconInfo& right) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return left.width < right.width;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeleteShortcutsOnFileThread(
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ShellIntegration::ShortcutInfo& shortcut_info) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath shortcut_data_dir = web_app::GetWebAppDataDirectory(
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcut_info.profile_path, shortcut_info.extension_id, GURL());
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return web_app::internals::DeletePlatformShortcuts(
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcut_data_dir, shortcut_info);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UpdateShortcutsOnFileThread(
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ShellIntegration::ShortcutInfo& shortcut_info) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath shortcut_data_dir = web_app::GetWebAppDataDirectory(
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcut_info.profile_path, shortcut_info.extension_id, GURL());
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return web_app::internals::UpdatePlatformShortcuts(
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcut_data_dir, shortcut_info);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace web_app {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following string is used to build the directory name for
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shortcuts to chrome applications (the kind which are installed
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from a CRX).  Application shortcuts to URLs use the {host}_{path}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the name of this directory.  Hosts can't include an underscore.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// By starting this string with an underscore, we ensure that there
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are no naming conflicts.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kCrxAppPrefix = "_crx_";
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internals {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FilePath GetSanitizedFileName(const string16& name) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 file_name = name;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string file_name = UTF16ToUTF8(name);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::ReplaceIllegalCharactersInPath(&file_name, '_');
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return FilePath(file_name);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internals
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FilePath GetWebAppDataDirectory(const FilePath& profile_path,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::string& extension_id,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const GURL& url) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!profile_path.empty());
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath app_data_dir(profile_path.Append(chrome::kWebAppDirname));
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension_id.empty()) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return app_data_dir.AppendASCII(
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GenerateApplicationNameFromExtensionId(extension_id));
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string host(url.host());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string scheme(url.has_scheme() ? url.scheme() : "http");
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string port(url.has_port() ? url.port() : "80");
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string scheme_port(scheme + "_" + port);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath::StringType host_path(UTF8ToUTF16(host));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath::StringType scheme_port_path(UTF8ToUTF16(scheme_port));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath::StringType host_path(host);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath::StringType scheme_port_path(scheme_port);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return app_data_dir.Append(host_path).Append(scheme_port_path);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FilePath GetWebAppDataDirectory(const FilePath& profile_path,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const extensions::Extension& extension) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetWebAppDataDirectory(
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_path, extension.id(), GURL(extension.launch_web_url()));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromInfo(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ShellIntegration::ShortcutInfo& shortcut_info) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!shortcut_info.extension_id.empty()) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return web_app::GenerateApplicationNameFromExtensionId(
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        shortcut_info.extension_id);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return web_app::GenerateApplicationNameFromURL(
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        shortcut_info.url);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromURL(const GURL& url) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string t;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t.append(url.host());
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t.append("_");
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t.append(url.path());
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return t;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromExtensionId(const std::string& id) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string t(web_app::kCrxAppPrefix);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t.append(id);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return t;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetExtensionIdFromApplicationName(const std::string& app_name) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string prefix(kCrxAppPrefix);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (app_name.substr(0, prefix.length()) != prefix)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::string();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return app_name.substr(prefix.length());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateShortcuts(const ShellIntegration::ShortcutInfo& shortcut_info) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::FILE,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(base::IgnoreResult(&CreateShortcutsOnFileThread),
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 shortcut_info));
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeleteAllShortcuts(const ShellIntegration::ShortcutInfo& shortcut_info) {
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(&DeleteShortcutsOnFileThread, shortcut_info));
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UpdateAllShortcuts(const ShellIntegration::ShortcutInfo& shortcut_info) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::FILE,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&UpdateShortcutsOnFileThread, shortcut_info));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreateShortcutsOnFileThread(
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ShellIntegration::ShortcutInfo& shortcut_info) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FilePath shortcut_data_dir = GetWebAppDataDirectory(
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcut_info.profile_path, shortcut_info.extension_id,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcut_info.url);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return internals::CreatePlatformShortcuts(shortcut_data_dir, shortcut_info);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValidUrl(const GURL& url) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kValidUrlSchemes[] = {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::kFileScheme,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::kFileSystemScheme,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::kFtpScheme,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::kHttpScheme,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::kHttpsScheme,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::kExtensionScheme,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kValidUrlSchemes); ++i) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (url.SchemeIs(kValidUrlSchemes[i]))
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_VIEWS)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetIconsInfo(const WebApplicationInfo& app_info,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  IconInfoList* icons) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(icons);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icons->clear();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < app_info.icons.size(); ++i) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We only take square shaped icons (i.e. width == height).
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (app_info.icons[i].width == app_info.icons[i].height) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icons->push_back(app_info.icons[i]);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(icons->begin(), icons->end(), &IconPrecedes);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetWMClassFromAppName(std::string app_name) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_util::ReplaceIllegalCharactersInPath(&app_name, '_');
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TrimString(app_name, "_", &app_name);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return app_name;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace web_app
224