web_app.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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" 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" 15e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/extensions/image_loader.h" 16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/extensions/tab_helper.h" 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/favicon/favicon_tab_helper.h" 18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/profiles/profile.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/chrome_version_info.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 22e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/common/pref_names.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h" 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/manifest_handlers/icons_handler.h" 27e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "grit/theme_resources.h" 28e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "skia/ext/image_operations.h" 29e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "third_party/skia/include/core/SkBitmap.h" 30e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/base/resource/resource_bundle.h" 31e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/gfx/image/image.h" 32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/gfx/image/image_family.h" 33e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/gfx/image/image_skia.h" 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "url/url_constants.h" 35e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#if defined(OS_WIN) 37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/gfx/icon_util.h" 38e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochtypedef base::Callback<void(const web_app::ShortcutInfo&, 45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const extensions::FileHandlersInfo&)> InfoCallback; 46a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 47e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#if defined(OS_MACOSX) 48e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst int kDesiredSizes[] = {16, 32, 128, 256, 512}; 49e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst size_t kNumDesiredSizes = arraysize(kDesiredSizes); 50e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#elif defined(OS_LINUX) 51e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Linux supports icons of any size. FreeDesktop Icon Theme Specification states 52e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// that "Minimally you should install a 48x48 icon in the hicolor theme." 53e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst int kDesiredSizes[] = {16, 32, 48, 128, 256, 512}; 54e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst size_t kNumDesiredSizes = arraysize(kDesiredSizes); 55e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#elif defined(OS_WIN) 56e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst int* kDesiredSizes = IconUtil::kIconDimensions; 57e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst size_t kNumDesiredSizes = IconUtil::kNumIconDimensions; 58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#else 59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst int kDesiredSizes[] = {32}; 60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst size_t kNumDesiredSizes = arraysize(kDesiredSizes); 61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif 62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_VIEWS) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Predicator for sorting images from largest to smallest. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IconPrecedes(const WebApplicationInfo::IconInfo& left, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebApplicationInfo::IconInfo& right) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return left.width < right.width; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::FilePath GetShortcutDataDir(const web_app::ShortcutInfo& shortcut_info) { 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return web_app::GetWebAppDataDirectory(shortcut_info.profile_path, 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) shortcut_info.extension_id, 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) shortcut_info.url); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid CreateShortcutsWithInfo( 78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch web_app::ShortcutCreationReason reason, 79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const web_app::ShortcutLocations& locations, 80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const web_app::ShortcutInfo& shortcut_info, 81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const extensions::FileHandlersInfo& file_handlers_info) { 82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch BrowserThread::PostTask( 85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch BrowserThread::FILE, 86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FROM_HERE, 87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind( 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::IgnoreResult(&web_app::internals::CreatePlatformShortcuts), 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetShortcutDataDir(shortcut_info), 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) shortcut_info, file_handlers_info, locations, reason)); 91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid UpdateAllShortcutsForShortcutInfo( 94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const base::string16& old_app_title, 95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const web_app::ShortcutInfo& shortcut_info, 96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const extensions::FileHandlersInfo& file_handlers_info) { 97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch BrowserThread::PostTask( 98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch BrowserThread::FILE, 99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FROM_HERE, 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&web_app::internals::UpdatePlatformShortcuts, 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetShortcutDataDir(shortcut_info), 102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch old_app_title, shortcut_info, file_handlers_info)); 103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid OnImageLoaded(web_app::ShortcutInfo shortcut_info, 106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extensions::FileHandlersInfo file_handlers_info, 107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch InfoCallback callback, 108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const gfx::ImageFamily& image_family) { 109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // If the image failed to load (e.g. if the resource being loaded was empty) 110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // use the standard application icon. 111e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (image_family.empty()) { 112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch gfx::Image default_icon = 113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ResourceBundle::GetSharedInstance().GetImageNamed(IDR_APP_DEFAULT_ICON); 114e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch int size = kDesiredSizes[kNumDesiredSizes - 1]; 115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch SkBitmap bmp = skia::ImageOperations::Resize( 116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch *default_icon.ToSkBitmap(), skia::ImageOperations::RESIZE_BEST, 117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch size, size); 118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bmp); 119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // We are on the UI thread, and this image is needed from the FILE thread, 120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // for creating shortcut icon files. 121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch image_skia.MakeThreadSafe(); 122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shortcut_info.favicon.Add(gfx::Image(image_skia)); 123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } else { 124e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shortcut_info.favicon = image_family; 125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callback.Run(shortcut_info, file_handlers_info); 128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid GetInfoForApp(const extensions::Extension* extension, 131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch Profile* profile, 132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const InfoCallback& callback) { 133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch web_app::ShortcutInfo shortcut_info = 134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch web_app::ShortcutInfoForExtensionAndProfile(extension, profile); 1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::vector<extensions::FileHandlerInfo>* file_handlers = 1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu extensions::FileHandlers::GetFileHandlers(extension); 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extensions::FileHandlersInfo file_handlers_info = 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) file_handlers ? *file_handlers : extensions::FileHandlersInfo(); 139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 140a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::vector<extensions::ImageLoader::ImageRepresentation> info_list; 141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch for (size_t i = 0; i < kNumDesiredSizes; ++i) { 142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int size = kDesiredSizes[i]; 143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extensions::ExtensionResource resource = 144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extensions::IconsInfo::GetIconResource( 145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extension, size, ExtensionIconSet::MATCH_EXACTLY); 146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!resource.empty()) { 147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch info_list.push_back(extensions::ImageLoader::ImageRepresentation( 148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch resource, 149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extensions::ImageLoader::ImageRepresentation::ALWAYS_RESIZE, 150a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Size(size, size), 151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ui::SCALE_FACTOR_100P)); 152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 154a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (info_list.empty()) { 156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch size_t i = kNumDesiredSizes - 1; 157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int size = kDesiredSizes[i]; 158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 159a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // If there is no icon at the desired sizes, we will resize what we can get. 160a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Making a large icon smaller is preferred to making a small icon larger, 161a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // so look for a larger icon first: 162a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extensions::ExtensionResource resource = 163a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extensions::IconsInfo::GetIconResource( 164a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extension, size, ExtensionIconSet::MATCH_BIGGER); 165a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (resource.empty()) { 166a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch resource = extensions::IconsInfo::GetIconResource( 167a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extension, size, ExtensionIconSet::MATCH_SMALLER); 168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 169a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch info_list.push_back(extensions::ImageLoader::ImageRepresentation( 170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch resource, 171a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extensions::ImageLoader::ImageRepresentation::ALWAYS_RESIZE, 172a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Size(size, size), 173a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ui::SCALE_FACTOR_100P)); 174a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // |info_list| may still be empty at this point, in which case 177a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // LoadImageFamilyAsync will call the OnImageLoaded callback with an empty 178a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // image and exit immediately. 179a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extensions::ImageLoader::Get(profile)->LoadImageFamilyAsync( 180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extension, 181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch info_list, 182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&OnImageLoaded, shortcut_info, file_handlers_info, callback)); 183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 184a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 185a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid IgnoreFileHandlersInfo( 186a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const web_app::ShortcutInfoCallback& shortcut_info_callback, 187a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const web_app::ShortcutInfo& shortcut_info, 188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const extensions::FileHandlersInfo& file_handlers_info) { 189a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch shortcut_info_callback.Run(shortcut_info); 190e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 191e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace web_app { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following string is used to build the directory name for 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shortcuts to chrome applications (the kind which are installed 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from a CRX). Application shortcuts to URLs use the {host}_{path} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the name of this directory. Hosts can't include an underscore. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// By starting this string with an underscore, we ensure that there 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are no naming conflicts. 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kCrxAppPrefix = "_crx_"; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internals { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::FilePath GetSanitizedFileName(const base::string16& name) { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 file_name = name; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string file_name = base::UTF16ToUTF8(name); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::ReplaceIllegalCharactersInPath(&file_name, '_'); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::FilePath(file_name); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool CreateShortcutsOnFileThread(ShortcutCreationReason reason, 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ShortcutLocations& locations, 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ShortcutInfo& shortcut_info) { 219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return CreatePlatformShortcuts( 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetShortcutDataDir(shortcut_info), 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) shortcut_info, extensions::FileHandlersInfo(), locations, reason); 224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internals 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ShortcutInfo::ShortcutInfo() 229a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : is_platform_app(false) { 230a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 231a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ShortcutInfo::~ShortcutInfo() {} 233a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ShortcutLocations::ShortcutLocations() 235a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : on_desktop(false), 236a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch applications_menu_location(APP_MENU_LOCATION_NONE), 237a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch in_quick_launch_bar(false) 238a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_POSIX) 239a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch , hidden(false) 240a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif 241a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch { 242a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 243a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GetShortcutInfoForTab(content::WebContents* web_contents, 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ShortcutInfo* info) { 246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(info); // Must provide a valid info. 247c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 248c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const FaviconTabHelper* favicon_tab_helper = 249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FaviconTabHelper::FromWebContents(web_contents); 250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const extensions::TabHelper* extensions_tab_helper = 251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch extensions::TabHelper::FromWebContents(web_contents); 252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const WebApplicationInfo& app_info = extensions_tab_helper->web_app_info(); 253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch info->url = app_info.app_url.is_empty() ? web_contents->GetURL() : 255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch app_info.app_url; 256c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch info->title = app_info.title.empty() ? 257c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch (web_contents->GetTitle().empty() ? base::UTF8ToUTF16(info->url.spec()) : 258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch web_contents->GetTitle()) : 259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch app_info.title; 260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch info->description = app_info.description; 261c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch info->favicon.Add(favicon_tab_helper->GetFavicon()); 262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Profile* profile = 264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Profile::FromBrowserContext(web_contents->GetBrowserContext()); 265c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch info->profile_path = profile->GetPath(); 266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 267c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 268c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if !defined(OS_WIN) 269c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid UpdateShortcutForTabContents(content::WebContents* web_contents) {} 270c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif 271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ShortcutInfo ShortcutInfoForExtensionAndProfile( 273e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const extensions::Extension* app, Profile* profile) { 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ShortcutInfo shortcut_info; 275e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shortcut_info.extension_id = app->id(); 276e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shortcut_info.is_platform_app = app->is_platform_app(); 277e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shortcut_info.url = extensions::AppLaunchInfo::GetLaunchWebURL(app); 278e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shortcut_info.title = base::UTF8ToUTF16(app->name()); 279e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shortcut_info.description = base::UTF8ToUTF16(app->description()); 280e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shortcut_info.extension_path = app->path(); 281e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shortcut_info.profile_path = profile->GetPath(); 282e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shortcut_info.profile_name = 283e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch profile->GetPrefs()->GetString(prefs::kProfileName); 284e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return shortcut_info; 285e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 286e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void UpdateShortcutInfoAndIconForApp(const extensions::Extension* extension, 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile, 289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ShortcutInfoCallback& callback) { 290a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetInfoForApp(extension, 291a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch profile, 292a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&IgnoreFileHandlersInfo, callback)); 293e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 294e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path, 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& extension_id, 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& url) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!profile_path.empty()); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath app_data_dir(profile_path.Append(chrome::kWebAppDirname)); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension_id.empty()) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return app_data_dir.AppendASCII( 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateApplicationNameFromExtensionId(extension_id)); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string host(url.host()); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string scheme(url.has_scheme() ? url.scheme() : "http"); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string port(url.has_port() ? url.port() : "80"); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string scheme_port(scheme + "_" + port); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::FilePath::StringType host_path(base::UTF8ToUTF16(host)); 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::FilePath::StringType scheme_port_path(base::UTF8ToUTF16(scheme_port)); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath::StringType host_path(host); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath::StringType scheme_port_path(scheme_port); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return app_data_dir.Append(host_path).Append(scheme_port_path); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path, 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const extensions::Extension& extension) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetWebAppDataDirectory( 325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) profile_path, 326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.id(), 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GURL(extensions::AppLaunchInfo::GetLaunchWebURL(&extension))); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string GenerateApplicationNameFromInfo(const ShortcutInfo& shortcut_info) { 331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!shortcut_info.extension_id.empty()) 332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return GenerateApplicationNameFromExtensionId(shortcut_info.extension_id); 333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else 334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return GenerateApplicationNameFromURL(shortcut_info.url); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromURL(const GURL& url) { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string t; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t.append(url.host()); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t.append("_"); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t.append(url.path()); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return t; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateApplicationNameFromExtensionId(const std::string& id) { 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string t(kCrxAppPrefix); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t.append(id); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return t; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetExtensionIdFromApplicationName(const std::string& app_name) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string prefix(kCrxAppPrefix); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (app_name.substr(0, prefix.length()) != prefix) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return app_name.substr(prefix.length()); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void CreateShortcutsForShortcutInfo(ShortcutCreationReason reason, 359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ShortcutLocations& locations, 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ShortcutInfo& shortcut_info) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::FILE, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 366c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Bind( 367c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::IgnoreResult(&web_app::internals::CreateShortcutsOnFileThread), 368c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch reason, locations, shortcut_info)); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void CreateShortcuts(ShortcutCreationReason reason, 372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ShortcutLocations& locations, 373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile, 374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const extensions::Extension* app) { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 377a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetInfoForApp(app, 378a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch profile, 379a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&CreateShortcutsWithInfo, reason, locations)); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 382c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid DeleteAllShortcuts(Profile* profile, const extensions::Extension* app) { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ShortcutInfo shortcut_info = 386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ShortcutInfoForExtensionAndProfile(app, profile); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::FILE, 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&web_app::internals::DeletePlatformShortcuts, 391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetShortcutDataDir(shortcut_info), shortcut_info)); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 394c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid UpdateAllShortcuts(const base::string16& old_app_title, 395c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Profile* profile, 396c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const extensions::Extension* app) { 397c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 399a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetInfoForApp(app, 400a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch profile, 401a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&UpdateAllShortcutsForShortcutInfo, old_app_title)); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValidUrl(const GURL& url) { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* const kValidUrlSchemes[] = { 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url::kFileScheme, 407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url::kFileSystemScheme, 408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url::kFtpScheme, 409010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url::kHttpScheme, 410010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url::kHttpsScheme, 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::kExtensionScheme, 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(kValidUrlSchemes); ++i) { 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.SchemeIs(kValidUrlSchemes[i])) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_VIEWS) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetIconsInfo(const WebApplicationInfo& app_info, 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IconInfoList* icons) { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(icons); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icons->clear(); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < app_info.icons.size(); ++i) { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only take square shaped icons (i.e. width == height). 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (app_info.icons[i].width == app_info.icons[i].height) { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icons->push_back(app_info.icons[i]); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(icons->begin(), icons->end(), &IconPrecedes); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_LINUX) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetWMClassFromAppName(std::string app_name) { 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::ReplaceIllegalCharactersInPath(&app_name, '_'); 442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::TrimString(app_name, "_", &app_name); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return app_name; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace web_app 448