• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
set_delay_for_testing(const base::TimeDelta & delay)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