diff options
author | caitkp@chromium.org <caitkp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-22 17:21:09 +0000 |
---|---|---|
committer | caitkp@chromium.org <caitkp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-22 17:21:09 +0000 |
commit | 7adf79213d0b31fb401592dde55f3292eb474609 (patch) | |
tree | 81e16ab659e9da27de4a305a924f14ecdaded78d | |
parent | ef64608c4e58b969b3a204cff6106a9f8e991784 (diff) | |
download | chromium_src-7adf79213d0b31fb401592dde55f3292eb474609.zip chromium_src-7adf79213d0b31fb401592dde55f3292eb474609.tar.gz chromium_src-7adf79213d0b31fb401592dde55f3292eb474609.tar.bz2 |
Exposed the Notification Observer interface in jumplist_win, so that it could receive notifications
and query TopSites for updates.
Also, refactored jumplist (and a bit of browser_view) so that jumplist would properly
handle receiving notifications from both TabService and TopSites.
BUG=77756
TEST=Manual
Review URL: http://codereview.chromium.org/7538022
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97672 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/jumplist_win.cc | 402 | ||||
-rw-r--r-- | chrome/browser/jumplist_win.h | 65 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view.cc | 8 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view.h | 2 |
4 files changed, 271 insertions, 206 deletions
diff --git a/chrome/browser/jumplist_win.cc b/chrome/browser/jumplist_win.cc index 1336ee6..87a0643 100644 --- a/chrome/browser/jumplist_win.cc +++ b/chrome/browser/jumplist_win.cc @@ -24,15 +24,18 @@ #include "chrome/browser/favicon/favicon_service.h" #include "chrome/browser/history/history.h" #include "chrome/browser/history/page_usage_data.h" +#include "chrome/browser/history/top_sites.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/session_types.h" #include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/sessions/tab_restore_service_factory.h" #include "chrome/browser/shell_integration.h" #include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" #include "content/browser/browser_thread.h" +#include "content/common/notification_service.h" #include "googleurl/src/gurl.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" @@ -476,109 +479,15 @@ bool UpdateJumpList(const wchar_t* app_id, return true; } -// Represents a task which updates an application JumpList. -// This task encapsulates all I/O tasks and OS-specific tasks required for -// updating a JumpList from Chromium, such as: -// * Deleting the directory containing temporary icon files; -// * Creating temporary icon files used by the JumpList; -// * Creating an ICustomDestinationList instance; -// * Adding items in the ICustomDestinationList instance. -// To spawn this task, -// 1. Prepare objects required by this task: -// * a std::wstring that contains a temporary icons; -// * a ShellLinkItemList that contains the items of the "Most Visited" -// category, and; -// * a ShellLinkItemList that contains the items of the "Recently Closed" -// category. -// 2. Create a JumpListUpdateTask instance, and; -// 3. Post this task to the file thread. -class JumpListUpdateTask : public Task { - public: - JumpListUpdateTask(const wchar_t* app_id, - const FilePath& icon_dir, - const ShellLinkItemList& most_visited_pages, - const ShellLinkItemList& recently_closed_pages) - : app_id_(app_id), - icon_dir_(icon_dir), - most_visited_pages_(most_visited_pages), - recently_closed_pages_(recently_closed_pages) { - } - - private: - // Represents an entry point of this task. - // When we post this task to a file thread, the thread calls this function. - void Run(); - - // App id to associate with the jump list. - std::wstring app_id_; - - // The directory which contains JumpList icons. - FilePath icon_dir_; - - // Items in the "Most Visited" category of the application JumpList. - ShellLinkItemList most_visited_pages_; - - // Items in the "Recently Closed" category of the application JumpList. - ShellLinkItemList recently_closed_pages_; -}; - -void JumpListUpdateTask::Run() { - // Delete the directory which contains old icon files, rename the current - // icon directory, and create a new directory which contains new JumpList - // icon files. - FilePath icon_dir_old(icon_dir_.value() + L"Old"); - if (file_util::PathExists(icon_dir_old)) - file_util::Delete(icon_dir_old, true); - file_util::Move(icon_dir_, icon_dir_old); - file_util::CreateDirectory(icon_dir_); - - // Create temporary icon files for shortcuts in the "Most Visited" category. - for (ShellLinkItemList::const_iterator item = most_visited_pages_.begin(); - item != most_visited_pages_.end(); ++item) { - SkBitmap icon_bitmap; - if ((*item)->data().get() && - gfx::PNGCodec::Decode((*item)->data()->front(), - (*item)->data()->size(), - &icon_bitmap)) { - FilePath icon_path; - if (CreateIconFile(icon_bitmap, icon_dir_, &icon_path)) - (*item)->SetIcon(icon_path.value(), 0, true); - } - } - - // Create temporary icon files for shortcuts in the "Recently Closed" - // category. - for (ShellLinkItemList::const_iterator item = recently_closed_pages_.begin(); - item != recently_closed_pages_.end(); ++item) { - SkBitmap icon_bitmap; - if ((*item)->data().get() && - gfx::PNGCodec::Decode((*item)->data()->front(), - (*item)->data()->size(), - &icon_bitmap)) { - FilePath icon_path; - if (CreateIconFile(icon_bitmap, icon_dir_, &icon_path)) - (*item)->SetIcon(icon_path.value(), 0, true); - } - } - - // We finished collecting all resources needed for updating an appliation - // JumpList. So, create a new JumpList and replace the current JumpList - // with it. - UpdateJumpList(app_id_.c_str(), most_visited_pages_, recently_closed_pages_); - - // Delete all items in these lists now since we don't need the ShellLinkItem - // objects in these lists. - most_visited_pages_.clear(); - recently_closed_pages_.clear(); -} - } // namespace -JumpList::JumpList() : profile_(NULL) { +JumpList::JumpList() + : profile_(NULL), + handle_(NULL) { } JumpList::~JumpList() { - RemoveObserver(); + Terminate(); } // static @@ -605,39 +514,142 @@ bool JumpList::AddObserver(Profile* profile) { app_id_ = ShellIntegration::GetChromiumAppId(profile->GetPath()); icon_dir_ = profile->GetPath().Append(chrome::kJumpListIconDirname); profile_ = profile; + history::TopSites* top_sites = profile_->GetTopSites(); + if (top_sites) { + // TopSites updates itself after a delay. This is especially noticable when + // your profile is empty. Ask TopSites to update itself when jumplist is + // initialized. + top_sites->SyncWithHistory(); + // Register for notification when TopSites changes so that we can update + // ourself. + registrar_.Add(this, chrome::NOTIFICATION_TOP_SITES_CHANGED, + Source<history::TopSites>(top_sites)); + // Register for notification when profile is destroyed to ensure that all + // observers are detatched at that time. + registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, + Source<Profile>(profile_)); + } tab_restore_service->AddObserver(this); return true; } +void JumpList::Observe(int type, + const NotificationSource& source, + const NotificationDetails& details) { + switch (type) { + case chrome::NOTIFICATION_TOP_SITES_CHANGED: { + // Most visited urls changed, query again. + history::TopSites* top_sites = profile_->GetTopSites(); + if (top_sites) { + top_sites->GetMostVisitedURLs( + &topsites_consumer_, + NewCallback(this, &JumpList::OnMostVisitedURLsAvailable)); + } + break; + } + case chrome::NOTIFICATION_PROFILE_DESTROYED: { + // Profile was destroyed, do clean-up. + Terminate(); + break; + } + default: + NOTREACHED() << "Unexpected notification type."; + } +} + void JumpList::RemoveObserver() { if (profile_) { TabRestoreService* tab_restore_service = TabRestoreServiceFactory::GetForProfile(profile_); if (tab_restore_service) tab_restore_service->RemoveObserver(this); + registrar_.Remove(this, chrome::NOTIFICATION_TOP_SITES_CHANGED, + Source<history::TopSites>(profile_->GetTopSites())); + registrar_.Remove(this, chrome::NOTIFICATION_PROFILE_DESTROYED, + Source<Profile>(profile_)); } profile_ = NULL; } +void JumpList::CancelPendingUpdate() { + if (handle_) { + FaviconService* favicon_service = + profile_->GetFaviconService(Profile::EXPLICIT_ACCESS); + favicon_service->CancelRequest(handle_); + handle_ = NULL; + } +} + +void JumpList::Terminate() { + CancelPendingUpdate(); + RemoveObserver(); +} + +void JumpList::OnMostVisitedURLsAvailable( + const history::MostVisitedURLList& data) { + + // If we have a pending favicon request, cancel it here (it is out of date). + CancelPendingUpdate(); + + { + base::AutoLock auto_lock(list_lock_); + most_visited_pages_.clear(); + for (size_t i = 0; i < data.size(); i++) { + const history::MostVisitedURL& url = data[i]; + scoped_refptr<ShellLinkItem> link(new ShellLinkItem); + std::string url_string = url.url.spec(); + link->SetArguments(UTF8ToWide(url_string)); + link->SetTitle(!url.title.empty()? url.title : link->arguments()); + most_visited_pages_.push_back(link); + icon_urls_.push_back(make_pair(url_string, link)); + } + } + + // Send a query that retrieves the first favicon. + StartLoadingFavicon(); +} + void JumpList::TabRestoreServiceChanged(TabRestoreService* service) { - // Added or removed a tab. - // Exit if we are updating the application JumpList. - if (!icon_urls_.empty()) - return; + // if we have a pending handle request, cancel it here (it is out of date). + CancelPendingUpdate(); + + // local list to pass to methods + ShellLinkItemList temp_list; - // Send a query to HistoryService and retrieve the "Most Visited" pages. - // This code is copied from MostVisitedHandler::HandleGetMostVisited() to - // emulate its behaviors. - const int kMostVisitedScope = 90; - const int kMostVisitedCount = 9; - int result_count = kMostVisitedCount; - HistoryService* history_service = - profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); - history_service->QuerySegmentUsageSince( - &most_visited_consumer_, - base::Time::Now() - base::TimeDelta::FromDays(kMostVisitedScope), - result_count, - NewCallback(this, &JumpList::OnSegmentUsageAvailable)); + // Create a list of ShellLinkItems from the "Recently Closed" pages. + // As noted above, we create a ShellLinkItem objects with the following + // parameters. + // * arguments + // The last URL of the tab object. + // * title + // The title of the last URL. + // * icon + // An empty string. This value is to be updated in OnFaviconDataAvailable(). + // This code is copied from + // RecentlyClosedTabsHandler::TabRestoreServiceChanged() to emulate it. + const int kRecentlyClosedCount = 4; + TabRestoreService* tab_restore_service = + TabRestoreServiceFactory::GetForProfile(profile_); + const TabRestoreService::Entries& entries = tab_restore_service->entries(); + for (TabRestoreService::Entries::const_iterator it = entries.begin(); + it != entries.end(); ++it) { + const TabRestoreService::Entry* entry = *it; + if (entry->type == TabRestoreService::TAB) { + AddTab(static_cast<const TabRestoreService::Tab*>(entry), + &temp_list, kRecentlyClosedCount); + } else if (entry->type == TabRestoreService::WINDOW) { + AddWindow(static_cast<const TabRestoreService::Window*>(entry), + &temp_list, kRecentlyClosedCount); + } + } + // Lock recently_closed_pages and copy temp_list into it. + { + base::AutoLock auto_lock(list_lock_); + recently_closed_pages_ = temp_list; + } + + // Send a query that retrieves the first favicon. + StartLoadingFavicon(); } void JumpList::TabRestoreServiceDestroyed(TabRestoreService* service) { @@ -685,104 +697,104 @@ bool JumpList::AddWindow(const TabRestoreService::Window* window, } bool JumpList::StartLoadingFavicon() { - if (icon_urls_.empty()) - return false; - - // Ask FaviconService if it has a favicon of a URL. - // When FaviconService has one, it will call OnFaviconDataAvailable(). - GURL url(icon_urls_.front().first); + GURL url; + { + base::AutoLock auto_lock(list_lock_); + if (icon_urls_.empty()) + return false; + // Ask FaviconService if it has a favicon of a URL. + // When FaviconService has one, it will call OnFaviconDataAvailable(). + url = GURL(icon_urls_.front().first); + } FaviconService* favicon_service = profile_->GetFaviconService(Profile::EXPLICIT_ACCESS); - FaviconService::Handle handle = favicon_service->GetFaviconForURL( + handle_ = favicon_service->GetFaviconForURL( url, history::FAVICON, &favicon_consumer_, NewCallback(this, &JumpList::OnFaviconDataAvailable)); return true; } -void JumpList::OnSegmentUsageAvailable( - CancelableRequestProvider::Handle handle, - std::vector<PageUsageData*>* data) { - // Create a list of ShellLinkItem objects from the given list of - // PageUsageData objects. - // The command that opens a web page with chrome is: - // "chrome.exe <url-to-the-web-page>". - // So, we create a ShellLinkItem object with the following parameters. - // * arguments - // The URL of a PageUsagedata object (converted to std::wstring). - // * title - // The title of a PageUsageData object. If this string is empty, we use - // the URL as our "Most Visited" page does. - // * icon - // An empty string. This value is to be updated in OnFaviconDataAvailable(). - most_visited_pages_.clear(); - for (std::vector<PageUsageData*>::const_iterator page = data->begin(); - page != data->end(); ++page) { - scoped_refptr<ShellLinkItem> link(new ShellLinkItem); - std::string url = (*page)->GetURL().spec(); - link->SetArguments(UTF8ToWide(url)); - link->SetTitle( - !(*page)->GetTitle().empty() ? (*page)->GetTitle() : link->arguments()); - most_visited_pages_.push_back(link); - icon_urls_.push_back(make_pair(url, link)); - } - - // Create a list of ShellLinkItems from the "Recently Closed" pages. - // As noted above, we create a ShellLinkItem objects with the following - // parameters. - // * arguments - // The last URL of the tab object. - // * title - // The title of the last URL. - // * icon - // An empty string. This value is to be updated in OnFaviconDataAvailable(). - // This code is copied from - // RecentlyClosedTabsHandler::TabRestoreServiceChanged() to emulate it. - const int kRecentlyClosedCount = 4; - recently_closed_pages_.clear(); - TabRestoreService* tab_restore_service = - TabRestoreServiceFactory::GetForProfile(profile_); - const TabRestoreService::Entries& entries = tab_restore_service->entries(); - for (TabRestoreService::Entries::const_iterator it = entries.begin(); - it != entries.end(); ++it) { - const TabRestoreService::Entry* entry = *it; - if (entry->type == TabRestoreService::TAB) { - AddTab(static_cast<const TabRestoreService::Tab*>(entry), - &recently_closed_pages_, kRecentlyClosedCount); - } else if (entry->type == TabRestoreService::WINDOW) { - AddWindow(static_cast<const TabRestoreService::Window*>(entry), - &recently_closed_pages_, kRecentlyClosedCount); - } - } - - // Send a query that retrieves the first favicon. - StartLoadingFavicon(); -} - void JumpList::OnFaviconDataAvailable( FaviconService::Handle handle, history::FaviconData favicon) { - // Attach the received data to the ShellLinkItem object. - // This data will be decoded by JumpListUpdateTask. - if (favicon.is_valid()) { - if (!icon_urls_.empty() && icon_urls_.front().second) - icon_urls_.front().second->SetIconData(favicon.image_data); - } + // If there is currently a favicon request in progress, it is now outdated, + // as we have received another, so nullify the handle from the old request. + handle_ = NULL; + // lock the list to set icon data and pop the url + { + base::AutoLock auto_lock(list_lock_); + // Attach the received data to the ShellLinkItem object. + // This data will be decoded by the RunUpdate method. + if (favicon.is_valid()) { + if (!icon_urls_.empty() && icon_urls_.front().second) + icon_urls_.front().second->SetIconData(favicon.image_data); + } + if (!icon_urls_.empty()) + icon_urls_.pop_front(); + } // if we need to load more favicons, we send another query and exit. - if (!icon_urls_.empty()) - icon_urls_.pop_front(); if (StartLoadingFavicon()) return; // Finished loading all favicons needed by the application JumpList. - // We create a JumpListUpdateTask that creates icon files, and we post it to + // We use a RunnableMethod that creates icon files, and we post it to // the file thread. BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, - new JumpListUpdateTask(app_id_.c_str(), icon_dir_, most_visited_pages_, - recently_closed_pages_)); + NewRunnableMethod(this, &JumpList::RunUpdate)); +} + +void JumpList::RunUpdate() { + ShellLinkItemList local_most_visited_pages; + ShellLinkItemList local_recently_closed_pages; + + { + base::AutoLock auto_lock(list_lock_); + // Make sure we are not out of date: if icon_urls_ is not empty, then + // another notification has been received since we processed this one + if (!icon_urls_.empty()) + return; + + // Make local copies of lists so we can release the lock. + local_most_visited_pages = most_visited_pages_; + local_recently_closed_pages = recently_closed_pages_; + } + + // Delete the directory which contains old icon files, rename the current + // icon directory, and create a new directory which contains new JumpList + // icon files. + FilePath icon_dir_old(icon_dir_.value() + L"Old"); + if (file_util::PathExists(icon_dir_old)) + file_util::Delete(icon_dir_old, true); + file_util::Move(icon_dir_, icon_dir_old); + file_util::CreateDirectory(icon_dir_); + + // Create temporary icon files for shortcuts in the "Most Visited" category. + DecodeIconData(local_most_visited_pages); + + // Create temporary icon files for shortcuts in the "Recently Closed" + // category. + DecodeIconData(local_recently_closed_pages); + + // We finished collecting all resources needed for updating an appliation + // JumpList. So, create a new JumpList and replace the current JumpList + // with it. + UpdateJumpList(app_id_.c_str(), local_most_visited_pages, + local_recently_closed_pages); +} - // Delete all items in these lists since we don't need these lists any longer. - most_visited_pages_.clear(); - recently_closed_pages_.clear(); +void JumpList::DecodeIconData(const ShellLinkItemList& item_list) { + for (ShellLinkItemList::const_iterator item = item_list.begin(); + item != item_list.end(); ++item) { + SkBitmap icon_bitmap; + if ((*item)->data().get() && + gfx::PNGCodec::Decode((*item)->data()->front(), + (*item)->data()->size(), + &icon_bitmap)) { + FilePath icon_path; + if (CreateIconFile(icon_bitmap, icon_dir_, &icon_path)) + (*item)->SetIcon(icon_path.value(), 0, true); + } + } } diff --git a/chrome/browser/jumplist_win.h b/chrome/browser/jumplist_win.h index 88cc085..22f49ad 100644 --- a/chrome/browser/jumplist_win.h +++ b/chrome/browser/jumplist_win.h @@ -12,7 +12,9 @@ #include <vector> #include "base/memory/ref_counted.h" +#include "base/synchronization/lock.h" #include "chrome/browser/history/history.h" +#include "chrome/browser/history/history_types.h" #include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/sessions/tab_restore_service_observer.h" #include "content/browser/cancelable_request.h" @@ -97,13 +99,18 @@ typedef std::vector<scoped_refptr<ShellLinkItem> > ShellLinkItemList; // updates a JumpList when a tab is added or removed. // // Updating a JumpList requires some file operations and it is not good to -// update it in a UI thread. To solve this problem, this class posts a -// task when it actually updates a JumpList. (This task is implemented in an -// anomynous namespace in "jumplist_win.cc".) -class JumpList : public TabRestoreServiceObserver { +// update it in a UI thread. To solve this problem, this class posts to a +// runnable method when it actually updates a JumpList. +class JumpList : public TabRestoreServiceObserver, + public NotificationObserver, + public base::RefCountedThreadSafe<JumpList> { public: JumpList(); - ~JumpList(); + + // NotificationObserver implementation. + virtual void Observe(int type, + const NotificationSource& source, + const NotificationDetails& details); // Registers (or unregisters) this object as an observer. // When the TabRestoreService object notifies the tab status is changed, this @@ -122,6 +129,14 @@ class JumpList : public TabRestoreServiceObserver { // is destroyed. virtual void TabRestoreServiceDestroyed(TabRestoreService* service); + // Cancel a pending jumplist update. + void CancelPendingUpdate(); + + // Terminate the jumplist: cancel any pending updates and remove observer + // from TabRestoreService. This must be called before the profile provided + // in the AddObserver method is destroyed. + void Terminate(); + // Returns true if the custom JumpList is enabled. // We use the custom JumpList when we satisfy the following conditions: // * Chromium is running on Windows 7 and; @@ -162,29 +177,61 @@ class JumpList : public TabRestoreServiceObserver { void OnFaviconDataAvailable(HistoryService::Handle handle, history::FaviconData favicon); + // Callback for TopSites that notifies when the "Most + // Visited" list is available. This function updates the ShellLinkItemList + // objects and send another query that retrieves a favicon for each URL in + // the list. + void OnMostVisitedURLsAvailable( + const history::MostVisitedURLList& data); + + // Runnable method that updates the jumplist, once all the data + // has been fetched. + void RunUpdate(); + + // Helper method for RunUpdate to decode the data about the asynchrounously + // loaded icons. + void DecodeIconData(const ShellLinkItemList& item_list); + private: + friend class base::RefCountedThreadSafe<JumpList>; + ~JumpList(); + // Our consumers for HistoryService. CancelableRequestConsumer most_visited_consumer_; CancelableRequestConsumer favicon_consumer_; + CancelableRequestConsumer topsites_consumer_; - // The Profile object used for listening its events. + // The Profile object is used to listen for events Profile* profile_; + NotificationRegistrar registrar_; + // App id to associate with the jump list. std::wstring app_id_; // The directory which contains JumpList icons. FilePath icon_dir_; - // Items in the "Most Visited" category of the application JumpList. + // Items in the "Most Visited" category of the application JumpList, + // protected by the list_lock_. ShellLinkItemList most_visited_pages_; - // Items in the "Recently Closed" category of the application JumpList. + // Items in the "Recently Closed" category of the application JumpList, + // protected by the list_lock_. ShellLinkItemList recently_closed_pages_; - // A list of URLs we need to retrieve their favicons. + // A list of URLs we need to retrieve their favicons, + // protected by the list_lock_. typedef std::pair<std::string, scoped_refptr<ShellLinkItem> > URLPair; std::list<URLPair> icon_urls_; + + // Handle of last favicon request used to cancel if a new request + // comes in before the current one returns. + FaviconService::Handle handle_; + + // Lock for most_visited_pages_, recently_closed_pages_, icon_urls_ + // as they may be used by up to 3 threads. + base::Lock list_lock_; }; #endif // CHROME_BROWSER_JUMPLIST_WIN_H_ diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index e206a6d..59c87a7 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -353,6 +353,12 @@ BrowserView::~BrowserView() { // Stop hung plugin monitoring. ticker_.Stop(); ticker_.UnregisterTickHandler(&hung_window_detector_); + + // Terminate the jumplist (must be called before browser_->profile() is + // destroyed. + if (jumplist_) { + jumplist_->Terminate(); + } #endif #if !defined(OS_CHROMEOS) @@ -2015,7 +2021,7 @@ void BrowserView::Init() { // Create a custom JumpList and add it to an observer of TabRestoreService // so we can update the custom JumpList when a tab is added or removed. if (JumpList::Enabled()) { - jumplist_.reset(new JumpList); + jumplist_ = new JumpList(); jumplist_->AddObserver(browser_->profile()); } diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 66aba98..9cf273c 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h @@ -717,7 +717,7 @@ class BrowserView : public BrowserBubbleHost, HungPluginAction hung_plugin_action_; // The custom JumpList for Windows 7. - scoped_ptr<JumpList> jumplist_; + scoped_refptr<JumpList> jumplist_; // The custom AeroPeek manager for Windows 7. scoped_ptr<AeroPeekManager> aeropeek_manager_; |