1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_CHROMEOS_DRIVE_SYNC_CLIENT_H_ 6 #define CHROME_BROWSER_CHROMEOS_DRIVE_SYNC_CLIENT_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/callback.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/time/time.h" 16 #include "chrome/browser/chromeos/drive/file_errors.h" 17 #include "chrome/browser/chromeos/drive/job_scheduler.h" 18 #include "chrome/browser/chromeos/drive/resource_metadata.h" 19 20 namespace base { 21 class SequencedTaskRunner; 22 } 23 24 namespace drive { 25 26 class FileCacheEntry; 27 class JobScheduler; 28 class ResourceEntry; 29 struct ClientContext; 30 31 namespace file_system { 32 class DownloadOperation; 33 class OperationDelegate; 34 } 35 36 namespace internal { 37 38 class ChangeListLoader; 39 class EntryUpdatePerformer; 40 class FileCache; 41 class LoaderController; 42 class ResourceMetadata; 43 44 // The SyncClient is used to synchronize pinned files on Drive and the 45 // cache on the local drive. 46 // 47 // If the user logs out before fetching of the pinned files is complete, this 48 // client resumes fetching operations next time the user logs in, based on 49 // the states left in the cache. 50 class SyncClient { 51 public: 52 SyncClient(base::SequencedTaskRunner* blocking_task_runner, 53 file_system::OperationDelegate* delegate, 54 JobScheduler* scheduler, 55 ResourceMetadata* metadata, 56 FileCache* cache, 57 LoaderController* loader_controller, 58 const base::FilePath& temporary_file_directory); 59 virtual ~SyncClient(); 60 61 // Adds a fetch task. 62 void AddFetchTask(const std::string& local_id); 63 64 // Removes a fetch task. 65 void RemoveFetchTask(const std::string& local_id); 66 67 // Adds a update task. 68 void AddUpdateTask(const ClientContext& context, const std::string& local_id); 69 70 // Waits for the update task to complete and runs the callback. 71 // Returns false if no task is found for the spcecified ID. 72 bool WaitForUpdateTaskToComplete(const std::string& local_id, 73 const FileOperationCallback& callback); 74 75 // Starts processing the backlog (i.e. pinned-but-not-filed files and 76 // dirty-but-not-uploaded files). Kicks off retrieval of the local 77 // IDs of these files, and then starts the sync loop. 78 void StartProcessingBacklog(); 79 80 // Starts checking the existing pinned files to see if these are 81 // up-to-date. If stale files are detected, the local IDs of these files 82 // are added and the sync loop is started. 83 void StartCheckingExistingPinnedFiles(); 84 85 // Sets a delay for testing. 86 void set_delay_for_testing(const base::TimeDelta& delay) { 87 delay_ = delay; 88 } 89 90 private: 91 // Types of sync tasks. 92 enum SyncType { 93 FETCH, // Fetch a file from the Drive server. 94 UPDATE, // Updates an entry's metadata or content on the Drive server. 95 }; 96 97 // States of sync tasks. 98 enum SyncState { 99 SUSPENDED, // Task is currently inactive. 100 PENDING, // Task is going to run. 101 RUNNING, // Task is running. 102 }; 103 104 typedef std::pair<SyncType, std::string> SyncTaskKey; 105 106 struct SyncTask { 107 SyncTask(); 108 ~SyncTask(); 109 SyncState state; 110 ClientContext context; 111 base::Callback<base::Closure(const ClientContext& context)> task; 112 bool should_run_again; 113 base::Closure cancel_closure; 114 std::vector<SyncTaskKey> dependent_tasks; 115 std::vector<FileOperationCallback> waiting_callbacks; 116 }; 117 118 typedef std::map<SyncTaskKey, SyncTask> SyncTasks; 119 120 // Performs a FETCH task. 121 base::Closure PerformFetchTask(const std::string& local_id, 122 const ClientContext& context); 123 124 // Adds a FETCH task. 125 void AddFetchTaskInternal(const std::string& local_id, 126 const base::TimeDelta& delay); 127 128 // Performs a UPDATE task. 129 base::Closure PerformUpdateTask(const std::string& local_id, 130 const ClientContext& context); 131 132 // Adds a UPDATE task. 133 void AddUpdateTaskInternal(const ClientContext& context, 134 const std::string& local_id, 135 const base::TimeDelta& delay); 136 137 // Adds the given task. If the same task is found, does nothing. 138 void AddTask(const SyncTasks::key_type& key, 139 const SyncTask& task, 140 const base::TimeDelta& delay); 141 142 // Called when a task is ready to start. 143 void StartTask(const SyncTasks::key_type& key); 144 void StartTaskAfterGetParentResourceEntry(const SyncTasks::key_type& key, 145 const ResourceEntry* parent, 146 FileError error); 147 148 // Called when the local IDs of files in the backlog are obtained. 149 void OnGetLocalIdsOfBacklog(const std::vector<std::string>* to_fetch, 150 const std::vector<std::string>* to_update); 151 152 // Adds fetch tasks. 153 void AddFetchTasks(const std::vector<std::string>* local_ids); 154 155 // Called when a task is completed. 156 void OnTaskComplete(SyncType type, 157 const std::string& local_id, 158 FileError error); 159 160 // Called when the file for |local_id| is fetched. 161 void OnFetchFileComplete(const std::string& local_id, 162 FileError error, 163 const base::FilePath& local_path, 164 scoped_ptr<ResourceEntry> entry); 165 166 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; 167 file_system::OperationDelegate* operation_delegate_; 168 ResourceMetadata* metadata_; 169 FileCache* cache_; 170 171 // Used to fetch pinned files. 172 scoped_ptr<file_system::DownloadOperation> download_operation_; 173 174 // Used to update entry metadata. 175 scoped_ptr<EntryUpdatePerformer> entry_update_performer_; 176 177 // Sync tasks to be processed. 178 SyncTasks tasks_; 179 180 // The delay is used for delaying processing tasks in AddTask(). 181 base::TimeDelta delay_; 182 183 // The delay is used for delaying retry of tasks on server errors. 184 base::TimeDelta long_delay_; 185 186 // Note: This should remain the last member so it'll be destroyed and 187 // invalidate its weak pointers before any other members are destroyed. 188 base::WeakPtrFactory<SyncClient> weak_ptr_factory_; 189 190 DISALLOW_COPY_AND_ASSIGN(SyncClient); 191 }; 192 193 } // namespace internal 194 } // namespace drive 195 196 #endif // CHROME_BROWSER_CHROMEOS_DRIVE_SYNC_CLIENT_H_ 197