diff options
author | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-24 00:08:26 +0000 |
---|---|---|
committer | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-24 00:08:26 +0000 |
commit | f847e608f1cfead35cf71a3d254f116e54aa4294 (patch) | |
tree | 4b7f217c5733b8084c05bf6f7352189b55f82acc | |
parent | dd29bcd78feba27e2093d0b2cacbd6e9d8e314ef (diff) | |
download | chromium_src-f847e608f1cfead35cf71a3d254f116e54aa4294.zip chromium_src-f847e608f1cfead35cf71a3d254f116e54aa4294.tar.gz chromium_src-f847e608f1cfead35cf71a3d254f116e54aa4294.tar.bz2 |
Split off web_app's ui into ui files, plumb TCW rather than TC.
BUG=71097
TEST=none; no visible change
Review URL: http://codereview.chromium.org/6672059
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79220 0039d316-1c4b-4281-b951-d872f2087c98
20 files changed, 462 insertions, 385 deletions
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 22aada8..e3f2dcc 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -80,6 +80,7 @@ #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/tabs/dock_info.h" #include "chrome/browser/ui/tabs/tab_menu_model.h" +#include "chrome/browser/ui/web_applications/web_app_ui.h" #include "chrome/browser/ui/webui/bug_report_ui.h" #include "chrome/browser/ui/webui/filebrowse_ui.h" #include "chrome/browser/ui/webui/options/content_settings_handler.h" @@ -3223,8 +3224,8 @@ bool Browser::ShouldAddNavigationToHistory( void Browser::OnDidGetApplicationInfo(TabContents* tab_contents, int32 page_id) { - TabContents* current_tab = GetSelectedTabContents(); - if (current_tab != tab_contents) + TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper(); + if (current_tab->tab_contents() != tab_contents) return; NavigationEntry* entry = current_tab->controller().GetLastCommittedEntry(); diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index ea54e3c..2ec5d6c 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h @@ -289,7 +289,8 @@ class BrowserWindow { virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) = 0; // Shows the create web app shortcut dialog box. - virtual void ShowCreateWebAppShortcutsDialog(TabContents* tab_contents) = 0; + virtual void ShowCreateWebAppShortcutsDialog( + TabContentsWrapper* tab_contents) = 0; // Shows the create chrome app shortcut dialog box. virtual void ShowCreateChromeAppShortcutsDialog(Profile* profile, diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h index e72bc14..571732684 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.h +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h @@ -96,7 +96,8 @@ class BrowserWindowCocoa : public BrowserWindow, virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut); virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); - virtual void ShowCreateWebAppShortcutsDialog(TabContents* tab_contents); + virtual void ShowCreateWebAppShortcutsDialog( + TabContentsWrapper* tab_contents); virtual void ShowCreateChromeAppShortcutsDialog(Profile* profile, const Extension* app); virtual void Cut(); diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm index 70045d1..691db38 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm @@ -516,7 +516,7 @@ bool BrowserWindowCocoa::HandleKeyboardEventInternal(NSEvent* event) { } void BrowserWindowCocoa::ShowCreateWebAppShortcutsDialog( - TabContents* tab_contents) { + TabContentsWrapper* tab_contents) { NOTIMPLEMENTED(); } diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc index f546e5f..1bb2747 100644 --- a/chrome/browser/ui/gtk/browser_window_gtk.cc +++ b/chrome/browser/ui/gtk/browser_window_gtk.cc @@ -1023,7 +1023,7 @@ void BrowserWindowGtk::HandleKeyboardEvent( } void BrowserWindowGtk::ShowCreateWebAppShortcutsDialog( - TabContents* tab_contents) { + TabContentsWrapper* tab_contents) { CreateWebApplicationShortcutsDialogGtk::Show(window_, tab_contents); } diff --git a/chrome/browser/ui/gtk/browser_window_gtk.h b/chrome/browser/ui/gtk/browser_window_gtk.h index 7866cf9..d5c4095 100644 --- a/chrome/browser/ui/gtk/browser_window_gtk.h +++ b/chrome/browser/ui/gtk/browser_window_gtk.h @@ -117,7 +117,8 @@ class BrowserWindowGtk : public BrowserWindow, virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut); virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); - virtual void ShowCreateWebAppShortcutsDialog(TabContents* tab_contents); + virtual void ShowCreateWebAppShortcutsDialog( + TabContentsWrapper* tab_contents); virtual void ShowCreateChromeAppShortcutsDialog(Profile* profile, const Extension* app); virtual void Cut(); 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 b13a26b..30e8c62 100644 --- a/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.cc +++ b/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.cc @@ -10,7 +10,8 @@ #include "base/utf_string_conversions.h" #include "chrome/browser/shell_integration.h" #include "chrome/browser/ui/gtk/gtk_util.h" -#include "chrome/browser/web_applications/web_app.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/browser/ui/web_applications/web_app_ui.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_resource.h" #include "content/browser/browser_thread.h" @@ -33,8 +34,8 @@ const int kDescriptionLabelHeightLines = 3; } // namespace // static -void CreateWebApplicationShortcutsDialogGtk::Show(GtkWindow* parent, - TabContents* tab_contents) { +void CreateWebApplicationShortcutsDialogGtk::Show( + GtkWindow* parent, TabContentsWrapper* tab_contents) { new CreateWebApplicationShortcutsDialogGtk(parent, tab_contents); } @@ -271,7 +272,7 @@ void CreateApplicationShortcutsDialogGtk::OnToggleCheckbox(GtkWidget* sender) { CreateWebApplicationShortcutsDialogGtk::CreateWebApplicationShortcutsDialogGtk( GtkWindow* parent, - TabContents* tab_contents) + TabContentsWrapper* tab_contents) : CreateApplicationShortcutsDialogGtk(parent), tab_contents_(tab_contents) { @@ -283,8 +284,9 @@ CreateWebApplicationShortcutsDialogGtk::CreateWebApplicationShortcutsDialogGtk( } void CreateWebApplicationShortcutsDialogGtk::OnCreatedShortcut() { - if (tab_contents_->delegate()) - tab_contents_->delegate()->ConvertContentsToApplication(tab_contents_); + if (tab_contents_->tab_contents()->delegate()) + tab_contents_->tab_contents()->delegate()->ConvertContentsToApplication( + tab_contents_->tab_contents()); } CreateChromeApplicationShortcutsDialogGtk:: diff --git a/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h b/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h index 647b318..955db21 100644 --- a/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h +++ b/chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h @@ -20,6 +20,7 @@ typedef struct _GtkWindow GtkWindow; class Extension; class TabContents; +class TabContentsWrapper; class CreateApplicationShortcutsDialogGtk : public base::RefCountedThreadSafe<CreateApplicationShortcutsDialogGtk, @@ -76,18 +77,18 @@ class CreateWebApplicationShortcutsDialogGtk : public CreateApplicationShortcutsDialogGtk { public: // Displays the dialog box to create application shortcuts for |tab_contents|. - static void Show(GtkWindow* parent, TabContents* tab_contents); + static void Show(GtkWindow* parent, TabContentsWrapper* tab_contents); - explicit CreateWebApplicationShortcutsDialogGtk(GtkWindow* parent, - TabContents* tab_contents); + CreateWebApplicationShortcutsDialogGtk(GtkWindow* parent, + TabContentsWrapper* tab_contents); virtual ~CreateWebApplicationShortcutsDialogGtk() {} virtual void OnCreatedShortcut(void); private: - // TabContents for which the shortcut will be created. - TabContents* tab_contents_; + // TabContentsWrapper for which the shortcut will be created. + TabContentsWrapper* tab_contents_; DISALLOW_COPY_AND_ASSIGN(CreateWebApplicationShortcutsDialogGtk); }; diff --git a/chrome/browser/ui/views/browser_dialogs.h b/chrome/browser/ui/views/browser_dialogs.h index 2bd98df..b3341734 100644 --- a/chrome/browser/ui/views/browser_dialogs.h +++ b/chrome/browser/ui/views/browser_dialogs.h @@ -25,6 +25,7 @@ class GURL; class InfoBubbleDelegate; class Profile; class TabContents; +class TabContentsWrapper; class TemplateURL; namespace gfx { @@ -87,7 +88,7 @@ void ShowCollectedCookiesDialog(gfx::NativeWindow parent_window, // Shows the create web app shortcut dialog box. void ShowCreateWebAppShortcutsDialog(gfx::NativeWindow parent_window, - TabContents* tab_contents); + TabContentsWrapper* tab_contents); // Shows the create chrome app shortcut dialog box. void ShowCreateChromeAppShortcutsDialog(gfx::NativeWindow parent_window, diff --git a/chrome/browser/ui/views/create_application_shortcut_view.cc b/chrome/browser/ui/views/create_application_shortcut_view.cc index b722006..a2167fa 100644 --- a/chrome/browser/ui/views/create_application_shortcut_view.cc +++ b/chrome/browser/ui/views/create_application_shortcut_view.cc @@ -9,6 +9,8 @@ #include "base/win/windows_version.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/browser/ui/web_applications/web_app_ui.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_resource.h" @@ -191,7 +193,7 @@ void AppInfoView::OnPaint(gfx::Canvas* canvas) { namespace browser { void ShowCreateWebAppShortcutsDialog(gfx::NativeWindow parent_window, - TabContents* tab_contents) { + TabContentsWrapper* tab_contents) { views::Window::CreateChromeWindow(parent_window, gfx::Rect(), new CreateUrlApplicationShortcutView(tab_contents))->Show(); } @@ -407,13 +409,14 @@ void CreateApplicationShortcutView::ButtonPressed(views::Button* sender, } CreateUrlApplicationShortcutView::CreateUrlApplicationShortcutView( - TabContents* tab_contents) + TabContentsWrapper* tab_contents) : CreateApplicationShortcutView(tab_contents->profile()), tab_contents_(tab_contents), pending_download_(NULL) { web_app::GetShortcutInfoForTab(tab_contents_, &shortcut_info_); - const WebApplicationInfo& app_info = tab_contents_->web_app_info(); + const WebApplicationInfo& app_info = + tab_contents_->tab_contents()->web_app_info(); if (!app_info.icons.empty()) { web_app::GetIconsInfo(app_info, &unprocessed_icons_); FetchIcon(); @@ -431,9 +434,11 @@ bool CreateUrlApplicationShortcutView::Accept() { if (!CreateApplicationShortcutView::Accept()) return false; - tab_contents_->SetAppIcon(shortcut_info_.favicon); - if (tab_contents_->delegate()) - tab_contents_->delegate()->ConvertContentsToApplication(tab_contents_); + tab_contents_->tab_contents()->SetAppIcon(shortcut_info_.favicon); + if (tab_contents_->tab_contents()->delegate()) { + tab_contents_->tab_contents()->delegate()->ConvertContentsToApplication( + tab_contents_->tab_contents()); + } return true; } @@ -447,7 +452,7 @@ void CreateUrlApplicationShortcutView::FetchIcon() { pending_download_ = new IconDownloadCallbackFunctor(this); DCHECK(pending_download_); - tab_contents_->favicon_helper().DownloadImage( + tab_contents_->tab_contents()->favicon_helper().DownloadImage( unprocessed_icons_.back().url, std::max(unprocessed_icons_.back().width, unprocessed_icons_.back().height), diff --git a/chrome/browser/ui/views/create_application_shortcut_view.h b/chrome/browser/ui/views/create_application_shortcut_view.h index f13b9e9..5f4efae 100644 --- a/chrome/browser/ui/views/create_application_shortcut_view.h +++ b/chrome/browser/ui/views/create_application_shortcut_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -25,6 +25,7 @@ class Extension; class MessageLoop; class Profile; class TabContents; +class TabContentsWrapper; // CreateShortcutViewCommon implements a dialog that asks user where to create // the shortcut for given web app. There are two variants of this dialog: @@ -84,7 +85,7 @@ class CreateApplicationShortcutView : public views::View, // Create an application shortcut pointing to a URL. class CreateUrlApplicationShortcutView : public CreateApplicationShortcutView { public: - explicit CreateUrlApplicationShortcutView(TabContents* tab_contents); + explicit CreateUrlApplicationShortcutView(TabContentsWrapper* tab_contents); virtual ~CreateUrlApplicationShortcutView(); virtual bool Accept(); @@ -98,7 +99,7 @@ class CreateUrlApplicationShortcutView : public CreateApplicationShortcutView { void OnIconDownloaded(bool errored, const SkBitmap& image); // The tab whose URL is being turned into an app. - TabContents* tab_contents_; + TabContentsWrapper* tab_contents_; // Pending app icon download tracked by us. class IconDownloadCallbackFunctor; diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 97298b0..7f660b3 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -1131,7 +1131,8 @@ void BrowserView::ShowHTMLDialog(HtmlDialogUIDelegate* delegate, browser::ShowHtmlDialog(parent, browser_.get()->profile(), delegate); } -void BrowserView::ShowCreateWebAppShortcutsDialog(TabContents* tab_contents) { +void BrowserView::ShowCreateWebAppShortcutsDialog( + TabContentsWrapper* tab_contents) { browser::ShowCreateWebAppShortcutsDialog(GetNativeHandle(), tab_contents); } diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index a53fefa..4032e40 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h @@ -294,7 +294,7 @@ class BrowserView : public BrowserBubbleHost, bool* is_keyboard_shortcut) OVERRIDE; virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) OVERRIDE; - virtual void ShowCreateWebAppShortcutsDialog(TabContents* tab_contents) + virtual void ShowCreateWebAppShortcutsDialog(TabContentsWrapper* tab_contents) OVERRIDE; virtual void ShowCreateChromeAppShortcutsDialog( Profile*, const Extension* app) OVERRIDE; diff --git a/chrome/browser/ui/web_applications/web_app_ui.cc b/chrome/browser/ui/web_applications/web_app_ui.cc new file mode 100644 index 0000000..5c92e0e --- /dev/null +++ b/chrome/browser/ui/web_applications/web_app_ui.cc @@ -0,0 +1,315 @@ +// Copyright (c) 2011 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/file_util.h" +#include "base/path_service.h" +#include "base/task.h" +#include "base/win/windows_version.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/web_applications/web_app.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/common/chrome_paths.h" +#include "content/browser/browser_thread.h" +#include "content/browser/tab_contents/tab_contents.h" +#include "content/common/notification_registrar.h" + +#if defined(OS_LINUX) +#include "base/environment.h" +#endif // defined(OS_LINUX) + +#if defined(OS_WIN) +#include "content/common/notification_details.h" +#include "content/common/notification_source.h" +#endif // defined(OS_WIN) + +namespace { + +#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 NotificationObserver { + public: + explicit UpdateShortcutWorker(TabContentsWrapper* tab_contents); + + void Run(); + + private: + // Overridden from NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // Downloads icon via TabContents. + void DownloadIcon(); + + // Callback when icon downloaded. + void OnIconDownloaded(int download_id, bool errored, const SkBitmap& image); + + // 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(); + + NotificationRegistrar registrar_; + + // Underlying TabContentsWrapper whose shortcuts will be updated. + TabContentsWrapper* tab_contents_; + + // Icons info from tab_contents_'s web app data. + web_app::IconInfoList unprocessed_icons_; + + // Cached shortcut data from the tab_contents_. + ShellIntegration::ShortcutInfo shortcut_info_; + + // Our copy of profile path. + FilePath profile_path_; + + // File name of shortcut/ico file based on app title. + FilePath file_name_; + + // Existing shortcuts. + std::vector<FilePath> shortcut_files_; + + DISALLOW_COPY_AND_ASSIGN(UpdateShortcutWorker); +}; + +UpdateShortcutWorker::UpdateShortcutWorker(TabContentsWrapper* tab_contents) + : tab_contents_(tab_contents), + profile_path_(tab_contents->profile()->GetPath()) { + web_app::GetShortcutInfoForTab(tab_contents_, &shortcut_info_); + web_app::GetIconsInfo(tab_contents_->tab_contents()->web_app_info(), + &unprocessed_icons_); + file_name_ = web_app::internals::GetSanitizedFileName(shortcut_info_.title); + + registrar_.Add(this, NotificationType::TAB_CLOSING, + Source<NavigationController>(&tab_contents_->controller())); +} + +void UpdateShortcutWorker::Run() { + // Starting by downloading app icon. + DownloadIcon(); +} + +void UpdateShortcutWorker::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::TAB_CLOSING && + Source<NavigationController>(source).ptr() == + &tab_contents_->controller()) { + // Underlying tab is closing. + tab_contents_ = NULL; + } +} + +void UpdateShortcutWorker::DownloadIcon() { + // FetchIcon must run on UI thread because it relies on TabContents + // to download the icon. + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + if (tab_contents_ == NULL) { + DeleteMe(); // We are done if underlying TabContents is gone. + return; + } + + if (unprocessed_icons_.empty()) { + // No app icon. Just use the favicon from TabContents. + UpdateShortcuts(); + return; + } + + tab_contents_->tab_contents()->favicon_helper().DownloadImage( + unprocessed_icons_.back().url, + std::max(unprocessed_icons_.back().width, + unprocessed_icons_.back().height), + NewCallback(this, &UpdateShortcutWorker::OnIconDownloaded)); + unprocessed_icons_.pop_back(); +} + +void UpdateShortcutWorker::OnIconDownloaded(int download_id, + bool errored, + const SkBitmap& image) { + if (tab_contents_ == NULL) { + DeleteMe(); // We are done if underlying TabContents is gone. + return; + } + + if (!errored && !image.isNull()) { + // Update icon with download image and update shortcut. + shortcut_info_.favicon = image; + tab_contents_->tab_contents()->SetAppIcon(image); + UpdateShortcuts(); + } else { + // Try the next icon otherwise. + DownloadIcon(); + } +} + +void UpdateShortcutWorker::CheckExistingShortcuts() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + // Locations to check to shortcut_paths. + struct { + bool& use_this_location; + int location_id; + const wchar_t* sub_dir; + } locations[] = { + { + shortcut_info_.create_on_desktop, + chrome::DIR_USER_DESKTOP, + NULL + }, { + shortcut_info_.create_in_applications_menu, + base::DIR_START_MENU, + NULL + }, { + shortcut_info_.create_in_quick_launch_bar, + // 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) { + locations[i].use_this_location = false; + + 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); + + FilePath shortcut_file = path.Append(file_name_). + ReplaceExtension(FILE_PATH_LITERAL(".lnk")); + if (file_util::PathExists(shortcut_file)) { + locations[i].use_this_location = true; + shortcut_files_.push_back(shortcut_file); + } + } +} + +void UpdateShortcutWorker::UpdateShortcuts() { + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, + NewRunnableMethod(this, + &UpdateShortcutWorker::UpdateShortcutsOnFileThread)); +} + +void UpdateShortcutWorker::UpdateShortcutsOnFileThread() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + FilePath web_app_path = web_app::internals::GetWebAppDataDirectory( + web_app::GetDataDir(profile_path_), shortcut_info_); + + // Ensure web_app_path exists. web_app_path could be missing for a legacy + // shortcut created by Gears. + if (!file_util::PathExists(web_app_path) && + !file_util::CreateDirectory(web_app_path)) { + NOTREACHED(); + return; + } + + FilePath icon_file = web_app_path.Append(file_name_).ReplaceExtension( + FILE_PATH_LITERAL(".ico")); + 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. + std::wstring app_id = ShellIntegration::GetAppId( + 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) { + file_util::UpdateShortcutLink(NULL, + shortcut_files_[i].value().c_str(), + NULL, + NULL, + shortcut_info_.description.c_str(), + icon_file.value().c_str(), + 0, + app_id.c_str()); + } + } + + 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, + NewRunnableMethod(this, &UpdateShortcutWorker::DeleteMeOnUIThread)); + } +} + +void UpdateShortcutWorker::DeleteMeOnUIThread() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + delete this; +} +#endif // defined(OS_WIN) + +} // namespace + +#if defined(OS_WIN) +// Allows UpdateShortcutWorker without adding refcounting. UpdateShortcutWorker +// manages its own life time and will delete itself when it's done. +DISABLE_RUNNABLE_METHOD_REFCOUNT(UpdateShortcutWorker); +#endif // defined(OS_WIN) + +namespace web_app { + +void GetShortcutInfoForTab(TabContentsWrapper* tab_contents_wrapper, + ShellIntegration::ShortcutInfo* info) { + DCHECK(info); // Must provide a valid info. + const TabContents* tab_contents = tab_contents_wrapper->tab_contents(); + + const WebApplicationInfo& app_info = tab_contents->web_app_info(); + + info->url = app_info.app_url.is_empty() ? tab_contents->GetURL() : + app_info.app_url; + info->title = app_info.title.empty() ? + (tab_contents->GetTitle().empty() ? UTF8ToUTF16(info->url.spec()) : + tab_contents->GetTitle()) : + app_info.title; + info->description = app_info.description; + info->favicon = tab_contents->GetFavicon(); +} + +void UpdateShortcutForTabContents(TabContentsWrapper* tab_contents) { +#if defined(OS_WIN) + // UpdateShortcutWorker will delete itself when it's done. + UpdateShortcutWorker* worker = new UpdateShortcutWorker(tab_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 new file mode 100644 index 0000000..386f621 --- /dev/null +++ b/chrome/browser/ui/web_applications/web_app_ui.h @@ -0,0 +1,30 @@ +// Copyright (c) 2011 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_ +#pragma once + +#include <vector> + +#include "chrome/browser/shell_integration.h" + +class TabContentsWrapper; + +namespace web_app { + +// Extracts shortcut info of given TabContents. +void GetShortcutInfoForTab(TabContentsWrapper* tab_contents, + ShellIntegration::ShortcutInfo* info); + +// Updates web app shortcut of the TabContents. 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(TabContentsWrapper* tab_contents); + +} // namespace web_app + +#endif // CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_UI_H_ diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc index 8915277..c4046c8 100644 --- a/chrome/browser/web_applications/web_app.cc +++ b/chrome/browser/web_applications/web_app.cc @@ -5,43 +5,27 @@ #include "chrome/browser/web_applications/web_app.h" #if defined(OS_WIN) -#include <shellapi.h> #include <shlobj.h> #endif // defined(OS_WIN) -#include <algorithm> -#include <string> -#include <vector> - -#include "base/callback.h" #include "base/command_line.h" #include "base/file_util.h" #include "base/md5.h" -#include "base/message_loop.h" #include "base/path_service.h" -#include "base/scoped_ptr.h" #include "base/threading/thread.h" #include "base/utf_string_conversions.h" #include "base/win/windows_version.h" #include "chrome/browser/download/download_util.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" -#include "chrome/common/extensions/extension.h" #include "chrome/common/url_constants.h" -#include "chrome/common/web_apps.h" #include "content/browser/browser_thread.h" -#include "content/browser/tab_contents/tab_contents.h" -#include "content/common/notification_registrar.h" #if defined(OS_LINUX) #include "base/environment.h" #endif // defined(OS_LINUX) #if defined(OS_WIN) -#include "base/win/win_util.h" -#include "content/common/notification_details.h" -#include "content/common/notification_source.h" #include "ui/gfx/icon_util.h" #endif // defined(OS_WIN) @@ -74,20 +58,6 @@ bool IsValidFilePathChar(char16 c) { return true; } -// Returns sanitized name that could be used as a file name -FilePath GetSanitizedFileName(const string16& name) { - string16 file_name; - - for (size_t i = 0; i < name.length(); ++i) { - char16 c = name[i]; - if (!IsValidFilePathChar(c)) - c = '_'; - - file_name += c; - } - - return FilePath(file_name); -} #endif // defined(OS_WIN) // Returns relative directory of given web app url. @@ -118,12 +88,6 @@ FilePath GetWebAppDir(const ShellIntegration::ShortcutInfo& info) { } } -// Returns data directory for given web app url -FilePath GetWebAppDataDirectory(const FilePath& root_dir, - const ShellIntegration::ShortcutInfo& info) { - return root_dir.Append(GetWebAppDir(info)); -} - #if defined(TOOLKIT_VIEWS) // Predicator for sorting images from largest to smallest. bool IconPrecedes(const WebApplicationInfo::IconInfo& left, @@ -178,25 +142,6 @@ bool ShouldUpdateIcon(const FilePath& icon_file, const SkBitmap& image) { sizeof(MD5Digest)) != 0; } -// Saves |image| to |icon_file| if the file is outdated and refresh shell's -// icon cache to ensure correct icon is displayed. Returns true if icon_file -// is up to date or successfully updated. -bool CheckAndSaveIcon(const FilePath& icon_file, const SkBitmap& image) { - if (ShouldUpdateIcon(icon_file, image)) { - if (SaveIconWithCheckSum(icon_file, image)) { - // Refresh shell's icon cache. This call is quite disruptive as user would - // see explorer rebuilding the icon cache. It would be great that we find - // a better way to achieve this. - SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT, - NULL, NULL); - } else { - return false; - } - } - - return true; -} - #endif // defined(OS_WIN) // Represents a task that creates web application shortcut. This runs on @@ -253,7 +198,7 @@ CreateShortcutTask::CreateShortcutTask( const FilePath& profile_path, const ShellIntegration::ShortcutInfo& shortcut_info, web_app::CreateShortcutCallback* callback) - : web_app_path_(GetWebAppDataDirectory( + : web_app_path_(web_app::internals::GetWebAppDataDirectory( web_app::GetDataDir(profile_path), shortcut_info)), profile_path_(profile_path), @@ -359,12 +304,14 @@ bool CreateShortcutTask::CreateShortcut() { } // Generates file name to use with persisted ico and shortcut file. - FilePath file_name = GetSanitizedFileName(shortcut_info_.title); + FilePath file_name = + web_app::internals::GetSanitizedFileName(shortcut_info_.title); // Creates an ico file to use with shortcut. FilePath icon_file = web_app_path_.Append(file_name).ReplaceExtension( FILE_PATH_LITERAL(".ico")); - if (!CheckAndSaveIcon(icon_file, shortcut_info_.favicon)) { + if (!web_app::internals::CheckAndSaveIcon(icon_file, + shortcut_info_.favicon)) { NOTREACHED(); return false; } @@ -449,272 +396,63 @@ bool CreateShortcutTask::CreateShortcut() { #endif } -#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 NotificationObserver { - public: - explicit UpdateShortcutWorker(TabContents* tab_contents); - - void Run(); - - private: - // Overridden from NotificationObserver: - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - // Downloads icon via TabContents. - void DownloadIcon(); - - // Callback when icon downloaded. - void OnIconDownloaded(int download_id, bool errored, const SkBitmap& image); - - // 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(); - - NotificationRegistrar registrar_; - - // Underlying TabContents whose shortcuts will be updated. - TabContents* tab_contents_; - - // Icons info from tab_contents_'s web app data. - web_app::IconInfoList unprocessed_icons_; - - // Cached shortcut data from the tab_contents_. - ShellIntegration::ShortcutInfo shortcut_info_; - - // Our copy of profile path. - FilePath profile_path_; - - // File name of shortcut/ico file based on app title. - FilePath file_name_; - - // Existing shortcuts. - std::vector<FilePath> shortcut_files_; - - DISALLOW_COPY_AND_ASSIGN(UpdateShortcutWorker); -}; - -UpdateShortcutWorker::UpdateShortcutWorker(TabContents* tab_contents) - : tab_contents_(tab_contents), - profile_path_(tab_contents->profile()->GetPath()) { - web_app::GetShortcutInfoForTab(tab_contents_, &shortcut_info_); - web_app::GetIconsInfo(tab_contents_->web_app_info(), &unprocessed_icons_); - file_name_ = GetSanitizedFileName(shortcut_info_.title); - - registrar_.Add(this, NotificationType::TAB_CLOSING, - Source<NavigationController>(&tab_contents_->controller())); -} - -void UpdateShortcutWorker::Run() { - // Starting by downloading app icon. - DownloadIcon(); -} +} // namespace -void UpdateShortcutWorker::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - if (type == NotificationType::TAB_CLOSING && - Source<NavigationController>(source).ptr() == - &tab_contents_->controller()) { - // Underlying tab is closing. - tab_contents_ = NULL; - } -} - -void UpdateShortcutWorker::DownloadIcon() { - // FetchIcon must run on UI thread because it relies on TabContents - // to download the icon. - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (tab_contents_ == NULL) { - DeleteMe(); // We are done if underlying TabContents is gone. - return; - } - - if (unprocessed_icons_.empty()) { - // No app icon. Just use the favicon from TabContents. - UpdateShortcuts(); - return; - } - - tab_contents_->favicon_helper().DownloadImage( - unprocessed_icons_.back().url, - std::max(unprocessed_icons_.back().width, - unprocessed_icons_.back().height), - NewCallback(this, &UpdateShortcutWorker::OnIconDownloaded)); - unprocessed_icons_.pop_back(); -} - -void UpdateShortcutWorker::OnIconDownloaded(int download_id, - bool errored, - const SkBitmap& image) { - if (tab_contents_ == NULL) { - DeleteMe(); // We are done if underlying TabContents is gone. - return; - } - - if (!errored && !image.isNull()) { - // Update icon with download image and update shortcut. - shortcut_info_.favicon = image; - tab_contents_->SetAppIcon(image); - UpdateShortcuts(); - } else { - // Try the next icon otherwise. - DownloadIcon(); - } -} - -void UpdateShortcutWorker::CheckExistingShortcuts() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); +namespace web_app { - // Locations to check to shortcut_paths. - struct { - bool& use_this_location; - int location_id; - const wchar_t* sub_dir; - } locations[] = { - { - shortcut_info_.create_on_desktop, - chrome::DIR_USER_DESKTOP, - NULL - }, { - shortcut_info_.create_in_applications_menu, - base::DIR_START_MENU, - NULL - }, { - shortcut_info_.create_in_quick_launch_bar, - // 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" - } - }; +// The following string is used to build the directory name for +// shortcuts to chrome applications (the kind which are installed +// from a CRX). Application shortcuts to URLs use the {host}_{path} +// for the name of this directory. Hosts can't include an underscore. +// By starting this string with an underscore, we ensure that there +// are no naming conflicts. +static const char* kCrxAppPrefix = "_crx_"; - for (int i = 0; i < arraysize(locations); ++i) { - locations[i].use_this_location = false; +namespace internals { - FilePath path; - if (!PathService::Get(locations[i].location_id, &path)) { - NOTREACHED(); - continue; - } +#if defined(OS_WIN) +// Returns sanitized name that could be used as a file name +FilePath GetSanitizedFileName(const string16& name) { + string16 file_name; - if (locations[i].sub_dir != NULL) - path = path.Append(locations[i].sub_dir); + for (size_t i = 0; i < name.length(); ++i) { + char16 c = name[i]; + if (!IsValidFilePathChar(c)) + c = '_'; - FilePath shortcut_file = path.Append(file_name_). - ReplaceExtension(FILE_PATH_LITERAL(".lnk")); - if (file_util::PathExists(shortcut_file)) { - locations[i].use_this_location = true; - shortcut_files_.push_back(shortcut_file); - } + file_name += c; } -} -void UpdateShortcutWorker::UpdateShortcuts() { - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, - NewRunnableMethod(this, - &UpdateShortcutWorker::UpdateShortcutsOnFileThread)); + return FilePath(file_name); } -void UpdateShortcutWorker::UpdateShortcutsOnFileThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - - FilePath web_app_path = GetWebAppDataDirectory( - web_app::GetDataDir(profile_path_), shortcut_info_); - - // Ensure web_app_path exists. web_app_path could be missing for a legacy - // shortcut created by Gears. - if (!file_util::PathExists(web_app_path) && - !file_util::CreateDirectory(web_app_path)) { - NOTREACHED(); - return; - } - - FilePath icon_file = web_app_path.Append(file_name_).ReplaceExtension( - FILE_PATH_LITERAL(".ico")); - 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. - std::wstring app_id = ShellIntegration::GetAppId( - 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) { - file_util::UpdateShortcutLink(NULL, - shortcut_files_[i].value().c_str(), - NULL, - NULL, - shortcut_info_.description.c_str(), - icon_file.value().c_str(), - 0, - app_id.c_str()); +// Saves |image| to |icon_file| if the file is outdated and refresh shell's +// icon cache to ensure correct icon is displayed. Returns true if icon_file +// is up to date or successfully updated. +bool CheckAndSaveIcon(const FilePath& icon_file, const SkBitmap& image) { + if (ShouldUpdateIcon(icon_file, image)) { + if (SaveIconWithCheckSum(icon_file, image)) { + // Refresh shell's icon cache. This call is quite disruptive as user would + // see explorer rebuilding the icon cache. It would be great that we find + // a better way to achieve this. + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT, + NULL, NULL); + } else { + return false; } } - OnShortcutsUpdated(true); -} - -void UpdateShortcutWorker::OnShortcutsUpdated(bool) { - DeleteMe(); // We are done. + return true; } +#endif // OS_WIN -void UpdateShortcutWorker::DeleteMe() { - if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { - DeleteMeOnUIThread(); - } else { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - NewRunnableMethod(this, &UpdateShortcutWorker::DeleteMeOnUIThread)); - } +// Returns data directory for given web app url +FilePath GetWebAppDataDirectory(const FilePath& root_dir, + const ShellIntegration::ShortcutInfo& info) { + return root_dir.Append(GetWebAppDir(info)); } -void UpdateShortcutWorker::DeleteMeOnUIThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - delete this; -} -#endif // defined(OS_WIN) - -}; // namespace - -#if defined(OS_WIN) -// Allows UpdateShortcutWorker without adding refcounting. UpdateShortcutWorker -// manages its own life time and will delete itself when it's done. -DISABLE_RUNNABLE_METHOD_REFCOUNT(UpdateShortcutWorker); -#endif // defined(OS_WIN) - -namespace web_app { - -// The following string is used to build the directory name for -// shortcuts to chrome applications (the kind which are installed -// from a CRX). Application shortcuts to URLs use the {host}_{path} -// for the name of this directory. Hosts can't include an underscore. -// By starting this string with an underscore, we ensure that there -// are no naming conflicts. -static const char* kCrxAppPrefix = "_crx_"; +} // namespace internals std::string GenerateApplicationNameFromURL(const GURL& url) { std::string t; @@ -776,28 +514,4 @@ void GetIconsInfo(const WebApplicationInfo& app_info, } #endif -void GetShortcutInfoForTab(TabContents* tab_contents, - ShellIntegration::ShortcutInfo* info) { - DCHECK(info); // Must provide a valid info. - - const WebApplicationInfo& app_info = tab_contents->web_app_info(); - - info->url = app_info.app_url.is_empty() ? tab_contents->GetURL() : - app_info.app_url; - info->title = app_info.title.empty() ? - (tab_contents->GetTitle().empty() ? UTF8ToUTF16(info->url.spec()) : - tab_contents->GetTitle()) : - app_info.title; - info->description = app_info.description; - info->favicon = tab_contents->GetFavicon(); -} - -void UpdateShortcutForTabContents(TabContents* tab_contents) { -#if defined(OS_WIN) - // UpdateShortcutWorker will delete itself when it's done. - UpdateShortcutWorker* worker = new UpdateShortcutWorker(tab_contents); - worker->Run(); -#endif // defined(OS_WIN) -} - -}; // namespace web_app +} // namespace web_app diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h index 76b666c..7ccb33f 100644 --- a/chrome/browser/web_applications/web_app.h +++ b/chrome/browser/web_applications/web_app.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -9,13 +9,12 @@ #include <vector> #include "base/callback.h" +#include "base/file_path.h" #include "build/build_config.h" #include "chrome/browser/shell_integration.h" #include "chrome/common/web_apps.h" -class FilePath; class Profile; -class TabContents; namespace web_app { @@ -55,17 +54,18 @@ void GetIconsInfo(const WebApplicationInfo& app_info, IconInfoList* icons); #endif -// Extracts shortcut info of given TabContents. -void GetShortcutInfoForTab(TabContents* tab_contents, - ShellIntegration::ShortcutInfo* info); +namespace internals { -// Updates web app shortcut of the TabContents. 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(TabContents* tab_contents); +#if defined(OS_WIN) +FilePath GetSanitizedFileName(const string16& name); -}; // namespace web_app +bool CheckAndSaveIcon(const FilePath& icon_file, const SkBitmap& image); +#endif + +FilePath GetWebAppDataDirectory(const FilePath& root_dir, + const ShellIntegration::ShortcutInfo& info); +} // namespace internals + +} // namespace web_app #endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_H_ diff --git a/chrome/browser/web_applications/web_app_unittest.cc b/chrome/browser/web_applications/web_app_unittest.cc index e245645..931add1 100644 --- a/chrome/browser/web_applications/web_app_unittest.cc +++ b/chrome/browser/web_applications/web_app_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -7,17 +7,17 @@ #include "base/file_path.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" +#include "chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h" +#include "chrome/browser/ui/web_applications/web_app_ui.h" #include "chrome/common/render_messages.h" #include "chrome/test/testing_profile.h" #include "content/browser/browser_thread.h" -#include "content/browser/renderer_host/test_render_view_host.h" -#include "content/browser/tab_contents/test_tab_contents.h" #include "testing/gtest/include/gtest/gtest.h" -class WebApplicationTest : public RenderViewHostTestHarness { +class WebApplicationTest : public TabContentsWrapperTestHarness { public: WebApplicationTest() - : RenderViewHostTestHarness(), + : TabContentsWrapperTestHarness(), ui_thread_(BrowserThread::UI, &message_loop_) { } @@ -27,11 +27,11 @@ class WebApplicationTest : public RenderViewHostTestHarness { virtual void SetUp() { profile_.reset(new TestingProfile()); - RenderViewHostTestHarness::SetUp(); + TabContentsWrapperTestHarness::SetUp(); } virtual void TearDown() { - RenderViewHostTestHarness::TearDown(); + TabContentsWrapperTestHarness::TearDown(); profile_.reset(NULL); } @@ -51,7 +51,7 @@ TEST_F(WebApplicationTest, GetShortcutInfoForTab) { rvh()->TestOnMessageReceived( ViewHostMsg_DidGetApplicationInfo(0, 0, web_app_info)); ShellIntegration::ShortcutInfo info; - web_app::GetShortcutInfoForTab(contents(), &info); + web_app::GetShortcutInfoForTab(contents_wrapper(), &info); EXPECT_EQ(title, info.title); EXPECT_EQ(description, info.description); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 7ea845b..bee151c 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -3087,6 +3087,8 @@ 'browser/ui/views/window.h', 'browser/ui/views/wrench_menu.cc', 'browser/ui/views/wrench_menu.h', + 'browser/ui/web_applications/web_app_ui.cc', + 'browser/ui/web_applications/web_app_ui.h', 'browser/ui/webui/app_launcher_handler.cc', 'browser/ui/webui/app_launcher_handler.h', 'browser/ui/webui/bookmarks_ui.cc', diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h index a384d7e..e7e6cb8 100644 --- a/chrome/test/test_browser_window.h +++ b/chrome/test/test_browser_window.h @@ -54,7 +54,8 @@ class TestBrowserWindow : public BrowserWindow { virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut); virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {} - virtual void ShowCreateWebAppShortcutsDialog(TabContents* tab_contents) {} + virtual void ShowCreateWebAppShortcutsDialog( + TabContentsWrapper* tab_contents) {} virtual void ShowCreateChromeAppShortcutsDialog(Profile* profile, const Extension* app) {} #if defined(TOOLKIT_VIEWS) |