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"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/file_util_icu.h"
11e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/prefs/pref_service.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/extensions/extension_ui_util.h"
16e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/profiles/profile.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/chrome_version_info.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
20e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/common/pref_names.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/browser/extension_registry.h"
236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "extensions/browser/image_loader.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/common/extension_set.h"
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/manifest_handlers/icons_handler.h"
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/grit/extensions_browser_resources.h"
29e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "skia/ext/image_operations.h"
30e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "third_party/skia/include/core/SkBitmap.h"
31e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/base/resource/resource_bundle.h"
32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/gfx/image/image.h"
33e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/gfx/image/image_family.h"
34e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/gfx/image/image_skia.h"
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "url/url_constants.h"
36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#if defined(OS_WIN)
38e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/gfx/icon_util.h"
39e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(TOOLKIT_VIEWS)
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/tab_helper.h"
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/favicon/favicon_tab_helper.h"
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#if defined(OS_MACOSX)
51e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst int kDesiredSizes[] = {16, 32, 128, 256, 512};
52e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst size_t kNumDesiredSizes = arraysize(kDesiredSizes);
53e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#elif defined(OS_LINUX)
54e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Linux supports icons of any size. FreeDesktop Icon Theme Specification states
55e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// that "Minimally you should install a 48x48 icon in the hicolor theme."
56e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst int kDesiredSizes[] = {16, 32, 48, 128, 256, 512};
57e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst size_t kNumDesiredSizes = arraysize(kDesiredSizes);
58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#elif defined(OS_WIN)
59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst int* kDesiredSizes = IconUtil::kIconDimensions;
60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst size_t kNumDesiredSizes = IconUtil::kNumIconDimensions;
61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#else
62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst int kDesiredSizes[] = {32};
63e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst size_t kNumDesiredSizes = arraysize(kDesiredSizes);
64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif
65e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_VIEWS)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Predicator for sorting images from largest to smallest.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IconPrecedes(const WebApplicationInfo::IconInfo& left,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const WebApplicationInfo::IconInfo& right) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return left.width < right.width;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::FilePath GetShortcutDataDir(const web_app::ShortcutInfo& shortcut_info) {
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return web_app::GetWebAppDataDirectory(shortcut_info.profile_path,
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         shortcut_info.extension_id,
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         shortcut_info.url);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid UpdateAllShortcutsForShortcutInfo(
81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const base::string16& old_app_title,
82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const web_app::ShortcutInfo& shortcut_info,
83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const extensions::FileHandlersInfo& file_handlers_info) {
84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  BrowserThread::PostTask(
85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      BrowserThread::FILE,
86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      FROM_HERE,
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&web_app::internals::UpdatePlatformShortcuts,
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 GetShortcutDataDir(shortcut_info),
89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 old_app_title, shortcut_info, file_handlers_info));
90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid OnImageLoaded(web_app::ShortcutInfo shortcut_info,
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   extensions::FileHandlersInfo file_handlers_info,
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   web_app::InfoCallback callback,
95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                   const gfx::ImageFamily& image_family) {
96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // If the image failed to load (e.g. if the resource being loaded was empty)
97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // use the standard application icon.
98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (image_family.empty()) {
99e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    gfx::Image default_icon =
100e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        ResourceBundle::GetSharedInstance().GetImageNamed(IDR_APP_DEFAULT_ICON);
101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    int size = kDesiredSizes[kNumDesiredSizes - 1];
102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    SkBitmap bmp = skia::ImageOperations::Resize(
103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          *default_icon.ToSkBitmap(), skia::ImageOperations::RESIZE_BEST,
104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          size, size);
105e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bmp);
106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // We are on the UI thread, and this image is needed from the FILE thread,
107e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // for creating shortcut icon files.
108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    image_skia.MakeThreadSafe();
109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    shortcut_info.favicon.Add(gfx::Image(image_skia));
110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  } else {
111e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    shortcut_info.favicon = image_family;
112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  callback.Run(shortcut_info, file_handlers_info);
115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void IgnoreFileHandlersInfo(
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const web_app::ShortcutInfoCallback& shortcut_info_callback,
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const web_app::ShortcutInfo& shortcut_info,
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const extensions::FileHandlersInfo& file_handlers_info) {
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  shortcut_info_callback.Run(shortcut_info);
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace web_app {
127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// The following string is used to build the directory name for
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// shortcuts to chrome applications (the kind which are installed
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// from a CRX).  Application shortcuts to URLs use the {host}_{path}
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// for the name of this directory.  Hosts can't include an underscore.
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// By starting this string with an underscore, we ensure that there
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// are no naming conflicts.
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)static const char kCrxAppPrefix[] = "_crx_";
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace internals {
137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::FilePath GetSanitizedFileName(const base::string16& name) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 file_name = name;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string file_name = base::UTF16ToUTF8(name);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::i18n::ReplaceIllegalCharactersInPath(&file_name, '_');
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::FilePath(file_name);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internals
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ShortcutInfo::ShortcutInfo()
151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    : is_platform_app(false) {
152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ShortcutInfo::~ShortcutInfo() {}
155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ShortcutLocations::ShortcutLocations()
157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    : on_desktop(false),
158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      applications_menu_location(APP_MENU_LOCATION_NONE),
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      in_quick_launch_bar(false) {
160a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
161a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(TOOLKIT_VIEWS)
163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GetShortcutInfoForTab(content::WebContents* web_contents,
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           ShortcutInfo* info) {
165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(info);  // Must provide a valid info.
166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  const FaviconTabHelper* favicon_tab_helper =
168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      FaviconTabHelper::FromWebContents(web_contents);
169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  const extensions::TabHelper* extensions_tab_helper =
170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      extensions::TabHelper::FromWebContents(web_contents);
171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  const WebApplicationInfo& app_info = extensions_tab_helper->web_app_info();
172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  info->url = app_info.app_url.is_empty() ? web_contents->GetURL() :
174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                            app_info.app_url;
175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  info->title = app_info.title.empty() ?
176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      (web_contents->GetTitle().empty() ? base::UTF8ToUTF16(info->url.spec()) :
177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                          web_contents->GetTitle()) :
178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      app_info.title;
179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  info->description = app_info.description;
180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  info->favicon.Add(favicon_tab_helper->GetFavicon());
181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Profile* profile =
183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Profile::FromBrowserContext(web_contents->GetBrowserContext());
184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  info->profile_path = profile->GetPath();
185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
187c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if !defined(OS_WIN)
189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid UpdateShortcutForTabContents(content::WebContents* web_contents) {}
190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ShortcutInfo ShortcutInfoForExtensionAndProfile(
193e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    const extensions::Extension* app, Profile* profile) {
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ShortcutInfo shortcut_info;
195e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  shortcut_info.extension_id = app->id();
196e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  shortcut_info.is_platform_app = app->is_platform_app();
197e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  shortcut_info.url = extensions::AppLaunchInfo::GetLaunchWebURL(app);
198e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  shortcut_info.title = base::UTF8ToUTF16(app->name());
199e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  shortcut_info.description = base::UTF8ToUTF16(app->description());
200e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  shortcut_info.extension_path = app->path();
201e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  shortcut_info.profile_path = profile->GetPath();
202e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  shortcut_info.profile_name =
203e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      profile->GetPrefs()->GetString(prefs::kProfileName);
204e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  return shortcut_info;
205e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
206e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GetInfoForApp(const extensions::Extension* extension,
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   Profile* profile,
209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   const InfoCallback& callback) {
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  web_app::ShortcutInfo shortcut_info =
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      web_app::ShortcutInfoForExtensionAndProfile(extension, profile);
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const std::vector<extensions::FileHandlerInfo>* file_handlers =
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      extensions::FileHandlers::GetFileHandlers(extension);
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  extensions::FileHandlersInfo file_handlers_info =
215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      file_handlers ? *file_handlers : extensions::FileHandlersInfo();
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::vector<extensions::ImageLoader::ImageRepresentation> info_list;
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (size_t i = 0; i < kNumDesiredSizes; ++i) {
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int size = kDesiredSizes[i];
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    extensions::ExtensionResource resource =
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        extensions::IconsInfo::GetIconResource(
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            extension, size, ExtensionIconSet::MATCH_EXACTLY);
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!resource.empty()) {
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      info_list.push_back(extensions::ImageLoader::ImageRepresentation(
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          resource,
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          extensions::ImageLoader::ImageRepresentation::ALWAYS_RESIZE,
227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          gfx::Size(size, size),
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          ui::SCALE_FACTOR_100P));
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (info_list.empty()) {
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    size_t i = kNumDesiredSizes - 1;
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int size = kDesiredSizes[i];
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // If there is no icon at the desired sizes, we will resize what we can get.
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Making a large icon smaller is preferred to making a small icon larger,
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // so look for a larger icon first:
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    extensions::ExtensionResource resource =
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        extensions::IconsInfo::GetIconResource(
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            extension, size, ExtensionIconSet::MATCH_BIGGER);
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (resource.empty()) {
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      resource = extensions::IconsInfo::GetIconResource(
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          extension, size, ExtensionIconSet::MATCH_SMALLER);
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    info_list.push_back(extensions::ImageLoader::ImageRepresentation(
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        resource,
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        extensions::ImageLoader::ImageRepresentation::ALWAYS_RESIZE,
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        gfx::Size(size, size),
250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ui::SCALE_FACTOR_100P));
251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |info_list| may still be empty at this point, in which case
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // LoadImageFamilyAsync will call the OnImageLoaded callback with an empty
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // image and exit immediately.
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  extensions::ImageLoader::Get(profile)->LoadImageFamilyAsync(
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      extension,
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      info_list,
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&OnImageLoaded, shortcut_info, file_handlers_info, callback));
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GetShortcutInfoForApp(const extensions::Extension* extension,
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           Profile* profile,
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           const ShortcutInfoCallback& callback) {
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GetInfoForApp(
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extension, profile, base::Bind(&IgnoreFileHandlersInfo, callback));
267e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
268e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool ShouldCreateShortcutFor(Profile* profile,
27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                             const extensions::Extension* extension) {
27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return extension->is_platform_app() &&
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)         extension->location() != extensions::Manifest::COMPONENT &&
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)         extensions::ui_util::CanDisplayInAppLauncher(extension, profile);
27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path,
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const std::string& extension_id,
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const GURL& url) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!profile_path.empty());
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath app_data_dir(profile_path.Append(chrome::kWebAppDirname));
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension_id.empty()) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return app_data_dir.AppendASCII(
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GenerateApplicationNameFromExtensionId(extension_id));
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string host(url.host());
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string scheme(url.has_scheme() ? url.scheme() : "http");
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string port(url.has_port() ? url.port() : "80");
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string scheme_port(scheme + "_" + port);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath::StringType host_path(base::UTF8ToUTF16(host));
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath::StringType scheme_port_path(base::UTF8ToUTF16(scheme_port));
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType host_path(host);
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType scheme_port_path(scheme_port);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return app_data_dir.Append(host_path).Append(scheme_port_path);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path,
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const extensions::Extension& extension) {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetWebAppDataDirectory(
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      profile_path,
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      extension.id(),
308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GURL(extensions::AppLaunchInfo::GetLaunchWebURL(&extension)));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string GenerateApplicationNameFromInfo(const ShortcutInfo& shortcut_info) {
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!shortcut_info.extension_id.empty())
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return GenerateApplicationNameFromExtensionId(shortcut_info.extension_id);
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return GenerateApplicationNameFromURL(shortcut_info.url);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromURL(const GURL& url) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string t;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t.append(url.host());
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t.append("_");
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t.append(url.path());
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return t;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromExtensionId(const std::string& id) {
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string t(kCrxAppPrefix);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t.append(id);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return t;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetExtensionIdFromApplicationName(const std::string& app_name) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string prefix(kCrxAppPrefix);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (app_name.substr(0, prefix.length()) != prefix)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::string();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return app_name.substr(prefix.length());
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
339116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid CreateShortcutsWithInfo(
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ShortcutCreationReason reason,
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const ShortcutLocations& locations,
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const ShortcutInfo& shortcut_info,
343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const extensions::FileHandlersInfo& file_handlers_info) {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::FILE,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(base::IgnoreResult(&internals::CreatePlatformShortcuts),
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 GetShortcutDataDir(shortcut_info),
351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 shortcut_info,
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 file_handlers_info,
353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 locations,
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 reason));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void CreateShortcuts(ShortcutCreationReason reason,
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     const ShortcutLocations& locations,
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     Profile* profile,
360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     const extensions::Extension* app) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!ShouldCreateShortcutFor(profile, app))
36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GetInfoForApp(
367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      app, profile, base::Bind(&CreateShortcutsWithInfo, reason, locations));
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
370c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid DeleteAllShortcuts(Profile* profile, const extensions::Extension* app) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ShortcutInfo shortcut_info =
374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ShortcutInfoForExtensionAndProfile(app, profile);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::FILE,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&web_app::internals::DeletePlatformShortcuts,
379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 GetShortcutDataDir(shortcut_info), shortcut_info));
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
382c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid UpdateAllShortcuts(const base::string16& old_app_title,
383c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                        Profile* profile,
384c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                        const extensions::Extension* app) {
385c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GetInfoForApp(app,
388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                profile,
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                base::Bind(&UpdateAllShortcutsForShortcutInfo, old_app_title));
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValidUrl(const GURL& url) {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kValidUrlSchemes[] = {
394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      url::kFileScheme,
395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      url::kFileSystemScheme,
396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      url::kFtpScheme,
397010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      url::kHttpScheme,
398010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      url::kHttpsScheme,
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::kExtensionScheme,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kValidUrlSchemes); ++i) {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (url.SchemeIs(kValidUrlSchemes[i]))
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_VIEWS)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetIconsInfo(const WebApplicationInfo& app_info,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  IconInfoList* icons) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(icons);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icons->clear();
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < app_info.icons.size(); ++i) {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We only take square shaped icons (i.e. width == height).
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (app_info.icons[i].width == app_info.icons[i].height) {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icons->push_back(app_info.icons[i]);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(icons->begin(), icons->end(), &IconPrecedes);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_LINUX)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetWMClassFromAppName(std::string app_name) {
4296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::i18n::ReplaceIllegalCharactersInPath(&app_name, '_');
430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::TrimString(app_name, "_", &app_name);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return app_name;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace web_app
436