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
20namespace base {
21class SequencedTaskRunner;
22}
23
24namespace drive {
25
26class FileCacheEntry;
27class JobScheduler;
28class ResourceEntry;
29struct ClientContext;
30
31namespace file_system {
32class DownloadOperation;
33class OperationDelegate;
34}
35
36namespace internal {
37
38class ChangeListLoader;
39class EntryUpdatePerformer;
40class FileCache;
41class LoaderController;
42class 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.
50class 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