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