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