From 2d1d16f1498a988a09c74ac33b475dbd428af495 Mon Sep 17 00:00:00 2001 From: "jackhou@chromium.org" Date: Thu, 3 Apr 2014 18:18:05 +0000 Subject: Remove web_app_ui.[cc|h]. The UpdateShortcutWorker class is windows specific and is moved to its own file. UpdateShortcutForTabContents is moved to web_app_win. GetShortcutInfoForTab is moved to web_app. TBR=sky@chromium.org BUG=356889 Review URL: https://codereview.chromium.org/213113005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@261481 0039d316-1c4b-4281-b951-d872f2087c98 --- apps/app_shim/DEPS | 1 - chrome/browser/extensions/tab_helper.cc | 5 +- .../gtk/create_application_shortcuts_dialog_gtk.cc | 1 - .../apps/chrome_native_app_window_views_win.cc | 1 - .../ui/views/create_application_shortcut_view.cc | 2 +- chrome/browser/ui/web_applications/web_app_ui.cc | 353 --------------------- chrome/browser/ui/web_applications/web_app_ui.h | 37 --- .../web_applications/update_shortcut_worker_win.cc | 242 ++++++++++++++ .../web_applications/update_shortcut_worker_win.h | 89 ++++++ chrome/browser/web_applications/web_app.cc | 30 ++ chrome/browser/web_applications/web_app.h | 15 + .../browser/web_applications/web_app_unittest.cc | 1 - chrome/browser/web_applications/web_app_win.cc | 7 + chrome/browser/web_applications/web_app_win.h | 4 + chrome/chrome_browser.gypi | 2 + chrome/chrome_browser_ui.gypi | 2 - 16 files changed, 394 insertions(+), 398 deletions(-) delete mode 100644 chrome/browser/ui/web_applications/web_app_ui.cc delete mode 100644 chrome/browser/ui/web_applications/web_app_ui.h create mode 100644 chrome/browser/web_applications/update_shortcut_worker_win.cc create mode 100644 chrome/browser/web_applications/update_shortcut_worker_win.h diff --git a/apps/app_shim/DEPS b/apps/app_shim/DEPS index 6c77a25..e836a97 100644 --- a/apps/app_shim/DEPS +++ b/apps/app_shim/DEPS @@ -7,7 +7,6 @@ include_rules = [ "+chrome/browser/ui/extensions/application_launch.h", "+chrome/browser/ui/extensions/extension_enable_flow.h", "+chrome/browser/ui/extensions/extension_enable_flow_delegate.h", - "+chrome/browser/ui/web_applications/web_app_ui.h", "+chrome/browser/ui/webui/ntp/core_app_launcher_handler.h", "+chrome/browser/web_applications/web_app_mac.h", "+chrome/common/chrome_constants.h", diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc index 402c89b..d38c151 100644 --- a/chrome/browser/extensions/tab_helper.cc +++ b/chrome/browser/extensions/tab_helper.cc @@ -34,7 +34,6 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/host_desktop.h" -#include "chrome/browser/ui/web_applications/web_app_ui.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/chrome_extension_messages.h" @@ -70,6 +69,10 @@ #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #endif +#if defined(OS_WIN) +#include "chrome/browser/web_applications/web_app_win.h" +#endif + using content::NavigationController; using content::NavigationEntry; using content::RenderViewHost; diff --git a/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.cc b/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.cc index 625b2a8..503bff6 100644 --- a/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.cc +++ b/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.cc @@ -17,7 +17,6 @@ #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/gtk/gtk_util.h" -#include "chrome/browser/ui/web_applications/web_app_ui.h" #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/common/extensions/manifest_handlers/icons_handler.h" diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_win.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_win.cc index 18b5b82..2c7ef56 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_win.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_win.cc @@ -18,7 +18,6 @@ #include "chrome/browser/metro_utils/metro_chrome_win.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/shell_integration.h" -#include "chrome/browser/ui/web_applications/web_app_ui.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_win.h" #include "chrome/common/chrome_icon_resources_win.h" diff --git a/chrome/browser/ui/views/create_application_shortcut_view.cc b/chrome/browser/ui/views/create_application_shortcut_view.cc index d2d90a7..238e6ed 100644 --- a/chrome/browser/ui/views/create_application_shortcut_view.cc +++ b/chrome/browser/ui/views/create_application_shortcut_view.cc @@ -19,8 +19,8 @@ #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/views/constrained_window_views.h" -#include "chrome/browser/ui/web_applications/web_app_ui.h" #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" +#include "chrome/browser/web_applications/web_app.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/pref_names.h" #include "content/public/browser/render_view_host.h" diff --git a/chrome/browser/ui/web_applications/web_app_ui.cc b/chrome/browser/ui/web_applications/web_app_ui.cc deleted file mode 100644 index 759491a..0000000 --- a/chrome/browser/ui/web_applications/web_app_ui.cc +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/web_applications/web_app_ui.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/file_util.h" -#include "base/path_service.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/extensions/tab_helper.h" -#include "chrome/browser/favicon/favicon_tab_helper.h" -#include "chrome/browser/history/select_favicon_frames.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/web_applications/web_app.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_registrar.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/web_contents.h" -#include "url/gurl.h" - -#if defined(OS_POSIX) && !defined(OS_MACOSX) -#include "base/environment.h" -#endif - -#if defined(OS_WIN) -#include "base/win/shortcut.h" -#include "base/win/windows_version.h" -#include "chrome/browser/web_applications/web_app_win.h" -#include "ui/gfx/icon_util.h" -#endif - -using content::BrowserThread; -using content::NavigationController; -using content::WebContents; - -namespace { - -// TODO(jackhou): Move all win-specific code to web_app_win. -#if defined(OS_WIN) -// UpdateShortcutWorker holds all context data needed for update shortcut. -// It schedules a pre-update check to find all shortcuts that needs to be -// updated. If there are such shortcuts, it schedules icon download and -// update them when icons are downloaded. It observes TAB_CLOSING notification -// and cancels all the work when the underlying tab is closing. -class UpdateShortcutWorker : public content::NotificationObserver { - public: - explicit UpdateShortcutWorker(WebContents* web_contents); - - void Run(); - - private: - // Overridden from content::NotificationObserver: - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details); - - // Downloads icon via the FaviconTabHelper. - void DownloadIcon(); - - // Favicon download callback. - void DidDownloadFavicon( - int requested_size, - int id, - int http_status_code, - const GURL& image_url, - const std::vector& bitmaps, - const std::vector& original_bitmap_sizes); - - // Checks if shortcuts exists on desktop, start menu and quick launch. - void CheckExistingShortcuts(); - - // Update shortcut files and icons. - void UpdateShortcuts(); - void UpdateShortcutsOnFileThread(); - - // Callback after shortcuts are updated. - void OnShortcutsUpdated(bool); - - // Deletes the worker on UI thread where it gets created. - void DeleteMe(); - void DeleteMeOnUIThread(); - - content::NotificationRegistrar registrar_; - - // Underlying WebContents whose shortcuts will be updated. - WebContents* web_contents_; - - // Icons info from web_contents_'s web app data. - web_app::IconInfoList unprocessed_icons_; - - // Cached shortcut data from the web_contents_. - ShellIntegration::ShortcutInfo shortcut_info_; - - // Our copy of profile path. - base::FilePath profile_path_; - - // File name of shortcut/ico file based on app title. - base::FilePath file_name_; - - // Existing shortcuts. - std::vector shortcut_files_; - - DISALLOW_COPY_AND_ASSIGN(UpdateShortcutWorker); -}; - -UpdateShortcutWorker::UpdateShortcutWorker(WebContents* web_contents) - : web_contents_(web_contents), - profile_path_(Profile::FromBrowserContext( - web_contents->GetBrowserContext())->GetPath()) { - extensions::TabHelper* extensions_tab_helper = - extensions::TabHelper::FromWebContents(web_contents); - web_app::GetShortcutInfoForTab(web_contents_, &shortcut_info_); - web_app::GetIconsInfo(extensions_tab_helper->web_app_info(), - &unprocessed_icons_); - file_name_ = web_app::internals::GetSanitizedFileName(shortcut_info_.title); - - registrar_.Add( - this, - chrome::NOTIFICATION_TAB_CLOSING, - content::Source(&web_contents->GetController())); -} - -void UpdateShortcutWorker::Run() { - // Starting by downloading app icon. - DownloadIcon(); -} - -void UpdateShortcutWorker::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - if (type == chrome::NOTIFICATION_TAB_CLOSING && - content::Source(source).ptr() == - &web_contents_->GetController()) { - // Underlying tab is closing. - web_contents_ = NULL; - } -} - -void UpdateShortcutWorker::DownloadIcon() { - // FetchIcon must run on UI thread because it relies on WebContents - // to download the icon. - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - if (web_contents_ == NULL) { - DeleteMe(); // We are done if underlying WebContents is gone. - return; - } - - if (unprocessed_icons_.empty()) { - // No app icon. Just use the favicon from WebContents. - UpdateShortcuts(); - return; - } - - int preferred_size = std::max(unprocessed_icons_.back().width, - unprocessed_icons_.back().height); - web_contents_->DownloadImage( - unprocessed_icons_.back().url, - true, // favicon - 0, // no maximum size - base::Bind(&UpdateShortcutWorker::DidDownloadFavicon, - base::Unretained(this), - preferred_size)); - unprocessed_icons_.pop_back(); -} - -void UpdateShortcutWorker::DidDownloadFavicon( - int requested_size, - int id, - int http_status_code, - const GURL& image_url, - const std::vector& bitmaps, - const std::vector& original_sizes) { - std::vector scale_factors; - scale_factors.push_back(ui::SCALE_FACTOR_100P); - - std::vector closest_indices; - SelectFaviconFrameIndices(original_sizes, - scale_factors, - requested_size, - &closest_indices, - NULL); - size_t closest_index = closest_indices[0]; - - if (!bitmaps.empty() && !bitmaps[closest_index].isNull()) { - // Update icon with download image and update shortcut. - shortcut_info_.favicon.Add( - gfx::Image::CreateFrom1xBitmap(bitmaps[closest_index])); - extensions::TabHelper* extensions_tab_helper = - extensions::TabHelper::FromWebContents(web_contents_); - extensions_tab_helper->SetAppIcon(bitmaps[closest_index]); - UpdateShortcuts(); - } else { - // Try the next icon otherwise. - DownloadIcon(); - } -} - -void UpdateShortcutWorker::CheckExistingShortcuts() { - DCHECK_CURRENTLY_ON(BrowserThread::FILE); - - // Locations to check to shortcut_paths. - struct { - int location_id; - const wchar_t* sub_dir; - } locations[] = { - { - base::DIR_USER_DESKTOP, - NULL - }, { - base::DIR_START_MENU, - NULL - }, { - // For Win7, create_in_quick_launch_bar means pinning to taskbar. - base::DIR_APP_DATA, - (base::win::GetVersion() >= base::win::VERSION_WIN7) ? - L"Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar" : - L"Microsoft\\Internet Explorer\\Quick Launch" - } - }; - - for (int i = 0; i < arraysize(locations); ++i) { - base::FilePath path; - if (!PathService::Get(locations[i].location_id, &path)) { - NOTREACHED(); - continue; - } - - if (locations[i].sub_dir != NULL) - path = path.Append(locations[i].sub_dir); - - base::FilePath shortcut_file = path.Append(file_name_). - ReplaceExtension(FILE_PATH_LITERAL(".lnk")); - if (base::PathExists(shortcut_file)) { - shortcut_files_.push_back(shortcut_file); - } - } -} - -void UpdateShortcutWorker::UpdateShortcuts() { - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, - base::Bind(&UpdateShortcutWorker::UpdateShortcutsOnFileThread, - base::Unretained(this))); -} - -void UpdateShortcutWorker::UpdateShortcutsOnFileThread() { - DCHECK_CURRENTLY_ON(BrowserThread::FILE); - - base::FilePath web_app_path = web_app::GetWebAppDataDirectory( - profile_path_, shortcut_info_.extension_id, shortcut_info_.url); - - // Ensure web_app_path exists. web_app_path could be missing for a legacy - // shortcut created by Gears. - if (!base::PathExists(web_app_path) && - !base::CreateDirectory(web_app_path)) { - NOTREACHED(); - return; - } - - base::FilePath icon_file = - web_app::internals::GetIconFilePath(web_app_path, shortcut_info_.title); - web_app::internals::CheckAndSaveIcon(icon_file, shortcut_info_.favicon); - - // Update existing shortcuts' description, icon and app id. - CheckExistingShortcuts(); - if (!shortcut_files_.empty()) { - // Generates app id from web app url and profile path. - base::string16 app_id = ShellIntegration::GetAppModelIdForProfile( - base::UTF8ToWide( - web_app::GenerateApplicationNameFromURL(shortcut_info_.url)), - profile_path_); - - // Sanitize description - if (shortcut_info_.description.length() >= MAX_PATH) - shortcut_info_.description.resize(MAX_PATH - 1); - - for (size_t i = 0; i < shortcut_files_.size(); ++i) { - base::win::ShortcutProperties shortcut_properties; - shortcut_properties.set_target(shortcut_files_[i]); - shortcut_properties.set_description(shortcut_info_.description); - shortcut_properties.set_icon(icon_file, 0); - shortcut_properties.set_app_id(app_id); - base::win::CreateOrUpdateShortcutLink( - shortcut_files_[i], shortcut_properties, - base::win::SHORTCUT_UPDATE_EXISTING); - } - } - - OnShortcutsUpdated(true); -} - -void UpdateShortcutWorker::OnShortcutsUpdated(bool) { - DeleteMe(); // We are done. -} - -void UpdateShortcutWorker::DeleteMe() { - if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { - DeleteMeOnUIThread(); - } else { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(&UpdateShortcutWorker::DeleteMeOnUIThread, - base::Unretained(this))); - } -} - -void UpdateShortcutWorker::DeleteMeOnUIThread() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - delete this; -} -#endif // defined(OS_WIN) - -} // namespace - -namespace web_app { - -void GetShortcutInfoForTab(WebContents* web_contents, - ShellIntegration::ShortcutInfo* info) { - DCHECK(info); // Must provide a valid info. - - const FaviconTabHelper* favicon_tab_helper = - FaviconTabHelper::FromWebContents(web_contents); - const extensions::TabHelper* extensions_tab_helper = - extensions::TabHelper::FromWebContents(web_contents); - const WebApplicationInfo& app_info = extensions_tab_helper->web_app_info(); - - info->url = app_info.app_url.is_empty() ? web_contents->GetURL() : - app_info.app_url; - info->title = app_info.title.empty() ? - (web_contents->GetTitle().empty() ? base::UTF8ToUTF16(info->url.spec()) : - web_contents->GetTitle()) : - app_info.title; - info->description = app_info.description; - info->favicon.Add(favicon_tab_helper->GetFavicon()); - - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); - info->profile_path = profile->GetPath(); -} - -void UpdateShortcutForTabContents(WebContents* web_contents) { -#if defined(OS_WIN) - // UpdateShortcutWorker will delete itself when it's done. - UpdateShortcutWorker* worker = new UpdateShortcutWorker(web_contents); - worker->Run(); -#endif // defined(OS_WIN) -} - -} // namespace web_app diff --git a/chrome/browser/ui/web_applications/web_app_ui.h b/chrome/browser/ui/web_applications/web_app_ui.h deleted file mode 100644 index 0758119..0000000 --- a/chrome/browser/ui/web_applications/web_app_ui.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_UI_H_ -#define CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_UI_H_ - -#include - -#include "chrome/browser/shell_integration.h" - -namespace content { -class WebContents; -} - -namespace extensions { -class Extension; -} - -class Profile; - -namespace web_app { - -// Extracts shortcut info of the given WebContents. -void GetShortcutInfoForTab(content::WebContents* web_contents, - ShellIntegration::ShortcutInfo* info); - -// Updates web app shortcut of the WebContents. This function checks and -// updates web app icon and shortcuts if needed. For icon, the check is based -// on MD5 hash of icon image. For shortcuts, it checks the desktop, start menu -// and quick launch (as well as pinned shortcut) for shortcut and only -// updates (recreates) them if they exits. -void UpdateShortcutForTabContents(content::WebContents* web_contents); - -} // namespace web_app - -#endif // CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_UI_H_ diff --git a/chrome/browser/web_applications/update_shortcut_worker_win.cc b/chrome/browser/web_applications/update_shortcut_worker_win.cc new file mode 100644 index 0000000..11e2c91 --- /dev/null +++ b/chrome/browser/web_applications/update_shortcut_worker_win.cc @@ -0,0 +1,242 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/web_applications/update_shortcut_worker_win.h" + +#include + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/file_util.h" +#include "base/path_service.h" +#include "base/strings/utf_string_conversions.h" +#include "base/win/shortcut.h" +#include "base/win/windows_version.h" +#include "chrome/browser/chrome_notification_types.h" +#include "chrome/browser/extensions/tab_helper.h" +#include "chrome/browser/favicon/favicon_tab_helper.h" +#include "chrome/browser/history/select_favicon_frames.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/web_applications/web_app.h" +#include "chrome/browser/web_applications/web_app_win.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/notification_details.h" +#include "content/public/browser/notification_source.h" +#include "content/public/browser/web_contents.h" +#include "ui/gfx/icon_util.h" +#include "url/gurl.h" + +using content::BrowserThread; +using content::NavigationController; +using content::WebContents; + +namespace web_app { + +UpdateShortcutWorker::UpdateShortcutWorker(WebContents* web_contents) + : web_contents_(web_contents), + profile_path_(Profile::FromBrowserContext( + web_contents->GetBrowserContext())->GetPath()) { + extensions::TabHelper* extensions_tab_helper = + extensions::TabHelper::FromWebContents(web_contents); + web_app::GetShortcutInfoForTab(web_contents_, &shortcut_info_); + web_app::GetIconsInfo(extensions_tab_helper->web_app_info(), + &unprocessed_icons_); + file_name_ = web_app::internals::GetSanitizedFileName(shortcut_info_.title); + + registrar_.Add( + this, + chrome::NOTIFICATION_TAB_CLOSING, + content::Source(&web_contents->GetController())); +} + +void UpdateShortcutWorker::Run() { + // Starting by downloading app icon. + DownloadIcon(); +} + +void UpdateShortcutWorker::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + if (type == chrome::NOTIFICATION_TAB_CLOSING && + content::Source(source).ptr() == + &web_contents_->GetController()) { + // Underlying tab is closing. + web_contents_ = NULL; + } +} + +void UpdateShortcutWorker::DownloadIcon() { + // FetchIcon must run on UI thread because it relies on WebContents + // to download the icon. + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + if (web_contents_ == NULL) { + DeleteMe(); // We are done if underlying WebContents is gone. + return; + } + + if (unprocessed_icons_.empty()) { + // No app icon. Just use the favicon from WebContents. + UpdateShortcuts(); + return; + } + + int preferred_size = std::max(unprocessed_icons_.back().width, + unprocessed_icons_.back().height); + web_contents_->DownloadImage( + unprocessed_icons_.back().url, + true, // favicon + 0, // no maximum size + base::Bind(&UpdateShortcutWorker::DidDownloadFavicon, + base::Unretained(this), + preferred_size)); + unprocessed_icons_.pop_back(); +} + +void UpdateShortcutWorker::DidDownloadFavicon( + int requested_size, + int id, + int http_status_code, + const GURL& image_url, + const std::vector& bitmaps, + const std::vector& original_sizes) { + std::vector scale_factors; + scale_factors.push_back(ui::SCALE_FACTOR_100P); + + std::vector closest_indices; + SelectFaviconFrameIndices(original_sizes, + scale_factors, + requested_size, + &closest_indices, + NULL); + size_t closest_index = closest_indices[0]; + + if (!bitmaps.empty() && !bitmaps[closest_index].isNull()) { + // Update icon with download image and update shortcut. + shortcut_info_.favicon.Add( + gfx::Image::CreateFrom1xBitmap(bitmaps[closest_index])); + extensions::TabHelper* extensions_tab_helper = + extensions::TabHelper::FromWebContents(web_contents_); + extensions_tab_helper->SetAppIcon(bitmaps[closest_index]); + UpdateShortcuts(); + } else { + // Try the next icon otherwise. + DownloadIcon(); + } +} + +void UpdateShortcutWorker::CheckExistingShortcuts() { + DCHECK_CURRENTLY_ON(BrowserThread::FILE); + + // Locations to check to shortcut_paths. + struct { + int location_id; + const wchar_t* sub_dir; + } locations[] = { + { + base::DIR_USER_DESKTOP, + NULL + }, { + base::DIR_START_MENU, + NULL + }, { + // For Win7, create_in_quick_launch_bar means pinning to taskbar. + base::DIR_APP_DATA, + (base::win::GetVersion() >= base::win::VERSION_WIN7) ? + L"Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar" : + L"Microsoft\\Internet Explorer\\Quick Launch" + } + }; + + for (int i = 0; i < arraysize(locations); ++i) { + base::FilePath path; + if (!PathService::Get(locations[i].location_id, &path)) { + NOTREACHED(); + continue; + } + + if (locations[i].sub_dir != NULL) + path = path.Append(locations[i].sub_dir); + + base::FilePath shortcut_file = path.Append(file_name_). + ReplaceExtension(FILE_PATH_LITERAL(".lnk")); + if (base::PathExists(shortcut_file)) { + shortcut_files_.push_back(shortcut_file); + } + } +} + +void UpdateShortcutWorker::UpdateShortcuts() { + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, + base::Bind(&UpdateShortcutWorker::UpdateShortcutsOnFileThread, + base::Unretained(this))); +} + +void UpdateShortcutWorker::UpdateShortcutsOnFileThread() { + DCHECK_CURRENTLY_ON(BrowserThread::FILE); + + base::FilePath web_app_path = web_app::GetWebAppDataDirectory( + profile_path_, shortcut_info_.extension_id, shortcut_info_.url); + + // Ensure web_app_path exists. web_app_path could be missing for a legacy + // shortcut created by Gears. + if (!base::PathExists(web_app_path) && + !base::CreateDirectory(web_app_path)) { + NOTREACHED(); + return; + } + + base::FilePath icon_file = + web_app::internals::GetIconFilePath(web_app_path, shortcut_info_.title); + web_app::internals::CheckAndSaveIcon(icon_file, shortcut_info_.favicon); + + // Update existing shortcuts' description, icon and app id. + CheckExistingShortcuts(); + if (!shortcut_files_.empty()) { + // Generates app id from web app url and profile path. + base::string16 app_id = ShellIntegration::GetAppModelIdForProfile( + base::UTF8ToWide( + web_app::GenerateApplicationNameFromURL(shortcut_info_.url)), + profile_path_); + + // Sanitize description + if (shortcut_info_.description.length() >= MAX_PATH) + shortcut_info_.description.resize(MAX_PATH - 1); + + for (size_t i = 0; i < shortcut_files_.size(); ++i) { + base::win::ShortcutProperties shortcut_properties; + shortcut_properties.set_target(shortcut_files_[i]); + shortcut_properties.set_description(shortcut_info_.description); + shortcut_properties.set_icon(icon_file, 0); + shortcut_properties.set_app_id(app_id); + base::win::CreateOrUpdateShortcutLink( + shortcut_files_[i], shortcut_properties, + base::win::SHORTCUT_UPDATE_EXISTING); + } + } + + OnShortcutsUpdated(true); +} + +void UpdateShortcutWorker::OnShortcutsUpdated(bool) { + DeleteMe(); // We are done. +} + +void UpdateShortcutWorker::DeleteMe() { + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { + DeleteMeOnUIThread(); + } else { + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&UpdateShortcutWorker::DeleteMeOnUIThread, + base::Unretained(this))); + } +} + +void UpdateShortcutWorker::DeleteMeOnUIThread() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + delete this; +} + +} // namespace web_app diff --git a/chrome/browser/web_applications/update_shortcut_worker_win.h b/chrome/browser/web_applications/update_shortcut_worker_win.h new file mode 100644 index 0000000..fcfa000 --- /dev/null +++ b/chrome/browser/web_applications/update_shortcut_worker_win.h @@ -0,0 +1,89 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_WEB_APPLICATIONS_UPDATE_SHORTCUT_WORKER_WIN_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_UPDATE_SHORTCUT_WORKER_WIN_H_ + +#include "chrome/browser/shell_integration.h" +#include "chrome/browser/web_applications/web_app.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" + +namespace content { +class NotificationDetails; +class NotificationSource; +class WebContents; +} + +namespace web_app { + +// UpdateShortcutWorker holds all context data needed for update shortcut. +// It schedules a pre-update check to find all shortcuts that needs to be +// updated. If there are such shortcuts, it schedules icon download and +// update them when icons are downloaded. It observes TAB_CLOSING notification +// and cancels all the work when the underlying tab is closing. +class UpdateShortcutWorker : public content::NotificationObserver { + public: + explicit UpdateShortcutWorker(content::WebContents* web_contents); + + void Run(); + + private: + // Overridden from content::NotificationObserver: + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details); + + // Downloads icon via the FaviconTabHelper. + void DownloadIcon(); + + // Favicon download callback. + void DidDownloadFavicon( + int requested_size, + int id, + int http_status_code, + const GURL& image_url, + const std::vector& bitmaps, + const std::vector& original_bitmap_sizes); + + // Checks if shortcuts exists on desktop, start menu and quick launch. + void CheckExistingShortcuts(); + + // Update shortcut files and icons. + void UpdateShortcuts(); + void UpdateShortcutsOnFileThread(); + + // Callback after shortcuts are updated. + void OnShortcutsUpdated(bool); + + // Deletes the worker on UI thread where it gets created. + void DeleteMe(); + void DeleteMeOnUIThread(); + + content::NotificationRegistrar registrar_; + + // Underlying WebContents whose shortcuts will be updated. + content::WebContents* web_contents_; + + // Icons info from web_contents_'s web app data. + web_app::IconInfoList unprocessed_icons_; + + // Cached shortcut data from the web_contents_. + ShellIntegration::ShortcutInfo shortcut_info_; + + // Our copy of profile path. + base::FilePath profile_path_; + + // File name of shortcut/ico file based on app title. + base::FilePath file_name_; + + // Existing shortcuts. + std::vector shortcut_files_; + + DISALLOW_COPY_AND_ASSIGN(UpdateShortcutWorker); +}; + +} // namespace web_app + +#endif // CHROME_BROWSER_WEB_APPLICATIONS_UPDATE_SHORTCUT_WORKER_WIN_H_ diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc index 5149be7..0d90975 100644 --- a/chrome/browser/web_applications/web_app.cc +++ b/chrome/browser/web_applications/web_app.cc @@ -13,6 +13,8 @@ #include "base/strings/utf_string_conversions.h" #include "base/threading/thread.h" #include "chrome/browser/extensions/image_loader.h" +#include "chrome/browser/extensions/tab_helper.h" +#include "chrome/browser/favicon/favicon_tab_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_version_info.h" @@ -134,6 +136,34 @@ base::FilePath GetSanitizedFileName(const base::string16& name) { } // namespace internals +void GetShortcutInfoForTab(content::WebContents* web_contents, + ShellIntegration::ShortcutInfo* info) { + DCHECK(info); // Must provide a valid info. + + const FaviconTabHelper* favicon_tab_helper = + FaviconTabHelper::FromWebContents(web_contents); + const extensions::TabHelper* extensions_tab_helper = + extensions::TabHelper::FromWebContents(web_contents); + const WebApplicationInfo& app_info = extensions_tab_helper->web_app_info(); + + info->url = app_info.app_url.is_empty() ? web_contents->GetURL() : + app_info.app_url; + info->title = app_info.title.empty() ? + (web_contents->GetTitle().empty() ? base::UTF8ToUTF16(info->url.spec()) : + web_contents->GetTitle()) : + app_info.title; + info->description = app_info.description; + info->favicon.Add(favicon_tab_helper->GetFavicon()); + + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + info->profile_path = profile->GetPath(); +} + +#if !defined(OS_WIN) +void UpdateShortcutForTabContents(content::WebContents* web_contents) {} +#endif + ShellIntegration::ShortcutInfo ShortcutInfoForExtensionAndProfile( const extensions::Extension* app, Profile* profile) { ShellIntegration::ShortcutInfo shortcut_info; diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h index 986dcf1..79ea5a5 100644 --- a/chrome/browser/web_applications/web_app.h +++ b/chrome/browser/web_applications/web_app.h @@ -17,6 +17,10 @@ class Profile; +namespace content { +class WebContents; +} + namespace extensions { class Extension; } @@ -37,6 +41,17 @@ enum ShortcutCreationReason { typedef base::Callback ShortcutInfoCallback; +// Extracts shortcut info of the given WebContents. +void GetShortcutInfoForTab(content::WebContents* web_contents, + ShellIntegration::ShortcutInfo* info); + +// Updates web app shortcut of the WebContents. This function checks and +// updates web app icon and shortcuts if needed. For icon, the check is based +// on MD5 hash of icon image. For shortcuts, it checks the desktop, start menu +// and quick launch (as well as pinned shortcut) for shortcut and only +// updates (recreates) them if they exits. +void UpdateShortcutForTabContents(content::WebContents* web_contents); + ShellIntegration::ShortcutInfo ShortcutInfoForExtensionAndProfile( const extensions::Extension* app, Profile* profile); diff --git a/chrome/browser/web_applications/web_app_unittest.cc b/chrome/browser/web_applications/web_app_unittest.cc index 3e145d0..4866102 100644 --- a/chrome/browser/web_applications/web_app_unittest.cc +++ b/chrome/browser/web_applications/web_app_unittest.cc @@ -9,7 +9,6 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/tab_helper.h" #include "chrome/browser/favicon/favicon_tab_helper.h" -#include "chrome/browser/ui/web_applications/web_app_ui.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/common/extensions/chrome_extension_messages.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" diff --git a/chrome/browser/web_applications/web_app_win.cc b/chrome/browser/web_applications/web_app_win.cc index 3178d67..d1dccce 100644 --- a/chrome/browser/web_applications/web_app_win.cc +++ b/chrome/browser/web_applications/web_app_win.cc @@ -17,6 +17,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/win/shortcut.h" #include "base/win/windows_version.h" +#include "chrome/browser/web_applications/update_shortcut_worker_win.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/common/chrome_switches.h" #include "chrome/installer/util/browser_distribution.h" @@ -548,4 +549,10 @@ base::FilePath GetIconFilePath(const base::FilePath& web_app_path, } // namespace internals +void UpdateShortcutForTabContents(content::WebContents* web_contents) { + // UpdateShortcutWorker will delete itself when it's done. + UpdateShortcutWorker* worker = new UpdateShortcutWorker(web_contents); + worker->Run(); +} + } // namespace web_app diff --git a/chrome/browser/web_applications/web_app_win.h b/chrome/browser/web_applications/web_app_win.h index 3c0dafe..4f4c541 100644 --- a/chrome/browser/web_applications/web_app_win.h +++ b/chrome/browser/web_applications/web_app_win.h @@ -8,6 +8,10 @@ #include "base/files/file_path.h" #include "chrome/browser/shell_integration.h" +namespace content { +class WebContents; +} + namespace gfx { class ImageFamily; } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 3074c51..31d07b5 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2585,6 +2585,8 @@ 'browser/usb/usb_context.h', 'browser/usb/usb_service.cc', 'browser/usb/usb_service.h', + 'browser/web_applications/update_shortcut_worker_win.cc', + 'browser/web_applications/update_shortcut_worker_win.h', 'browser/web_applications/web_app.cc', 'browser/web_applications/web_app.h', 'browser/web_applications/web_app_android.cc', diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 4e90367..6e6b106 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -2211,8 +2211,6 @@ 'browser/ui/views/website_settings/permission_selector_view_observer.h', 'browser/ui/views/website_settings/website_settings_popup_view.cc', 'browser/ui/views/website_settings/website_settings_popup_view.h', - 'browser/ui/web_applications/web_app_ui.cc', - 'browser/ui/web_applications/web_app_ui.h', 'browser/ui/website_settings/permission_bubble_manager.cc', 'browser/ui/website_settings/permission_bubble_manager.h', 'browser/ui/website_settings/permission_bubble_request.h', -- cgit v1.1