Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / drive / sync_client.cc
index a679f3f..08ba438 100644 (file)
@@ -38,7 +38,7 @@ namespace {
 //
 // TODO(satorux): We should find a way to handle the upload case more nicely,
 // and shorten the delay. crbug.com/134774
-const int kDelaySeconds = 5;
+const int kDelaySeconds = 1;
 
 // The delay constant is used to delay retrying a sync task on server errors.
 const int kLongDelaySeconds = 600;
@@ -136,6 +136,7 @@ SyncClient::SyncClient(base::SequencedTaskRunner* blocking_task_runner,
                        JobScheduler* scheduler,
                        ResourceMetadata* metadata,
                        FileCache* cache,
+                       LoaderController* loader_controller,
                        const base::FilePath& temporary_file_directory)
     : blocking_task_runner_(blocking_task_runner),
       operation_observer_(observer),
@@ -152,7 +153,8 @@ SyncClient::SyncClient(base::SequencedTaskRunner* blocking_task_runner,
                                                        observer,
                                                        scheduler,
                                                        metadata,
-                                                       cache)),
+                                                       cache,
+                                                       loader_controller)),
       delay_(base::TimeDelta::FromSeconds(kDelaySeconds)),
       long_delay_(base::TimeDelta::FromSeconds(kLongDelaySeconds)),
       weak_ptr_factory_(this) {
@@ -210,7 +212,8 @@ void SyncClient::RemoveFetchTask(const std::string& local_id) {
       tasks_.erase(it);
       break;
     case RUNNING:
-      // TODO(kinaba): Cancel tasks in JobScheduler as well. crbug.com/248856
+      if (!task->cancel_closure.is_null())
+        task->cancel_closure.Run();
       break;
   }
 }
@@ -231,7 +234,8 @@ void SyncClient::AddFetchTaskInternal(const std::string& local_id,
       base::Unretained(download_operation_.get()),
       local_id,
       ClientContext(BACKGROUND),
-      GetFileContentInitializedCallback(),
+      base::Bind(&SyncClient::OnGetFileContentInitialized,
+                 weak_ptr_factory_.GetWeakPtr()),
       google_apis::GetContentCallback(),
       base::Bind(&SyncClient::OnFetchFileComplete,
                  weak_ptr_factory_.GetWeakPtr(),
@@ -325,6 +329,23 @@ void SyncClient::AddFetchTasks(const std::vector<std::string>* local_ids) {
     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));
 
@@ -395,8 +416,22 @@ void SyncClient::OnUpdateComplete(const std::string& local_id,
 
   if (error == FILE_ERROR_OK) {
     DVLOG(1) << "Updated " << local_id;
+
+    // Add update tasks for child entries which may be waiting for the parent to
+    // be updated.
+    ResourceEntryVector* entries = new ResourceEntryVector;
+    base::PostTaskAndReplyWithResult(
+        blocking_task_runner_.get(),
+        FROM_HERE,
+        base::Bind(&ResourceMetadata::ReadDirectoryById,
+                   base::Unretained(metadata_), local_id, entries),
+        base::Bind(&SyncClient::AddChildUpdateTasks,
+                   weak_ptr_factory_.GetWeakPtr(), base::Owned(entries)));
   } else {
     switch (error) {
+      case FILE_ERROR_ABORT:
+        // Ignore it because this is caused by user's cancel operations.
+        break;
       case FILE_ERROR_NO_CONNECTION:
         // Add the task again so that we'll retry once the connection is back.
         AddUpdateTaskInternal(ClientContext(BACKGROUND), local_id,
@@ -419,5 +454,19 @@ void SyncClient::OnUpdateComplete(const std::string& local_id,
   }
 }
 
+void SyncClient::AddChildUpdateTasks(const ResourceEntryVector* entries,
+                                     FileError error) {
+  if (error != FILE_ERROR_OK)
+    return;
+
+  for (size_t i = 0; i < entries->size(); ++i) {
+    const ResourceEntry& entry = (*entries)[i];
+    if (entry.metadata_edit_state() != ResourceEntry::CLEAN) {
+      AddUpdateTaskInternal(ClientContext(BACKGROUND), entry.local_id(),
+                            base::TimeDelta::FromSeconds(0));
+    }
+  }
+}
+
 }  // namespace internal
 }  // namespace drive