drive: Return cancel closure from FileSystem::GetFileContent

This change does not fix the bug, just a preparation for the actual fix.
No behavior change is intended.

Return cancel closure from DownloadOperation and FileSystem.
Change user code (SyncClient and DriveFileStreamReader) to use the returned closure.

BUG=344789
TEST=unit_tests

Review URL: https://codereview.chromium.org/214363002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260184 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/chromeos/drive/drive_file_stream_reader.cc b/chrome/browser/chromeos/drive/drive_file_stream_reader.cc
index e9d97b1..44d9bf45 100644
--- a/chrome/browser/chromeos/drive/drive_file_stream_reader.cc
+++ b/chrome/browser/chromeos/drive/drive_file_stream_reader.cc
@@ -29,12 +29,6 @@
   return net::FileErrorToNetError(FileErrorToBaseFileError(error));
 }
 
-// Runs task on UI thread.
-void RunTaskOnUIThread(const base::Closure& task) {
-  google_apis::RunTaskOnThread(
-      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), task);
-}
-
 // Computes the concrete |start| offset and the |length| of |range| in a file
 // of |total| size.
 //
@@ -273,7 +267,7 @@
 // Calls FileSystemInterface::GetFileContent if the file system
 // is available. If not, the |completion_callback| is invoked with
 // FILE_ERROR_FAILED.
-void GetFileContentOnUIThread(
+base::Closure GetFileContentOnUIThread(
     const DriveFileStreamReader::FileSystemGetter& file_system_getter,
     const base::FilePath& drive_file_path,
     const GetFileContentInitializedCallback& initialized_callback,
@@ -284,13 +278,14 @@
   FileSystemInterface* file_system = file_system_getter.Run();
   if (!file_system) {
     completion_callback.Run(FILE_ERROR_FAILED);
-    return;
+    return base::Closure();
   }
 
-  file_system->GetFileContent(drive_file_path,
-                              initialized_callback,
-                              get_content_callback,
-                              completion_callback);
+  return google_apis::CreateRelayCallback(
+      file_system->GetFileContent(drive_file_path,
+                                  initialized_callback,
+                                  get_content_callback,
+                                  completion_callback));
 }
 
 // Helper to run FileSystemInterface::GetFileContent on UI thread.
@@ -299,10 +294,11 @@
     const base::FilePath& drive_file_path,
     const GetFileContentInitializedCallback& initialized_callback,
     const google_apis::GetContentCallback& get_content_callback,
-    const FileOperationCallback& completion_callback) {
+    const FileOperationCallback& completion_callback,
+    const base::Callback<void(const base::Closure&)>& reply_callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
-  BrowserThread::PostTask(
+  BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::UI,
       FROM_HERE,
       base::Bind(&GetFileContentOnUIThread,
@@ -310,7 +306,8 @@
                  drive_file_path,
                  google_apis::CreateRelayCallback(initialized_callback),
                  google_apis::CreateRelayCallback(get_content_callback),
-                 google_apis::CreateRelayCallback(completion_callback)));
+                 google_apis::CreateRelayCallback(completion_callback)),
+      reply_callback);
 }
 
 }  // namespace
@@ -351,7 +348,9 @@
                  weak_ptr_factory_.GetWeakPtr()),
       base::Bind(&DriveFileStreamReader::OnGetFileContentCompletion,
                  weak_ptr_factory_.GetWeakPtr(),
-                 callback));
+                 callback),
+      base::Bind(&DriveFileStreamReader::StoreCancelDownloadClosure,
+                 weak_ptr_factory_.GetWeakPtr()));
 }
 
 int DriveFileStreamReader::Read(net::IOBuffer* buffer, int buffer_length,
@@ -363,14 +362,21 @@
   return reader_proxy_->Read(buffer, buffer_length, callback);
 }
 
+void DriveFileStreamReader::StoreCancelDownloadClosure(
+    const base::Closure& cancel_download_closure) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  cancel_download_closure_ = cancel_download_closure;
+}
+
 void DriveFileStreamReader::InitializeAfterGetFileContentInitialized(
     const net::HttpByteRange& byte_range,
     const InitializeCompletionCallback& callback,
     FileError error,
-    scoped_ptr<ResourceEntry> entry,
     const base::FilePath& local_cache_file_path,
-    const base::Closure& ui_cancel_download_closure) {
+    scoped_ptr<ResourceEntry> entry) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+  // StoreCancelDownloadClosure() should be called before this function.
+  DCHECK(!cancel_download_closure_.is_null());
 
   if (error != FILE_ERROR_OK) {
     callback.Run(FileErrorToNetError(error), scoped_ptr<ResourceEntry>());
@@ -385,8 +391,7 @@
     // At the same time, we cancel the in-flight downloading operation if
     // needed and and invalidate weak pointers so that we won't
     // receive unwanted callbacks.
-    if (!ui_cancel_download_closure.is_null())
-      RunTaskOnUIThread(ui_cancel_download_closure);
+    cancel_download_closure_.Run();
     weak_ptr_factory_.InvalidateWeakPtrs();
     callback.Run(
         net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, scoped_ptr<ResourceEntry>());
@@ -395,11 +400,9 @@
 
   if (local_cache_file_path.empty()) {
     // The file is not cached, and being downloaded.
-    DCHECK(!ui_cancel_download_closure.is_null());
     reader_proxy_.reset(
         new internal::NetworkReaderProxy(
-            range_start, range_length,
-            base::Bind(&RunTaskOnUIThread, ui_cancel_download_closure)));
+            range_start, range_length, cancel_download_closure_));
     callback.Run(net::OK, entry.Pass());
     return;
   }
diff --git a/chrome/browser/chromeos/drive/drive_file_stream_reader.h b/chrome/browser/chromeos/drive/drive_file_stream_reader.h
index c39f285..b6a2b1d 100644
--- a/chrome/browser/chromeos/drive/drive_file_stream_reader.h
+++ b/chrome/browser/chromeos/drive/drive_file_stream_reader.h
@@ -172,15 +172,17 @@
            const net::CompletionCallback& callback);
 
  private:
+  // Used to store the cancel closure returned by FileSystemInterface.
+  void StoreCancelDownloadClosure(const base::Closure& cancel_download_closure);
+
   // Part of Initialize. Called after GetFileContent's initialization
   // is done.
   void InitializeAfterGetFileContentInitialized(
       const net::HttpByteRange& byte_range,
       const InitializeCompletionCallback& callback,
       FileError error,
-      scoped_ptr<ResourceEntry> entry,
       const base::FilePath& local_cache_file_path,
-      const base::Closure& cancel_download_closure);
+      scoped_ptr<ResourceEntry> entry);
 
   // Part of Initialize. Called when the local file open process is done.
   void InitializeAfterLocalFileOpen(
@@ -201,6 +203,7 @@
 
   const FileSystemGetter file_system_getter_;
   scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
+  base::Closure cancel_download_closure_;
   scoped_ptr<internal::ReaderProxy> reader_proxy_;
 
   // This should remain the last member so it'll be destroyed first and
diff --git a/chrome/browser/chromeos/drive/dummy_file_system.cc b/chrome/browser/chromeos/drive/dummy_file_system.cc
new file mode 100644
index 0000000..696d695
--- /dev/null
+++ b/chrome/browser/chromeos/drive/dummy_file_system.cc
@@ -0,0 +1,17 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/drive/dummy_file_system.h"
+
+namespace drive {
+
+base::Closure DummyFileSystem::GetFileContent(
+      const base::FilePath& file_path,
+      const GetFileContentInitializedCallback& initialized_callback,
+      const google_apis::GetContentCallback& get_content_callback,
+      const FileOperationCallback& completion_callback) {
+  return base::Bind(&base::DoNothing);
+}
+
+}  // namespace drive
diff --git a/chrome/browser/chromeos/drive/dummy_file_system.h b/chrome/browser/chromeos/drive/dummy_file_system.h
index 464a0e4..1147f8c 100644
--- a/chrome/browser/chromeos/drive/dummy_file_system.h
+++ b/chrome/browser/chromeos/drive/dummy_file_system.h
@@ -58,11 +58,11 @@
                        const GetFileCallback& callback) OVERRIDE {}
   virtual void GetFileForSaving(const base::FilePath& file_path,
                                 const GetFileCallback& callback) OVERRIDE {}
-  virtual void GetFileContent(
+  virtual base::Closure GetFileContent(
       const base::FilePath& file_path,
       const GetFileContentInitializedCallback& initialized_callback,
       const google_apis::GetContentCallback& get_content_callback,
-      const FileOperationCallback& completion_callback) OVERRIDE {}
+      const FileOperationCallback& completion_callback) OVERRIDE;
   virtual void GetResourceEntry(
       const base::FilePath& file_path,
       const GetResourceEntryCallback& callback) OVERRIDE {}
diff --git a/chrome/browser/chromeos/drive/fake_file_system.cc b/chrome/browser/chromeos/drive/fake_file_system.cc
index 2ed13c0..00555dc 100644
--- a/chrome/browser/chromeos/drive/fake_file_system.cc
+++ b/chrome/browser/chromeos/drive/fake_file_system.cc
@@ -127,7 +127,7 @@
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 }
 
-void FakeFileSystem::GetFileContent(
+base::Closure FakeFileSystem::GetFileContent(
     const base::FilePath& file_path,
     const GetFileContentInitializedCallback& initialized_callback,
     const google_apis::GetContentCallback& get_content_callback,
@@ -140,6 +140,7 @@
                  weak_ptr_factory_.GetWeakPtr(),
                  initialized_callback, get_content_callback,
                  completion_callback));
+  return base::Bind(&base::DoNothing);
 }
 
 void FakeFileSystem::GetResourceEntry(
@@ -295,14 +296,12 @@
       cache_dir_.path().AppendASCII(entry->resource_id());
   if (base::PathExists(cache_path)) {
     // Cache file is found.
-    initialized_callback.Run(FILE_ERROR_OK, entry.Pass(), cache_path,
-                             base::Closure());
+    initialized_callback.Run(FILE_ERROR_OK, cache_path, entry.Pass());
     completion_callback.Run(FILE_ERROR_OK);
     return;
   }
 
-  initialized_callback.Run(FILE_ERROR_OK, entry.Pass(), base::FilePath(),
-                           base::Bind(&base::DoNothing));
+  initialized_callback.Run(FILE_ERROR_OK, base::FilePath(), entry.Pass());
   drive_service_->DownloadFile(
       cache_path,
       gdata_entry->resource_id(),
diff --git a/chrome/browser/chromeos/drive/fake_file_system.h b/chrome/browser/chromeos/drive/fake_file_system.h
index a12f046..5c4cffb 100644
--- a/chrome/browser/chromeos/drive/fake_file_system.h
+++ b/chrome/browser/chromeos/drive/fake_file_system.h
@@ -87,7 +87,7 @@
                        const GetFileCallback& callback) OVERRIDE;
   virtual void GetFileForSaving(const base::FilePath& file_path,
                                 const GetFileCallback& callback) OVERRIDE;
-  virtual void GetFileContent(
+  virtual base::Closure GetFileContent(
       const base::FilePath& file_path,
       const GetFileContentInitializedCallback& initialized_callback,
       const google_apis::GetContentCallback& get_content_callback,
diff --git a/chrome/browser/chromeos/drive/fake_file_system_unittest.cc b/chrome/browser/chromeos/drive/fake_file_system_unittest.cc
index 6b014ab..a391d125 100644
--- a/chrome/browser/chromeos/drive/fake_file_system_unittest.cc
+++ b/chrome/browser/chromeos/drive/fake_file_system_unittest.cc
@@ -38,7 +38,6 @@
   FileError initialize_error = FILE_ERROR_FAILED;
   scoped_ptr<ResourceEntry> entry;
   base::FilePath cache_file_path;
-  base::Closure cancel_download;
   google_apis::test_util::TestGetContentCallback get_content_callback;
   FileError completion_error = FILE_ERROR_FAILED;
 
@@ -46,10 +45,10 @@
       util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
 
   // For the first time, the file should be downloaded from the service.
-  fake_file_system_->GetFileContent(
+  base::Closure cancel_download = fake_file_system_->GetFileContent(
       kDriveFile,
       google_apis::test_util::CreateCopyResultCallback(
-          &initialize_error, &entry, &cache_file_path, &cancel_download),
+          &initialize_error, &cache_file_path, &entry),
       get_content_callback.callback(),
       google_apis::test_util::CreateCopyResultCallback(&completion_error));
   base::RunLoop().RunUntilIdle();
@@ -72,10 +71,10 @@
   completion_error = FILE_ERROR_FAILED;
 
   // For the second time, the cache file should be found.
-  fake_file_system_->GetFileContent(
+  cancel_download = fake_file_system_->GetFileContent(
       kDriveFile,
       google_apis::test_util::CreateCopyResultCallback(
-          &initialize_error, &entry, &cache_file_path, &cancel_download),
+          &initialize_error, &cache_file_path, &entry),
       get_content_callback.callback(),
       google_apis::test_util::CreateCopyResultCallback(&completion_error));
   base::RunLoop().RunUntilIdle();
@@ -103,12 +102,10 @@
   base::FilePath cache_file_path;
   google_apis::test_util::TestGetContentCallback get_content_callback;
   FileError completion_error = FILE_ERROR_FAILED;
-  base::Closure cancel_download;
-
-  fake_file_system_->GetFileContent(
+  base::Closure cancel_download = fake_file_system_->GetFileContent(
       util::GetDriveMyDriveRootPath(),
       google_apis::test_util::CreateCopyResultCallback(
-          &initialize_error, &entry, &cache_file_path, &cancel_download),
+          &initialize_error, &cache_file_path, &entry),
       get_content_callback.callback(),
       google_apis::test_util::CreateCopyResultCallback(&completion_error));
   base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/chromeos/drive/file_system.cc b/chrome/browser/chromeos/drive/file_system.cc
index 3d1fad19..4e67ffa 100644
--- a/chrome/browser/chromeos/drive/file_system.cc
+++ b/chrome/browser/chromeos/drive/file_system.cc
@@ -612,7 +612,7 @@
   get_file_for_saving_operation_->GetFileForSaving(file_path, callback);
 }
 
-void FileSystem::GetFileContent(
+base::Closure FileSystem::GetFileContent(
     const base::FilePath& file_path,
     const GetFileContentInitializedCallback& initialized_callback,
     const google_apis::GetContentCallback& get_content_callback,
@@ -622,7 +622,7 @@
   DCHECK(!get_content_callback.is_null());
   DCHECK(!completion_callback.is_null());
 
-  download_operation_->EnsureFileDownloadedByPath(
+  return download_operation_->EnsureFileDownloadedByPath(
       file_path,
       ClientContext(USER_INITIATED),
       initialized_callback,
diff --git a/chrome/browser/chromeos/drive/file_system.h b/chrome/browser/chromeos/drive/file_system.h
index 61fa643..062afe9 100644
--- a/chrome/browser/chromeos/drive/file_system.h
+++ b/chrome/browser/chromeos/drive/file_system.h
@@ -127,7 +127,7 @@
                              const GetFileCallback& callback) OVERRIDE;
   virtual void GetFileForSaving(const base::FilePath& file_path,
                                       const GetFileCallback& callback) OVERRIDE;
-  virtual void GetFileContent(
+  virtual base::Closure GetFileContent(
       const base::FilePath& file_path,
       const GetFileContentInitializedCallback& initialized_callback,
       const google_apis::GetContentCallback& get_content_callback,
diff --git a/chrome/browser/chromeos/drive/file_system/download_operation.cc b/chrome/browser/chromeos/drive/file_system/download_operation.cc
index f1f2af9..778f2b7 100644
--- a/chrome/browser/chromeos/drive/file_system/download_operation.cc
+++ b/chrome/browser/chromeos/drive/file_system/download_operation.cc
@@ -263,30 +263,34 @@
       : initialized_callback_(initialized_callback),
         get_content_callback_(get_content_callback),
         completion_callback_(completion_callback),
-        entry_(entry.Pass()) {
+        entry_(entry.Pass()),
+        weak_ptr_factory_(this) {
     DCHECK(!completion_callback_.is_null());
     DCHECK(entry_);
   }
 
+  base::Closure GetCancelClosure() {
+    return base::Bind(&DownloadParams::Cancel, weak_ptr_factory_.GetWeakPtr());
+  }
+
   void OnCacheFileFound(const base::FilePath& cache_file_path) const {
     if (initialized_callback_.is_null())
       return;
 
     DCHECK(entry_);
-    initialized_callback_.Run(
-        FILE_ERROR_OK, make_scoped_ptr(new ResourceEntry(*entry_)),
-        cache_file_path, base::Closure());
+    initialized_callback_.Run(FILE_ERROR_OK, cache_file_path,
+                              make_scoped_ptr(new ResourceEntry(*entry_)));
   }
 
-  void OnStartDownloading(const base::Closure& cancel_download_closure) const {
+  void OnStartDownloading(const base::Closure& cancel_download_closure) {
+    cancel_download_closure_ = cancel_download_closure;
     if (initialized_callback_.is_null()) {
       return;
     }
 
     DCHECK(entry_);
-    initialized_callback_.Run(
-        FILE_ERROR_OK, make_scoped_ptr(new ResourceEntry(*entry_)),
-        base::FilePath(), cancel_download_closure);
+    initialized_callback_.Run(FILE_ERROR_OK, base::FilePath(),
+                              make_scoped_ptr(new ResourceEntry(*entry_)));
   }
 
   void OnError(FileError error) const {
@@ -305,12 +309,19 @@
   const ResourceEntry& entry() const { return *entry_; }
 
  private:
+  void Cancel() {
+    if (!cancel_download_closure_.is_null())
+      cancel_download_closure_.Run();
+  }
+
   const GetFileContentInitializedCallback initialized_callback_;
   const google_apis::GetContentCallback get_content_callback_;
   const GetFileCallback completion_callback_;
 
   scoped_ptr<ResourceEntry> entry_;
+  base::Closure cancel_download_closure_;
 
+  base::WeakPtrFactory<DownloadParams> weak_ptr_factory_;
   DISALLOW_COPY_AND_ASSIGN(DownloadParams);
 };
 
@@ -333,7 +344,7 @@
 DownloadOperation::~DownloadOperation() {
 }
 
-void DownloadOperation::EnsureFileDownloadedByLocalId(
+base::Closure DownloadOperation::EnsureFileDownloadedByLocalId(
     const std::string& local_id,
     const ClientContext& context,
     const GetFileContentInitializedCallback& initialized_callback,
@@ -348,6 +359,7 @@
   scoped_ptr<DownloadParams> params(new DownloadParams(
       initialized_callback, get_content_callback, completion_callback,
       make_scoped_ptr(entry)));
+  base::Closure cancel_closure = params->GetCancelClosure();
   base::PostTaskAndReplyWithResult(
       blocking_task_runner_.get(),
       FROM_HERE,
@@ -365,9 +377,10 @@
                  context,
                  base::Owned(drive_file_path),
                  base::Owned(cache_file_path)));
+  return cancel_closure;
 }
 
-void DownloadOperation::EnsureFileDownloadedByPath(
+base::Closure DownloadOperation::EnsureFileDownloadedByPath(
     const base::FilePath& file_path,
     const ClientContext& context,
     const GetFileContentInitializedCallback& initialized_callback,
@@ -382,6 +395,7 @@
   scoped_ptr<DownloadParams> params(new DownloadParams(
       initialized_callback, get_content_callback, completion_callback,
       make_scoped_ptr(entry)));
+  base::Closure cancel_closure = params->GetCancelClosure();
   base::PostTaskAndReplyWithResult(
       blocking_task_runner_.get(),
       FROM_HERE,
@@ -398,6 +412,7 @@
                  context,
                  base::Owned(drive_file_path),
                  base::Owned(cache_file_path)));
+  return cancel_closure;
 }
 
 void DownloadOperation::EnsureFileDownloadedAfterCheckPreCondition(
diff --git a/chrome/browser/chromeos/drive/file_system/download_operation.h b/chrome/browser/chromeos/drive/file_system/download_operation.h
index 7e739f5..19a4240 100644
--- a/chrome/browser/chromeos/drive/file_system/download_operation.h
+++ b/chrome/browser/chromeos/drive/file_system/download_operation.h
@@ -47,7 +47,7 @@
   ~DownloadOperation();
 
   // Ensures that the file content specified by |local_id| is locally
-  // downloaded.
+  // downloaded and returns a closure to cancel the task.
   // For hosted documents, this method may create a JSON file representing the
   // file.
   // For regular files, if the locally cached file is found, returns it.
@@ -62,7 +62,7 @@
   // |initialized_callback| and |get_content_callback| can be null if not
   // needed.
   // |completion_callback| must not be null.
-  void EnsureFileDownloadedByLocalId(
+  base::Closure EnsureFileDownloadedByLocalId(
       const std::string& local_id,
       const ClientContext& context,
       const GetFileContentInitializedCallback& initialized_callback,
@@ -71,7 +71,7 @@
 
   // Does the same thing as EnsureFileDownloadedByLocalId for the file
   // specified by |file_path|.
-  void EnsureFileDownloadedByPath(
+  base::Closure EnsureFileDownloadedByPath(
       const base::FilePath& file_path,
       const ClientContext& context,
       const GetFileContentInitializedCallback& initialized_callback,
diff --git a/chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc
index 652e639..6718f73 100644
--- a/chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc
+++ b/chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc
@@ -298,27 +298,24 @@
     FileError initialized_error = FILE_ERROR_FAILED;
     scoped_ptr<ResourceEntry> entry, entry_dontcare;
     base::FilePath local_path, local_path_dontcare;
-    base::Closure cancel_download;
     google_apis::test_util::TestGetContentCallback get_content_callback;
-
     FileError completion_error = FILE_ERROR_FAILED;
-
-    operation_->EnsureFileDownloadedByPath(
+    base::Closure cancel_download = operation_->EnsureFileDownloadedByPath(
         file_in_root,
         ClientContext(USER_INITIATED),
         google_apis::test_util::CreateCopyResultCallback(
-            &initialized_error, &entry, &local_path, &cancel_download),
+            &initialized_error, &local_path, &entry),
         get_content_callback.callback(),
         google_apis::test_util::CreateCopyResultCallback(
             &completion_error, &local_path_dontcare, &entry_dontcare));
     test_util::RunBlockingPoolTask();
 
     // For the first time, file is downloaded from the remote server.
-    // In this case, |local_path| is empty while |cancel_download| is not.
+    // In this case, |local_path| is empty.
     EXPECT_EQ(FILE_ERROR_OK, initialized_error);
     ASSERT_TRUE(entry);
     ASSERT_TRUE(local_path.empty());
-    EXPECT_TRUE(!cancel_download.is_null());
+    EXPECT_FALSE(cancel_download.is_null());
     // Content is available through the second callback argument.
     EXPECT_EQ(static_cast<size_t>(entry->file_info().size()),
               get_content_callback.GetConcatenatedData().size());
@@ -335,27 +332,24 @@
     FileError initialized_error = FILE_ERROR_FAILED;
     scoped_ptr<ResourceEntry> entry, entry_dontcare;
     base::FilePath local_path, local_path_dontcare;
-    base::Closure cancel_download;
     google_apis::test_util::TestGetContentCallback get_content_callback;
-
     FileError completion_error = FILE_ERROR_FAILED;
-
-    operation_->EnsureFileDownloadedByPath(
+    base::Closure cancel_download = operation_->EnsureFileDownloadedByPath(
         file_in_root,
         ClientContext(USER_INITIATED),
         google_apis::test_util::CreateCopyResultCallback(
-            &initialized_error, &entry, &local_path, &cancel_download),
+            &initialized_error, &local_path, &entry),
         get_content_callback.callback(),
         google_apis::test_util::CreateCopyResultCallback(
             &completion_error, &local_path_dontcare, &entry_dontcare));
     test_util::RunBlockingPoolTask();
 
     // Try second download. In this case, the file should be cached, so
-    // |local_path| should not be empty while |cancel_download| is empty.
+    // |local_path| should not be empty.
     EXPECT_EQ(FILE_ERROR_OK, initialized_error);
     ASSERT_TRUE(entry);
     ASSERT_TRUE(!local_path.empty());
-    EXPECT_TRUE(cancel_download.is_null());
+    EXPECT_FALSE(cancel_download.is_null());
     // The content is available from the cache file.
     EXPECT_TRUE(get_content_callback.data().empty());
     int64 local_file_size = 0;
@@ -439,15 +433,13 @@
   FileError init_error;
   base::FilePath init_path;
   scoped_ptr<ResourceEntry> init_entry;
-  base::Closure cancel_callback;
-
   base::FilePath file_path;
   scoped_ptr<ResourceEntry> entry;
-  operation_->EnsureFileDownloadedByPath(
+  base::Closure cancel_callback = operation_->EnsureFileDownloadedByPath(
       file_in_root,
       ClientContext(USER_INITIATED),
       google_apis::test_util::CreateCopyResultCallback(
-          &init_error, &init_entry, &init_path, &cancel_callback),
+          &init_error, &init_path, &init_entry),
       google_apis::GetContentCallback(),
       google_apis::test_util::CreateCopyResultCallback(
           &error, &file_path, &entry));
diff --git a/chrome/browser/chromeos/drive/file_system_interface.h b/chrome/browser/chromeos/drive/file_system_interface.h
index 0f9c3f1..d80e2922 100644
--- a/chrome/browser/chromeos/drive/file_system_interface.h
+++ b/chrome/browser/chromeos/drive/file_system_interface.h
@@ -71,15 +71,11 @@
 
 // Used to get file content from the file system.
 // If the file content is available in local cache, |local_file| is filled with
-// the path to the cache file and |cancel_download_closure| is null. If the file
-// content starts to be downloaded from the server, |local_file| is empty and
-// |cancel_download_closure| is filled with a closure by calling which the
-// download job can be cancelled.
-// |cancel_download_closure| must be called on the UI thread.
+// the path to the cache file. If the file content starts to be downloaded from
+// the server, |local_file| is empty.
 typedef base::Callback<void(FileError error,
-                            scoped_ptr<ResourceEntry> entry,
                             const base::FilePath& local_file,
-                            const base::Closure& cancel_download_closure)>
+                            scoped_ptr<ResourceEntry> entry)>
     GetFileContentInitializedCallback;
 
 // Used to get list of entries under a directory.
@@ -336,7 +332,8 @@
   virtual void GetFileForSaving(const base::FilePath& file_path,
                                 const GetFileCallback& callback) = 0;
 
-  // Gets a file by the given |file_path|.
+  // Gets a file by the given |file_path| and returns a closure to cancel the
+  // task.
   // Calls |initialized_callback| when either:
   //   1) The cached file (or JSON file for hosted file) is found, or
   //   2) Starting to download the file from drive server.
@@ -347,7 +344,7 @@
   // is successfully done.
   // |initialized_callback|, |get_content_callback| and |completion_callback|
   // must not be null.
-  virtual void GetFileContent(
+  virtual base::Closure GetFileContent(
       const base::FilePath& file_path,
       const GetFileContentInitializedCallback& initialized_callback,
       const google_apis::GetContentCallback& get_content_callback,
diff --git a/chrome/browser/chromeos/drive/sync_client.cc b/chrome/browser/chromeos/drive/sync_client.cc
index 489769c5..f76b3b2 100644
--- a/chrome/browser/chromeos/drive/sync_client.cc
+++ b/chrome/browser/chromeos/drive/sync_client.cc
@@ -127,6 +127,12 @@
   DCHECK(!it->HasError());
 }
 
+// Runs the task and returns a dummy cancel closure.
+base::Closure RunTaskAndReturnDummyCancelClosure(const base::Closure& task) {
+  task.Run();
+  return base::Closure();
+}
+
 }  // namespace
 
 SyncClient::SyncTask::SyncTask() : state(PENDING), should_run_again(false) {}
@@ -235,8 +241,7 @@
       base::Unretained(download_operation_.get()),
       local_id,
       ClientContext(BACKGROUND),
-      base::Bind(&SyncClient::OnGetFileContentInitialized,
-                 weak_ptr_factory_.GetWeakPtr()),
+      GetFileContentInitializedCallback(),
       google_apis::GetContentCallback(),
       base::Bind(&SyncClient::OnFetchFileComplete,
                  weak_ptr_factory_.GetWeakPtr(),
@@ -249,13 +254,14 @@
                                        const base::TimeDelta& delay) {
   SyncTask task;
   task.task = base::Bind(
-      &EntryUpdatePerformer::UpdateEntry,
-      base::Unretained(entry_update_performer_.get()),
-      local_id,
-      context,
-      base::Bind(&SyncClient::OnUpdateComplete,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 local_id));
+      &RunTaskAndReturnDummyCancelClosure,
+      base::Bind(&EntryUpdatePerformer::UpdateEntry,
+                 base::Unretained(entry_update_performer_.get()),
+                 local_id,
+                 context,
+                 base::Bind(&SyncClient::OnUpdateComplete,
+                            weak_ptr_factory_.GetWeakPtr(),
+                            local_id)));
   AddTask(SyncTasks::key_type(UPDATE, local_id), task, delay);
 }
 
@@ -296,7 +302,7 @@
   switch (task->state) {
     case PENDING:
       task->state = RUNNING;
-      task->task.Run();
+      task->cancel_closure = task->task.Run();
       break;
     case RUNNING:  // Do nothing.
       break;
@@ -330,23 +336,6 @@
     AddFetchTask((*local_ids)[i]);
 }
 
-void SyncClient::OnGetFileContentInitialized(
-    FileError error,
-    scoped_ptr<ResourceEntry> entry,
-    const base::FilePath& local_cache_file_path,
-    const base::Closure& cancel_download_closure) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
-  if (error != FILE_ERROR_OK)
-    return;
-
-  const SyncTasks::key_type key(FETCH, entry->local_id());
-  SyncTasks::iterator it = tasks_.find(key);
-  DCHECK(it != tasks_.end());
-
-  it->second.cancel_closure = cancel_download_closure;
-}
-
 bool SyncClient::OnTaskComplete(SyncType type, const std::string& local_id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
diff --git a/chrome/browser/chromeos/drive/sync_client.h b/chrome/browser/chromeos/drive/sync_client.h
index a68458e..a8f6d1b 100644
--- a/chrome/browser/chromeos/drive/sync_client.h
+++ b/chrome/browser/chromeos/drive/sync_client.h
@@ -101,7 +101,7 @@
     SyncTask();
     ~SyncTask();
     SyncState state;
-    base::Closure task;
+    base::Callback<base::Closure()> task;
     bool should_run_again;
     base::Closure cancel_closure;
   };
@@ -132,13 +132,6 @@
   // Adds fetch tasks.
   void AddFetchTasks(const std::vector<std::string>* local_ids);
 
-  // Used as GetFileContentInitializedCallback.
-  void OnGetFileContentInitialized(
-      FileError error,
-      scoped_ptr<ResourceEntry> entry,
-      const base::FilePath& local_cache_file_path,
-      const base::Closure& cancel_download_closure);
-
   // Erases the task and returns true if task is completed.
   bool OnTaskComplete(SyncType type, const std::string& local_id);