Convert IconManager to use new CancelableTaskTracker

BUG=155883


Review URL: https://chromiumcodereview.appspot.com/11441006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171296 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/api/downloads/downloads_api.cc b/chrome/browser/extensions/api/downloads/downloads_api.cc
index 9ee19547..b9d24cf 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api.cc
@@ -38,6 +38,7 @@
 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/webui/web_ui_util.h"
+#include "chrome/common/cancelable_task_tracker.h"
 #include "chrome/common/chrome_notification_types.h"
 #include "chrome/common/extensions/api/downloads.h"
 #include "content/public/browser/download_interrupt_reasons.h"
@@ -228,9 +229,9 @@
                                      IconLoader::IconSize icon_size,
                                      IconURLCallback callback) OVERRIDE;
  private:
-  void OnIconLoadComplete(IconManager::Handle handle, gfx::Image* icon);
+  void OnIconLoadComplete(gfx::Image* icon);
 
-  CancelableRequestConsumer cancelable_consumer_;
+  CancelableTaskTracker cancelable_task_tracker_;
   IconURLCallback callback_;
 };
 
@@ -244,16 +245,15 @@
   // request, in which case the associated icon may also have changed.
   // Therefore, for the moment we always call LoadIcon instead of attempting
   // a LookupIcon.
-  im->LoadIcon(
-      path, icon_size, &cancelable_consumer_,
-      base::Bind(&DownloadFileIconExtractorImpl::OnIconLoadComplete,
-                 base::Unretained(this)));
+  im->LoadIcon(path,
+               icon_size,
+               base::Bind(&DownloadFileIconExtractorImpl::OnIconLoadComplete,
+                          base::Unretained(this)),
+               &cancelable_task_tracker_);
   return true;
 }
 
-void DownloadFileIconExtractorImpl::OnIconLoadComplete(
-    IconManager::Handle handle,
-    gfx::Image* icon) {
+void DownloadFileIconExtractorImpl::OnIconLoadComplete(gfx::Image* icon) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   std::string url;
   if (icon)
diff --git a/chrome/browser/icon_manager.cc b/chrome/browser/icon_manager.cc
index e22ccefe..2f1444e 100644
--- a/chrome/browser/icon_manager.cc
+++ b/chrome/browser/icon_manager.cc
@@ -4,14 +4,29 @@
 
 #include "chrome/browser/icon_manager.h"
 
+#include "base/bind.h"
 #include "base/file_util.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/stl_util.h"
+#include "base/task_runner.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 
+namespace {
+
+void RunCallbackIfNotCanceled(
+    const CancelableTaskTracker::IsCanceledCallback& is_canceled,
+    const IconManager::IconRequestCallback& callback,
+    gfx::Image* image) {
+  if (is_canceled.Run())
+    return;
+  callback.Run(image);
+}
+
+}  // namespace
+
 struct IconManager::ClientRequest {
-  scoped_refptr<IconRequest> request;
+  IconRequestCallback callback;
   IconGroupID group;
   IconLoader::IconSize size;
 };
@@ -33,29 +48,34 @@
   return NULL;
 }
 
-IconManager::Handle IconManager::LoadIcon(
+CancelableTaskTracker::TaskId IconManager::LoadIcon(
     const FilePath& file_name,
     IconLoader::IconSize size,
-    CancelableRequestConsumerBase* consumer,
-    const IconRequestCallback& callback) {
+    const IconRequestCallback& callback,
+    CancelableTaskTracker* tracker) {
   IconGroupID group = GetGroupIDFromFilepath(file_name);
-  IconRequest* request = new IconRequest(callback);
-  AddRequest(request, consumer);
 
   IconLoader* loader = new IconLoader(group, size, this);
   loader->AddRef();
   loader->Start();
-  ClientRequest client_request = { request, group, size };
+
+  CancelableTaskTracker::IsCanceledCallback is_canceled;
+  CancelableTaskTracker::TaskId id = tracker->NewTrackedTaskId(&is_canceled);
+  IconRequestCallback callback_runner = base::Bind(
+      &RunCallbackIfNotCanceled, is_canceled, callback);
+
+  ClientRequest client_request = { callback_runner, group, size };
   requests_[loader] = client_request;
-  return request->handle();
+  return id;
 }
 
 // IconLoader::Delegate implementation -----------------------------------------
 
-bool IconManager::OnImageLoaded(IconLoader* source, gfx::Image* result) {
-  ClientRequests::iterator rit = requests_.find(source);
+bool IconManager::OnImageLoaded(IconLoader* loader, gfx::Image* result) {
+  ClientRequests::iterator rit = requests_.find(loader);
+
   // Balances the AddRef() in LoadIcon().
-  source->Release();
+  loader->Release();
 
   // Look up our client state.
   if (rit == requests_.end()) {
@@ -63,11 +83,7 @@
     return false;  // Return false to indicate result should be deleted.
   }
 
-  ClientRequest client_request = rit->second;
-  if (client_request.request->canceled()) {
-    requests_.erase(rit);
-    return false;  // Return false to indicate result should be deleted.
-  }
+  const ClientRequest& client_request = rit->second;
 
   // Cache the bitmap. Watch out: |result| or the cached bitmap may be NULL to
   // indicate a current or past failure.
@@ -82,8 +98,7 @@
   }
 
   // Inform our client that the request has completed.
-  IconRequest* icon_request = client_request.request;
-  icon_request->ForwardResult(icon_request->handle(), result);
+  client_request.callback.Run(result);
   requests_.erase(rit);
 
   return true;  // Indicates we took ownership of result.
diff --git a/chrome/browser/icon_manager.h b/chrome/browser/icon_manager.h
index f02b9aa..d6e17d4 100644
--- a/chrome/browser/icon_manager.h
+++ b/chrome/browser/icon_manager.h
@@ -47,15 +47,13 @@
 
 #include <map>
 
-#include "base/hash_tables.h"
-#include "chrome/browser/common/cancelable_request.h"
 #include "chrome/browser/icon_loader.h"
+#include "chrome/common/cancelable_task_tracker.h"
 #include "ui/gfx/image/image.h"
 
 class FilePath;
 
-class IconManager : public IconLoader::Delegate,
-                    public CancelableRequestProvider {
+class IconManager : public IconLoader::Delegate {
  public:
   IconManager();
   virtual ~IconManager();
@@ -65,25 +63,27 @@
   // it via 'LoadIcon'. The returned bitmap is owned by the IconManager and must
   // not be free'd by the caller. If the caller needs to modify the icon, it
   // must make a copy and modify the copy.
-  gfx::Image* LookupIcon(const FilePath& file_name,
-                         IconLoader::IconSize size);
+  gfx::Image* LookupIcon(const FilePath& file_name, IconLoader::IconSize size);
 
-  typedef CancelableRequestProvider::Handle Handle;
-  typedef base::Callback<void(Handle, gfx::Image*)> IconRequestCallback;
+  typedef base::Callback<void(gfx::Image*)> IconRequestCallback;
 
   // Asynchronous call to lookup and return the icon associated with file. The
-  // work is done on the file thread, with the callbacks running on the UI
-  // thread. The return value is the 'request_id' that will be passed to the
-  // client in the callback. Note: this does *not* check the cache.
+  // work is done on the file thread, with the callbacks running on the thread
+  // this function is called.
   //
-  // WATCH OUT: The returned bitmap pointer may be NULL if decoding failed.
-  Handle LoadIcon(const FilePath& file_name,
-                  IconLoader::IconSize size,
-                  CancelableRequestConsumerBase* consumer,
-                  const IconRequestCallback& callback);
+  // Note:
+  // 1. This does *not* check the cache.
+  // 2. The returned bitmap pointer is *not* owned by callback. So callback
+  //    should never keep it or delete it.
+  // 3. The gfx::Image pointer passed to the callback may be NULL if decoding
+  //    failed.
+  CancelableTaskTracker::TaskId LoadIcon(const FilePath& file_name,
+                                         IconLoader::IconSize size,
+                                         const IconRequestCallback& callback,
+                                         CancelableTaskTracker* tracker);
 
   // IconLoader::Delegate interface.
-  virtual bool OnImageLoaded(IconLoader* source, gfx::Image* result) OVERRIDE;
+  virtual bool OnImageLoaded(IconLoader* loader, gfx::Image* result) OVERRIDE;
 
   // Get the identifying string for the given file. The implementation
   // is in icon_manager_[platform].cc.
@@ -103,8 +103,6 @@
   typedef std::map<CacheKey, gfx::Image*> IconMap;
   IconMap icon_cache_;
 
-  typedef CancelableRequest<IconRequestCallback> IconRequest;
-
   // Asynchronous requests that have not yet been completed.
   struct ClientRequest;
   typedef std::map<IconLoader*, ClientRequest> ClientRequests;
diff --git a/chrome/browser/ui/cocoa/download/download_item_mac.h b/chrome/browser/ui/cocoa/download/download_item_mac.h
index f1b5d778..b82c16d 100644
--- a/chrome/browser/ui/cocoa/download/download_item_mac.h
+++ b/chrome/browser/ui/cocoa/download/download_item_mac.h
@@ -9,8 +9,8 @@
 
 #include "base/memory/scoped_nsobject.h"
 #include "base/memory/scoped_ptr.h"
-#include "chrome/browser/common/cancelable_request.h"
 #include "chrome/browser/icon_manager.h"
+#include "chrome/common/cancelable_task_tracker.h"
 #include "content/public/browser/download_item.h"
 #include "content/public/browser/download_manager.h"
 
@@ -46,8 +46,7 @@
 
  private:
   // Callback for asynchronous icon loading.
-  void OnExtractIconComplete(IconManager::Handle handle,
-                             gfx::Image* icon_bitmap);
+  void OnExtractIconComplete(gfx::Image* icon_bitmap);
 
   // The download item model we represent.
   scoped_ptr<DownloadItemModel> download_model_;
@@ -56,7 +55,7 @@
   DownloadItemController* item_controller_;  // weak, owns us.
 
   // For canceling an in progress icon request.
-  CancelableRequestConsumerT<int, 0> icon_consumer_;
+  CancelableTaskTracker cancelable_task_tracker_;
 
   // Stores the last known path where the file will be saved.
   FilePath lastFilePath_;
diff --git a/chrome/browser/ui/cocoa/download/download_item_mac.mm b/chrome/browser/ui/cocoa/download/download_item_mac.mm
index 4e69a60..2b17c08 100644
--- a/chrome/browser/ui/cocoa/download/download_item_mac.mm
+++ b/chrome/browser/ui/cocoa/download/download_item_mac.mm
@@ -23,7 +23,6 @@
 
 DownloadItemMac::~DownloadItemMac() {
   download_model_->download()->RemoveObserver(this);
-  icon_consumer_.CancelAllRequests();
 }
 
 void DownloadItemMac::OnDownloadUpdated(content::DownloadItem* download) {
@@ -89,13 +88,14 @@
   }
 
   // The icon isn't cached, load it asynchronously.
-  icon_manager->LoadIcon(file, IconLoader::ALL, &icon_consumer_,
+  icon_manager->LoadIcon(file,
+                         IconLoader::ALL,
                          base::Bind(&DownloadItemMac::OnExtractIconComplete,
-                                    base::Unretained(this)));
+                                    base::Unretained(this)),
+                         &cancelable_task_tracker_);
 }
 
-void DownloadItemMac::OnExtractIconComplete(IconManager::Handle handle,
-                                            gfx::Image* icon) {
+void DownloadItemMac::OnExtractIconComplete(gfx::Image* icon) {
   if (!icon)
     return;
   [item_controller_ setIcon:icon->ToNSImage()];
diff --git a/chrome/browser/ui/gtk/download/download_item_gtk.cc b/chrome/browser/ui/gtk/download/download_item_gtk.cc
index 2c7bc552..c2d5ad3 100644
--- a/chrome/browser/ui/gtk/download/download_item_gtk.cc
+++ b/chrome/browser/ui/gtk/download/download_item_gtk.cc
@@ -283,7 +283,6 @@
   if (menu_.get())
     menu_.reset();
 
-  icon_consumer_.CancelAllRequests();
   StopDownloadProgress();
   get_download()->RemoveObserver(this);
 
@@ -452,30 +451,30 @@
 
 // Icon loading functions.
 
-void DownloadItemGtk::OnLoadSmallIconComplete(IconManager::Handle handle,
-                                              gfx::Image* image) {
+void DownloadItemGtk::OnLoadSmallIconComplete(gfx::Image* image) {
   icon_small_ = image;
   gtk_widget_queue_draw(progress_area_.get());
 }
 
-void DownloadItemGtk::OnLoadLargeIconComplete(IconManager::Handle handle,
-                                              gfx::Image* image) {
+void DownloadItemGtk::OnLoadLargeIconComplete(gfx::Image* image) {
   icon_large_ = image;
   DownloadItemDrag::SetSource(body_.get(), get_download(), icon_large_);
 }
 
 void DownloadItemGtk::LoadIcon() {
-  icon_consumer_.CancelAllRequests();
+  cancelable_task_tracker_.TryCancelAll();
   IconManager* im = g_browser_process->icon_manager();
   icon_filepath_ = get_download()->GetUserVerifiedFilePath();
   im->LoadIcon(icon_filepath_,
-               IconLoader::SMALL, &icon_consumer_,
+               IconLoader::SMALL,
                base::Bind(&DownloadItemGtk::OnLoadSmallIconComplete,
-                          base::Unretained(this)));
+                          base::Unretained(this)),
+               &cancelable_task_tracker_);
   im->LoadIcon(icon_filepath_,
-               IconLoader::LARGE, &icon_consumer_,
+               IconLoader::LARGE,
                base::Bind(&DownloadItemGtk::OnLoadLargeIconComplete,
-                          base::Unretained(this)));
+                          base::Unretained(this)),
+               &cancelable_task_tracker_);
 }
 
 void DownloadItemGtk::UpdateTooltip() {
diff --git a/chrome/browser/ui/gtk/download/download_item_gtk.h b/chrome/browser/ui/gtk/download/download_item_gtk.h
index 0150583..0efcab4 100644
--- a/chrome/browser/ui/gtk/download/download_item_gtk.h
+++ b/chrome/browser/ui/gtk/download/download_item_gtk.h
@@ -15,6 +15,7 @@
 #include "base/time.h"
 #include "base/timer.h"
 #include "chrome/browser/icon_manager.h"
+#include "chrome/common/cancelable_task_tracker.h"
 #include "content/public/browser/download_item.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -63,10 +64,8 @@
 
   // Called when the icon manager has finished loading the icon. We take
   // ownership of |icon_bitmap|.
-  void OnLoadSmallIconComplete(IconManager::Handle handle,
-                               gfx::Image* image);
-  void OnLoadLargeIconComplete(IconManager::Handle handle,
-                               gfx::Image* image);
+  void OnLoadSmallIconComplete(gfx::Image* image);
+  void OnLoadLargeIconComplete(gfx::Image* image);
 
   // Returns the DownloadItem model object belonging to this item.
   content::DownloadItem* get_download();
@@ -236,7 +235,7 @@
   base::Time creation_time_;
 
   // For canceling an in progress icon request.
-  CancelableRequestConsumerT<int, 0> icon_consumer_;
+  CancelableTaskTracker cancelable_task_tracker_;
 
   // Indicates when the download has completed, so we don't redo
   // on-completion actions.
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc
index 2fe55db..6325ef9 100644
--- a/chrome/browser/ui/views/download/download_item_view.cc
+++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -217,7 +217,6 @@
 }
 
 DownloadItemView::~DownloadItemView() {
-  icon_consumer_.CancelAllRequests();
   StopDownloadProgress();
   download_->RemoveObserver(this);
 }
@@ -243,8 +242,7 @@
   progress_timer_.Stop();
 }
 
-void DownloadItemView::OnExtractIconComplete(IconManager::Handle handle,
-                                             gfx::Image* icon_bitmap) {
+void DownloadItemView::OnExtractIconComplete(gfx::Image* icon_bitmap) {
   if (icon_bitmap)
     parent()->SchedulePaint();
 }
@@ -856,9 +854,10 @@
   IconManager* im = g_browser_process->icon_manager();
   last_download_item_path_ = download_->GetUserVerifiedFilePath();
   im->LoadIcon(last_download_item_path_,
-               IconLoader::SMALL, &icon_consumer_,
+               IconLoader::SMALL,
                base::Bind(&DownloadItemView::OnExtractIconComplete,
-                          base::Unretained(this)));
+                          base::Unretained(this)),
+               &cancelable_task_tracker_);
 }
 
 void DownloadItemView::LoadIconIfItemPathChanged() {
diff --git a/chrome/browser/ui/views/download/download_item_view.h b/chrome/browser/ui/views/download/download_item_view.h
index f4d91b2..b4e1ead 100644
--- a/chrome/browser/ui/views/download/download_item_view.h
+++ b/chrome/browser/ui/views/download/download_item_view.h
@@ -69,7 +69,7 @@
   void StopDownloadProgress();
 
   // IconManager::Client interface.
-  void OnExtractIconComplete(IconManager::Handle handle, gfx::Image* icon);
+  void OnExtractIconComplete(gfx::Image* icon);
 
   // Returns the DownloadItem model object belonging to this item.
   content::DownloadItem* download() const { return download_; }
@@ -281,7 +281,7 @@
   gfx::Point drag_start_point_;
 
   // For canceling an in progress icon request.
-  CancelableRequestConsumerT<int, 0> icon_consumer_;
+  CancelableTaskTracker cancelable_task_tracker_;
 
   // A model class to control the status text we display and the cancel
   // behavior.
diff --git a/chrome/browser/ui/webui/fileicon_source.cc b/chrome/browser/ui/webui/fileicon_source.cc
index 8f8a80d..4ca7e811 100644
--- a/chrome/browser/ui/webui/fileicon_source.cc
+++ b/chrome/browser/ui/webui/fileicon_source.cc
@@ -5,9 +5,11 @@
 #include "chrome/browser/ui/webui/fileicon_source.h"
 
 #include "base/basictypes.h"
+#include "base/bind.h"
 #include "base/callback.h"
 #include "base/file_path.h"
 #include "base/memory/ref_counted_memory.h"
+#include "base/message_loop.h"
 #include "base/string_split.h"
 #include "base/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
@@ -91,9 +93,7 @@
 FileIconSource::FileIconSource()
     : DataSource(kFileIconPath, MessageLoop::current()) {}
 
-FileIconSource::~FileIconSource() {
-  cancelable_consumer_.CancelAllRequests();
-}
+FileIconSource::~FileIconSource() {}
 
 void FileIconSource::FetchFileIcon(const FilePath& path,
                                    ui::ScaleFactor scale_factor,
@@ -110,17 +110,17 @@
 
     SendResponse(request_id, icon_data);
   } else {
-    // Icon was not in cache, go fetch it slowly.
-    IconManager::Handle h = im->LoadIcon(
-        path, icon_size, &cancelable_consumer_,
-        base::Bind(&FileIconSource::OnFileIconDataAvailable,
-                   base::Unretained(this)));
-
     // Attach the ChromeURLDataManager request ID to the history request.
     IconRequestDetails details;
     details.request_id = request_id;
     details.scale_factor = scale_factor;
-    cancelable_consumer_.SetClientData(im, h, details);
+
+    // Icon was not in cache, go fetch it slowly.
+    im->LoadIcon(path,
+                 icon_size,
+                 base::Bind(&FileIconSource::OnFileIconDataAvailable,
+                            base::Unretained(this), details),
+                 &cancelable_task_tracker_);
   }
 }
 
@@ -141,17 +141,15 @@
   return std::string();
 }
 
-void FileIconSource::OnFileIconDataAvailable(IconManager::Handle handle,
+void FileIconSource::OnFileIconDataAvailable(const IconRequestDetails& details,
                                              gfx::Image* icon) {
-  IconManager* im = g_browser_process->icon_manager();
-  IconRequestDetails details = cancelable_consumer_.GetClientData(im, handle);
-
   if (icon) {
     scoped_refptr<base::RefCountedBytes> icon_data(new base::RefCountedBytes);
     gfx::PNGCodec::EncodeBGRASkBitmap(
-        icon->ToImageSkia()->GetRepresentation(
-            details.scale_factor).sk_bitmap(),
-        false, &icon_data->data());
+        icon->ToImageSkia()->GetRepresentation(details.scale_factor)
+            .sk_bitmap(),
+        false,
+        &icon_data->data());
 
     SendResponse(details.request_id, icon_data);
   } else {
diff --git a/chrome/browser/ui/webui/fileicon_source.h b/chrome/browser/ui/webui/fileicon_source.h
index c9194a9..ef43f841 100644
--- a/chrome/browser/ui/webui/fileicon_source.h
+++ b/chrome/browser/ui/webui/fileicon_source.h
@@ -10,6 +10,7 @@
 #include "base/file_path.h"
 #include "chrome/browser/icon_manager.h"
 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
+#include "chrome/common/cancelable_task_tracker.h"
 #include "ui/base/layout.h"
 
 namespace gfx {
@@ -30,11 +31,6 @@
 
   virtual std::string GetMimeType(const std::string&) const OVERRIDE;
 
-  // Called when favicon data is available from the history backend.
-  void OnFileIconDataAvailable(
-      IconManager::Handle request_handle,
-      gfx::Image* icon);
-
  protected:
   virtual ~FileIconSource();
 
@@ -56,8 +52,12 @@
     ui::ScaleFactor scale_factor;
   };
 
-  // Consumer for requesting file icons.
-  CancelableRequestConsumerTSimple<IconRequestDetails> cancelable_consumer_;
+  // Called when favicon data is available from the history backend.
+  void OnFileIconDataAvailable(const IconRequestDetails& details,
+                               gfx::Image* icon);
+
+  // Tracks tasks requesting file icons.
+  CancelableTaskTracker cancelable_task_tracker_;
 
   DISALLOW_COPY_AND_ASSIGN(FileIconSource);
 };