| Index: chrome/browser/ui/web_applications/web_app_ui.cc
|
| 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 596764b5cdb7dad928b4af487fde86d16a6af1cb..0000000000000000000000000000000000000000
|
| --- 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<SkBitmap>& bitmaps,
|
| - const std::vector<gfx::Size>& 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<base::FilePath> 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<NavigationController>(&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<NavigationController>(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(BrowserThread::CurrentlyOn(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<SkBitmap>& bitmaps,
|
| - const std::vector<gfx::Size>& original_sizes) {
|
| - std::vector<ui::ScaleFactor> scale_factors;
|
| - scale_factors.push_back(ui::SCALE_FACTOR_100P);
|
| -
|
| - std::vector<size_t> 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(BrowserThread::CurrentlyOn(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(BrowserThread::CurrentlyOn(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(BrowserThread::CurrentlyOn(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
|
|
|