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_
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/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"
23 class SeqencedTaskRunner
;
30 // Priority of a job. Higher values are lower priority.
34 // Indicates the number of values of this enum.
38 struct ClientContext
{
39 explicit ClientContext(ContextType in_type
) : type(in_type
) {}
43 // The JobScheduler is responsible for queuing and scheduling drive jobs.
44 // Because jobs are executed concurrently by priority and retried for network
45 // failures, there is no guarantee of orderings.
47 // Jobs are grouped into two priority levels:
48 // - USER_INITIATED jobs are those occur as a result of direct user actions.
49 // - BACKGROUND jobs runs in response to state changes, server actions, etc.
50 // USER_INITIATED jobs must be handled immediately, thus have higher priority.
51 // BACKGROUND jobs run only after all USER_INITIATED jobs have run.
53 // Orthogonally, jobs are grouped into two types:
54 // - "File jobs" transfer the contents of files.
55 // - "Metadata jobs" operates on file metadata or the directory structure.
56 // On WiFi or Ethernet connections, all types of jobs just run.
57 // On mobile connections (2G/3G/4G), we don't want large background traffic.
58 // USER_INITIATED jobs or metadata jobs will run. BACKGROUND file jobs wait
59 // in the queue until the network type changes.
60 // On offline case, no jobs run. USER_INITIATED jobs fail immediately.
61 // BACKGROUND jobs stay in the queue and wait for network connection.
63 : public net::NetworkChangeNotifier::ConnectionTypeObserver
,
64 public JobListInterface
{
66 JobScheduler(PrefService
* pref_service
,
68 DriveServiceInterface
* drive_service
,
69 base::SequencedTaskRunner
* blocking_task_runner
);
70 ~JobScheduler() override
;
72 // JobListInterface overrides.
73 std::vector
<JobInfo
> GetJobInfoList() override
;
74 void AddObserver(JobListObserver
* observer
) override
;
75 void RemoveObserver(JobListObserver
* observer
) override
;
76 void CancelJob(JobID job_id
) override
;
77 void CancelAllJobs() override
;
79 // Adds a GetAppList operation to the queue.
80 // |callback| must not be null.
81 void GetAppList(const google_apis::AppListCallback
& callback
);
83 // Adds a GetAboutResource operation to the queue.
84 // |callback| must not be null.
85 void GetAboutResource(const google_apis::AboutResourceCallback
& callback
);
87 // Adds a GetAllFileList operation to the queue.
88 // |callback| must not be null.
89 void GetAllFileList(const google_apis::FileListCallback
& callback
);
91 // Adds a GetFileListInDirectory operation to the queue.
92 // |callback| must not be null.
93 void GetFileListInDirectory(const std::string
& directory_resource_id
,
94 const google_apis::FileListCallback
& callback
);
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::FileListCallback
& callback
);
101 // Adds a GetChangeList operation to the queue.
102 // |callback| must not be null.
103 void GetChangeList(int64 start_changestamp
,
104 const google_apis::ChangeListCallback
& callback
);
106 // Adds GetRemainingChangeList operation to the queue.
107 // |callback| must not be null.
108 void GetRemainingChangeList(const GURL
& next_link
,
109 const google_apis::ChangeListCallback
& callback
);
111 // Adds GetRemainingFileList operation to the queue.
112 // |callback| must not be null.
113 void GetRemainingFileList(const GURL
& next_link
,
114 const google_apis::FileListCallback
& callback
);
116 // Adds a GetFileResource operation to the queue.
117 void GetFileResource(const std::string
& resource_id
,
118 const ClientContext
& context
,
119 const google_apis::FileResourceCallback
& callback
);
121 // Adds a GetShareUrl operation to the queue.
122 void GetShareUrl(const std::string
& resource_id
,
123 const GURL
& embed_origin
,
124 const ClientContext
& context
,
125 const google_apis::GetShareUrlCallback
& callback
);
127 // Adds a TrashResource operation to the queue.
128 void TrashResource(const std::string
& resource_id
,
129 const ClientContext
& context
,
130 const google_apis::EntryActionCallback
& callback
);
132 // Adds a CopyResource operation to the queue.
133 void CopyResource(const std::string
& resource_id
,
134 const std::string
& parent_resource_id
,
135 const std::string
& new_title
,
136 const base::Time
& last_modified
,
137 const google_apis::FileResourceCallback
& callback
);
139 // Adds a UpdateResource operation to the queue.
140 void UpdateResource(const std::string
& resource_id
,
141 const std::string
& parent_resource_id
,
142 const std::string
& new_title
,
143 const base::Time
& last_modified
,
144 const base::Time
& last_viewed_by_me
,
145 const google_apis::drive::Properties
& properties
,
146 const ClientContext
& context
,
147 const google_apis::FileResourceCallback
& callback
);
149 // Adds a AddResourceToDirectory operation to the queue.
150 void AddResourceToDirectory(const std::string
& parent_resource_id
,
151 const std::string
& resource_id
,
152 const google_apis::EntryActionCallback
& callback
);
154 // Adds a RemoveResourceFromDirectory operation to the queue.
155 void RemoveResourceFromDirectory(
156 const std::string
& parent_resource_id
,
157 const std::string
& resource_id
,
158 const ClientContext
& context
,
159 const google_apis::EntryActionCallback
& callback
);
161 // Adds a AddNewDirectory operation to the queue.
162 void AddNewDirectory(const std::string
& parent_resource_id
,
163 const std::string
& directory_title
,
164 const AddNewDirectoryOptions
& options
,
165 const ClientContext
& context
,
166 const google_apis::FileResourceCallback
& callback
);
168 // Adds a DownloadFile operation to the queue.
169 // The first two arguments |virtual_path| and |expected_file_size| are used
170 // only for filling JobInfo for the operation so that observers can get the
171 // detail. The actual operation never refers these values.
173 const base::FilePath
& virtual_path
,
174 int64 expected_file_size
,
175 const base::FilePath
& local_cache_path
,
176 const std::string
& resource_id
,
177 const ClientContext
& context
,
178 const google_apis::DownloadActionCallback
& download_action_callback
,
179 const google_apis::GetContentCallback
& get_content_callback
);
181 // Adds an UploadNewFile operation to the queue.
182 void UploadNewFile(const std::string
& parent_resource_id
,
183 const base::FilePath
& drive_file_path
,
184 const base::FilePath
& local_file_path
,
185 const std::string
& title
,
186 const std::string
& content_type
,
187 const UploadNewFileOptions
& options
,
188 const ClientContext
& context
,
189 const google_apis::FileResourceCallback
& callback
);
191 // Adds an UploadExistingFile operation to the queue.
192 void UploadExistingFile(const std::string
& resource_id
,
193 const base::FilePath
& drive_file_path
,
194 const base::FilePath
& local_file_path
,
195 const std::string
& content_type
,
196 const UploadExistingFileOptions
& options
,
197 const ClientContext
& context
,
198 const google_apis::FileResourceCallback
& callback
);
200 // Adds AddPermission operation to the queue. |callback| must not be null.
201 void AddPermission(const std::string
& resource_id
,
202 const std::string
& email
,
203 google_apis::drive::PermissionRole role
,
204 const google_apis::EntryActionCallback
& callback
);
207 friend class JobSchedulerTest
;
215 static const int kMaxJobCount
[NUM_QUEUES
];
217 // Represents a single entry in the job map.
219 explicit JobEntry(JobType type
);
222 // General user-visible information on the job.
225 // Context of the job.
226 ClientContext context
;
228 // The number of times the jobs is retried due to server errors.
231 // The callback to start the job. Called each time it is retry.
232 base::Callback
<google_apis::CancelCallback()> task
;
234 // The callback to cancel the running job. It is returned from task.Run().
235 google_apis::CancelCallback cancel_callback
;
237 // The callback to notify an error to the client of JobScheduler.
238 // This is used to notify cancel of a job that is not running yet.
239 base::Callback
<void(google_apis::DriveApiErrorCode
)> abort_callback
;
242 // Parameters for DriveUploader::ResumeUploadFile.
243 struct ResumeUploadParams
;
245 // Creates a new job and add it to the job map.
246 JobEntry
* CreateNewJob(JobType type
);
248 // Adds the specified job to the queue and starts the job loop for the queue
250 void StartJob(JobEntry
* job
);
252 // Adds the specified job to the queue.
253 void QueueJob(JobID job_id
);
255 // Determines the next job that should run, and starts it.
256 void DoJobLoop(QueueType queue_type
);
258 // Returns the lowest acceptable priority level of the operations that is
259 // currently allowed to start for the |queue_type|.
260 int GetCurrentAcceptedPriority(QueueType queue_type
);
262 // Updates |wait_until_| to throttle requests.
265 // Retries the job if needed and returns false. Otherwise returns true.
266 bool OnJobDone(JobID job_id
, google_apis::DriveApiErrorCode error
);
268 // Callback for job finishing with a FileListCallback.
269 void OnGetFileListJobDone(
271 const google_apis::FileListCallback
& callback
,
272 google_apis::DriveApiErrorCode error
,
273 scoped_ptr
<google_apis::FileList
> file_list
);
275 // Callback for job finishing with a ChangeListCallback.
276 void OnGetChangeListJobDone(
278 const google_apis::ChangeListCallback
& callback
,
279 google_apis::DriveApiErrorCode error
,
280 scoped_ptr
<google_apis::ChangeList
> change_list
);
282 // Callback for job finishing with a FileResourceCallback.
283 void OnGetFileResourceJobDone(
285 const google_apis::FileResourceCallback
& callback
,
286 google_apis::DriveApiErrorCode error
,
287 scoped_ptr
<google_apis::FileResource
> entry
);
289 // Callback for job finishing with a AboutResourceCallback.
290 void OnGetAboutResourceJobDone(
292 const google_apis::AboutResourceCallback
& callback
,
293 google_apis::DriveApiErrorCode error
,
294 scoped_ptr
<google_apis::AboutResource
> about_resource
);
296 // Callback for job finishing with a GetShareUrlCallback.
297 void OnGetShareUrlJobDone(
299 const google_apis::GetShareUrlCallback
& callback
,
300 google_apis::DriveApiErrorCode error
,
301 const GURL
& share_url
);
303 // Callback for job finishing with a AppListCallback.
304 void OnGetAppListJobDone(
306 const google_apis::AppListCallback
& callback
,
307 google_apis::DriveApiErrorCode error
,
308 scoped_ptr
<google_apis::AppList
> app_list
);
310 // Callback for job finishing with a EntryActionCallback.
311 void OnEntryActionJobDone(JobID job_id
,
312 const google_apis::EntryActionCallback
& callback
,
313 google_apis::DriveApiErrorCode error
);
315 // Callback for job finishing with a DownloadActionCallback.
316 void OnDownloadActionJobDone(
318 const google_apis::DownloadActionCallback
& callback
,
319 google_apis::DriveApiErrorCode error
,
320 const base::FilePath
& temp_file
);
322 // Callback for job finishing with a UploadCompletionCallback.
323 void OnUploadCompletionJobDone(
325 const ResumeUploadParams
& resume_params
,
326 const google_apis::FileResourceCallback
& callback
,
327 google_apis::DriveApiErrorCode error
,
328 const GURL
& upload_location
,
329 scoped_ptr
<google_apis::FileResource
> entry
);
331 // Callback for DriveUploader::ResumeUploadFile().
332 void OnResumeUploadFileDone(
334 const base::Callback
<google_apis::CancelCallback()>& original_task
,
335 const google_apis::FileResourceCallback
& callback
,
336 google_apis::DriveApiErrorCode error
,
337 const GURL
& upload_location
,
338 scoped_ptr
<google_apis::FileResource
> entry
);
340 // Updates the progress status of the specified job.
341 void UpdateProgress(JobID job_id
, int64 progress
, int64 total
);
343 // net::NetworkChangeNotifier::ConnectionTypeObserver override.
344 void OnConnectionTypeChanged(
345 net::NetworkChangeNotifier::ConnectionType type
) override
;
347 // Updates total_bytes in JobInfo.
348 void OnGotFileSizeForJob(JobID job_id
,
349 const std::string
& histogram_name
,
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 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 // Note: This should remain the last member so it'll be destroyed and
402 // invalidate its weak pointers before any other members are destroyed.
403 base::WeakPtrFactory
<JobScheduler
> weak_ptr_factory_
;
404 DISALLOW_COPY_AND_ASSIGN(JobScheduler
);
409 #endif // CHROME_BROWSER_CHROMEOS_DRIVE_JOB_SCHEDULER_H_