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

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

Issue 3347018: GTTF: Clean up DownloadFileManager (Closed)
Patch Set: shutdowns Created 10 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/download/download_file_manager.h" 5 #include "chrome/browser/download/download_file_manager.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/stl_util-inl.h" 8 #include "base/stl_util-inl.h"
9 #include "base/task.h" 9 #include "base/task.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
(...skipping 17 matching lines...) Expand all
28 #elif defined(OS_MACOSX) 28 #elif defined(OS_MACOSX)
29 #include "chrome/browser/cocoa/file_metadata.h" 29 #include "chrome/browser/cocoa/file_metadata.h"
30 #endif 30 #endif
31 31
32 namespace { 32 namespace {
33 33
34 // Throttle updates to the UI thread so that a fast moving download doesn't 34 // Throttle updates to the UI thread so that a fast moving download doesn't
35 // cause it to become unresponsive (in milliseconds). 35 // cause it to become unresponsive (in milliseconds).
36 const int kUpdatePeriodMs = 500; 36 const int kUpdatePeriodMs = 500;
37 37
38 DownloadManager* DownloadManagerForRenderViewHost(int render_process_id,
39 int render_view_id) {
40 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
41
42 TabContents* contents = tab_util::GetTabContentsByID(render_process_id,
43 render_view_id);
44 if (contents) {
45 Profile* profile = contents->profile();
46 if (profile)
47 return profile->GetDownloadManager();
48 }
49
50 return NULL;
51 }
52
38 } // namespace 53 } // namespace
39 54
40 DownloadFileManager::DownloadFileManager(ResourceDispatcherHost* rdh) 55 DownloadFileManager::DownloadFileManager(ResourceDispatcherHost* rdh)
41 : next_id_(0), 56 : next_id_(0),
42 resource_dispatcher_host_(rdh) { 57 resource_dispatcher_host_(rdh) {
43 } 58 }
44 59
45 DownloadFileManager::~DownloadFileManager() { 60 DownloadFileManager::~DownloadFileManager() {
46 // Check for clean shutdown.
47 DCHECK(downloads_.empty()); 61 DCHECK(downloads_.empty());
48 } 62 }
49 63
50 // Called during the browser shutdown process to clean up any state (open files,
51 // timers) that live on the download_thread_.
52 void DownloadFileManager::Shutdown() { 64 void DownloadFileManager::Shutdown() {
53 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 65 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
54 StopUpdateTimer();
55 ChromeThread::PostTask( 66 ChromeThread::PostTask(
56 ChromeThread::FILE, FROM_HERE, 67 ChromeThread::FILE, FROM_HERE,
57 NewRunnableMethod(this, &DownloadFileManager::OnShutdown)); 68 NewRunnableMethod(this, &DownloadFileManager::OnShutdown));
58 } 69 }
59 70
60 // Cease download thread operations.
61 void DownloadFileManager::OnShutdown() { 71 void DownloadFileManager::OnShutdown() {
62 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 72 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
73 StopUpdateTimer();
63 STLDeleteValues(&downloads_); 74 STLDeleteValues(&downloads_);
64 } 75 }
65 76
66 // Notifications sent from the download thread and run on the UI thread. 77 void DownloadFileManager::CreateDownloadFile(
78 DownloadCreateInfo* info, DownloadManager* download_manager) {
79 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
67 80
68 // Lookup the DownloadManager for this TabContents' profile and inform it of 81 scoped_ptr<DownloadFile> download_file(
69 // a new download. 82 new DownloadFile(info, download_manager));
70 // TODO(paulg): When implementing download restart via the Downloads tab, 83 if (!download_file->Initialize()) {
71 // there will be no 'render_process_id' or 'render_view_id'.
72 void DownloadFileManager::OnStartDownload(DownloadCreateInfo* info) {
73 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
74 DownloadManager* manager = DownloadManagerFromRenderIds(info->child_id,
75 info->render_view_id);
76 if (!manager) {
77 ChromeThread::PostTask( 84 ChromeThread::PostTask(
78 ChromeThread::IO, FROM_HERE, 85 ChromeThread::IO, FROM_HERE,
79 NewRunnableFunction(&download_util::CancelDownloadRequest, 86 NewRunnableFunction(&download_util::CancelDownloadRequest,
80 resource_dispatcher_host_, 87 resource_dispatcher_host_,
81 info->child_id, 88 info->child_id,
82 info->request_id)); 89 info->request_id));
83 delete info; 90 delete info;
84 return; 91 return;
85 } 92 }
86 93
94 DCHECK(GetDownloadFile(info->download_id) == NULL);
95 downloads_[info->download_id] = download_file.release();
96 // TODO(phajdan.jr): fix the duplication of path info below.
97 info->path = info->save_info.file_path;
98
99 // The file is now ready, we can un-pause the request and start saving data.
100 ChromeThread::PostTask(
101 ChromeThread::IO, FROM_HERE,
102 NewRunnableMethod(this, &DownloadFileManager::ResumeDownloadRequest,
103 info->child_id, info->request_id));
104
87 StartUpdateTimer(); 105 StartUpdateTimer();
88 106
89 // Add the download manager to our request maps for future updates. We want to 107 ChromeThread::PostTask(
90 // be able to cancel all in progress downloads when a DownloadManager is 108 ChromeThread::UI, FROM_HERE,
91 // deleted, such as when a profile is closed. We also want to be able to look 109 NewRunnableMethod(download_manager,
92 // up the DownloadManager associated with a given request without having to 110 &DownloadManager::StartDownload, info));
93 // rely on using tab information, since a tab may be closed while a download
94 // initiated from that tab is still in progress.
95 DownloadRequests& downloads = requests_[manager];
96 downloads.insert(info->download_id);
97
98 // TODO(paulg): The manager will exist when restarts are implemented.
99 DownloadManagerMap::iterator dit = managers_.find(info->download_id);
100 if (dit == managers_.end())
101 managers_[info->download_id] = manager;
102 else
103 NOTREACHED();
104
105 // StartDownload will clean up |info|.
106 manager->StartDownload(info);
107 } 111 }
108 112
109 // Update the Download Manager with the finish state, and remove the request 113 void DownloadFileManager::ResumeDownloadRequest(int child_id, int request_id) {
110 // tracking entries. 114 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
111 void DownloadFileManager::OnDownloadFinished(int id, 115
112 int64 bytes_so_far) { 116 // This balances the pause in DownloadResourceHandler::OnResponseStarted.
113 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 117 resource_dispatcher_host_->PauseRequest(child_id, request_id, false);
114 DownloadManager* manager = GetDownloadManager(id);
115 if (manager)
116 manager->DownloadFinished(id, bytes_so_far);
117 RemoveDownload(id, manager);
118 RemoveDownloadFromUIProgress(id);
119 } 118 }
120 119
121 // Lookup one in-progress download.
122 DownloadFile* DownloadFileManager::GetDownloadFile(int id) { 120 DownloadFile* DownloadFileManager::GetDownloadFile(int id) {
123 DownloadFileMap::iterator it = downloads_.find(id); 121 DownloadFileMap::iterator it = downloads_.find(id);
124 return it == downloads_.end() ? NULL : it->second; 122 return it == downloads_.end() ? NULL : it->second;
125 } 123 }
126 124
127 // The UI progress is updated on the file thread and removed on the UI thread.
128 void DownloadFileManager::RemoveDownloadFromUIProgress(int id) {
129 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
130 AutoLock lock(progress_lock_);
131 if (ui_progress_.find(id) != ui_progress_.end())
132 ui_progress_.erase(id);
133 }
134
135 // Throttle updates to the UI thread by only posting update notifications at a
136 // regularly controlled interval.
137 void DownloadFileManager::StartUpdateTimer() { 125 void DownloadFileManager::StartUpdateTimer() {
138 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 126 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
139 if (!update_timer_.IsRunning()) { 127 if (!update_timer_.IsRunning()) {
140 update_timer_.Start(base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), 128 update_timer_.Start(base::TimeDelta::FromMilliseconds(kUpdatePeriodMs),
141 this, &DownloadFileManager::UpdateInProgressDownloads); 129 this, &DownloadFileManager::UpdateInProgressDownloads);
142 } 130 }
143 } 131 }
144 132
145 void DownloadFileManager::StopUpdateTimer() { 133 void DownloadFileManager::StopUpdateTimer() {
146 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 134 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
147 update_timer_.Stop(); 135 update_timer_.Stop();
148 } 136 }
149 137
150 // Our periodic timer has fired so send the UI thread updates on all in progress
151 // downloads.
152 void DownloadFileManager::UpdateInProgressDownloads() { 138 void DownloadFileManager::UpdateInProgressDownloads() {
153 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 139 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
154 AutoLock lock(progress_lock_); 140 for (DownloadFileMap::iterator i = downloads_.begin();
155 ProgressMap::iterator it = ui_progress_.begin(); 141 i != downloads_.end(); ++i) {
156 for (; it != ui_progress_.end(); ++it) { 142 int id = i->first;
157 const int id = it->first; 143 DownloadFile* download_file = i->second;
158 DownloadManager* manager = GetDownloadManager(id); 144 DownloadManager* manager = download_file->GetDownloadManager();
159 if (manager) 145 if (manager) {
160 manager->UpdateDownload(id, it->second); 146 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE,
147 NewRunnableMethod(manager, &DownloadManager::UpdateDownload,
148 id, download_file->bytes_so_far()));
149 }
161 } 150 }
162 } 151 }
163 152
164 // Called on the IO thread once the ResourceDispatcherHost has decided that a 153 // Called on the IO thread once the ResourceDispatcherHost has decided that a
165 // request is a download. 154 // request is a download.
166 int DownloadFileManager::GetNextId() { 155 int DownloadFileManager::GetNextId() {
167 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 156 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
168 return next_id_++; 157 return next_id_++;
169 } 158 }
170 159
171 // Notifications sent from the IO thread and run on the download thread:
172
173 // The IO thread created 'info', but the download thread (this method) uses it
174 // to create a DownloadFile, then passes 'info' to the UI thread where it is
175 // finally consumed and deleted.
176 void DownloadFileManager::StartDownload(DownloadCreateInfo* info) { 160 void DownloadFileManager::StartDownload(DownloadCreateInfo* info) {
177 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 161 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
178 DCHECK(info); 162 DCHECK(info);
179 163
180 DownloadFile* download = new DownloadFile(info); 164 DownloadManager* manager = DownloadManagerForRenderViewHost(
181 if (!download->Initialize()) { 165 info->child_id, info->render_view_id);
182 // Couldn't open, cancel the operation. The UI thread does not yet know 166 if (!manager) {
183 // about this download so we have to clean up 'info'. We need to get back
184 // to the IO thread to cancel the network request and CancelDownloadRequest
185 // on the UI thread is the safe way to do that.
186 ChromeThread::PostTask( 167 ChromeThread::PostTask(
187 ChromeThread::IO, FROM_HERE, 168 ChromeThread::IO, FROM_HERE,
188 NewRunnableFunction(&download_util::CancelDownloadRequest, 169 NewRunnableFunction(&download_util::CancelDownloadRequest,
189 resource_dispatcher_host_, 170 resource_dispatcher_host_,
190 info->child_id, 171 info->child_id,
191 info->request_id)); 172 info->request_id));
192 delete info; 173 delete info;
193 delete download;
194 return; 174 return;
195 } 175 }
196 176
197 DCHECK(GetDownloadFile(info->download_id) == NULL); 177 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
198 downloads_[info->download_id] = download; 178 NewRunnableMethod(this, &DownloadFileManager::CreateDownloadFile,
199 // TODO(phajdan.jr): fix the duplication of path info below. 179 info, manager));
200 info->path = info->save_info.file_path;
201 {
202 AutoLock lock(progress_lock_);
203 ui_progress_[info->download_id] = info->received_bytes;
204 }
205
206 ChromeThread::PostTask(
207 ChromeThread::UI, FROM_HERE,
208 NewRunnableMethod(this, &DownloadFileManager::OnStartDownload, info));
209 } 180 }
210 181
211 // We don't forward an update to the UI thread here, since we want to throttle 182 // We don't forward an update to the UI thread here, since we want to throttle
212 // the UI update rate via a periodic timer. If the user has cancelled the 183 // the UI update rate via a periodic timer. If the user has cancelled the
213 // download (in the UI thread), we may receive a few more updates before the IO 184 // download (in the UI thread), we may receive a few more updates before the IO
214 // thread gets the cancel message: we just delete the data since the 185 // thread gets the cancel message: we just delete the data since the
215 // DownloadFile has been deleted. 186 // DownloadFile has been deleted.
216 void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) { 187 void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) {
217 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 188 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
218 std::vector<DownloadBuffer::Contents> contents; 189 std::vector<DownloadBuffer::Contents> contents;
219 { 190 {
220 AutoLock auto_lock(buffer->lock); 191 AutoLock auto_lock(buffer->lock);
221 contents.swap(buffer->contents); 192 contents.swap(buffer->contents);
222 } 193 }
223 194
224 // Keep track of how many bytes we have successfully saved to update
225 // our progress status in the UI.
226 int64 progress_bytes = 0;
227
228 DownloadFile* download = GetDownloadFile(id); 195 DownloadFile* download = GetDownloadFile(id);
229 for (size_t i = 0; i < contents.size(); ++i) { 196 for (size_t i = 0; i < contents.size(); ++i) {
230 net::IOBuffer* data = contents[i].first; 197 net::IOBuffer* data = contents[i].first;
231 const int data_len = contents[i].second; 198 const int data_len = contents[i].second;
232 if (download) { 199 if (download)
233 if (download->AppendDataToFile(data->data(), data_len)) 200 download->AppendDataToFile(data->data(), data_len);
234 progress_bytes += data_len;
235 }
236 data->Release(); 201 data->Release();
237 } 202 }
238
239 if (download) {
240 AutoLock lock(progress_lock_);
241 ui_progress_[download->id()] += progress_bytes;
242 }
243 } 203 }
244 204
245 void DownloadFileManager::DownloadFinished(int id, DownloadBuffer* buffer) { 205 void DownloadFileManager::DownloadFinished(int id, DownloadBuffer* buffer) {
246 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 206 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
247 delete buffer; 207 delete buffer;
248 DownloadFileMap::iterator it = downloads_.find(id); 208 DownloadFileMap::iterator it = downloads_.find(id);
249 if (it != downloads_.end()) { 209 if (it != downloads_.end()) {
250 DownloadFile* download = it->second; 210 DownloadFile* download = it->second;
251 download->Finish(); 211 download->Finish();
252 212
253 int64 download_size = -1; 213 DownloadManager* download_manager = download->GetDownloadManager();
254 { 214 if (download_manager) {
255 AutoLock lock(progress_lock_); 215 ChromeThread::PostTask(
256 download_size = ui_progress_[download->id()]; 216 ChromeThread::UI, FROM_HERE,
217 NewRunnableMethod(
218 download_manager, &DownloadManager::DownloadFinished,
219 id, download->bytes_so_far()));
257 } 220 }
258 221
259 ChromeThread::PostTask(
260 ChromeThread::UI, FROM_HERE,
261 NewRunnableMethod(
262 this, &DownloadFileManager::OnDownloadFinished,
263 id, download_size));
264
265 // We need to keep the download around until the UI thread has finalized 222 // We need to keep the download around until the UI thread has finalized
266 // the name. 223 // the name.
267 if (download->path_renamed()) { 224 if (download->path_renamed()) {
268 downloads_.erase(it); 225 downloads_.erase(it);
269 delete download; 226 delete download;
270 } 227 }
271 } 228 }
272 229
273 if (downloads_.empty()) 230 if (downloads_.empty())
274 ChromeThread::PostTask( 231 StopUpdateTimer();
275 ChromeThread::UI, FROM_HERE,
276 NewRunnableMethod(this, &DownloadFileManager::StopUpdateTimer));
277 } 232 }
278 233
279 // This method will be sent via a user action, or shutdown on the UI thread, and 234 // This method will be sent via a user action, or shutdown on the UI thread, and
280 // run on the download thread. Since this message has been sent from the UI 235 // run on the download thread. Since this message has been sent from the UI
281 // thread, the download may have already completed and won't exist in our map. 236 // thread, the download may have already completed and won't exist in our map.
282 void DownloadFileManager::CancelDownload(int id) { 237 void DownloadFileManager::CancelDownload(int id) {
283 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 238 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
284 DownloadFileMap::iterator it = downloads_.find(id); 239 DownloadFileMap::iterator it = downloads_.find(id);
285 if (it != downloads_.end()) { 240 if (it != downloads_.end()) {
286 DownloadFile* download = it->second; 241 DownloadFile* download = it->second;
287 download->Cancel(); 242 download->Cancel();
288 243
289 ChromeThread::PostTask(
290 ChromeThread::UI, FROM_HERE,
291 NewRunnableMethod(
292 this, &DownloadFileManager::RemoveDownloadFromUIProgress,
293 download->id()));
294
295 if (download->path_renamed()) { 244 if (download->path_renamed()) {
296 downloads_.erase(it); 245 downloads_.erase(it);
297 delete download; 246 delete download;
298 } 247 }
299 } 248 }
300 249
301 if (downloads_.empty()) { 250 if (downloads_.empty())
302 ChromeThread::PostTask( 251 StopUpdateTimer();
303 ChromeThread::UI, FROM_HERE, 252 }
304 NewRunnableMethod(this, &DownloadFileManager::StopUpdateTimer)); 253
254 void DownloadFileManager::OnDownloadManagerShutdown(DownloadManager* manager) {
255 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
256 DCHECK(manager);
257
258 for (DownloadFileMap::iterator i = downloads_.begin();
259 i != downloads_.end(); ++i) {
260 DownloadFile* download_file = i->second;
261 if (download_file->GetDownloadManager() == manager)
262 download_file->OnDownloadManagerShutdown();
305 } 263 }
306 } 264 }
307 265
308 // Relate a download ID to its owning DownloadManager.
309 DownloadManager* DownloadFileManager::GetDownloadManager(int download_id) {
310 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
311 DownloadManagerMap::iterator it = managers_.find(download_id);
312 if (it != managers_.end())
313 return it->second;
314 return NULL;
315 }
316
317 // Utility function for look up table maintenance, called on the UI thread.
318 // A manager may have multiple downloads in progress, so we just look up the
319 // one download (id) and remove it from the set, and remove the set if it
320 // becomes empty.
321 void DownloadFileManager::RemoveDownload(int id, DownloadManager* manager) {
322 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
323 if (manager) {
324 RequestMap::iterator it = requests_.find(manager);
325 if (it != requests_.end()) {
326 DownloadRequests& downloads = it->second;
327 DownloadRequests::iterator rit = downloads.find(id);
328 if (rit != downloads.end())
329 downloads.erase(rit);
330 if (downloads.empty())
331 requests_.erase(it);
332 }
333 }
334
335 // A download can only have one manager, so remove it if it exists.
336 DownloadManagerMap::iterator dit = managers_.find(id);
337 if (dit != managers_.end())
338 managers_.erase(dit);
339 }
340
341 // Utility function for converting request IDs to a TabContents. Must be called
342 // only on the UI thread since Profile operations may create UI objects, such as
343 // the first call to profile->GetDownloadManager().
344 // static
345 DownloadManager* DownloadFileManager::DownloadManagerFromRenderIds(
346 int render_process_id, int render_view_id) {
347 TabContents* contents = tab_util::GetTabContentsByID(render_process_id,
348 render_view_id);
349 if (contents) {
350 Profile* profile = contents->profile();
351 if (profile)
352 return profile->GetDownloadManager();
353 }
354
355 return NULL;
356 }
357
358 // Called by DownloadManagers in their destructor, and only on the UI thread.
359 void DownloadFileManager::RemoveDownloadManager(DownloadManager* manager) {
360 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
361 DCHECK(manager);
362 RequestMap::iterator it = requests_.find(manager);
363 if (it == requests_.end())
364 return;
365
366 const DownloadRequests& requests = it->second;
367 DownloadRequests::const_iterator i = requests.begin();
368 for (; i != requests.end(); ++i) {
369 DownloadManagerMap::iterator dit = managers_.find(*i);
370 if (dit != managers_.end()) {
371 DCHECK(dit->second == manager);
372 managers_.erase(dit);
373 }
374 }
375
376 requests_.erase(it);
377 }
378
379 // Actions from the UI thread and run on the download thread 266 // Actions from the UI thread and run on the download thread
380 267
381 // Open a download, or show it in a file explorer window. We run on this 268 // Open a download, or show it in a file explorer window. We run on this
382 // thread to avoid blocking the UI with (potentially) slow Shell operations. 269 // thread to avoid blocking the UI with (potentially) slow Shell operations.
383 // TODO(paulg): File 'stat' operations. 270 // TODO(paulg): File 'stat' operations.
384 #if !defined(OS_MACOSX) 271 #if !defined(OS_MACOSX)
385 void DownloadFileManager::OnShowDownloadInShell(const FilePath& full_path) { 272 void DownloadFileManager::OnShowDownloadInShell(const FilePath& full_path) {
386 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 273 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
387 platform_util::ShowItemInFolder(full_path); 274 platform_util::ShowItemInFolder(full_path);
388 } 275 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 if (need_delete_crdownload) 352 if (need_delete_crdownload)
466 download->DeleteCrDownload(); 353 download->DeleteCrDownload();
467 354
468 // If the download has completed before we got this final name, we remove it 355 // If the download has completed before we got this final name, we remove it
469 // from our in progress map. 356 // from our in progress map.
470 if (!download->in_progress()) { 357 if (!download->in_progress()) {
471 downloads_.erase(id); 358 downloads_.erase(id);
472 delete download; 359 delete download;
473 } 360 }
474 361
475 if (downloads_.empty()) { 362 if (downloads_.empty())
476 ChromeThread::PostTask( 363 StopUpdateTimer();
477 ChromeThread::UI, FROM_HERE,
478 NewRunnableMethod(this, &DownloadFileManager::StopUpdateTimer));
479 }
480 } 364 }
481 365
482 // Called only from OnFinalDownloadName or OnIntermediateDownloadName 366 // Called only from OnFinalDownloadName or OnIntermediateDownloadName
483 // on the FILE thread. 367 // on the FILE thread.
484 void DownloadFileManager::CancelDownloadOnRename(int id) { 368 void DownloadFileManager::CancelDownloadOnRename(int id) {
485 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 369 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
486 370
487 DownloadFile* download = GetDownloadFile(id); 371 DownloadFile* download = GetDownloadFile(id);
488 if (!download) 372 if (!download)
489 return; 373 return;
490 374
491 DownloadManagerMap::iterator dmit = managers_.find(download->id()); 375 DownloadManager* download_manager = download->GetDownloadManager();
492 if (dmit != managers_.end()) { 376 if (!download_manager) {
493 DownloadManager* dlm = dmit->second;
494 ChromeThread::PostTask(
495 ChromeThread::UI, FROM_HERE,
496 NewRunnableMethod(dlm, &DownloadManager::DownloadCancelled, id));
497 } else {
498 download->CancelDownloadRequest(resource_dispatcher_host_); 377 download->CancelDownloadRequest(resource_dispatcher_host_);
378 return;
499 } 379 }
380
381 ChromeThread::PostTask(
382 ChromeThread::UI, FROM_HERE,
383 NewRunnableMethod(download_manager,
384 &DownloadManager::DownloadCancelled, id));
500 } 385 }
OLDNEW
« no previous file with comments | « chrome/browser/download/download_file_manager.h ('k') | chrome/browser/download/download_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698