OLD | NEW |
| (Empty) |
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_DRIVE_SCHEDULER_H_ | |
6 #define CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_SCHEDULER_H_ | |
7 | |
8 #include <list> | |
9 #include <vector> | |
10 | |
11 #include "base/id_map.h" | |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "base/observer_list.h" | |
14 #include "chrome/browser/chromeos/drive/drive_file_system_interface.h" | |
15 #include "chrome/browser/chromeos/drive/job_list.h" | |
16 #include "chrome/browser/google_apis/drive_service_interface.h" | |
17 #include "chrome/browser/google_apis/drive_uploader.h" | |
18 #include "net/base/network_change_notifier.h" | |
19 | |
20 class Profile; | |
21 | |
22 namespace drive { | |
23 | |
24 // The DriveScheduler is responsible for queuing and scheduling drive | |
25 // operations. It is responsible for handling retry logic, rate limiting, as | |
26 // concurrency as appropriate. | |
27 class DriveScheduler | |
28 : public net::NetworkChangeNotifier::ConnectionTypeObserver, | |
29 public JobListInterface { | |
30 public: | |
31 DriveScheduler(Profile* profile, | |
32 google_apis::DriveServiceInterface* drive_service); | |
33 virtual ~DriveScheduler(); | |
34 | |
35 // JobListInterface overrides. | |
36 virtual std::vector<JobInfo> GetJobInfoList() OVERRIDE; | |
37 virtual void AddObserver(JobListObserver* observer) OVERRIDE; | |
38 virtual void RemoveObserver(JobListObserver* observer) OVERRIDE; | |
39 virtual void CancelJob(JobID job_id) OVERRIDE; | |
40 virtual void CancelAllJobs() OVERRIDE; | |
41 | |
42 // Adds a GetAccountMetadata operation to the queue. | |
43 // |callback| must not be null. | |
44 void GetAccountMetadata( | |
45 const google_apis::GetAccountMetadataCallback& callback); | |
46 | |
47 // Adds a GetAppList operation to the queue. | |
48 // |callback| must not be null. | |
49 void GetAppList(const google_apis::GetAppListCallback& callback); | |
50 | |
51 // Adds a GetAboutResource operation to the queue. | |
52 // |callback| must not be null. | |
53 void GetAboutResource(const google_apis::GetAboutResourceCallback& callback); | |
54 | |
55 // Adds a GetAllResourceList operation to the queue. | |
56 // |callback| must not be null. | |
57 void GetAllResourceList(const google_apis::GetResourceListCallback& callback); | |
58 | |
59 // Adds a GetResourceListInDirectory operation to the queue. | |
60 // |callback| must not be null. | |
61 void GetResourceListInDirectory( | |
62 const std::string& directory_resource_id, | |
63 const google_apis::GetResourceListCallback& callback); | |
64 | |
65 // Adds a Search operation to the queue. | |
66 // |callback| must not be null. | |
67 void Search(const std::string& search_query, | |
68 const google_apis::GetResourceListCallback& callback); | |
69 | |
70 // Adds a GetChangeList operation to the queue. | |
71 // |callback| must not be null. | |
72 void GetChangeList(int64 start_changestamp, | |
73 const google_apis::GetResourceListCallback& callback); | |
74 | |
75 // Adds ContinueGetResourceList operation to the queue. | |
76 // |callback| must not be null. | |
77 void ContinueGetResourceList( | |
78 const GURL& feed_url, | |
79 const google_apis::GetResourceListCallback& callback); | |
80 | |
81 // Adds a GetResourceEntry operation to the queue. | |
82 void GetResourceEntry(const std::string& resource_id, | |
83 const DriveClientContext& context, | |
84 const google_apis::GetResourceEntryCallback& callback); | |
85 | |
86 | |
87 // Adds a DeleteResource operation to the queue. | |
88 void DeleteResource(const std::string& resource_id, | |
89 const google_apis::EntryActionCallback& callback); | |
90 | |
91 | |
92 // Adds a CopyHostedDocument operation to the queue. | |
93 void CopyHostedDocument( | |
94 const std::string& resource_id, | |
95 const std::string& new_name, | |
96 const google_apis::GetResourceEntryCallback& callback); | |
97 | |
98 // Adds a RenameResource operation to the queue. | |
99 void RenameResource(const std::string& resource_id, | |
100 const std::string& new_name, | |
101 const google_apis::EntryActionCallback& callback); | |
102 | |
103 // Adds a AddResourceToDirectory operation to the queue. | |
104 void AddResourceToDirectory(const std::string& parent_resource_id, | |
105 const std::string& resource_id, | |
106 const google_apis::EntryActionCallback& callback); | |
107 | |
108 // Adds a RemoveResourceFromDirectory operation to the queue. | |
109 void RemoveResourceFromDirectory( | |
110 const std::string& parent_resource_id, | |
111 const std::string& resource_id, | |
112 const google_apis::EntryActionCallback& callback); | |
113 | |
114 // Adds a AddNewDirectory operation to the queue. | |
115 void AddNewDirectory(const std::string& parent_resource_id, | |
116 const std::string& directory_name, | |
117 const google_apis::GetResourceEntryCallback& callback); | |
118 | |
119 // Adds a DownloadFile operation to the queue. | |
120 void DownloadFile( | |
121 const base::FilePath& virtual_path, | |
122 const base::FilePath& local_cache_path, | |
123 const GURL& download_url, | |
124 const DriveClientContext& context, | |
125 const google_apis::DownloadActionCallback& download_action_callback, | |
126 const google_apis::GetContentCallback& get_content_callback); | |
127 | |
128 // Adds an UploadNewFile operation to the queue. | |
129 void UploadNewFile(const std::string& parent_resource_id, | |
130 const base::FilePath& drive_file_path, | |
131 const base::FilePath& local_file_path, | |
132 const std::string& title, | |
133 const std::string& content_type, | |
134 const DriveClientContext& context, | |
135 const google_apis::UploadCompletionCallback& callback); | |
136 | |
137 // Adds an UploadExistingFile operation to the queue. | |
138 void UploadExistingFile( | |
139 const std::string& resource_id, | |
140 const base::FilePath& drive_file_path, | |
141 const base::FilePath& local_file_path, | |
142 const std::string& content_type, | |
143 const std::string& etag, | |
144 const DriveClientContext& context, | |
145 const google_apis::UploadCompletionCallback& upload_completion_callback); | |
146 | |
147 private: | |
148 friend class DriveSchedulerTest; | |
149 | |
150 enum QueueType { | |
151 METADATA_QUEUE, | |
152 FILE_QUEUE, | |
153 NUM_QUEUES | |
154 }; | |
155 | |
156 static const int kMaxJobCount[NUM_QUEUES]; | |
157 | |
158 // Represents a single entry in the job queue. | |
159 struct QueueEntry { | |
160 QueueEntry(); | |
161 ~QueueEntry(); | |
162 | |
163 static bool Compare(const QueueEntry* left, const QueueEntry* right); | |
164 | |
165 JobID job_id; | |
166 | |
167 // Context of the job. | |
168 DriveClientContext context; | |
169 | |
170 // Resource ID to use for the operation. | |
171 // Used by: | |
172 // TYPE_GET_RESOURCE_ENTRY | |
173 // TYPE_DELETE_RESOURCE | |
174 // TYPE_RENAME_RESOURCE | |
175 // TYPE_ADD_RESOURCE_TO_DIRECTORY | |
176 // TYPE_UPLOAD_EXISTING_FILE | |
177 std::string resource_id; | |
178 | |
179 // URL to access the contents of the operation's target. | |
180 // Used by: | |
181 // TYPE_DOWNLOAD_FILE | |
182 GURL download_url; | |
183 | |
184 // Online and cache path of the operation's target. | |
185 // Used by: | |
186 // TYPE_DOWNLOAD_FILE | |
187 // TYPE_UPLOAD_NEW_FILE | |
188 // TYPE_UPLOAD_EXISTING_FILE | |
189 base::FilePath drive_file_path; | |
190 base::FilePath local_file_path; | |
191 | |
192 // Parameter to get change list. | |
193 // Used by: | |
194 // TYPE_GET_CHANGE_LIST | |
195 int64 start_changestamp; | |
196 | |
197 // Parameter to get a resource list in a particular directory. | |
198 // Used by: | |
199 // TYPE_GET_RESOURCE_LIST_IN_DIRECTORY | |
200 std::string directory_resource_id; | |
201 | |
202 // Parameter to search the resource list | |
203 // Used by: | |
204 // TYPE_SEARCH | |
205 std::string search_query; | |
206 | |
207 // Parameter to get remaining results of an operation via | |
208 // GetResourceListCallback. | |
209 // Used by: | |
210 // TYPE_CONTINUE_GET_RESOURCE_LIST | |
211 GURL feed_url; | |
212 | |
213 // Parameter for copy or rename. | |
214 // Used by: | |
215 // TYPE_COPY_HOSTED_DOCUMENT | |
216 // TYPE_RENAME_RESOURCE | |
217 std::string new_name; | |
218 | |
219 // Parameters for AddNewDirectory | |
220 // Used by: | |
221 // TYPE_ADD_NEW_DIRECTORY | |
222 // TYPE_ADD_RESOURCE_TO_DIRECTORY | |
223 // TYPE_REMOVE_RESOURCE_FROM_DIRECTORY | |
224 std::string parent_resource_id; | |
225 std::string directory_name; | |
226 | |
227 // Callback for operations that take a GetResourceListCallback. | |
228 // Used by: | |
229 // TYPE_GET_ALL_RESOURCE_LIST | |
230 // TYPE_GET_RESOURCE_LIST_IN_DIRECTORY | |
231 // TYPE_SEARCH | |
232 // TYPE_CONTINUE_GET_RESOURCE_LIST | |
233 google_apis::GetResourceListCallback get_resource_list_callback; | |
234 | |
235 // Callback for operations that take a GetResourceEntryCallback. | |
236 // Used by: | |
237 // TYPE_GET_RESOURCE_ENTRY, | |
238 // TYPE_COPY_HOSTED_DOCUMENT, | |
239 // TYPE_ADD_NEW_DIRECTORY, | |
240 google_apis::GetResourceEntryCallback get_resource_entry_callback; | |
241 | |
242 // Callback for operations that take a GetAccountMetadataCallback. | |
243 // Used by: | |
244 // TYPE_GET_ACCOUNT_METADATA, | |
245 google_apis::GetAccountMetadataCallback get_account_metadata_callback; | |
246 | |
247 // Callback for operations that take a GetAboutResourceCallback. | |
248 // Used by: | |
249 // TYPE_GET_ABOUT_RESOURCE, | |
250 google_apis::GetAboutResourceCallback get_about_resource_callback; | |
251 | |
252 // Callback for operations that take a GetAppListCallback. | |
253 // Used by: | |
254 // TYPE_GET_APP_LIST, | |
255 google_apis::GetAppListCallback get_app_list_callback; | |
256 | |
257 // Callback for operations that take a EntryActionCallback. | |
258 // Used by: | |
259 // TYPE_DELETE_RESOURCE, | |
260 // TYPE_RENAME_RESOURCE, | |
261 // TYPE_ADD_RESOURCE_TO_DIRECTORY, | |
262 // TYPE_REMOVE_RESOURCE_FROM_DIRECTORY, | |
263 google_apis::EntryActionCallback entry_action_callback; | |
264 | |
265 // Callback for operations that take a DownloadActionCallback | |
266 // Used by: | |
267 // TYPE_DOWNLOAD_FILE | |
268 google_apis::DownloadActionCallback download_action_callback; | |
269 | |
270 // Callback for result of GetContent. | |
271 // Used by: | |
272 // TYPE_DOWNLOAD_FILE | |
273 google_apis::GetContentCallback get_content_callback; | |
274 | |
275 // Parameters for UploadNewFile and UploadExistingFile | |
276 // Used by: | |
277 // TYPE_UPLOAD_NEW_FILE | |
278 // TYPE_UPLOAD_EXISTING_FILE | |
279 std::string content_type; | |
280 std::string etag; | |
281 std::string title; | |
282 google_apis::UploadCompletionCallback upload_completion_callback; | |
283 }; | |
284 | |
285 // Adds the specified job to the queue and starts the job loop for the queue | |
286 // if needed. | |
287 void StartNewJob(scoped_ptr<QueueEntry> job, JobType type); | |
288 | |
289 // Adds the specified job to the queue. Takes ownership of |job| | |
290 void QueueJob(scoped_ptr<QueueEntry> job); | |
291 | |
292 // Starts the job loop, if it is not already running. | |
293 void StartJobLoop(QueueType queue_type); | |
294 | |
295 // Determines the next job that should run, and starts it. | |
296 void DoJobLoop(QueueType queue_type); | |
297 | |
298 // Checks if operations should be suspended, such as if the network is | |
299 // disconnected. | |
300 // | |
301 // Returns true when it should stop, and false if it should continue. | |
302 bool ShouldStopJobLoop(QueueType queue_type, | |
303 const DriveClientContext& context); | |
304 | |
305 // Increases the throttle delay if it's below the maximum value, and posts a | |
306 // task to continue the loop after the delay. | |
307 void ThrottleAndContinueJobLoop(QueueType queue_type); | |
308 | |
309 // Resets the throttle delay to the initial value, and continues the job loop. | |
310 void ResetThrottleAndContinueJobLoop(QueueType queue_type); | |
311 | |
312 // Retries the |queue_entry| job if needed and returns null. Otherwise cleans | |
313 // up the job information and returns |queue_entry| as is so that callers can | |
314 // extract and invoke the callback function object stored there. | |
315 scoped_ptr<QueueEntry> OnJobDone(scoped_ptr<QueueEntry> queue_entry, | |
316 FileError error); | |
317 | |
318 // Callback for job finishing with a GetResourceListCallback. | |
319 void OnGetResourceListJobDone( | |
320 scoped_ptr<QueueEntry> queue_entry, | |
321 google_apis::GDataErrorCode error, | |
322 scoped_ptr<google_apis::ResourceList> resource_list); | |
323 | |
324 // Callback for job finishing with a GetResourceEntryCallback. | |
325 void OnGetResourceEntryJobDone( | |
326 scoped_ptr<QueueEntry> queue_entry, | |
327 google_apis::GDataErrorCode error, | |
328 scoped_ptr<google_apis::ResourceEntry> entry); | |
329 | |
330 // Callback for job finishing with a GetAboutResourceCallback. | |
331 void OnGetAboutResourceJobDone( | |
332 scoped_ptr<QueueEntry> queue_entry, | |
333 google_apis::GDataErrorCode error, | |
334 scoped_ptr<google_apis::AboutResource> about_resource); | |
335 | |
336 // Callback for job finishing with a GetAccountMetadataCallback. | |
337 void OnGetAccountMetadataJobDone( | |
338 scoped_ptr<QueueEntry> queue_entry, | |
339 google_apis::GDataErrorCode error, | |
340 scoped_ptr<google_apis::AccountMetadata> account_metadata); | |
341 | |
342 // Callback for job finishing with a GetAppListCallback. | |
343 void OnGetAppListJobDone( | |
344 scoped_ptr<QueueEntry> queue_entry, | |
345 google_apis::GDataErrorCode error, | |
346 scoped_ptr<google_apis::AppList> app_list); | |
347 | |
348 // Callback for job finishing with a EntryActionCallback. | |
349 void OnEntryActionJobDone(scoped_ptr<QueueEntry> queue_entry, | |
350 google_apis::GDataErrorCode error); | |
351 | |
352 // Callback for job finishing with a DownloadActionCallback. | |
353 void OnDownloadActionJobDone(scoped_ptr<QueueEntry> queue_entry, | |
354 google_apis::GDataErrorCode error, | |
355 const base::FilePath& temp_file); | |
356 | |
357 // Callback for job finishing with a UploadCompletionCallback. | |
358 void OnUploadCompletionJobDone( | |
359 scoped_ptr<QueueEntry> queue_entry, | |
360 google_apis::DriveUploadError error, | |
361 const base::FilePath& drive_path, | |
362 const base::FilePath& file_path, | |
363 scoped_ptr<google_apis::ResourceEntry> resource_entry); | |
364 | |
365 // Updates the progress status of the specified job. | |
366 void UpdateProgress(JobID job_id, int64 progress, int64 total); | |
367 | |
368 // net::NetworkChangeNotifier::ConnectionTypeObserver override. | |
369 virtual void OnConnectionTypeChanged( | |
370 net::NetworkChangeNotifier::ConnectionType type) OVERRIDE; | |
371 | |
372 // Get the type of queue the specified job should be put in. | |
373 QueueType GetJobQueueType(JobType type); | |
374 | |
375 // For testing only. Disables throttling so that testing is faster. | |
376 void SetDisableThrottling(bool disable) { disable_throttling_ = disable; } | |
377 | |
378 // Notifies updates to observers. | |
379 void NotifyJobAdded(const JobInfo& job_info); | |
380 void NotifyJobDone(const JobInfo& job_info, FileError error); | |
381 void NotifyJobUpdated(const JobInfo& job_info); | |
382 | |
383 // Number of jobs in flight for each queue. | |
384 int jobs_running_[NUM_QUEUES]; | |
385 | |
386 // The number of times operations have failed in a row, capped at | |
387 // kMaxThrottleCount. This is used to calculate the delay before running the | |
388 // next task. | |
389 int throttle_count_; | |
390 | |
391 // Disables throttling for testing. | |
392 bool disable_throttling_; | |
393 | |
394 // The queues of jobs. | |
395 std::list<QueueEntry*> queue_[NUM_QUEUES]; | |
396 | |
397 // The list of unfinished (= queued or running) job info indexed by job IDs. | |
398 typedef IDMap<JobInfo, IDMapOwnPointer> JobIDMap; | |
399 JobIDMap job_map_; | |
400 | |
401 // The list of observers for the scheduler. | |
402 ObserverList<JobListObserver> observer_list_; | |
403 | |
404 google_apis::DriveServiceInterface* drive_service_; | |
405 scoped_ptr<google_apis::DriveUploaderInterface> uploader_; | |
406 | |
407 Profile* profile_; | |
408 | |
409 // Note: This should remain the last member so it'll be destroyed and | |
410 // invalidate its weak pointers before any other members are destroyed. | |
411 base::WeakPtrFactory<DriveScheduler> weak_ptr_factory_; | |
412 DISALLOW_COPY_AND_ASSIGN(DriveScheduler); | |
413 }; | |
414 | |
415 } // namespace drive | |
416 | |
417 #endif // CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_SCHEDULER_H_ | |
OLD | NEW |