OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/drive/job_scheduler.h" | 5 #include "chrome/browser/chromeos/drive/job_scheduler.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 | 8 |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 | 26 |
27 namespace { | 27 namespace { |
28 const int kMaxThrottleCount = 5; | 28 const int kMaxThrottleCount = 5; |
29 } | 29 } |
30 | 30 |
31 const int JobScheduler::kMaxJobCount[] = { | 31 const int JobScheduler::kMaxJobCount[] = { |
32 5, // METADATA_QUEUE | 32 5, // METADATA_QUEUE |
33 1, // FILE_QUEUE | 33 1, // FILE_QUEUE |
34 }; | 34 }; |
35 | 35 |
36 JobScheduler::QueueEntry::QueueEntry() | 36 JobScheduler::JobEntry::JobEntry(JobType type) |
37 : job_id(-1), | 37 : job_info(type), |
38 context(DriveClientContext(USER_INITIATED)) { | 38 context(DriveClientContext(USER_INITIATED)) { |
39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
40 } | 40 } |
41 | 41 |
42 JobScheduler::QueueEntry::~QueueEntry() { | 42 JobScheduler::JobEntry::~JobEntry() { |
43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
44 } | 44 } |
45 | 45 |
46 bool JobScheduler::QueueEntry::Compare( | 46 bool JobScheduler::JobEntry::Less(const JobEntry& left, const JobEntry& right) { |
47 const JobScheduler::QueueEntry* left, | |
48 const JobScheduler::QueueEntry* right) { | |
49 // Lower values of ContextType are higher priority. | 47 // Lower values of ContextType are higher priority. |
50 // See also the comment at ContextType. | 48 // See also the comment at ContextType. |
51 return (left->context.type < right->context.type); | 49 return (left.context.type < right.context.type); |
52 } | 50 } |
53 | 51 |
54 JobScheduler::JobScheduler( | 52 JobScheduler::JobScheduler( |
55 Profile* profile, | 53 Profile* profile, |
56 google_apis::DriveServiceInterface* drive_service) | 54 google_apis::DriveServiceInterface* drive_service) |
57 : throttle_count_(0), | 55 : throttle_count_(0), |
58 disable_throttling_(false), | 56 disable_throttling_(false), |
59 drive_service_(drive_service), | 57 drive_service_(drive_service), |
60 uploader_(new google_apis::DriveUploader(drive_service)), | 58 uploader_(new google_apis::DriveUploader(drive_service)), |
61 profile_(profile), | 59 profile_(profile), |
(...skipping 10 matching lines...) Expand all Loading... |
72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 70 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
73 | 71 |
74 size_t num_pending_jobs = 0; | 72 size_t num_pending_jobs = 0; |
75 size_t num_running_jobs = 0; | 73 size_t num_running_jobs = 0; |
76 for (int i = 0; i < NUM_QUEUES; ++i) { | 74 for (int i = 0; i < NUM_QUEUES; ++i) { |
77 num_pending_jobs += queue_[i].size(); | 75 num_pending_jobs += queue_[i].size(); |
78 num_running_jobs += jobs_running_[i]; | 76 num_running_jobs += jobs_running_[i]; |
79 } | 77 } |
80 DCHECK_EQ(num_pending_jobs + num_running_jobs, job_map_.size()); | 78 DCHECK_EQ(num_pending_jobs + num_running_jobs, job_map_.size()); |
81 | 79 |
82 for (int i = 0; i < NUM_QUEUES; ++i) { | |
83 STLDeleteElements(&queue_[i]); | |
84 } | |
85 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 80 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
86 } | 81 } |
87 | 82 |
88 std::vector<JobInfo> JobScheduler::GetJobInfoList() { | 83 std::vector<JobInfo> JobScheduler::GetJobInfoList() { |
89 std::vector<JobInfo> job_info_list; | 84 std::vector<JobInfo> job_info_list; |
90 for (JobIDMap::iterator iter(&job_map_); !iter.IsAtEnd(); iter.Advance()) | 85 for (JobIDMap::iterator iter(&job_map_); !iter.IsAtEnd(); iter.Advance()) |
91 job_info_list.push_back(*iter.GetCurrentValue()); | 86 job_info_list.push_back(iter.GetCurrentValue()->job_info); |
92 return job_info_list; | 87 return job_info_list; |
93 } | 88 } |
94 | 89 |
95 void JobScheduler::AddObserver(JobListObserver* observer) { | 90 void JobScheduler::AddObserver(JobListObserver* observer) { |
96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
97 observer_list_.AddObserver(observer); | 92 observer_list_.AddObserver(observer); |
98 } | 93 } |
99 | 94 |
100 void JobScheduler::RemoveObserver(JobListObserver* observer) { | 95 void JobScheduler::RemoveObserver(JobListObserver* observer) { |
101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
102 observer_list_.RemoveObserver(observer); | 97 observer_list_.RemoveObserver(observer); |
103 } | 98 } |
104 | 99 |
105 void JobScheduler::CancelJob(JobID job_id) { | 100 void JobScheduler::CancelJob(JobID job_id) { |
106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
107 | 102 |
108 // TODO(kinaba): Move the cancellation feature from DriveService | 103 // TODO(kinaba): Move the cancellation feature from DriveService |
109 // to JobScheduler. In particular, implement cancel based on job_id. | 104 // to JobScheduler. In particular, implement cancel based on job_id. |
110 // crbug.com/231029 | 105 // crbug.com/231029 |
111 JobInfo* info = job_map_.Lookup(job_id); | 106 JobEntry* job = job_map_.Lookup(job_id); |
112 if (info) | 107 if (job) |
113 drive_service_->CancelForFilePath(info->file_path); | 108 drive_service_->CancelForFilePath(job->job_info.file_path); |
114 } | 109 } |
115 | 110 |
116 void JobScheduler::CancelAllJobs() { | 111 void JobScheduler::CancelAllJobs() { |
117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
118 | 113 |
119 // TODO(kinaba): Move the cancellation feature from DriveService | 114 // TODO(kinaba): Move the cancellation feature from DriveService |
120 // to JobScheduler. | 115 // to JobScheduler. |
121 drive_service_->CancelAll(); | 116 drive_service_->CancelAll(); |
122 } | 117 } |
123 | 118 |
124 void JobScheduler::GetAccountMetadata( | 119 void JobScheduler::GetAccountMetadata( |
125 const google_apis::GetAccountMetadataCallback& callback) { | 120 const google_apis::GetAccountMetadataCallback& callback) { |
126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
127 DCHECK(!callback.is_null()); | 122 DCHECK(!callback.is_null()); |
128 | 123 |
129 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 124 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_GET_ACCOUNT_METADATA)); |
130 new_job->get_account_metadata_callback = callback; | 125 new_job->get_account_metadata_callback = callback; |
131 | 126 |
132 StartNewJob(new_job.Pass(), TYPE_GET_ACCOUNT_METADATA); | 127 StartNewJob(new_job.Pass()); |
133 } | 128 } |
134 | 129 |
135 void JobScheduler::GetAboutResource( | 130 void JobScheduler::GetAboutResource( |
136 const google_apis::GetAboutResourceCallback& callback) { | 131 const google_apis::GetAboutResourceCallback& callback) { |
137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
138 DCHECK(!callback.is_null()); | 133 DCHECK(!callback.is_null()); |
139 | 134 |
140 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 135 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_GET_ABOUT_RESOURCE)); |
141 new_job->get_about_resource_callback = callback; | 136 new_job->get_about_resource_callback = callback; |
142 | 137 |
143 StartNewJob(new_job.Pass(), TYPE_GET_ABOUT_RESOURCE); | 138 StartNewJob(new_job.Pass()); |
144 } | 139 } |
145 | 140 |
146 void JobScheduler::GetAppList( | 141 void JobScheduler::GetAppList( |
147 const google_apis::GetAppListCallback& callback) { | 142 const google_apis::GetAppListCallback& callback) { |
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
149 DCHECK(!callback.is_null()); | 144 DCHECK(!callback.is_null()); |
150 | 145 |
151 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 146 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_GET_APP_LIST)); |
152 new_job->get_app_list_callback = callback; | 147 new_job->get_app_list_callback = callback; |
153 | 148 |
154 StartNewJob(new_job.Pass(), TYPE_GET_APP_LIST); | 149 StartNewJob(new_job.Pass()); |
155 } | 150 } |
156 | 151 |
157 void JobScheduler::GetAllResourceList( | 152 void JobScheduler::GetAllResourceList( |
158 const google_apis::GetResourceListCallback& callback) { | 153 const google_apis::GetResourceListCallback& callback) { |
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
160 DCHECK(!callback.is_null()); | 155 DCHECK(!callback.is_null()); |
161 | 156 |
162 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 157 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_GET_ALL_RESOURCE_LIST)); |
163 new_job->get_resource_list_callback = callback; | 158 new_job->get_resource_list_callback = callback; |
164 | 159 |
165 StartNewJob(new_job.Pass(), TYPE_GET_ALL_RESOURCE_LIST); | 160 StartNewJob(new_job.Pass()); |
166 } | 161 } |
167 | 162 |
168 void JobScheduler::GetResourceListInDirectory( | 163 void JobScheduler::GetResourceListInDirectory( |
169 const std::string& directory_resource_id, | 164 const std::string& directory_resource_id, |
170 const google_apis::GetResourceListCallback& callback) { | 165 const google_apis::GetResourceListCallback& callback) { |
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
172 DCHECK(!callback.is_null()); | 167 DCHECK(!callback.is_null()); |
173 | 168 |
174 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 169 scoped_ptr<JobEntry> new_job(new JobEntry( |
| 170 TYPE_GET_RESOURCE_LIST_IN_DIRECTORY)); |
175 new_job->directory_resource_id = directory_resource_id; | 171 new_job->directory_resource_id = directory_resource_id; |
176 new_job->get_resource_list_callback = callback; | 172 new_job->get_resource_list_callback = callback; |
177 | 173 |
178 StartNewJob(new_job.Pass(), TYPE_GET_RESOURCE_LIST_IN_DIRECTORY); | 174 StartNewJob(new_job.Pass()); |
179 } | 175 } |
180 | 176 |
181 void JobScheduler::Search( | 177 void JobScheduler::Search( |
182 const std::string& search_query, | 178 const std::string& search_query, |
183 const google_apis::GetResourceListCallback& callback) { | 179 const google_apis::GetResourceListCallback& callback) { |
184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
185 DCHECK(!callback.is_null()); | 181 DCHECK(!callback.is_null()); |
186 | 182 |
187 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 183 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_SEARCH)); |
188 new_job->search_query = search_query; | 184 new_job->search_query = search_query; |
189 new_job->get_resource_list_callback = callback; | 185 new_job->get_resource_list_callback = callback; |
190 | 186 |
191 StartNewJob(new_job.Pass(), TYPE_SEARCH); | 187 StartNewJob(new_job.Pass()); |
192 } | 188 } |
193 | 189 |
194 void JobScheduler::GetChangeList( | 190 void JobScheduler::GetChangeList( |
195 int64 start_changestamp, | 191 int64 start_changestamp, |
196 const google_apis::GetResourceListCallback& callback) { | 192 const google_apis::GetResourceListCallback& callback) { |
197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
198 DCHECK(!callback.is_null()); | 194 DCHECK(!callback.is_null()); |
199 | 195 |
200 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 196 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_GET_CHANGE_LIST)); |
201 new_job->start_changestamp = start_changestamp; | 197 new_job->start_changestamp = start_changestamp; |
202 new_job->get_resource_list_callback = callback; | 198 new_job->get_resource_list_callback = callback; |
203 | 199 |
204 StartNewJob(new_job.Pass(), TYPE_GET_CHANGE_LIST); | 200 StartNewJob(new_job.Pass()); |
205 } | 201 } |
206 | 202 |
207 void JobScheduler::ContinueGetResourceList( | 203 void JobScheduler::ContinueGetResourceList( |
208 const GURL& feed_url, | 204 const GURL& feed_url, |
209 const google_apis::GetResourceListCallback& callback) { | 205 const google_apis::GetResourceListCallback& callback) { |
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
211 DCHECK(!callback.is_null()); | 207 DCHECK(!callback.is_null()); |
212 | 208 |
213 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 209 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_CONTINUE_GET_RESOURCE_LIST)); |
214 new_job->feed_url = feed_url; | 210 new_job->feed_url = feed_url; |
215 new_job->get_resource_list_callback = callback; | 211 new_job->get_resource_list_callback = callback; |
216 | 212 |
217 StartNewJob(new_job.Pass(), TYPE_CONTINUE_GET_RESOURCE_LIST); | 213 StartNewJob(new_job.Pass()); |
218 } | 214 } |
219 | 215 |
220 void JobScheduler::GetResourceEntry( | 216 void JobScheduler::GetResourceEntry( |
221 const std::string& resource_id, | 217 const std::string& resource_id, |
222 const DriveClientContext& context, | 218 const DriveClientContext& context, |
223 const google_apis::GetResourceEntryCallback& callback) { | 219 const google_apis::GetResourceEntryCallback& callback) { |
224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
225 DCHECK(!callback.is_null()); | 221 DCHECK(!callback.is_null()); |
226 | 222 |
227 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 223 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_GET_RESOURCE_ENTRY)); |
228 new_job->resource_id = resource_id; | 224 new_job->resource_id = resource_id; |
229 new_job->context = context; | 225 new_job->context = context; |
230 new_job->get_resource_entry_callback = callback; | 226 new_job->get_resource_entry_callback = callback; |
231 | 227 |
232 StartNewJob(new_job.Pass(), TYPE_GET_RESOURCE_ENTRY); | 228 StartNewJob(new_job.Pass()); |
233 } | 229 } |
234 | 230 |
235 void JobScheduler::DeleteResource( | 231 void JobScheduler::DeleteResource( |
236 const std::string& resource_id, | 232 const std::string& resource_id, |
237 const google_apis::EntryActionCallback& callback) { | 233 const google_apis::EntryActionCallback& callback) { |
238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
239 DCHECK(!callback.is_null()); | 235 DCHECK(!callback.is_null()); |
240 | 236 |
241 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 237 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_DELETE_RESOURCE)); |
242 new_job->resource_id = resource_id; | 238 new_job->resource_id = resource_id; |
243 new_job->entry_action_callback = callback; | 239 new_job->entry_action_callback = callback; |
244 | 240 |
245 StartNewJob(new_job.Pass(), TYPE_DELETE_RESOURCE); | 241 StartNewJob(new_job.Pass()); |
246 } | 242 } |
247 | 243 |
248 | 244 |
249 void JobScheduler::CopyHostedDocument( | 245 void JobScheduler::CopyHostedDocument( |
250 const std::string& resource_id, | 246 const std::string& resource_id, |
251 const std::string& new_name, | 247 const std::string& new_name, |
252 const google_apis::GetResourceEntryCallback& callback) { | 248 const google_apis::GetResourceEntryCallback& callback) { |
253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
254 DCHECK(!callback.is_null()); | 250 DCHECK(!callback.is_null()); |
255 | 251 |
256 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 252 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_COPY_HOSTED_DOCUMENT)); |
257 new_job->resource_id = resource_id; | 253 new_job->resource_id = resource_id; |
258 new_job->new_name = new_name; | 254 new_job->new_name = new_name; |
259 new_job->get_resource_entry_callback = callback; | 255 new_job->get_resource_entry_callback = callback; |
260 | 256 |
261 StartNewJob(new_job.Pass(), TYPE_COPY_HOSTED_DOCUMENT); | 257 StartNewJob(new_job.Pass()); |
262 } | 258 } |
263 | 259 |
264 void JobScheduler::RenameResource( | 260 void JobScheduler::RenameResource( |
265 const std::string& resource_id, | 261 const std::string& resource_id, |
266 const std::string& new_name, | 262 const std::string& new_name, |
267 const google_apis::EntryActionCallback& callback) { | 263 const google_apis::EntryActionCallback& callback) { |
268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 264 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
269 DCHECK(!callback.is_null()); | 265 DCHECK(!callback.is_null()); |
270 | 266 |
271 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 267 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_RENAME_RESOURCE)); |
272 new_job->resource_id = resource_id; | 268 new_job->resource_id = resource_id; |
273 new_job->new_name = new_name; | 269 new_job->new_name = new_name; |
274 new_job->entry_action_callback = callback; | 270 new_job->entry_action_callback = callback; |
275 | 271 |
276 StartNewJob(new_job.Pass(), TYPE_RENAME_RESOURCE); | 272 StartNewJob(new_job.Pass()); |
277 } | 273 } |
278 | 274 |
279 void JobScheduler::AddResourceToDirectory( | 275 void JobScheduler::AddResourceToDirectory( |
280 const std::string& parent_resource_id, | 276 const std::string& parent_resource_id, |
281 const std::string& resource_id, | 277 const std::string& resource_id, |
282 const google_apis::EntryActionCallback& callback) { | 278 const google_apis::EntryActionCallback& callback) { |
283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
284 DCHECK(!callback.is_null()); | 280 DCHECK(!callback.is_null()); |
285 | 281 |
286 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 282 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_ADD_RESOURCE_TO_DIRECTORY)); |
287 new_job->parent_resource_id = parent_resource_id; | 283 new_job->parent_resource_id = parent_resource_id; |
288 new_job->resource_id = resource_id; | 284 new_job->resource_id = resource_id; |
289 new_job->entry_action_callback = callback; | 285 new_job->entry_action_callback = callback; |
290 | 286 |
291 StartNewJob(new_job.Pass(), TYPE_ADD_RESOURCE_TO_DIRECTORY); | 287 StartNewJob(new_job.Pass()); |
292 } | 288 } |
293 | 289 |
294 void JobScheduler::RemoveResourceFromDirectory( | 290 void JobScheduler::RemoveResourceFromDirectory( |
295 const std::string& parent_resource_id, | 291 const std::string& parent_resource_id, |
296 const std::string& resource_id, | 292 const std::string& resource_id, |
297 const google_apis::EntryActionCallback& callback) { | 293 const google_apis::EntryActionCallback& callback) { |
298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
299 | 295 |
300 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 296 scoped_ptr<JobEntry> new_job(new JobEntry( |
| 297 TYPE_REMOVE_RESOURCE_FROM_DIRECTORY)); |
301 new_job->parent_resource_id = parent_resource_id; | 298 new_job->parent_resource_id = parent_resource_id; |
302 new_job->resource_id = resource_id; | 299 new_job->resource_id = resource_id; |
303 new_job->entry_action_callback = callback; | 300 new_job->entry_action_callback = callback; |
304 | 301 |
305 StartNewJob(new_job.Pass(), TYPE_REMOVE_RESOURCE_FROM_DIRECTORY); | 302 StartNewJob(new_job.Pass()); |
306 } | 303 } |
307 | 304 |
308 void JobScheduler::AddNewDirectory( | 305 void JobScheduler::AddNewDirectory( |
309 const std::string& parent_resource_id, | 306 const std::string& parent_resource_id, |
310 const std::string& directory_name, | 307 const std::string& directory_name, |
311 const google_apis::GetResourceEntryCallback& callback) { | 308 const google_apis::GetResourceEntryCallback& callback) { |
312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
313 | 310 |
314 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 311 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_ADD_NEW_DIRECTORY)); |
315 new_job->parent_resource_id = parent_resource_id; | 312 new_job->parent_resource_id = parent_resource_id; |
316 new_job->directory_name = directory_name; | 313 new_job->directory_name = directory_name; |
317 new_job->get_resource_entry_callback = callback; | 314 new_job->get_resource_entry_callback = callback; |
318 | 315 |
319 StartNewJob(new_job.Pass(), TYPE_ADD_NEW_DIRECTORY); | 316 StartNewJob(new_job.Pass()); |
320 } | 317 } |
321 | 318 |
322 JobID JobScheduler::DownloadFile( | 319 JobID JobScheduler::DownloadFile( |
323 const base::FilePath& virtual_path, | 320 const base::FilePath& virtual_path, |
324 const base::FilePath& local_cache_path, | 321 const base::FilePath& local_cache_path, |
325 const GURL& download_url, | 322 const GURL& download_url, |
326 const DriveClientContext& context, | 323 const DriveClientContext& context, |
327 const google_apis::DownloadActionCallback& download_action_callback, | 324 const google_apis::DownloadActionCallback& download_action_callback, |
328 const google_apis::GetContentCallback& get_content_callback) { | 325 const google_apis::GetContentCallback& get_content_callback) { |
329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 326 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
330 | 327 |
331 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 328 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_DOWNLOAD_FILE)); |
332 new_job->drive_file_path = virtual_path; | 329 new_job->drive_file_path = virtual_path; |
333 new_job->local_file_path = local_cache_path; | 330 new_job->local_file_path = local_cache_path; |
334 new_job->download_url = download_url; | 331 new_job->download_url = download_url; |
335 new_job->context = context; | 332 new_job->context = context; |
336 new_job->download_action_callback = download_action_callback; | 333 new_job->download_action_callback = download_action_callback; |
337 new_job->get_content_callback = get_content_callback; | 334 new_job->get_content_callback = get_content_callback; |
338 | 335 |
339 return StartNewJob(new_job.Pass(), TYPE_DOWNLOAD_FILE); | 336 return StartNewJob(new_job.Pass()); |
340 } | 337 } |
341 | 338 |
342 void JobScheduler::UploadNewFile( | 339 void JobScheduler::UploadNewFile( |
343 const std::string& parent_resource_id, | 340 const std::string& parent_resource_id, |
344 const base::FilePath& drive_file_path, | 341 const base::FilePath& drive_file_path, |
345 const base::FilePath& local_file_path, | 342 const base::FilePath& local_file_path, |
346 const std::string& title, | 343 const std::string& title, |
347 const std::string& content_type, | 344 const std::string& content_type, |
348 const DriveClientContext& context, | 345 const DriveClientContext& context, |
349 const google_apis::UploadCompletionCallback& callback) { | 346 const google_apis::UploadCompletionCallback& callback) { |
350 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
351 | 348 |
352 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 349 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_UPLOAD_NEW_FILE)); |
353 new_job->resource_id = parent_resource_id; | 350 new_job->resource_id = parent_resource_id; |
354 new_job->drive_file_path = drive_file_path; | 351 new_job->drive_file_path = drive_file_path; |
355 new_job->local_file_path = local_file_path; | 352 new_job->local_file_path = local_file_path; |
356 new_job->title = title; | 353 new_job->title = title; |
357 new_job->content_type = content_type; | 354 new_job->content_type = content_type; |
358 new_job->upload_completion_callback = callback; | 355 new_job->upload_completion_callback = callback; |
359 new_job->context = context; | 356 new_job->context = context; |
360 | 357 |
361 StartNewJob(new_job.Pass(), TYPE_UPLOAD_NEW_FILE); | 358 StartNewJob(new_job.Pass()); |
362 } | 359 } |
363 | 360 |
364 void JobScheduler::UploadExistingFile( | 361 void JobScheduler::UploadExistingFile( |
365 const std::string& resource_id, | 362 const std::string& resource_id, |
366 const base::FilePath& drive_file_path, | 363 const base::FilePath& drive_file_path, |
367 const base::FilePath& local_file_path, | 364 const base::FilePath& local_file_path, |
368 const std::string& content_type, | 365 const std::string& content_type, |
369 const std::string& etag, | 366 const std::string& etag, |
370 const DriveClientContext& context, | 367 const DriveClientContext& context, |
371 const google_apis::UploadCompletionCallback& upload_completion_callback) { | 368 const google_apis::UploadCompletionCallback& upload_completion_callback) { |
372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
373 | 370 |
374 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 371 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_UPLOAD_EXISTING_FILE)); |
375 new_job->resource_id = resource_id; | 372 new_job->resource_id = resource_id; |
376 new_job->drive_file_path = drive_file_path; | 373 new_job->drive_file_path = drive_file_path; |
377 new_job->local_file_path = local_file_path; | 374 new_job->local_file_path = local_file_path; |
378 new_job->content_type = content_type; | 375 new_job->content_type = content_type; |
379 new_job->etag = etag; | 376 new_job->etag = etag; |
380 new_job->upload_completion_callback = upload_completion_callback; | 377 new_job->upload_completion_callback = upload_completion_callback; |
381 new_job->context = context; | 378 new_job->context = context; |
382 | 379 |
383 StartNewJob(new_job.Pass(), TYPE_UPLOAD_EXISTING_FILE); | 380 StartNewJob(new_job.Pass()); |
384 } | 381 } |
385 | 382 |
386 void JobScheduler::CreateFile( | 383 void JobScheduler::CreateFile( |
387 const std::string& parent_resource_id, | 384 const std::string& parent_resource_id, |
388 const base::FilePath& drive_file_path, | 385 const base::FilePath& drive_file_path, |
389 const std::string& title, | 386 const std::string& title, |
390 const std::string& content_type, | 387 const std::string& content_type, |
391 const DriveClientContext& context, | 388 const DriveClientContext& context, |
392 const google_apis::UploadCompletionCallback& callback) { | 389 const google_apis::UploadCompletionCallback& callback) { |
393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
394 | 391 |
395 scoped_ptr<QueueEntry> new_job(new QueueEntry); | 392 scoped_ptr<JobEntry> new_job(new JobEntry(TYPE_CREATE_FILE)); |
396 new_job->resource_id = parent_resource_id; | 393 new_job->resource_id = parent_resource_id; |
397 new_job->drive_file_path = drive_file_path; | 394 new_job->drive_file_path = drive_file_path; |
398 new_job->title = title; | 395 new_job->title = title; |
399 new_job->content_type = content_type; | 396 new_job->content_type = content_type; |
400 new_job->upload_completion_callback = callback; | 397 new_job->upload_completion_callback = callback; |
401 new_job->context = context; | 398 new_job->context = context; |
402 | 399 |
403 StartNewJob(new_job.Pass(), TYPE_CREATE_FILE); | 400 StartNewJob(new_job.Pass()); |
404 } | 401 } |
405 | 402 |
406 JobID JobScheduler::StartNewJob(scoped_ptr<QueueEntry> job, JobType type) { | 403 JobID JobScheduler::StartNewJob(scoped_ptr<JobEntry> job) { |
407 // job_info is owned by job_map_ and released when it is removed in OnJobDone. | 404 DCHECK(job); |
408 JobInfo* job_info = new JobInfo(type); | 405 |
409 job->job_id = job_info->job_id = job_map_.Add(job_info); | 406 // |job| is owned by job_map_ and released when it is removed in OnJobDone. |
| 407 JobInfo* job_info = &job->job_info; |
410 job_info->file_path = job->drive_file_path; | 408 job_info->file_path = job->drive_file_path; |
| 409 job_info->job_id = job_map_.Add(job.release()); |
411 | 410 |
412 QueueJob(job.Pass()); | 411 QueueJob(job_info->job_id); |
413 NotifyJobAdded(*job_info); | 412 NotifyJobAdded(*job_info); |
414 StartJobLoop(GetJobQueueType(type)); | 413 StartJobLoop(GetJobQueueType(job_info->job_type)); |
415 return job_info->job_id; | 414 return job_info->job_id; |
416 } | 415 } |
417 | 416 |
418 void JobScheduler::QueueJob(scoped_ptr<QueueEntry> job) { | 417 void JobScheduler::QueueJob(JobID job_id) { |
419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 418 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
420 | 419 |
421 JobInfo* job_info = job_map_.Lookup(job->job_id); | 420 JobEntry* job_entry = job_map_.Lookup(job_id); |
422 DCHECK(job_info); | 421 DCHECK(job_entry); |
| 422 const JobInfo& job_info = job_entry->job_info; |
423 | 423 |
424 QueueType queue_type = GetJobQueueType(job_info->job_type); | 424 QueueType queue_type = GetJobQueueType(job_info.job_type); |
425 std::list<QueueEntry*>& queue = queue_[queue_type]; | 425 std::list<JobID>* queue = &queue_[queue_type]; |
426 | 426 |
427 queue.push_back(job.release()); | 427 std::list<JobID>::iterator it = queue->begin(); |
428 queue.sort(&QueueEntry::Compare); | 428 for (; it != queue->end(); ++it) { |
| 429 JobEntry* job_entry2 = job_map_.Lookup(*it); |
| 430 if (JobEntry::Less(*job_entry, *job_entry2)) |
| 431 break; |
| 432 } |
| 433 queue->insert(it, job_id); |
429 | 434 |
430 util::Log("Job queued: %s - %s", job_info->ToString().c_str(), | 435 util::Log("Job queued: %s - %s", job_info.ToString().c_str(), |
431 GetQueueInfo(queue_type).c_str()); | 436 GetQueueInfo(queue_type).c_str()); |
432 } | 437 } |
433 | 438 |
434 void JobScheduler::StartJobLoop(QueueType queue_type) { | 439 void JobScheduler::StartJobLoop(QueueType queue_type) { |
435 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 440 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
436 | 441 |
437 if (jobs_running_[queue_type] < kMaxJobCount[queue_type]) | 442 if (jobs_running_[queue_type] < kMaxJobCount[queue_type]) |
438 DoJobLoop(queue_type); | 443 DoJobLoop(queue_type); |
439 } | 444 } |
440 | 445 |
441 void JobScheduler::DoJobLoop(QueueType queue_type) { | 446 void JobScheduler::DoJobLoop(QueueType queue_type) { |
442 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 447 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
443 | 448 |
444 if (queue_[queue_type].empty()) { | 449 if (queue_[queue_type].empty()) { |
445 return; | 450 return; |
446 } | 451 } |
447 | 452 |
| 453 JobID job_id = queue_[queue_type].front(); |
| 454 JobEntry* entry = job_map_.Lookup(job_id); |
| 455 DCHECK(entry); |
| 456 |
448 // Check if we should defer based on the first item in the queue | 457 // Check if we should defer based on the first item in the queue |
449 if (ShouldStopJobLoop(queue_type, queue_[queue_type].front()->context)) { | 458 if (ShouldStopJobLoop(queue_type, entry->context)) { |
450 return; | 459 return; |
451 } | 460 } |
452 | 461 |
453 // Increment the number of jobs. | 462 // Increment the number of jobs. |
454 ++jobs_running_[queue_type]; | 463 ++jobs_running_[queue_type]; |
455 | 464 |
456 // Should copy before calling queue_.pop_front(). | |
457 scoped_ptr<QueueEntry> queue_entry(queue_[queue_type].front()); | |
458 queue_[queue_type].pop_front(); | 465 queue_[queue_type].pop_front(); |
459 | 466 |
460 JobInfo* job_info = job_map_.Lookup(queue_entry->job_id); | 467 JobInfo* job_info = &entry->job_info; |
461 DCHECK(job_info); | |
462 job_info->state = STATE_RUNNING; | 468 job_info->state = STATE_RUNNING; |
463 job_info->start_time = base::Time::Now(); | 469 job_info->start_time = base::Time::Now(); |
464 NotifyJobUpdated(*job_info); | 470 NotifyJobUpdated(*job_info); |
465 | 471 |
466 // The some arguments are evaluated after bind, so we copy the pointer to the | |
467 // QueueEntry | |
468 QueueEntry* entry = queue_entry.get(); | |
469 | |
470 switch (job_info->job_type) { | 472 switch (job_info->job_type) { |
471 case TYPE_GET_ABOUT_RESOURCE: { | 473 case TYPE_GET_ABOUT_RESOURCE: { |
472 drive_service_->GetAboutResource( | 474 drive_service_->GetAboutResource( |
473 base::Bind(&JobScheduler::OnGetAboutResourceJobDone, | 475 base::Bind(&JobScheduler::OnGetAboutResourceJobDone, |
474 weak_ptr_factory_.GetWeakPtr(), | 476 weak_ptr_factory_.GetWeakPtr(), |
475 base::Passed(&queue_entry))); | 477 job_id, |
| 478 entry->get_about_resource_callback)); |
476 } | 479 } |
477 break; | 480 break; |
478 | 481 |
479 case TYPE_GET_ACCOUNT_METADATA: { | 482 case TYPE_GET_ACCOUNT_METADATA: { |
480 drive_service_->GetAccountMetadata( | 483 drive_service_->GetAccountMetadata( |
481 base::Bind(&JobScheduler::OnGetAccountMetadataJobDone, | 484 base::Bind(&JobScheduler::OnGetAccountMetadataJobDone, |
482 weak_ptr_factory_.GetWeakPtr(), | 485 weak_ptr_factory_.GetWeakPtr(), |
483 base::Passed(&queue_entry))); | 486 job_id, |
| 487 entry->get_account_metadata_callback)); |
484 } | 488 } |
485 break; | 489 break; |
486 | 490 |
487 case TYPE_GET_APP_LIST: { | 491 case TYPE_GET_APP_LIST: { |
488 drive_service_->GetAppList( | 492 drive_service_->GetAppList( |
489 base::Bind(&JobScheduler::OnGetAppListJobDone, | 493 base::Bind(&JobScheduler::OnGetAppListJobDone, |
490 weak_ptr_factory_.GetWeakPtr(), | 494 weak_ptr_factory_.GetWeakPtr(), |
491 base::Passed(&queue_entry))); | 495 job_id, |
| 496 entry->get_app_list_callback)); |
492 } | 497 } |
493 break; | 498 break; |
494 | 499 |
495 case TYPE_GET_ALL_RESOURCE_LIST: { | 500 case TYPE_GET_ALL_RESOURCE_LIST: { |
496 drive_service_->GetAllResourceList( | 501 drive_service_->GetAllResourceList( |
497 base::Bind(&JobScheduler::OnGetResourceListJobDone, | 502 base::Bind(&JobScheduler::OnGetResourceListJobDone, |
498 weak_ptr_factory_.GetWeakPtr(), | 503 weak_ptr_factory_.GetWeakPtr(), |
499 base::Passed(&queue_entry))); | 504 job_id, |
| 505 entry->get_resource_list_callback)); |
500 } | 506 } |
501 break; | 507 break; |
502 | 508 |
503 case TYPE_GET_RESOURCE_LIST_IN_DIRECTORY: { | 509 case TYPE_GET_RESOURCE_LIST_IN_DIRECTORY: { |
504 drive_service_->GetResourceListInDirectory( | 510 drive_service_->GetResourceListInDirectory( |
505 entry->directory_resource_id, | 511 entry->directory_resource_id, |
506 base::Bind(&JobScheduler::OnGetResourceListJobDone, | 512 base::Bind(&JobScheduler::OnGetResourceListJobDone, |
507 weak_ptr_factory_.GetWeakPtr(), | 513 weak_ptr_factory_.GetWeakPtr(), |
508 base::Passed(&queue_entry))); | 514 job_id, |
| 515 entry->get_resource_list_callback)); |
509 } | 516 } |
510 break; | 517 break; |
511 | 518 |
512 case TYPE_SEARCH: { | 519 case TYPE_SEARCH: { |
513 drive_service_->Search( | 520 drive_service_->Search( |
514 entry->search_query, | 521 entry->search_query, |
515 base::Bind(&JobScheduler::OnGetResourceListJobDone, | 522 base::Bind(&JobScheduler::OnGetResourceListJobDone, |
516 weak_ptr_factory_.GetWeakPtr(), | 523 weak_ptr_factory_.GetWeakPtr(), |
517 base::Passed(&queue_entry))); | 524 job_id, |
| 525 entry->get_resource_list_callback)); |
518 } | 526 } |
519 break; | 527 break; |
520 | 528 |
521 case TYPE_GET_CHANGE_LIST: { | 529 case TYPE_GET_CHANGE_LIST: { |
522 drive_service_->GetChangeList( | 530 drive_service_->GetChangeList( |
523 entry->start_changestamp, | 531 entry->start_changestamp, |
524 base::Bind(&JobScheduler::OnGetResourceListJobDone, | 532 base::Bind(&JobScheduler::OnGetResourceListJobDone, |
525 weak_ptr_factory_.GetWeakPtr(), | 533 weak_ptr_factory_.GetWeakPtr(), |
526 base::Passed(&queue_entry))); | 534 job_id, |
| 535 entry->get_resource_list_callback)); |
527 } | 536 } |
528 break; | 537 break; |
529 | 538 |
530 case TYPE_CONTINUE_GET_RESOURCE_LIST: { | 539 case TYPE_CONTINUE_GET_RESOURCE_LIST: { |
531 drive_service_->ContinueGetResourceList( | 540 drive_service_->ContinueGetResourceList( |
532 entry->feed_url, | 541 entry->feed_url, |
533 base::Bind(&JobScheduler::OnGetResourceListJobDone, | 542 base::Bind(&JobScheduler::OnGetResourceListJobDone, |
534 weak_ptr_factory_.GetWeakPtr(), | 543 weak_ptr_factory_.GetWeakPtr(), |
535 base::Passed(&queue_entry))); | 544 job_id, |
| 545 entry->get_resource_list_callback)); |
536 } | 546 } |
537 break; | 547 break; |
538 | 548 |
539 case TYPE_GET_RESOURCE_ENTRY: { | 549 case TYPE_GET_RESOURCE_ENTRY: { |
540 drive_service_->GetResourceEntry( | 550 drive_service_->GetResourceEntry( |
541 entry->resource_id, | 551 entry->resource_id, |
542 base::Bind(&JobScheduler::OnGetResourceEntryJobDone, | 552 base::Bind(&JobScheduler::OnGetResourceEntryJobDone, |
543 weak_ptr_factory_.GetWeakPtr(), | 553 weak_ptr_factory_.GetWeakPtr(), |
544 base::Passed(&queue_entry))); | 554 job_id, |
| 555 entry->get_resource_entry_callback)); |
545 } | 556 } |
546 break; | 557 break; |
547 | 558 |
548 case TYPE_DELETE_RESOURCE: { | 559 case TYPE_DELETE_RESOURCE: { |
549 drive_service_->DeleteResource( | 560 drive_service_->DeleteResource( |
550 entry->resource_id, | 561 entry->resource_id, |
551 "", // etag | 562 "", // etag |
552 base::Bind(&JobScheduler::OnEntryActionJobDone, | 563 base::Bind(&JobScheduler::OnEntryActionJobDone, |
553 weak_ptr_factory_.GetWeakPtr(), | 564 weak_ptr_factory_.GetWeakPtr(), |
554 base::Passed(&queue_entry))); | 565 job_id, |
| 566 entry->entry_action_callback)); |
555 } | 567 } |
556 break; | 568 break; |
557 | 569 |
558 case TYPE_COPY_HOSTED_DOCUMENT: { | 570 case TYPE_COPY_HOSTED_DOCUMENT: { |
559 drive_service_->CopyHostedDocument( | 571 drive_service_->CopyHostedDocument( |
560 entry->resource_id, | 572 entry->resource_id, |
561 entry->new_name, | 573 entry->new_name, |
562 base::Bind(&JobScheduler::OnGetResourceEntryJobDone, | 574 base::Bind(&JobScheduler::OnGetResourceEntryJobDone, |
563 weak_ptr_factory_.GetWeakPtr(), | 575 weak_ptr_factory_.GetWeakPtr(), |
564 base::Passed(&queue_entry))); | 576 job_id, |
| 577 entry->get_resource_entry_callback)); |
565 } | 578 } |
566 break; | 579 break; |
567 | 580 |
568 case TYPE_RENAME_RESOURCE: { | 581 case TYPE_RENAME_RESOURCE: { |
569 drive_service_->RenameResource( | 582 drive_service_->RenameResource( |
570 entry->resource_id, | 583 entry->resource_id, |
571 entry->new_name, | 584 entry->new_name, |
572 base::Bind(&JobScheduler::OnEntryActionJobDone, | 585 base::Bind(&JobScheduler::OnEntryActionJobDone, |
573 weak_ptr_factory_.GetWeakPtr(), | 586 weak_ptr_factory_.GetWeakPtr(), |
574 base::Passed(&queue_entry))); | 587 job_id, |
| 588 entry->entry_action_callback)); |
575 } | 589 } |
576 break; | 590 break; |
577 | 591 |
578 case TYPE_ADD_RESOURCE_TO_DIRECTORY: { | 592 case TYPE_ADD_RESOURCE_TO_DIRECTORY: { |
579 drive_service_->AddResourceToDirectory( | 593 drive_service_->AddResourceToDirectory( |
580 entry->parent_resource_id, | 594 entry->parent_resource_id, |
581 entry->resource_id, | 595 entry->resource_id, |
582 base::Bind(&JobScheduler::OnEntryActionJobDone, | 596 base::Bind(&JobScheduler::OnEntryActionJobDone, |
583 weak_ptr_factory_.GetWeakPtr(), | 597 weak_ptr_factory_.GetWeakPtr(), |
584 base::Passed(&queue_entry))); | 598 job_id, |
| 599 entry->entry_action_callback)); |
585 } | 600 } |
586 break; | 601 break; |
587 | 602 |
588 case TYPE_REMOVE_RESOURCE_FROM_DIRECTORY: { | 603 case TYPE_REMOVE_RESOURCE_FROM_DIRECTORY: { |
589 drive_service_->RemoveResourceFromDirectory( | 604 drive_service_->RemoveResourceFromDirectory( |
590 entry->parent_resource_id, | 605 entry->parent_resource_id, |
591 entry->resource_id, | 606 entry->resource_id, |
592 base::Bind(&JobScheduler::OnEntryActionJobDone, | 607 base::Bind(&JobScheduler::OnEntryActionJobDone, |
593 weak_ptr_factory_.GetWeakPtr(), | 608 weak_ptr_factory_.GetWeakPtr(), |
594 base::Passed(&queue_entry))); | 609 job_id, |
| 610 entry->entry_action_callback)); |
595 } | 611 } |
596 break; | 612 break; |
597 | 613 |
598 case TYPE_ADD_NEW_DIRECTORY: { | 614 case TYPE_ADD_NEW_DIRECTORY: { |
599 drive_service_->AddNewDirectory( | 615 drive_service_->AddNewDirectory( |
600 entry->parent_resource_id, | 616 entry->parent_resource_id, |
601 entry->directory_name, | 617 entry->directory_name, |
602 base::Bind(&JobScheduler::OnGetResourceEntryJobDone, | 618 base::Bind(&JobScheduler::OnGetResourceEntryJobDone, |
603 weak_ptr_factory_.GetWeakPtr(), | 619 weak_ptr_factory_.GetWeakPtr(), |
604 base::Passed(&queue_entry))); | 620 job_id, |
| 621 entry->get_resource_entry_callback)); |
605 } | 622 } |
606 break; | 623 break; |
607 | 624 |
608 case TYPE_DOWNLOAD_FILE: { | 625 case TYPE_DOWNLOAD_FILE: { |
609 drive_service_->DownloadFile( | 626 drive_service_->DownloadFile( |
610 entry->drive_file_path, | 627 entry->drive_file_path, |
611 entry->local_file_path, | 628 entry->local_file_path, |
612 entry->download_url, | 629 entry->download_url, |
613 base::Bind(&JobScheduler::OnDownloadActionJobDone, | 630 base::Bind(&JobScheduler::OnDownloadActionJobDone, |
614 weak_ptr_factory_.GetWeakPtr(), | 631 weak_ptr_factory_.GetWeakPtr(), |
615 base::Passed(&queue_entry)), | 632 job_id, |
| 633 entry->download_action_callback), |
616 entry->get_content_callback, | 634 entry->get_content_callback, |
617 base::Bind(&JobScheduler::UpdateProgress, | 635 base::Bind(&JobScheduler::UpdateProgress, |
618 weak_ptr_factory_.GetWeakPtr(), | 636 weak_ptr_factory_.GetWeakPtr(), |
619 job_info->job_id)); | 637 job_id)); |
620 } | 638 } |
621 break; | 639 break; |
622 | 640 |
623 case TYPE_UPLOAD_NEW_FILE: { | 641 case TYPE_UPLOAD_NEW_FILE: { |
624 uploader_->UploadNewFile( | 642 uploader_->UploadNewFile( |
625 entry->resource_id, | 643 entry->resource_id, |
626 entry->drive_file_path, | 644 entry->drive_file_path, |
627 entry->local_file_path, | 645 entry->local_file_path, |
628 entry->title, | 646 entry->title, |
629 entry->content_type, | 647 entry->content_type, |
630 base::Bind(&JobScheduler::OnUploadCompletionJobDone, | 648 base::Bind(&JobScheduler::OnUploadCompletionJobDone, |
631 weak_ptr_factory_.GetWeakPtr(), | 649 weak_ptr_factory_.GetWeakPtr(), |
632 base::Passed(&queue_entry)), | 650 job_id, |
| 651 entry->upload_completion_callback), |
633 base::Bind(&JobScheduler::UpdateProgress, | 652 base::Bind(&JobScheduler::UpdateProgress, |
634 weak_ptr_factory_.GetWeakPtr(), | 653 weak_ptr_factory_.GetWeakPtr(), |
635 job_info->job_id)); | 654 job_id)); |
636 } | 655 } |
637 break; | 656 break; |
638 | 657 |
639 case TYPE_UPLOAD_EXISTING_FILE: { | 658 case TYPE_UPLOAD_EXISTING_FILE: { |
640 uploader_->UploadExistingFile( | 659 uploader_->UploadExistingFile( |
641 entry->resource_id, | 660 entry->resource_id, |
642 entry->drive_file_path, | 661 entry->drive_file_path, |
643 entry->local_file_path, | 662 entry->local_file_path, |
644 entry->content_type, | 663 entry->content_type, |
645 entry->etag, | 664 entry->etag, |
646 base::Bind(&JobScheduler::OnUploadCompletionJobDone, | 665 base::Bind(&JobScheduler::OnUploadCompletionJobDone, |
647 weak_ptr_factory_.GetWeakPtr(), | 666 weak_ptr_factory_.GetWeakPtr(), |
648 base::Passed(&queue_entry)), | 667 job_id, |
| 668 entry->upload_completion_callback), |
649 base::Bind(&JobScheduler::UpdateProgress, | 669 base::Bind(&JobScheduler::UpdateProgress, |
650 weak_ptr_factory_.GetWeakPtr(), | 670 weak_ptr_factory_.GetWeakPtr(), |
651 job_info->job_id)); | 671 job_id)); |
652 } | 672 } |
653 break; | 673 break; |
654 | 674 |
655 case TYPE_CREATE_FILE: { | 675 case TYPE_CREATE_FILE: { |
656 // For now, creation is implemented by uploading an empty file /dev/null. | 676 // For now, creation is implemented by uploading an empty file /dev/null. |
657 // TODO(kinaba): http://crbug.com/135143. Implement in a nicer way. | 677 // TODO(kinaba): http://crbug.com/135143. Implement in a nicer way. |
658 uploader_->UploadNewFile( | 678 uploader_->UploadNewFile( |
659 entry->resource_id, | 679 entry->resource_id, |
660 entry->drive_file_path, | 680 entry->drive_file_path, |
661 base::FilePath(util::kSymLinkToDevNull), | 681 base::FilePath(util::kSymLinkToDevNull), |
662 entry->title, | 682 entry->title, |
663 entry->content_type, | 683 entry->content_type, |
664 base::Bind(&JobScheduler::OnUploadCompletionJobDone, | 684 base::Bind(&JobScheduler::OnUploadCompletionJobDone, |
665 weak_ptr_factory_.GetWeakPtr(), | 685 weak_ptr_factory_.GetWeakPtr(), |
666 base::Passed(&queue_entry)), | 686 job_id, |
| 687 entry->upload_completion_callback), |
667 google_apis::ProgressCallback()); | 688 google_apis::ProgressCallback()); |
668 } | 689 } |
669 break; | 690 break; |
670 | 691 |
671 // There is no default case so that there will be a compiler error if a type | 692 // There is no default case so that there will be a compiler error if a type |
672 // is added but unhandled. | 693 // is added but unhandled. |
673 } | 694 } |
674 | 695 |
675 util::Log("Job started: %s - %s", | 696 util::Log("Job started: %s - %s", |
676 job_info->ToString().c_str(), | 697 job_info->ToString().c_str(), |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 | 762 |
742 // Post a task to continue the job loop. This allows us to finish handling | 763 // Post a task to continue the job loop. This allows us to finish handling |
743 // the current job before starting the next one. | 764 // the current job before starting the next one. |
744 throttle_count_ = 0; | 765 throttle_count_ = 0; |
745 base::MessageLoopProxy::current()->PostTask(FROM_HERE, | 766 base::MessageLoopProxy::current()->PostTask(FROM_HERE, |
746 base::Bind(&JobScheduler::DoJobLoop, | 767 base::Bind(&JobScheduler::DoJobLoop, |
747 weak_ptr_factory_.GetWeakPtr(), | 768 weak_ptr_factory_.GetWeakPtr(), |
748 queue_type)); | 769 queue_type)); |
749 } | 770 } |
750 | 771 |
751 bool JobScheduler::OnJobDone(scoped_ptr<JobScheduler::QueueEntry> queue_entry, | 772 bool JobScheduler::OnJobDone(JobID job_id, FileError error) { |
752 FileError error) { | |
753 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 773 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
754 | 774 |
755 JobInfo* job_info = job_map_.Lookup(queue_entry->job_id); | 775 JobEntry* job_entry = job_map_.Lookup(job_id); |
756 DCHECK(job_info); | 776 DCHECK(job_entry); |
| 777 JobInfo* job_info = &job_entry->job_info; |
757 QueueType queue_type = GetJobQueueType(job_info->job_type); | 778 QueueType queue_type = GetJobQueueType(job_info->job_type); |
758 | 779 |
759 const base::TimeDelta elapsed = base::Time::Now() - job_info->start_time; | 780 const base::TimeDelta elapsed = base::Time::Now() - job_info->start_time; |
760 util::Log("Job done: %s => %s (elapsed time: %sms) - %s", | 781 util::Log("Job done: %s => %s (elapsed time: %sms) - %s", |
761 job_info->ToString().c_str(), | 782 job_info->ToString().c_str(), |
762 FileErrorToString(error).c_str(), | 783 FileErrorToString(error).c_str(), |
763 base::Int64ToString(elapsed.InMilliseconds()).c_str(), | 784 base::Int64ToString(elapsed.InMilliseconds()).c_str(), |
764 GetQueueInfo(queue_type).c_str()); | 785 GetQueueInfo(queue_type).c_str()); |
765 | 786 |
766 // Decrement the number of jobs for this queue. | 787 // Decrement the number of jobs for this queue. |
767 --jobs_running_[queue_type]; | 788 --jobs_running_[queue_type]; |
768 | 789 |
769 // Retry, depending on the error. | 790 // Retry, depending on the error. |
770 if (error == FILE_ERROR_THROTTLED) { | 791 if (error == FILE_ERROR_THROTTLED) { |
771 job_info->state = STATE_RETRY; | 792 job_info->state = STATE_RETRY; |
772 NotifyJobUpdated(*job_info); | 793 NotifyJobUpdated(*job_info); |
773 | 794 |
774 // Requeue the job. | 795 // Requeue the job. |
775 QueueJob(queue_entry.Pass()); | 796 QueueJob(job_id); |
776 | 797 |
777 ThrottleAndContinueJobLoop(queue_type); | 798 ThrottleAndContinueJobLoop(queue_type); |
778 return false; | 799 return false; |
779 } else { | 800 } else { |
780 NotifyJobDone(*job_info, error); | 801 NotifyJobDone(*job_info, error); |
781 // The job has finished, no retry will happen in the scheduler. Now we can | 802 // The job has finished, no retry will happen in the scheduler. Now we can |
782 // remove the job info from the map. This is the only place of the removal. | 803 // remove the job info from the map. This is the only place of the removal. |
783 job_map_.Remove(queue_entry->job_id); | 804 job_map_.Remove(job_id); |
784 | 805 |
785 ResetThrottleAndContinueJobLoop(queue_type); | 806 ResetThrottleAndContinueJobLoop(queue_type); |
786 return true; | 807 return true; |
787 } | 808 } |
788 } | 809 } |
789 | 810 |
790 void JobScheduler::OnGetResourceListJobDone( | 811 void JobScheduler::OnGetResourceListJobDone( |
791 scoped_ptr<JobScheduler::QueueEntry> queue_entry, | 812 JobID job_id, |
| 813 const google_apis::GetResourceListCallback& callback, |
792 google_apis::GDataErrorCode error, | 814 google_apis::GDataErrorCode error, |
793 scoped_ptr<google_apis::ResourceList> resource_list) { | 815 scoped_ptr<google_apis::ResourceList> resource_list) { |
794 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 816 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
795 DCHECK(!queue_entry->get_resource_list_callback.is_null()); | 817 DCHECK(!callback.is_null()); |
796 | 818 |
797 google_apis::GetResourceListCallback callback = | 819 if (OnJobDone(job_id, util::GDataToFileError(error))) |
798 queue_entry->get_resource_list_callback; | |
799 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error))) | |
800 callback.Run(error, resource_list.Pass()); | 820 callback.Run(error, resource_list.Pass()); |
801 } | 821 } |
802 | 822 |
803 void JobScheduler::OnGetResourceEntryJobDone( | 823 void JobScheduler::OnGetResourceEntryJobDone( |
804 scoped_ptr<JobScheduler::QueueEntry> queue_entry, | 824 JobID job_id, |
| 825 const google_apis::GetResourceEntryCallback& callback, |
805 google_apis::GDataErrorCode error, | 826 google_apis::GDataErrorCode error, |
806 scoped_ptr<google_apis::ResourceEntry> entry) { | 827 scoped_ptr<google_apis::ResourceEntry> entry) { |
807 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 828 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
808 DCHECK(!queue_entry->get_resource_entry_callback.is_null()); | 829 DCHECK(!callback.is_null()); |
809 | 830 |
810 google_apis::GetResourceEntryCallback callback = | 831 if (OnJobDone(job_id, util::GDataToFileError(error))) |
811 queue_entry->get_resource_entry_callback; | |
812 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error))) | |
813 callback.Run(error, entry.Pass()); | 832 callback.Run(error, entry.Pass()); |
814 } | 833 } |
815 | 834 |
816 void JobScheduler::OnGetAboutResourceJobDone( | 835 void JobScheduler::OnGetAboutResourceJobDone( |
817 scoped_ptr<QueueEntry> queue_entry, | 836 JobID job_id, |
| 837 const google_apis::GetAboutResourceCallback& callback, |
818 google_apis::GDataErrorCode error, | 838 google_apis::GDataErrorCode error, |
819 scoped_ptr<google_apis::AboutResource> about_resource) { | 839 scoped_ptr<google_apis::AboutResource> about_resource) { |
820 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 840 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
821 DCHECK(!queue_entry->get_about_resource_callback.is_null()); | 841 DCHECK(!callback.is_null()); |
822 | 842 |
823 google_apis::GetAboutResourceCallback callback = | 843 if (OnJobDone(job_id, util::GDataToFileError(error))) |
824 queue_entry->get_about_resource_callback; | |
825 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error))) | |
826 callback.Run(error, about_resource.Pass()); | 844 callback.Run(error, about_resource.Pass()); |
827 } | 845 } |
828 | 846 |
829 void JobScheduler::OnGetAccountMetadataJobDone( | 847 void JobScheduler::OnGetAccountMetadataJobDone( |
830 scoped_ptr<QueueEntry> queue_entry, | 848 JobID job_id, |
| 849 const google_apis::GetAccountMetadataCallback& callback, |
831 google_apis::GDataErrorCode error, | 850 google_apis::GDataErrorCode error, |
832 scoped_ptr<google_apis::AccountMetadata> account_metadata) { | 851 scoped_ptr<google_apis::AccountMetadata> account_metadata) { |
833 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 852 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
834 DCHECK(!queue_entry->get_account_metadata_callback.is_null()); | 853 DCHECK(!callback.is_null()); |
835 | 854 |
836 google_apis::GetAccountMetadataCallback callback = | 855 if (OnJobDone(job_id, util::GDataToFileError(error))) |
837 queue_entry->get_account_metadata_callback; | |
838 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error))) | |
839 callback.Run(error, account_metadata.Pass()); | 856 callback.Run(error, account_metadata.Pass()); |
840 } | 857 } |
841 | 858 |
842 void JobScheduler::OnGetAppListJobDone( | 859 void JobScheduler::OnGetAppListJobDone( |
843 scoped_ptr<JobScheduler::QueueEntry> queue_entry, | 860 JobID job_id, |
| 861 const google_apis::GetAppListCallback& callback, |
844 google_apis::GDataErrorCode error, | 862 google_apis::GDataErrorCode error, |
845 scoped_ptr<google_apis::AppList> app_list) { | 863 scoped_ptr<google_apis::AppList> app_list) { |
846 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 864 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
847 DCHECK(!queue_entry->get_app_list_callback.is_null()); | 865 DCHECK(!callback.is_null()); |
848 | 866 |
849 google_apis::GetAppListCallback callback = queue_entry->get_app_list_callback; | 867 if (OnJobDone(job_id, util::GDataToFileError(error))) |
850 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error))) | |
851 callback.Run(error, app_list.Pass()); | 868 callback.Run(error, app_list.Pass()); |
852 } | 869 } |
853 | 870 |
854 void JobScheduler::OnEntryActionJobDone( | 871 void JobScheduler::OnEntryActionJobDone( |
855 scoped_ptr<JobScheduler::QueueEntry> queue_entry, | 872 JobID job_id, |
| 873 const google_apis::EntryActionCallback& callback, |
856 google_apis::GDataErrorCode error) { | 874 google_apis::GDataErrorCode error) { |
857 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 875 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
858 DCHECK(!queue_entry->entry_action_callback.is_null()); | 876 DCHECK(!callback.is_null()); |
859 | 877 |
860 google_apis::EntryActionCallback callback = | 878 if (OnJobDone(job_id, util::GDataToFileError(error))) |
861 queue_entry->entry_action_callback; | |
862 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error))) | |
863 callback.Run(error); | 879 callback.Run(error); |
864 } | 880 } |
865 | 881 |
866 void JobScheduler::OnDownloadActionJobDone( | 882 void JobScheduler::OnDownloadActionJobDone( |
867 scoped_ptr<JobScheduler::QueueEntry> queue_entry, | 883 JobID job_id, |
| 884 const google_apis::DownloadActionCallback& callback, |
868 google_apis::GDataErrorCode error, | 885 google_apis::GDataErrorCode error, |
869 const base::FilePath& temp_file) { | 886 const base::FilePath& temp_file) { |
870 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 887 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
871 DCHECK(!queue_entry->download_action_callback.is_null()); | 888 DCHECK(!callback.is_null()); |
872 | 889 |
873 google_apis::DownloadActionCallback callback = | 890 if (OnJobDone(job_id, util::GDataToFileError(error))) |
874 queue_entry->download_action_callback; | |
875 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error))) | |
876 callback.Run(error, temp_file); | 891 callback.Run(error, temp_file); |
877 } | 892 } |
878 | 893 |
879 void JobScheduler::OnUploadCompletionJobDone( | 894 void JobScheduler::OnUploadCompletionJobDone( |
880 scoped_ptr<QueueEntry> queue_entry, | 895 JobID job_id, |
| 896 const google_apis::UploadCompletionCallback& callback, |
881 google_apis::GDataErrorCode error, | 897 google_apis::GDataErrorCode error, |
882 const base::FilePath& drive_path, | 898 const base::FilePath& drive_path, |
883 const base::FilePath& file_path, | 899 const base::FilePath& file_path, |
884 scoped_ptr<google_apis::ResourceEntry> resource_entry) { | 900 scoped_ptr<google_apis::ResourceEntry> resource_entry) { |
885 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 901 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
886 DCHECK(!queue_entry->upload_completion_callback.is_null()); | 902 DCHECK(!callback.is_null()); |
887 | 903 |
888 google_apis::UploadCompletionCallback callback = | 904 if (OnJobDone(job_id, util::GDataToFileError(error))) |
889 queue_entry->upload_completion_callback; | |
890 if (OnJobDone(queue_entry.Pass(), util::GDataToFileError(error))) | |
891 callback.Run(error, drive_path, file_path, resource_entry.Pass()); | 905 callback.Run(error, drive_path, file_path, resource_entry.Pass()); |
892 } | 906 } |
893 | 907 |
894 void JobScheduler::UpdateProgress(JobID job_id, int64 progress, int64 total) { | 908 void JobScheduler::UpdateProgress(JobID job_id, int64 progress, int64 total) { |
895 JobInfo* job_info = job_map_.Lookup(job_id); | 909 JobEntry* job_entry = job_map_.Lookup(job_id); |
896 DCHECK(job_info); | 910 DCHECK(job_entry); |
897 | 911 |
898 job_info->num_completed_bytes = progress; | 912 job_entry->job_info.num_completed_bytes = progress; |
899 job_info->num_total_bytes = total; | 913 job_entry->job_info.num_total_bytes = total; |
900 NotifyJobUpdated(*job_info); | 914 NotifyJobUpdated(job_entry->job_info); |
901 } | 915 } |
902 | 916 |
903 void JobScheduler::OnConnectionTypeChanged( | 917 void JobScheduler::OnConnectionTypeChanged( |
904 net::NetworkChangeNotifier::ConnectionType type) { | 918 net::NetworkChangeNotifier::ConnectionType type) { |
905 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 919 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
906 | 920 |
907 // Resume the job loop if the network is back online. Note that we don't | 921 // Resume the job loop if the network is back online. Note that we don't |
908 // need to check the type of the network as it will be checked in | 922 // need to check the type of the network as it will be checked in |
909 // ShouldStopJobLoop() as soon as the loop is resumed. | 923 // ShouldStopJobLoop() as soon as the loop is resumed. |
910 if (!net::NetworkChangeNotifier::IsOffline()) { | 924 if (!net::NetworkChangeNotifier::IsOffline()) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 return "FILE_QUEUE"; | 990 return "FILE_QUEUE"; |
977 case NUM_QUEUES: | 991 case NUM_QUEUES: |
978 return "NUM_QUEUES"; | 992 return "NUM_QUEUES"; |
979 } | 993 } |
980 NOTREACHED(); | 994 NOTREACHED(); |
981 return ""; | 995 return ""; |
982 } | 996 } |
983 | 997 |
984 | 998 |
985 } // namespace drive | 999 } // namespace drive |
OLD | NEW |