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