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 COMPONENTS_DRIVE_JOB_SCHEDULER_H_
6 #define COMPONENTS_DRIVE_JOB_SCHEDULER_H_
11 #include "base/id_map.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/observer_list.h"
14 #include "base/threading/thread_checker.h"
15 #include "components/drive/drive_uploader.h"
16 #include "components/drive/job_list.h"
17 #include "components/drive/job_queue.h"
18 #include "components/drive/service/drive_service_interface.h"
19 #include "net/base/network_change_notifier.h"
24 class SeqencedTaskRunner
;
31 // Priority of a job. Higher values are lower priority.
35 // Indicates the number of values of this enum.
39 struct ClientContext
{
40 explicit ClientContext(ContextType in_type
) : type(in_type
) {}
44 // The JobScheduler is responsible for queuing and scheduling drive jobs.
45 // Because jobs are executed concurrently by priority and retried for network
46 // failures, there is no guarantee of orderings.
48 // Jobs are grouped into two priority levels:
49 // - USER_INITIATED jobs are those occur as a result of direct user actions.
50 // - BACKGROUND jobs runs in response to state changes, server actions, etc.
51 // USER_INITIATED jobs must be handled immediately, thus have higher priority.
52 // BACKGROUND jobs run only after all USER_INITIATED jobs have run.
54 // Orthogonally, jobs are grouped into two types:
55 // - "File jobs" transfer the contents of files.
56 // - "Metadata jobs" operates on file metadata or the directory structure.
57 // On WiFi or Ethernet connections, all types of jobs just run.
58 // On mobile connections (2G/3G/4G), we don't want large background traffic.
59 // USER_INITIATED jobs or metadata jobs will run. BACKGROUND file jobs wait
60 // in the queue until the network type changes.
61 // On offline case, no jobs run. USER_INITIATED jobs fail immediately.
62 // BACKGROUND jobs stay in the queue and wait for network connection.
64 : public net::NetworkChangeNotifier::ConnectionTypeObserver
,
65 public JobListInterface
{
67 JobScheduler(PrefService
* pref_service
,
69 DriveServiceInterface
* drive_service
,
70 base::SequencedTaskRunner
* blocking_task_runner
);
71 ~JobScheduler() override
;
73 // JobListInterface overrides.
74 std::vector
<JobInfo
> GetJobInfoList() override
;
75 void AddObserver(JobListObserver
* observer
) override
;
76 void RemoveObserver(JobListObserver
* observer
) override
;
77 void CancelJob(JobID job_id
) override
;
78 void CancelAllJobs() override
;
80 // Adds a GetAppList operation to the queue.
81 // |callback| must not be null.
82 void GetAppList(const google_apis::AppListCallback
& callback
);
84 // Adds a GetAboutResource operation to the queue.
85 // |callback| must not be null.
86 void GetAboutResource(const google_apis::AboutResourceCallback
& callback
);
88 // Adds a GetAllFileList operation to the queue.
89 // |callback| must not be null.
90 void GetAllFileList(const google_apis::FileListCallback
& callback
);
92 // Adds a GetFileListInDirectory operation to the queue.
93 // |callback| must not be null.
94 void GetFileListInDirectory(const std::string
& directory_resource_id
,
95 const google_apis::FileListCallback
& callback
);
97 // Adds a Search operation to the queue.
98 // |callback| must not be null.
99 void Search(const std::string
& search_query
,
100 const google_apis::FileListCallback
& callback
);
102 // Adds a GetChangeList operation to the queue.
103 // |callback| must not be null.
104 void GetChangeList(int64 start_changestamp
,
105 const google_apis::ChangeListCallback
& callback
);
107 // Adds GetRemainingChangeList operation to the queue.
108 // |callback| must not be null.
109 void GetRemainingChangeList(const GURL
& next_link
,
110 const google_apis::ChangeListCallback
& callback
);
112 // Adds GetRemainingFileList operation to the queue.
113 // |callback| must not be null.
114 void GetRemainingFileList(const GURL
& next_link
,
115 const google_apis::FileListCallback
& callback
);
117 // Adds a GetFileResource operation to the queue.
118 void GetFileResource(const std::string
& resource_id
,
119 const ClientContext
& context
,
120 const google_apis::FileResourceCallback
& callback
);
122 // Adds a GetShareUrl operation to the queue.
123 void GetShareUrl(const std::string
& resource_id
,
124 const GURL
& embed_origin
,
125 const ClientContext
& context
,
126 const google_apis::GetShareUrlCallback
& callback
);
128 // Adds a TrashResource operation to the queue.
129 void TrashResource(const std::string
& resource_id
,
130 const ClientContext
& context
,
131 const google_apis::EntryActionCallback
& callback
);
133 // Adds a CopyResource operation to the queue.
134 void CopyResource(const std::string
& resource_id
,
135 const std::string
& parent_resource_id
,
136 const std::string
& new_title
,
137 const base::Time
& last_modified
,
138 const google_apis::FileResourceCallback
& callback
);
140 // Adds a UpdateResource operation to the queue.
141 void UpdateResource(const std::string
& resource_id
,
142 const std::string
& parent_resource_id
,
143 const std::string
& new_title
,
144 const base::Time
& last_modified
,
145 const base::Time
& last_viewed_by_me
,
146 const google_apis::drive::Properties
& properties
,
147 const ClientContext
& context
,
148 const google_apis::FileResourceCallback
& callback
);
150 // Adds a AddResourceToDirectory operation to the queue.
151 void AddResourceToDirectory(const std::string
& parent_resource_id
,
152 const std::string
& resource_id
,
153 const google_apis::EntryActionCallback
& callback
);
155 // Adds a RemoveResourceFromDirectory operation to the queue.
156 void RemoveResourceFromDirectory(
157 const std::string
& parent_resource_id
,
158 const std::string
& resource_id
,
159 const ClientContext
& context
,
160 const google_apis::EntryActionCallback
& callback
);
162 // Adds a AddNewDirectory operation to the queue.
163 void AddNewDirectory(const std::string
& parent_resource_id
,
164 const std::string
& directory_title
,
165 const AddNewDirectoryOptions
& options
,
166 const ClientContext
& context
,
167 const google_apis::FileResourceCallback
& callback
);
169 // Adds a DownloadFile operation to the queue.
170 // The first two arguments |virtual_path| and |expected_file_size| are used
171 // only for filling JobInfo for the operation so that observers can get the
172 // detail. The actual operation never refers these values.
174 const base::FilePath
& virtual_path
,
175 int64 expected_file_size
,
176 const base::FilePath
& local_cache_path
,
177 const std::string
& resource_id
,
178 const ClientContext
& context
,
179 const google_apis::DownloadActionCallback
& download_action_callback
,
180 const google_apis::GetContentCallback
& get_content_callback
);
182 // Adds an UploadNewFile operation to the queue.
183 void UploadNewFile(const std::string
& parent_resource_id
,
184 int64 expected_file_size
,
185 const base::FilePath
& drive_file_path
,
186 const base::FilePath
& local_file_path
,
187 const std::string
& title
,
188 const std::string
& content_type
,
189 const UploadNewFileOptions
& options
,
190 const ClientContext
& context
,
191 const google_apis::FileResourceCallback
& callback
);
193 // Adds an UploadExistingFile operation to the queue.
194 void UploadExistingFile(const std::string
& resource_id
,
195 int64 expected_file_size
,
196 const base::FilePath
& drive_file_path
,
197 const base::FilePath
& local_file_path
,
198 const std::string
& content_type
,
199 const UploadExistingFileOptions
& options
,
200 const ClientContext
& context
,
201 const google_apis::FileResourceCallback
& callback
);
203 // Adds AddPermission operation to the queue. |callback| must not be null.
204 void AddPermission(const std::string
& resource_id
,
205 const std::string
& email
,
206 google_apis::drive::PermissionRole role
,
207 const google_apis::EntryActionCallback
& callback
);
210 friend class JobSchedulerTest
;
218 static const int kMaxJobCount
[NUM_QUEUES
];
220 // Represents a single entry in the job map.
222 explicit JobEntry(JobType type
);
225 // General user-visible information on the job.
228 // Context of the job.
229 ClientContext context
;
231 // The number of times the jobs is retried due to server errors.
234 // The callback to start the job. Called each time it is retry.
235 base::Callback
<google_apis::CancelCallback()> task
;
237 // The callback to cancel the running job. It is returned from task.Run().
238 google_apis::CancelCallback cancel_callback
;
240 // The callback to notify an error to the client of JobScheduler.
241 // This is used to notify cancel of a job that is not running yet.
242 base::Callback
<void(google_apis::DriveApiErrorCode
)> abort_callback
;
244 base::ThreadChecker thread_checker_
;
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
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.
270 // Retries the job if needed and returns false. Otherwise returns true.
271 bool OnJobDone(JobID job_id
, google_apis::DriveApiErrorCode error
);
273 // Callback for job finishing with a FileListCallback.
274 void OnGetFileListJobDone(
276 const google_apis::FileListCallback
& callback
,
277 google_apis::DriveApiErrorCode error
,
278 scoped_ptr
<google_apis::FileList
> file_list
);
280 // Callback for job finishing with a ChangeListCallback.
281 void OnGetChangeListJobDone(
283 const google_apis::ChangeListCallback
& callback
,
284 google_apis::DriveApiErrorCode error
,
285 scoped_ptr
<google_apis::ChangeList
> change_list
);
287 // Callback for job finishing with a FileResourceCallback.
288 void OnGetFileResourceJobDone(
290 const google_apis::FileResourceCallback
& callback
,
291 google_apis::DriveApiErrorCode error
,
292 scoped_ptr
<google_apis::FileResource
> entry
);
294 // Callback for job finishing with a AboutResourceCallback.
295 void OnGetAboutResourceJobDone(
297 const google_apis::AboutResourceCallback
& callback
,
298 google_apis::DriveApiErrorCode error
,
299 scoped_ptr
<google_apis::AboutResource
> about_resource
);
301 // Callback for job finishing with a GetShareUrlCallback.
302 void OnGetShareUrlJobDone(
304 const google_apis::GetShareUrlCallback
& callback
,
305 google_apis::DriveApiErrorCode error
,
306 const GURL
& share_url
);
308 // Callback for job finishing with a AppListCallback.
309 void OnGetAppListJobDone(
311 const google_apis::AppListCallback
& callback
,
312 google_apis::DriveApiErrorCode error
,
313 scoped_ptr
<google_apis::AppList
> app_list
);
315 // Callback for job finishing with a EntryActionCallback.
316 void OnEntryActionJobDone(JobID job_id
,
317 const google_apis::EntryActionCallback
& callback
,
318 google_apis::DriveApiErrorCode error
);
320 // Callback for job finishing with a DownloadActionCallback.
321 void OnDownloadActionJobDone(
323 const google_apis::DownloadActionCallback
& callback
,
324 google_apis::DriveApiErrorCode error
,
325 const base::FilePath
& temp_file
);
327 // Callback for job finishing with a UploadCompletionCallback.
328 void OnUploadCompletionJobDone(
330 const ResumeUploadParams
& resume_params
,
331 const google_apis::FileResourceCallback
& callback
,
332 google_apis::DriveApiErrorCode error
,
333 const GURL
& upload_location
,
334 scoped_ptr
<google_apis::FileResource
> entry
);
336 // Callback for DriveUploader::ResumeUploadFile().
337 void OnResumeUploadFileDone(
339 const base::Callback
<google_apis::CancelCallback()>& original_task
,
340 const google_apis::FileResourceCallback
& callback
,
341 google_apis::DriveApiErrorCode error
,
342 const GURL
& upload_location
,
343 scoped_ptr
<google_apis::FileResource
> entry
);
345 // Updates the progress status of the specified job.
346 void UpdateProgress(JobID job_id
, int64 progress
, int64 total
);
348 // net::NetworkChangeNotifier::ConnectionTypeObserver override.
349 void OnConnectionTypeChanged(
350 net::NetworkChangeNotifier::ConnectionType type
) override
;
352 // Get the type of queue the specified job should be put in.
353 QueueType
GetJobQueueType(JobType type
);
355 // For testing only. Disables throttling so that testing is faster.
356 void SetDisableThrottling(bool disable
) { disable_throttling_
= disable
; }
358 // Aborts a job which is not in STATE_RUNNING.
359 void AbortNotRunningJob(JobEntry
* job
, google_apis::DriveApiErrorCode error
);
361 // Notifies updates to observers.
362 void NotifyJobAdded(const JobInfo
& job_info
);
363 void NotifyJobDone(const JobInfo
& job_info
,
364 google_apis::DriveApiErrorCode error
);
365 void NotifyJobUpdated(const JobInfo
& job_info
);
367 // Gets information of the queue of the given type as string.
368 std::string
GetQueueInfo(QueueType type
) const;
370 // Returns a string representation of QueueType.
371 static std::string
QueueTypeToString(QueueType type
);
373 // The number of times operations have failed in a row, capped at
374 // kMaxThrottleCount. This is used to calculate the delay before running the
378 // Jobs should not start running until this time. Used for throttling.
379 base::Time wait_until_
;
381 // Disables throttling for testing.
382 bool disable_throttling_
;
384 // The queues of jobs.
385 scoped_ptr
<JobQueue
> queue_
[NUM_QUEUES
];
387 // The list of queued job info indexed by job IDs.
388 typedef IDMap
<JobEntry
, IDMapOwnPointer
> JobIDMap
;
391 // The list of observers for the scheduler.
392 base::ObserverList
<JobListObserver
> observer_list_
;
394 EventLogger
* logger_
;
395 DriveServiceInterface
* drive_service_
;
396 base::SequencedTaskRunner
* blocking_task_runner_
;
397 scoped_ptr
<DriveUploaderInterface
> uploader_
;
399 PrefService
* pref_service_
;
401 base::ThreadChecker thread_checker_
;
403 // Note: This should remain the last member so it'll be destroyed and
404 // invalidate its weak pointers before any other members are destroyed.
405 base::WeakPtrFactory
<JobScheduler
> weak_ptr_factory_
;
406 DISALLOW_COPY_AND_ASSIGN(JobScheduler
);
411 #endif // COMPONENTS_DRIVE_JOB_SCHEDULER_H_