Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / job_scheduler.h
blob38e9a36d2c80e0b4d2f28108c862d4e4618a83f4
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.
5 #ifndef CHROME_BROWSER_CHROMEOS_DRIVE_JOB_SCHEDULER_H_
6 #define CHROME_BROWSER_CHROMEOS_DRIVE_JOB_SCHEDULER_H_
8 #include <vector>
10 #include "base/id_map.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/observer_list.h"
13 #include "chrome/browser/chromeos/drive/file_system_interface.h"
14 #include "chrome/browser/chromeos/drive/job_list.h"
15 #include "chrome/browser/chromeos/drive/job_queue.h"
16 #include "chrome/browser/drive/drive_service_interface.h"
17 #include "chrome/browser/drive/drive_uploader.h"
18 #include "net/base/network_change_notifier.h"
20 class PrefService;
22 namespace base {
23 class SeqencedTaskRunner;
26 namespace drive {
28 // The JobScheduler is responsible for queuing and scheduling drive jobs.
29 // Because jobs are executed concurrently by priority and retried for network
30 // failures, there is no guarantee of orderings.
32 // Jobs are grouped into two priority levels:
33 // - USER_INITIATED jobs are those occur as a result of direct user actions.
34 // - BACKGROUND jobs runs in response to state changes, server actions, etc.
35 // USER_INITIATED jobs must be handled immediately, thus have higher priority.
36 // BACKGROUND jobs run only after all USER_INITIATED jobs have run.
38 // Orthogonally, jobs are grouped into two types:
39 // - "File jobs" transfer the contents of files.
40 // - "Metadata jobs" operates on file metadata or the directory structure.
41 // On WiFi or Ethernet connections, all types of jobs just run.
42 // On mobile connections (2G/3G/4G), we don't want large background traffic.
43 // USER_INITIATED jobs or metadata jobs will run. BACKGROUND file jobs wait
44 // in the queue until the network type changes.
45 // On offline case, no jobs run. USER_INITIATED jobs fail immediately.
46 // BACKGROUND jobs stay in the queue and wait for network connection.
47 class JobScheduler
48 : public net::NetworkChangeNotifier::ConnectionTypeObserver,
49 public JobListInterface {
50 public:
51 JobScheduler(PrefService* pref_service,
52 DriveServiceInterface* drive_service,
53 base::SequencedTaskRunner* blocking_task_runner);
54 virtual ~JobScheduler();
56 // JobListInterface overrides.
57 virtual std::vector<JobInfo> GetJobInfoList() OVERRIDE;
58 virtual void AddObserver(JobListObserver* observer) OVERRIDE;
59 virtual void RemoveObserver(JobListObserver* observer) OVERRIDE;
60 virtual void CancelJob(JobID job_id) OVERRIDE;
61 virtual void CancelAllJobs() OVERRIDE;
63 // Adds a GetAppList operation to the queue.
64 // |callback| must not be null.
65 void GetAppList(const google_apis::AppListCallback& callback);
67 // Adds a GetAboutResource operation to the queue.
68 // |callback| must not be null.
69 void GetAboutResource(const google_apis::AboutResourceCallback& callback);
71 // Adds a GetAllResourceList operation to the queue.
72 // |callback| must not be null.
73 void GetAllResourceList(const google_apis::GetResourceListCallback& callback);
75 // Adds a GetResourceListInDirectory operation to the queue.
76 // |callback| must not be null.
77 void GetResourceListInDirectory(
78 const std::string& directory_resource_id,
79 const google_apis::GetResourceListCallback& callback);
81 // Adds a Search operation to the queue.
82 // |callback| must not be null.
83 void Search(const std::string& search_query,
84 const google_apis::GetResourceListCallback& callback);
86 // Adds a GetChangeList operation to the queue.
87 // |callback| must not be null.
88 void GetChangeList(int64 start_changestamp,
89 const google_apis::GetResourceListCallback& callback);
91 // Adds GetRemainingChangeList operation to the queue.
92 // |callback| must not be null.
93 void GetRemainingChangeList(
94 const GURL& next_link,
95 const google_apis::GetResourceListCallback& callback);
97 // Adds GetRemainingFileList operation to the queue.
98 // |callback| must not be null.
99 void GetRemainingFileList(
100 const GURL& next_link,
101 const google_apis::GetResourceListCallback& callback);
103 // Adds a GetResourceEntry operation to the queue.
104 void GetResourceEntry(const std::string& resource_id,
105 const ClientContext& context,
106 const google_apis::GetResourceEntryCallback& callback);
108 // Adds a GetShareUrl operation to the queue.
109 void GetShareUrl(const std::string& resource_id,
110 const GURL& embed_origin,
111 const ClientContext& context,
112 const google_apis::GetShareUrlCallback& callback);
114 // Adds a TrashResource operation to the queue.
115 void TrashResource(const std::string& resource_id,
116 const ClientContext& context,
117 const google_apis::EntryActionCallback& callback);
119 // Adds a CopyResource operation to the queue.
120 void CopyResource(
121 const std::string& resource_id,
122 const std::string& parent_resource_id,
123 const std::string& new_title,
124 const base::Time& last_modified,
125 const google_apis::GetResourceEntryCallback& callback);
127 // Adds a UpdateResource operation to the queue.
128 void UpdateResource(
129 const std::string& resource_id,
130 const std::string& parent_resource_id,
131 const std::string& new_title,
132 const base::Time& last_modified,
133 const base::Time& last_viewed_by_me,
134 const ClientContext& context,
135 const google_apis::GetResourceEntryCallback& callback);
137 // Adds a RenameResource operation to the queue.
138 void RenameResource(const std::string& resource_id,
139 const std::string& new_title,
140 const google_apis::EntryActionCallback& callback);
142 // Adds a AddResourceToDirectory operation to the queue.
143 void AddResourceToDirectory(const std::string& parent_resource_id,
144 const std::string& resource_id,
145 const google_apis::EntryActionCallback& callback);
147 // Adds a RemoveResourceFromDirectory operation to the queue.
148 void RemoveResourceFromDirectory(
149 const std::string& parent_resource_id,
150 const std::string& resource_id,
151 const ClientContext& context,
152 const google_apis::EntryActionCallback& callback);
154 // Adds a AddNewDirectory operation to the queue.
155 void AddNewDirectory(const std::string& parent_resource_id,
156 const std::string& directory_title,
157 const google_apis::GetResourceEntryCallback& callback);
159 // Adds a DownloadFile operation to the queue.
160 // The first two arguments |virtual_path| and |expected_file_size| are used
161 // only for filling JobInfo for the operation so that observers can get the
162 // detail. The actual operation never refers these values.
163 JobID DownloadFile(
164 const base::FilePath& virtual_path,
165 int64 expected_file_size,
166 const base::FilePath& local_cache_path,
167 const std::string& resource_id,
168 const ClientContext& context,
169 const google_apis::DownloadActionCallback& download_action_callback,
170 const google_apis::GetContentCallback& get_content_callback);
172 // Adds an UploadNewFile operation to the queue.
173 void UploadNewFile(const std::string& parent_resource_id,
174 const base::FilePath& drive_file_path,
175 const base::FilePath& local_file_path,
176 const std::string& title,
177 const std::string& content_type,
178 const ClientContext& context,
179 const google_apis::GetResourceEntryCallback& callback);
181 // Adds an UploadExistingFile operation to the queue.
182 void UploadExistingFile(
183 const std::string& resource_id,
184 const base::FilePath& drive_file_path,
185 const base::FilePath& local_file_path,
186 const std::string& content_type,
187 const std::string& etag,
188 const ClientContext& context,
189 const google_apis::GetResourceEntryCallback& callback);
191 // Adds a CreateFile operation to the queue.
192 void CreateFile(const std::string& parent_resource_id,
193 const base::FilePath& drive_file_path,
194 const std::string& title,
195 const std::string& content_type,
196 const ClientContext& context,
197 const google_apis::GetResourceEntryCallback& callback);
199 // Adds a GetResourceListInDirectoryByWapi operation to the queue.
200 // |callback| must not be null.
201 void GetResourceListInDirectoryByWapi(
202 const std::string& directory_resource_id,
203 const google_apis::GetResourceListCallback& callback);
205 // Adds GetRemainingResourceList operation to the queue.
206 // |callback| must not be null.
207 void GetRemainingResourceList(
208 const GURL& next_link,
209 const google_apis::GetResourceListCallback& callback);
211 private:
212 friend class JobSchedulerTest;
214 enum QueueType {
215 METADATA_QUEUE,
216 FILE_QUEUE,
217 NUM_QUEUES
220 static const int kMaxJobCount[NUM_QUEUES];
222 // Represents a single entry in the job map.
223 struct JobEntry {
224 explicit JobEntry(JobType type);
225 ~JobEntry();
227 // General user-visible information on the job.
228 JobInfo job_info;
230 // Context of the job.
231 ClientContext context;
233 // The number of times the jobs is retried due to server errors.
234 int retry_count;
236 // The callback to start the job. Called each time it is retry.
237 base::Callback<google_apis::CancelCallback()> task;
239 // The callback to cancel the running job. It is returned from task.Run().
240 google_apis::CancelCallback cancel_callback;
242 // The callback to notify an error to the client of JobScheduler.
243 // This is used to notify cancel of a job that is not running yet.
244 base::Callback<void(google_apis::GDataErrorCode)> abort_callback;
247 // Parameters for DriveUploader::ResumeUploadFile.
248 struct ResumeUploadParams;
250 // Creates a new job and add it to the job map.
251 JobEntry* CreateNewJob(JobType type);
253 // Adds the specified job to the queue and starts the job loop for the queue
254 // if needed.
255 void StartJob(JobEntry* job);
257 // Adds the specified job to the queue.
258 void QueueJob(JobID job_id);
260 // Determines the next job that should run, and starts it.
261 void DoJobLoop(QueueType queue_type);
263 // Returns the lowest acceptable priority level of the operations that is
264 // currently allowed to start for the |queue_type|.
265 int GetCurrentAcceptedPriority(QueueType queue_type);
267 // Updates |wait_until_| to throttle requests.
268 void UpdateWait();
270 // Retries the job if needed and returns false. Otherwise returns true.
271 bool OnJobDone(JobID job_id, google_apis::GDataErrorCode error);
273 // Callback for job finishing with a GetResourceListCallback.
274 void OnGetResourceListJobDone(
275 JobID job_id,
276 const google_apis::GetResourceListCallback& callback,
277 google_apis::GDataErrorCode error,
278 scoped_ptr<google_apis::ResourceList> resource_list);
280 // Callback for job finishing with a GetResourceEntryCallback.
281 void OnGetResourceEntryJobDone(
282 JobID job_id,
283 const google_apis::GetResourceEntryCallback& callback,
284 google_apis::GDataErrorCode error,
285 scoped_ptr<google_apis::ResourceEntry> entry);
287 // Callback for job finishing with a AboutResourceCallback.
288 void OnGetAboutResourceJobDone(
289 JobID job_id,
290 const google_apis::AboutResourceCallback& callback,
291 google_apis::GDataErrorCode error,
292 scoped_ptr<google_apis::AboutResource> about_resource);
294 // Callback for job finishing with a GetShareUrlCallback.
295 void OnGetShareUrlJobDone(
296 JobID job_id,
297 const google_apis::GetShareUrlCallback& callback,
298 google_apis::GDataErrorCode error,
299 const GURL& share_url);
301 // Callback for job finishing with a AppListCallback.
302 void OnGetAppListJobDone(
303 JobID job_id,
304 const google_apis::AppListCallback& callback,
305 google_apis::GDataErrorCode error,
306 scoped_ptr<google_apis::AppList> app_list);
308 // Callback for job finishing with a EntryActionCallback.
309 void OnEntryActionJobDone(JobID job_id,
310 const google_apis::EntryActionCallback& callback,
311 google_apis::GDataErrorCode error);
313 // Callback for job finishing with a DownloadActionCallback.
314 void OnDownloadActionJobDone(
315 JobID job_id,
316 const google_apis::DownloadActionCallback& callback,
317 google_apis::GDataErrorCode error,
318 const base::FilePath& temp_file);
320 // Callback for job finishing with a UploadCompletionCallback.
321 void OnUploadCompletionJobDone(
322 JobID job_id,
323 const ResumeUploadParams& resume_params,
324 const google_apis::GetResourceEntryCallback& callback,
325 google_apis::GDataErrorCode error,
326 const GURL& upload_location,
327 scoped_ptr<google_apis::ResourceEntry> resource_entry);
329 // Callback for DriveUploader::ResumeUploadFile().
330 void OnResumeUploadFileDone(
331 JobID job_id,
332 const base::Callback<google_apis::CancelCallback()>& original_task,
333 const google_apis::GetResourceEntryCallback& callback,
334 google_apis::GDataErrorCode error,
335 const GURL& upload_location,
336 scoped_ptr<google_apis::ResourceEntry> resource_entry);
338 // Updates the progress status of the specified job.
339 void UpdateProgress(JobID job_id, int64 progress, int64 total);
341 // net::NetworkChangeNotifier::ConnectionTypeObserver override.
342 virtual void OnConnectionTypeChanged(
343 net::NetworkChangeNotifier::ConnectionType type) OVERRIDE;
345 // Get the type of queue the specified job should be put in.
346 QueueType GetJobQueueType(JobType type);
348 // For testing only. Disables throttling so that testing is faster.
349 void SetDisableThrottling(bool disable) { disable_throttling_ = disable; }
351 // Aborts a job which is not in STATE_RUNNING.
352 void AbortNotRunningJob(JobEntry* job, google_apis::GDataErrorCode error);
354 // Notifies updates to observers.
355 void NotifyJobAdded(const JobInfo& job_info);
356 void NotifyJobDone(const JobInfo& job_info,
357 google_apis::GDataErrorCode error);
358 void NotifyJobUpdated(const JobInfo& job_info);
360 // Gets information of the queue of the given type as string.
361 std::string GetQueueInfo(QueueType type) const;
363 // Returns a string representation of QueueType.
364 static std::string QueueTypeToString(QueueType type);
366 // The number of times operations have failed in a row, capped at
367 // kMaxThrottleCount. This is used to calculate the delay before running the
368 // next task.
369 int throttle_count_;
371 // Jobs should not start running until this time. Used for throttling.
372 base::Time wait_until_;
374 // Disables throttling for testing.
375 bool disable_throttling_;
377 // The queues of jobs.
378 scoped_ptr<JobQueue> queue_[NUM_QUEUES];
380 // The list of queued job info indexed by job IDs.
381 typedef IDMap<JobEntry, IDMapOwnPointer> JobIDMap;
382 JobIDMap job_map_;
384 // The list of observers for the scheduler.
385 ObserverList<JobListObserver> observer_list_;
387 DriveServiceInterface* drive_service_;
388 scoped_ptr<DriveUploaderInterface> uploader_;
390 PrefService* pref_service_;
392 // Note: This should remain the last member so it'll be destroyed and
393 // invalidate its weak pointers before any other members are destroyed.
394 base::WeakPtrFactory<JobScheduler> weak_ptr_factory_;
395 DISALLOW_COPY_AND_ASSIGN(JobScheduler);
398 } // namespace drive
400 #endif // CHROME_BROWSER_CHROMEOS_DRIVE_JOB_SCHEDULER_H_