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

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

Issue 3245005: GTTF: Clean up DownloadFileManager (Closed)
Patch Set: fixes 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
87 StartUpdateTimer(); 99 StartUpdateTimer();
88 100
89 // Add the download manager to our request maps for future updates. We want to 101 ChromeThread::PostTask(
90 // be able to cancel all in progress downloads when a DownloadManager is 102 ChromeThread::UI, FROM_HERE,
91 // deleted, such as when a profile is closed. We also want to be able to look 103 NewRunnableMethod(download_manager,
92 // up the DownloadManager associated with a given request without having to 104 &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 } 105 }
108 106
109 // Update the Download Manager with the finish state, and remove the request
110 // tracking entries.
111 void DownloadFileManager::OnDownloadFinished(int id,
112 int64 bytes_so_far) {
113 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
114 DownloadManager* manager = GetDownloadManager(id);
115 if (manager)
116 manager->DownloadFinished(id, bytes_so_far);
117 RemoveDownload(id, manager);
118 RemoveDownloadFromUIProgress(id);
119 }
120
121 // Lookup one in-progress download.
122 DownloadFile* DownloadFileManager::GetDownloadFile(int id) { 107 DownloadFile* DownloadFileManager::GetDownloadFile(int id) {
123 DownloadFileMap::iterator it = downloads_.find(id); 108 DownloadFileMap::iterator it = downloads_.find(id);
124 return it == downloads_.end() ? NULL : it->second; 109 return it == downloads_.end() ? NULL : it->second;
125 } 110 }
126 111
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() { 112 void DownloadFileManager::StartUpdateTimer() {
138 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 113 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
139 if (!update_timer_.IsRunning()) { 114 if (!update_timer_.IsRunning()) {
140 update_timer_.Start(base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), 115 update_timer_.Start(base::TimeDelta::FromMilliseconds(kUpdatePeriodMs),
141 this, &DownloadFileManager::UpdateInProgressDownloads); 116 this, &DownloadFileManager::UpdateInProgressDownloads);
142 } 117 }
143 } 118 }
144 119
145 void DownloadFileManager::StopUpdateTimer() { 120 void DownloadFileManager::StopUpdateTimer() {
146 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 121 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
147 update_timer_.Stop(); 122 update_timer_.Stop();
148 } 123 }
149 124
150 // Our periodic timer has fired so send the UI thread updates on all in progress
151 // downloads.
152 void DownloadFileManager::UpdateInProgressDownloads() { 125 void DownloadFileManager::UpdateInProgressDownloads() {
153 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 126 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
154 AutoLock lock(progress_lock_); 127 for (DownloadFileMap::iterator i = downloads_.begin();
155 ProgressMap::iterator it = ui_progress_.begin(); 128 i != downloads_.end(); ++i) {
156 for (; it != ui_progress_.end(); ++it) { 129 int id = i->first;
157 const int id = it->first; 130 DownloadFile* download_file = i->second;
158 DownloadManager* manager = GetDownloadManager(id); 131 DownloadManager* manager = download_file->GetDownloadManager();
159 if (manager) 132 if (manager) {
160 manager->UpdateDownload(id, it->second); 133 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE,
134 NewRunnableMethod(manager, &DownloadManager::UpdateDownload,
135 id, download_file->bytes_so_far()));
136 }
161 } 137 }
162 } 138 }
163 139
164 // Called on the IO thread once the ResourceDispatcherHost has decided that a 140 // Called on the IO thread once the ResourceDispatcherHost has decided that a
165 // request is a download. 141 // request is a download.
166 int DownloadFileManager::GetNextId() { 142 int DownloadFileManager::GetNextId() {
167 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 143 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
168 return next_id_++; 144 return next_id_++;
169 } 145 }
170 146
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) { 147 void DownloadFileManager::StartDownload(DownloadCreateInfo* info) {
177 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 148 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
178 DCHECK(info); 149 DCHECK(info);
179 150
180 DownloadFile* download = new DownloadFile(info); 151 DownloadManager* manager = DownloadManagerForRenderViewHost(
181 if (!download->Initialize()) { 152 info->child_id, info->render_view_id);
182 // Couldn't open, cancel the operation. The UI thread does not yet know 153 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( 154 ChromeThread::PostTask(
187 ChromeThread::IO, FROM_HERE, 155 ChromeThread::IO, FROM_HERE,
188 NewRunnableFunction(&download_util::CancelDownloadRequest, 156 NewRunnableFunction(&download_util::CancelDownloadRequest,
189 resource_dispatcher_host_, 157 resource_dispatcher_host_,
190 info->child_id, 158 info->child_id,
191 info->request_id)); 159 info->request_id));
192 delete info; 160 delete info;
193 delete download;
194 return; 161 return;
195 } 162 }
196 163
197 DCHECK(GetDownloadFile(info->download_id) == NULL); 164 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
198 downloads_[info->download_id] = download; 165 NewRunnableMethod(this, &DownloadFileManager::CreateDownloadFile,
199 // TODO(phajdan.jr): fix the duplication of path info below. 166 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 } 167 }
210 168
211 // We don't forward an update to the UI thread here, since we want to throttle 169 // 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 170 // 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 171 // 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 172 // thread gets the cancel message: we just delete the data since the
215 // DownloadFile has been deleted. 173 // DownloadFile has been deleted.
216 void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) { 174 void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) {
217 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 175 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
218 std::vector<DownloadBuffer::Contents> contents; 176 std::vector<DownloadBuffer::Contents> contents;
219 { 177 {
220 AutoLock auto_lock(buffer->lock); 178 AutoLock auto_lock(buffer->lock);
221 contents.swap(buffer->contents); 179 contents.swap(buffer->contents);
222 } 180 }
223 181
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); 182 DownloadFile* download = GetDownloadFile(id);
229 for (size_t i = 0; i < contents.size(); ++i) { 183 for (size_t i = 0; i < contents.size(); ++i) {
230 net::IOBuffer* data = contents[i].first; 184 net::IOBuffer* data = contents[i].first;
231 const int data_len = contents[i].second; 185 const int data_len = contents[i].second;
232 if (download) { 186 if (download)
233 if (download->AppendDataToFile(data->data(), data_len)) 187 download->AppendDataToFile(data->data(), data_len);
234 progress_bytes += data_len;
235 }
236 data->Release(); 188 data->Release();
237 } 189 }
238
239 if (download) {
240 AutoLock lock(progress_lock_);
241 ui_progress_[download->id()] += progress_bytes;
242 }
243 } 190 }
244 191
245 void DownloadFileManager::DownloadFinished(int id, DownloadBuffer* buffer) { 192 void DownloadFileManager::DownloadFinished(int id, DownloadBuffer* buffer) {
246 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 193 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
247 delete buffer; 194 delete buffer;
248 DownloadFileMap::iterator it = downloads_.find(id); 195 DownloadFileMap::iterator it = downloads_.find(id);
249 if (it != downloads_.end()) { 196 if (it != downloads_.end()) {
250 DownloadFile* download = it->second; 197 DownloadFile* download = it->second;
251 download->Finish(); 198 download->Finish();
252 199
253 int64 download_size = -1; 200 DownloadManager* download_manager = download->GetDownloadManager();
254 { 201 if (download_manager) {
255 AutoLock lock(progress_lock_); 202 ChromeThread::PostTask(
256 download_size = ui_progress_[download->id()]; 203 ChromeThread::UI, FROM_HERE,
204 NewRunnableMethod(
205 download_manager, &DownloadManager::DownloadFinished,
206 id, download->bytes_so_far()));
257 } 207 }
258 208
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 209 // We need to keep the download around until the UI thread has finalized
266 // the name. 210 // the name.
267 if (download->path_renamed()) { 211 if (download->path_renamed()) {
268 downloads_.erase(it); 212 downloads_.erase(it);
269 delete download; 213 delete download;
270 } 214 }
271 } 215 }
272 216
273 if (downloads_.empty()) 217 if (downloads_.empty())
274 ChromeThread::PostTask( 218 StopUpdateTimer();
275 ChromeThread::UI, FROM_HERE,
276 NewRunnableMethod(this, &DownloadFileManager::StopUpdateTimer));
277 } 219 }
278 220
279 // This method will be sent via a user action, or shutdown on the UI thread, and 221 // 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 222 // 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. 223 // thread, the download may have already completed and won't exist in our map.
282 void DownloadFileManager::CancelDownload(int id) { 224 void DownloadFileManager::CancelDownload(int id) {
283 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 225 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
284 DownloadFileMap::iterator it = downloads_.find(id); 226 DownloadFileMap::iterator it = downloads_.find(id);
285 if (it != downloads_.end()) { 227 if (it != downloads_.end()) {
286 DownloadFile* download = it->second; 228 DownloadFile* download = it->second;
287 download->Cancel(); 229 download->Cancel();
288 230
289 ChromeThread::PostTask(
290 ChromeThread::UI, FROM_HERE,
291 NewRunnableMethod(
292 this, &DownloadFileManager::RemoveDownloadFromUIProgress,
293 download->id()));
294
295 if (download->path_renamed()) { 231 if (download->path_renamed()) {
296 downloads_.erase(it); 232 downloads_.erase(it);
297 delete download; 233 delete download;
298 } 234 }
299 } 235 }
300 236
301 if (downloads_.empty()) { 237 if (downloads_.empty())
302 ChromeThread::PostTask( 238 StopUpdateTimer();
303 ChromeThread::UI, FROM_HERE, 239 }
304 NewRunnableMethod(this, &DownloadFileManager::StopUpdateTimer)); 240
241 void DownloadFileManager::OnDownloadManagerShutdown(DownloadManager* manager) {
242 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
243 DCHECK(manager);
244
245 for (DownloadFileMap::iterator i = downloads_.begin();
246 i != downloads_.end(); ++i) {
247 DownloadFile* download_file = i->second;
248 if (download_file->GetDownloadManager() == manager)
249 download_file->OnDownloadManagerShutdown();
305 } 250 }
306 } 251 }
307 252
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 253 // Actions from the UI thread and run on the download thread
380 254
381 // Open a download, or show it in a file explorer window. We run on this 255 // 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. 256 // thread to avoid blocking the UI with (potentially) slow Shell operations.
383 // TODO(paulg): File 'stat' operations. 257 // TODO(paulg): File 'stat' operations.
384 #if !defined(OS_MACOSX) 258 #if !defined(OS_MACOSX)
385 void DownloadFileManager::OnShowDownloadInShell(const FilePath& full_path) { 259 void DownloadFileManager::OnShowDownloadInShell(const FilePath& full_path) {
386 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 260 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
387 platform_util::ShowItemInFolder(full_path); 261 platform_util::ShowItemInFolder(full_path);
388 } 262 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 if (need_delete_crdownload) 339 if (need_delete_crdownload)
466 download->DeleteCrDownload(); 340 download->DeleteCrDownload();
467 341
468 // If the download has completed before we got this final name, we remove it 342 // If the download has completed before we got this final name, we remove it
469 // from our in progress map. 343 // from our in progress map.
470 if (!download->in_progress()) { 344 if (!download->in_progress()) {
471 downloads_.erase(id); 345 downloads_.erase(id);
472 delete download; 346 delete download;
473 } 347 }
474 348
475 if (downloads_.empty()) { 349 if (downloads_.empty())
476 ChromeThread::PostTask( 350 StopUpdateTimer();
477 ChromeThread::UI, FROM_HERE,
478 NewRunnableMethod(this, &DownloadFileManager::StopUpdateTimer));
479 }
480 } 351 }
481 352
482 // Called only from OnFinalDownloadName or OnIntermediateDownloadName 353 // Called only from OnFinalDownloadName or OnIntermediateDownloadName
483 // on the FILE thread. 354 // on the FILE thread.
484 void DownloadFileManager::CancelDownloadOnRename(int id) { 355 void DownloadFileManager::CancelDownloadOnRename(int id) {
485 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 356 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
486 357
487 DownloadFile* download = GetDownloadFile(id); 358 DownloadFile* download = GetDownloadFile(id);
488 if (!download) 359 if (!download)
489 return; 360 return;
490 361
491 DownloadManagerMap::iterator dmit = managers_.find(download->id()); 362 DownloadManager* download_manager = download->GetDownloadManager();
492 if (dmit != managers_.end()) { 363 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_); 364 download->CancelDownloadRequest(resource_dispatcher_host_);
365 return;
499 } 366 }
367
368 ChromeThread::PostTask(
369 ChromeThread::UI, FROM_HERE,
370 NewRunnableMethod(download_manager,
371 &DownloadManager::DownloadCancelled, id));
500 } 372 }
OLDNEW
« no previous file with comments | « chrome/browser/download/download_file_manager.h ('k') | chrome/browser/download/download_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698