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/file_system/update_operation.h" 18 19 namespace base { 20 class SequencedTaskRunner; 21 } 22 23 namespace drive { 24 25 class FileCacheEntry; 26 class JobScheduler; 27 class ResourceEntry; 28 struct ClientContext; 29 30 namespace file_system { 31 class DownloadOperation; 32 class OperationObserver; 33 class UpdateOperation; 34 } 35 36 namespace internal { 37 38 class EntryUpdatePerformer; 39 class FileCache; 40 class ResourceMetadata; 41 42 // The SyncClient is used to synchronize pinned files on Drive and the 43 // cache on the local drive. 44 // 45 // If the user logs out before fetching of the pinned files is complete, this 46 // client resumes fetching operations next time the user logs in, based on 47 // the states left in the cache. 48 class SyncClient { 49 public: 50 SyncClient(base::SequencedTaskRunner* blocking_task_runner, 51 file_system::OperationObserver* observer, 52 JobScheduler* scheduler, 53 ResourceMetadata* metadata, 54 FileCache* cache, 55 const base::FilePath& temporary_file_directory); 56 virtual ~SyncClient(); 57 58 // Adds a fetch task. 59 void AddFetchTask(const std::string& local_id); 60 61 // Removes a fetch task. 62 void RemoveFetchTask(const std::string& local_id); 63 64 // Adds an upload task. 65 void AddUploadTask(const ClientContext& context, const std::string& local_id); 66 67 // Adds a update task. 68 void AddUpdateTask(const std::string& local_id); 69 70 // Starts processing the backlog (i.e. pinned-but-not-filed files and 71 // dirty-but-not-uploaded files). Kicks off retrieval of the local 72 // IDs of these files, and then starts the sync loop. 73 void StartProcessingBacklog(); 74 75 // Starts checking the existing pinned files to see if these are 76 // up-to-date. If stale files are detected, the local IDs of these files 77 // are added and the sync loop is started. 78 void StartCheckingExistingPinnedFiles(); 79 80 // Sets a delay for testing. 81 void set_delay_for_testing(const base::TimeDelta& delay) { 82 delay_ = delay; 83 } 84 85 // Starts the sync loop if it's not running. 86 void StartSyncLoop(); 87 88 private: 89 // Types of sync tasks. 90 enum SyncType { 91 FETCH, // Fetch a file from the Drive server. 92 UPLOAD, // Upload a file to the Drive server. 93 UPDATE, // Updates an entry's metadata on the Drive server. 94 }; 95 96 // States of sync tasks. 97 enum SyncState { 98 PENDING, 99 RUNNING, 100 }; 101 102 struct SyncTask { 103 SyncTask(); 104 ~SyncTask(); 105 SyncState state; 106 base::Closure task; 107 bool should_run_again; 108 }; 109 110 typedef std::map<std::pair<SyncType, std::string>, SyncTask> SyncTasks; 111 112 // Adds a FETCH task. 113 void AddFetchTaskInternal(const std::string& local_id, 114 const base::TimeDelta& delay); 115 116 // Adds a UPLOAD task. 117 void AddUploadTaskInternal( 118 const ClientContext& context, 119 const std::string& local_id, 120 file_system::UpdateOperation::ContentCheckMode content_check_mode, 121 const base::TimeDelta& delay); 122 123 // Adds a UPDATE task. 124 void AddUpdateTaskInternal(const std::string& local_id, 125 const base::TimeDelta& delay); 126 127 // Adds the given task. If the same task is found, does nothing. 128 void AddTask(const SyncTasks::key_type& key, 129 const SyncTask& task, 130 const base::TimeDelta& delay); 131 132 // Called when a task is ready to start. 133 void StartTask(const SyncTasks::key_type& key); 134 135 // Called when the local IDs of files in the backlog are obtained. 136 void OnGetLocalIdsOfBacklog(const std::vector<std::string>* to_fetch, 137 const std::vector<std::string>* to_upload, 138 const std::vector<std::string>* to_update); 139 140 // Adds fetch tasks. 141 void AddFetchTasks(const std::vector<std::string>* local_ids); 142 143 // Erases the task and returns true if task is completed. 144 bool OnTaskComplete(SyncType type, const std::string& local_id); 145 146 // Called when the file for |local_id| is fetched. 147 // Calls DoSyncLoop() to go back to the sync loop. 148 void OnFetchFileComplete(const std::string& local_id, 149 FileError error, 150 const base::FilePath& local_path, 151 scoped_ptr<ResourceEntry> entry); 152 153 // Called when the file for |local_id| is uploaded. 154 // Calls DoSyncLoop() to go back to the sync loop. 155 void OnUploadFileComplete(const std::string& local_id, FileError error); 156 157 // Called when the entry is updated. 158 void OnUpdateComplete(const std::string& local_id, FileError error); 159 160 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; 161 ResourceMetadata* metadata_; 162 FileCache* cache_; 163 164 // Used to fetch pinned files. 165 scoped_ptr<file_system::DownloadOperation> download_operation_; 166 167 // Used to upload committed files. 168 scoped_ptr<file_system::UpdateOperation> update_operation_; 169 170 // Used to update entry metadata. 171 scoped_ptr<EntryUpdatePerformer> entry_update_performer_; 172 173 // Sync tasks to be processed. 174 SyncTasks tasks_; 175 176 // The delay is used for delaying processing tasks in AddTask(). 177 base::TimeDelta delay_; 178 179 // The delay is used for delaying retry of tasks on server errors. 180 base::TimeDelta long_delay_; 181 182 // Note: This should remain the last member so it'll be destroyed and 183 // invalidate its weak pointers before any other members are destroyed. 184 base::WeakPtrFactory<SyncClient> weak_ptr_factory_; 185 186 DISALLOW_COPY_AND_ASSIGN(SyncClient); 187 }; 188 189 } // namespace internal 190 } // namespace drive 191 192 #endif // CHROME_BROWSER_CHROMEOS_DRIVE_SYNC_CLIENT_H_ 193