Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(908)

Side by Side Diff: content/browser/download/download_file_manager.cc

Issue 7847027: DownloadId (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: 7776012 verbatim Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "content/browser/download/download_file_manager.h" 5 #include "content/browser/download/download_file_manager.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/task.h" 10 #include "base/task.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 // Life of |info| ends here. No more references to it after this method. 58 // Life of |info| ends here. No more references to it after this method.
59 scoped_ptr<DownloadCreateInfo> infop(info); 59 scoped_ptr<DownloadCreateInfo> infop(info);
60 60
61 scoped_ptr<DownloadFile> 61 scoped_ptr<DownloadFile>
62 download_file(new DownloadFile(info, download_manager)); 62 download_file(new DownloadFile(info, download_manager));
63 if (net::OK != download_file->Initialize(get_hash)) { 63 if (net::OK != download_file->Initialize(get_hash)) {
64 info->request_handle.CancelRequest(); 64 info->request_handle.CancelRequest();
65 return; 65 return;
66 } 66 }
67 67
68 int32 id = info->download_id; 68 DownloadId global_id(download_manager, info->download_id);
69 DCHECK(GetDownloadFile(id) == NULL); 69 DCHECK(GetDownloadFile(global_id) == NULL);
70 downloads_[id] = download_file.release(); 70 downloads_[global_id] = download_file.release();
71 71
72 // The file is now ready, we can un-pause the request and start saving data. 72 // The file is now ready, we can un-pause the request and start saving data.
73 info->request_handle.ResumeRequest(); 73 info->request_handle.ResumeRequest();
74 74
75 StartUpdateTimer(); 75 StartUpdateTimer();
76 76
77 BrowserThread::PostTask( 77 BrowserThread::PostTask(
78 BrowserThread::UI, FROM_HERE, 78 BrowserThread::UI, FROM_HERE,
79 NewRunnableMethod(download_manager, 79 NewRunnableMethod(download_manager,
80 &DownloadManager::StartDownload, id)); 80 &DownloadManager::StartDownload, info->download_id));
81 } 81 }
82 82
83 DownloadFile* DownloadFileManager::GetDownloadFile(int id) { 83 DownloadFile* DownloadFileManager::GetDownloadFile(DownloadId global_id) {
84 DownloadFileMap::iterator it = downloads_.find(id); 84 DownloadFileMap::iterator it = downloads_.find(global_id);
85 return it == downloads_.end() ? NULL : it->second; 85 return it == downloads_.end() ? NULL : it->second;
86 } 86 }
87 87
88 void DownloadFileManager::StartUpdateTimer() { 88 void DownloadFileManager::StartUpdateTimer() {
89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
90 if (!update_timer_.IsRunning()) { 90 if (!update_timer_.IsRunning()) {
91 update_timer_.Start(FROM_HERE, 91 update_timer_.Start(FROM_HERE,
92 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), 92 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs),
93 this, &DownloadFileManager::UpdateInProgressDownloads); 93 this, &DownloadFileManager::UpdateInProgressDownloads);
94 } 94 }
95 } 95 }
96 96
97 void DownloadFileManager::StopUpdateTimer() { 97 void DownloadFileManager::StopUpdateTimer() {
98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
99 update_timer_.Stop(); 99 update_timer_.Stop();
100 } 100 }
101 101
102 void DownloadFileManager::UpdateInProgressDownloads() { 102 void DownloadFileManager::UpdateInProgressDownloads() {
103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
104 for (DownloadFileMap::iterator i = downloads_.begin(); 104 for (DownloadFileMap::iterator i = downloads_.begin();
105 i != downloads_.end(); ++i) { 105 i != downloads_.end(); ++i) {
106 int id = i->first; 106 DownloadId global_id = i->first;
107 DownloadFile* download_file = i->second; 107 DownloadFile* download_file = i->second;
108 DownloadManager* manager = download_file->GetDownloadManager(); 108 DownloadManager* manager = download_file->GetDownloadManager();
109 if (manager) { 109 if (manager) {
110 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 110 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
111 NewRunnableMethod(manager, &DownloadManager::UpdateDownload, 111 NewRunnableMethod(manager, &DownloadManager::UpdateDownload,
112 id, download_file->bytes_so_far())); 112 global_id.local(), download_file->bytes_so_far()));
113 } 113 }
114 } 114 }
115 } 115 }
116 116
117 int DownloadFileManager::GetNextId() {
118 return next_id_.GetNext();
119 }
120
121 void DownloadFileManager::StartDownload(DownloadCreateInfo* info) { 117 void DownloadFileManager::StartDownload(DownloadCreateInfo* info) {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
123 DCHECK(info); 119 DCHECK(info);
124 120
125 DownloadManager* manager = info->request_handle.GetDownloadManager(); 121 DownloadManager* manager = info->request_handle.GetDownloadManager();
126 if (!manager) { 122 if (!manager) {
127 info->request_handle.CancelRequest(); 123 info->request_handle.CancelRequest();
128 delete info; 124 delete info;
129 return; 125 return;
130 } 126 }
131 127
132 // TODO(phajdan.jr): fix the duplication of path info below. 128 // TODO(phajdan.jr): fix the duplication of path info below.
133 info->path = info->save_info.file_path; 129 info->path = info->save_info.file_path;
134 130
135 manager->CreateDownloadItem(info); 131 manager->CreateDownloadItem(info);
136 bool hash_needed = manager->delegate()->GenerateFileHash(); 132 bool hash_needed = manager->delegate()->GenerateFileHash();
137 133
138 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 134 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
139 NewRunnableMethod(this, &DownloadFileManager::CreateDownloadFile, 135 NewRunnableMethod(this, &DownloadFileManager::CreateDownloadFile,
140 info, make_scoped_refptr(manager), hash_needed)); 136 info, make_scoped_refptr(manager), hash_needed));
141 } 137 }
142 138
143 // We don't forward an update to the UI thread here, since we want to throttle 139 // We don't forward an update to the UI thread here, since we want to throttle
144 // the UI update rate via a periodic timer. If the user has cancelled the 140 // the UI update rate via a periodic timer. If the user has cancelled the
145 // download (in the UI thread), we may receive a few more updates before the IO 141 // download (in the UI thread), we may receive a few more updates before the IO
146 // thread gets the cancel message: we just delete the data since the 142 // thread gets the cancel message: we just delete the data since the
147 // DownloadFile has been deleted. 143 // DownloadFile has been deleted.
148 void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) { 144 void DownloadFileManager::UpdateDownload(
145 DownloadId global_id, DownloadBuffer* buffer) {
149 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
150 std::vector<DownloadBuffer::Contents> contents; 147 std::vector<DownloadBuffer::Contents> contents;
151 { 148 {
152 base::AutoLock auto_lock(buffer->lock); 149 base::AutoLock auto_lock(buffer->lock);
153 contents.swap(buffer->contents); 150 contents.swap(buffer->contents);
154 } 151 }
155 152
156 DownloadFile* download_file = GetDownloadFile(id); 153 DownloadFile* download_file = GetDownloadFile(global_id);
157 bool had_error = false; 154 bool had_error = false;
158 for (size_t i = 0; i < contents.size(); ++i) { 155 for (size_t i = 0; i < contents.size(); ++i) {
159 net::IOBuffer* data = contents[i].first; 156 net::IOBuffer* data = contents[i].first;
160 const int data_len = contents[i].second; 157 const int data_len = contents[i].second;
161 if (!had_error && download_file) { 158 if (!had_error && download_file) {
162 net::Error write_result = 159 net::Error write_result =
163 download_file->AppendDataToFile(data->data(), data_len); 160 download_file->AppendDataToFile(data->data(), data_len);
164 if (write_result != net::OK) { 161 if (write_result != net::OK) {
165 // Write failed: interrupt the download. 162 // Write failed: interrupt the download.
166 DownloadManager* download_manager = download_file->GetDownloadManager(); 163 DownloadManager* download_manager = download_file->GetDownloadManager();
167 had_error = true; 164 had_error = true;
168 165
169 int64 bytes_downloaded = download_file->bytes_so_far(); 166 int64 bytes_downloaded = download_file->bytes_so_far();
170 // Calling this here in case we get more data, to avoid 167 // Calling this here in case we get more data, to avoid
171 // processing data after an error. That could lead to 168 // processing data after an error. That could lead to
172 // files that are corrupted if the later processing succeeded. 169 // files that are corrupted if the later processing succeeded.
173 CancelDownload(id); 170 CancelDownload(global_id);
174 download_file = NULL; // Was deleted in |CancelDownload|. 171 download_file = NULL; // Was deleted in |CancelDownload|.
175 172
176 if (download_manager) { 173 if (download_manager) {
177 BrowserThread::PostTask( 174 BrowserThread::PostTask(
178 BrowserThread::UI, 175 BrowserThread::UI,
179 FROM_HERE, 176 FROM_HERE,
180 NewRunnableMethod( 177 NewRunnableMethod(
181 download_manager, 178 download_manager,
182 &DownloadManager::OnDownloadError, 179 &DownloadManager::OnDownloadError,
183 id, 180 global_id.local(),
184 bytes_downloaded, 181 bytes_downloaded,
185 write_result)); 182 write_result));
186 } 183 }
187 } 184 }
188 } 185 }
189 data->Release(); 186 data->Release();
190 } 187 }
191 } 188 }
192 189
193 void DownloadFileManager::OnResponseCompleted( 190 void DownloadFileManager::OnResponseCompleted(
194 int id, 191 DownloadId global_id,
195 DownloadBuffer* buffer, 192 DownloadBuffer* buffer,
196 net::Error net_error, 193 net::Error net_error,
197 const std::string& security_info) { 194 const std::string& security_info) {
198 VLOG(20) << __FUNCTION__ << "()" << " id = " << id 195 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id
199 << " net_error = " << net_error 196 << " net_error = " << net_error
200 << " security_info = \"" << security_info << "\""; 197 << " security_info = \"" << security_info << "\"";
201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 198 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
202 delete buffer; 199 delete buffer;
203 DownloadFile* download_file = GetDownloadFile(id); 200 DownloadFile* download_file = GetDownloadFile(global_id);
204 if (!download_file) 201 if (!download_file)
205 return; 202 return;
206 203
207 download_file->Finish(); 204 download_file->Finish();
208 205
209 DownloadManager* download_manager = download_file->GetDownloadManager(); 206 DownloadManager* download_manager = download_file->GetDownloadManager();
210 if (!download_manager) { 207 if (!download_manager) {
211 CancelDownload(id); 208 CancelDownload(global_id);
212 return; 209 return;
213 } 210 }
214 211
215 std::string hash; 212 std::string hash;
216 if (!download_file->GetSha256Hash(&hash)) 213 if (!download_file->GetSha256Hash(&hash))
217 hash.clear(); 214 hash.clear();
218 215
219 // ERR_CONNECTION_CLOSED is allowed since a number of servers in the wild 216 // ERR_CONNECTION_CLOSED is allowed since a number of servers in the wild
220 // advertise a larger Content-Length than the amount of bytes in the message 217 // advertise a larger Content-Length than the amount of bytes in the message
221 // body, and then close the connection. Other browsers - IE8, Firefox 4.0.1, 218 // body, and then close the connection. Other browsers - IE8, Firefox 4.0.1,
222 // and Safari 5.0.4 - treat the download as complete in this case, so we 219 // and Safari 5.0.4 - treat the download as complete in this case, so we
223 // follow their lead. 220 // follow their lead.
224 if (net_error == net::OK || net_error == net::ERR_CONNECTION_CLOSED) { 221 if (net_error == net::OK || net_error == net::ERR_CONNECTION_CLOSED) {
225 BrowserThread::PostTask( 222 BrowserThread::PostTask(
226 BrowserThread::UI, 223 BrowserThread::UI,
227 FROM_HERE, 224 FROM_HERE,
228 NewRunnableMethod( 225 NewRunnableMethod(
229 download_manager, 226 download_manager,
230 &DownloadManager::OnResponseCompleted, 227 &DownloadManager::OnResponseCompleted,
231 id, 228 global_id.local(),
232 download_file->bytes_so_far(), 229 download_file->bytes_so_far(),
233 hash)); 230 hash));
234 } else { 231 } else {
235 BrowserThread::PostTask( 232 BrowserThread::PostTask(
236 BrowserThread::UI, 233 BrowserThread::UI,
237 FROM_HERE, 234 FROM_HERE,
238 NewRunnableMethod( 235 NewRunnableMethod(
239 download_manager, 236 download_manager,
240 &DownloadManager::OnDownloadError, 237 &DownloadManager::OnDownloadError,
241 id, 238 global_id.local(),
242 download_file->bytes_so_far(), 239 download_file->bytes_so_far(),
243 net_error)); 240 net_error));
244 } 241 }
245 // We need to keep the download around until the UI thread has finalized 242 // We need to keep the download around until the UI thread has finalized
246 // the name. 243 // the name.
247 } 244 }
248 245
249 // This method will be sent via a user action, or shutdown on the UI thread, and 246 // This method will be sent via a user action, or shutdown on the UI thread, and
250 // run on the download thread. Since this message has been sent from the UI 247 // run on the download thread. Since this message has been sent from the UI
251 // thread, the download may have already completed and won't exist in our map. 248 // thread, the download may have already completed and won't exist in our map.
252 void DownloadFileManager::CancelDownload(int id) { 249 void DownloadFileManager::CancelDownload(DownloadId global_id) {
253 VLOG(20) << __FUNCTION__ << "()" << " id = " << id; 250 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id;
254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 251 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
255 DownloadFileMap::iterator it = downloads_.find(id); 252 DownloadFileMap::iterator it = downloads_.find(global_id);
256 if (it == downloads_.end()) 253 if (it == downloads_.end())
257 return; 254 return;
258 255
259 DownloadFile* download_file = it->second; 256 DownloadFile* download_file = it->second;
260 VLOG(20) << __FUNCTION__ << "()" 257 VLOG(20) << __FUNCTION__ << "()"
261 << " download_file = " << download_file->DebugString(); 258 << " download_file = " << download_file->DebugString();
262 download_file->Cancel(); 259 download_file->Cancel();
263 260
264 EraseDownload(id); 261 EraseDownload(global_id);
265 } 262 }
266 263
267 void DownloadFileManager::CompleteDownload(int id) { 264 void DownloadFileManager::CompleteDownload(DownloadId global_id) {
268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
269 266
270 if (!ContainsKey(downloads_, id)) 267 if (!ContainsKey(downloads_, global_id))
271 return; 268 return;
272 269
273 DownloadFile* download_file = downloads_[id]; 270 DownloadFile* download_file = downloads_[global_id];
274 271
275 VLOG(20) << " " << __FUNCTION__ << "()" 272 VLOG(20) << " " << __FUNCTION__ << "()"
276 << " id = " << id 273 << " id = " << global_id
277 << " download_file = " << download_file->DebugString(); 274 << " download_file = " << download_file->DebugString();
278 275
279 download_file->Detach(); 276 download_file->Detach();
280 277
281 EraseDownload(id); 278 EraseDownload(global_id);
282 } 279 }
283 280
284 void DownloadFileManager::OnDownloadManagerShutdown(DownloadManager* manager) { 281 void DownloadFileManager::OnDownloadManagerShutdown(DownloadManager* manager) {
285 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
286 DCHECK(manager); 283 DCHECK(manager);
287 284
288 std::set<DownloadFile*> to_remove; 285 std::set<DownloadFile*> to_remove;
289 286
290 for (DownloadFileMap::iterator i = downloads_.begin(); 287 for (DownloadFileMap::iterator i = downloads_.begin();
291 i != downloads_.end(); ++i) { 288 i != downloads_.end(); ++i) {
292 DownloadFile* download_file = i->second; 289 DownloadFile* download_file = i->second;
293 if (download_file->GetDownloadManager() == manager) { 290 if (download_file->GetDownloadManager() == manager) {
294 download_file->CancelDownloadRequest(); 291 download_file->CancelDownloadRequest();
295 to_remove.insert(download_file); 292 to_remove.insert(download_file);
296 } 293 }
297 } 294 }
298 295
299 for (std::set<DownloadFile*>::iterator i = to_remove.begin(); 296 for (std::set<DownloadFile*>::iterator i = to_remove.begin();
300 i != to_remove.end(); ++i) { 297 i != to_remove.end(); ++i) {
301 downloads_.erase((*i)->id()); 298 downloads_.erase(DownloadId((*i)->GetDownloadManager(), (*i)->id()));
302 delete *i; 299 delete *i;
303 } 300 }
304 } 301 }
305 302
306 // Actions from the UI thread and run on the download thread 303 // Actions from the UI thread and run on the download thread
307 304
308 // The DownloadManager in the UI thread has provided an intermediate .crdownload 305 // The DownloadManager in the UI thread has provided an intermediate .crdownload
309 // name for the download specified by 'id'. Rename the in progress download. 306 // name for the download specified by 'id'. Rename the in progress download.
310 // 307 //
311 // There are 2 possible rename cases where this method can be called: 308 // There are 2 possible rename cases where this method can be called:
312 // 1. tmp -> foo.crdownload (not final, safe) 309 // 1. tmp -> foo.crdownload (not final, safe)
313 // 2. tmp-> Unconfirmed.xxx.crdownload (not final, dangerous) 310 // 2. tmp-> Unconfirmed.xxx.crdownload (not final, dangerous)
314 void DownloadFileManager::RenameInProgressDownloadFile( 311 void DownloadFileManager::RenameInProgressDownloadFile(
315 int id, const FilePath& full_path) { 312 DownloadId global_id, const FilePath& full_path) {
316 VLOG(20) << __FUNCTION__ << "()" << " id = " << id 313 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id
317 << " full_path = \"" << full_path.value() << "\""; 314 << " full_path = \"" << full_path.value() << "\"";
318 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
319 316
320 DownloadFile* download_file = GetDownloadFile(id); 317 DownloadFile* download_file = GetDownloadFile(global_id);
321 if (!download_file) 318 if (!download_file)
322 return; 319 return;
323 320
324 VLOG(20) << __FUNCTION__ << "()" 321 VLOG(20) << __FUNCTION__ << "()"
325 << " download_file = " << download_file->DebugString(); 322 << " download_file = " << download_file->DebugString();
326 323
327 net::Error rename_error = download_file->Rename(full_path); 324 net::Error rename_error = download_file->Rename(full_path);
328 if (net::OK != rename_error) { 325 if (net::OK != rename_error) {
329 // Error. Between the time the UI thread generated 'full_path' to the time 326 // Error. Between the time the UI thread generated 'full_path' to the time
330 // this code runs, something happened that prevents us from renaming. 327 // this code runs, something happened that prevents us from renaming.
331 CancelDownloadOnRename(id, rename_error); 328 CancelDownloadOnRename(global_id, rename_error);
332 } 329 }
333 } 330 }
334 331
335 // The DownloadManager in the UI thread has provided a final name for the 332 // The DownloadManager in the UI thread has provided a final name for the
336 // download specified by 'id'. Rename the download that's in the process 333 // download specified by 'id'. Rename the download that's in the process
337 // of completing. 334 // of completing.
338 // 335 //
339 // There are 2 possible rename cases where this method can be called: 336 // There are 2 possible rename cases where this method can be called:
340 // 1. foo.crdownload -> foo (final, safe) 337 // 1. foo.crdownload -> foo (final, safe)
341 // 2. Unconfirmed.xxx.crdownload -> xxx (final, validated) 338 // 2. Unconfirmed.xxx.crdownload -> xxx (final, validated)
342 void DownloadFileManager::RenameCompletingDownloadFile( 339 void DownloadFileManager::RenameCompletingDownloadFile(
343 int id, const FilePath& full_path, bool overwrite_existing_file) { 340 DownloadId global_id,
344 VLOG(20) << __FUNCTION__ << "()" << " id = " << id 341 const FilePath& full_path,
342 bool overwrite_existing_file) {
343 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id
345 << " overwrite_existing_file = " << overwrite_existing_file 344 << " overwrite_existing_file = " << overwrite_existing_file
346 << " full_path = \"" << full_path.value() << "\""; 345 << " full_path = \"" << full_path.value() << "\"";
347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
348 347
349 DownloadFile* download_file = GetDownloadFile(id); 348 DownloadFile* download_file = GetDownloadFile(global_id);
350 if (!download_file) 349 if (!download_file)
351 return; 350 return;
352 351
353 DCHECK(download_file->GetDownloadManager()); 352 DCHECK(download_file->GetDownloadManager());
354 DownloadManager* download_manager = download_file->GetDownloadManager(); 353 DownloadManager* download_manager = download_file->GetDownloadManager();
355 354
356 VLOG(20) << __FUNCTION__ << "()" 355 VLOG(20) << __FUNCTION__ << "()"
357 << " download_file = " << download_file->DebugString(); 356 << " download_file = " << download_file->DebugString();
358 357
359 int uniquifier = 0; 358 int uniquifier = 0;
(...skipping 10 matching lines...) Expand all
370 if (uniquifier > 0) { 369 if (uniquifier > 0) {
371 DownloadFile::AppendNumberToPath(&new_path, uniquifier); 370 DownloadFile::AppendNumberToPath(&new_path, uniquifier);
372 } 371 }
373 } 372 }
374 373
375 // Rename the file, overwriting if necessary. 374 // Rename the file, overwriting if necessary.
376 net::Error rename_error = download_file->Rename(full_path); 375 net::Error rename_error = download_file->Rename(full_path);
377 if (net::OK != rename_error) { 376 if (net::OK != rename_error) {
378 // Error. Between the time the UI thread generated 'full_path' to the time 377 // Error. Between the time the UI thread generated 'full_path' to the time
379 // this code runs, something happened that prevents us from renaming. 378 // this code runs, something happened that prevents us from renaming.
380 CancelDownloadOnRename(id, rename_error); 379 CancelDownloadOnRename(global_id, rename_error);
381 return; 380 return;
382 } 381 }
383 382
384 #if defined(OS_MACOSX) 383 #if defined(OS_MACOSX)
385 // Done here because we only want to do this once; see 384 // Done here because we only want to do this once; see
386 // http://crbug.com/13120 for details. 385 // http://crbug.com/13120 for details.
387 download_file->AnnotateWithSourceInformation(); 386 download_file->AnnotateWithSourceInformation();
388 #endif 387 #endif
389 388
390 BrowserThread::PostTask( 389 BrowserThread::PostTask(
391 BrowserThread::UI, FROM_HERE, 390 BrowserThread::UI, FROM_HERE,
392 NewRunnableMethod( 391 NewRunnableMethod(
393 download_manager, &DownloadManager::OnDownloadRenamedToFinalName, id, 392 download_manager, &DownloadManager::OnDownloadRenamedToFinalName,
394 new_path, uniquifier)); 393 global_id.local(), new_path, uniquifier));
395 } 394 }
396 395
397 // Called only from RenameInProgressDownloadFile and 396 // Called only from RenameInProgressDownloadFile and
398 // RenameCompletingDownloadFile on the FILE thread. 397 // RenameCompletingDownloadFile on the FILE thread.
399 void DownloadFileManager::CancelDownloadOnRename(int id, 398 void DownloadFileManager::CancelDownloadOnRename(
400 net::Error rename_error) { 399 DownloadId global_id, net::Error rename_error) {
401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 400 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
402 401
403 DownloadFile* download_file = GetDownloadFile(id); 402 DownloadFile* download_file = GetDownloadFile(global_id);
404 if (!download_file) 403 if (!download_file)
405 return; 404 return;
406 405
407 DownloadManager* download_manager = download_file->GetDownloadManager(); 406 DownloadManager* download_manager = download_file->GetDownloadManager();
408 if (!download_manager) { 407 if (!download_manager) {
409 // Without a download manager, we can't cancel the request normally, so we 408 // Without a download manager, we can't cancel the request normally, so we
410 // need to do it here. The normal path will also update the download 409 // need to do it here. The normal path will also update the download
411 // history before canceling the request. 410 // history before canceling the request.
412 download_file->CancelDownloadRequest(); 411 download_file->CancelDownloadRequest();
413 return; 412 return;
414 } 413 }
415 414
416 BrowserThread::PostTask( 415 BrowserThread::PostTask(
417 BrowserThread::UI, FROM_HERE, 416 BrowserThread::UI, FROM_HERE,
418 NewRunnableMethod(download_manager, 417 NewRunnableMethod(download_manager,
419 &DownloadManager::OnDownloadError, 418 &DownloadManager::OnDownloadError,
420 id, 419 global_id.local(),
421 download_file->bytes_so_far(), 420 download_file->bytes_so_far(),
422 rename_error)); 421 rename_error));
423 } 422 }
424 423
425 void DownloadFileManager::EraseDownload(int id) { 424 void DownloadFileManager::EraseDownload(DownloadId global_id) {
426 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 425 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
427 426
428 if (!ContainsKey(downloads_, id)) 427 if (!ContainsKey(downloads_, global_id))
429 return; 428 return;
430 429
431 DownloadFile* download_file = downloads_[id]; 430 DownloadFile* download_file = downloads_[global_id];
432 431
433 VLOG(20) << " " << __FUNCTION__ << "()" 432 VLOG(20) << " " << __FUNCTION__ << "()"
434 << " id = " << id 433 << " id = " << global_id
435 << " download_file = " << download_file->DebugString(); 434 << " download_file = " << download_file->DebugString();
436 435
437 downloads_.erase(id); 436 downloads_.erase(global_id);
438 437
439 delete download_file; 438 delete download_file;
440 439
441 if (downloads_.empty()) 440 if (downloads_.empty())
442 StopUpdateTimer(); 441 StopUpdateTimer();
443 } 442 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698