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/download/download_path_reservation_tracker.h" | 5 #include "chrome/browser/download/download_path_reservation_tracker.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 *path = dir.Append(truncated + ext); | 140 *path = dir.Append(truncated + ext); |
141 return true; | 141 return true; |
142 } | 142 } |
143 | 143 |
144 // Called on the FILE thread to reserve a download path. This method: | 144 // Called on the FILE thread to reserve a download path. This method: |
145 // - Creates directory |default_download_path| if it doesn't exist. | 145 // - Creates directory |default_download_path| if it doesn't exist. |
146 // - Verifies that the parent directory of |suggested_path| exists and is | 146 // - Verifies that the parent directory of |suggested_path| exists and is |
147 // writeable. | 147 // writeable. |
148 // - Truncates the suggested name if it exceeds the filesystem's limit. | 148 // - Truncates the suggested name if it exceeds the filesystem's limit. |
149 // - Uniquifies |suggested_path| if |should_uniquify_path| is true. | 149 // - Uniquifies |suggested_path| if |should_uniquify_path| is true. |
150 // - Schedules |callback| on the UI thread with the reserved path and a flag | 150 // - Returns true if |reserved_path| has been successfully verified. |
151 // indicating whether the returned path has been successfully verified. | 151 bool CreateReservation( |
152 void CreateReservation( | |
153 ReservationKey key, | 152 ReservationKey key, |
154 const base::FilePath& suggested_path, | 153 const base::FilePath& suggested_path, |
155 const base::FilePath& default_download_path, | 154 const base::FilePath& default_download_path, |
156 bool create_directory, | 155 bool create_directory, |
157 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | 156 DownloadPathReservationTracker::FilenameConflictAction conflict_action, |
158 const DownloadPathReservationTracker::ReservedPathCallback& callback) { | 157 base::FilePath* reserved_path) { |
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
160 DCHECK(suggested_path.IsAbsolute()); | 159 DCHECK(suggested_path.IsAbsolute()); |
161 | 160 |
162 // Create a reservation map if one doesn't exist. It will be automatically | 161 // Create a reservation map if one doesn't exist. It will be automatically |
163 // deleted when all the reservations are revoked. | 162 // deleted when all the reservations are revoked. |
164 if (g_reservation_map == NULL) | 163 if (g_reservation_map == NULL) |
165 g_reservation_map = new ReservationMap; | 164 g_reservation_map = new ReservationMap; |
166 | 165 |
167 ReservationMap& reservations = *g_reservation_map; | 166 ReservationMap& reservations = *g_reservation_map; |
168 DCHECK(!ContainsKey(reservations, key)); | 167 DCHECK(!ContainsKey(reservations, key)); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 has_conflicts = false; | 235 has_conflicts = false; |
237 break; | 236 break; |
238 } | 237 } |
239 } | 238 } |
240 } | 239 } |
241 } | 240 } |
242 } | 241 } |
243 | 242 |
244 reservations[key] = target_path; | 243 reservations[key] = target_path; |
245 bool verified = (is_path_writeable && !has_conflicts && !name_too_long); | 244 bool verified = (is_path_writeable && !has_conflicts && !name_too_long); |
246 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 245 *reserved_path = target_path; |
247 base::Bind(callback, target_path, verified)); | 246 return verified; |
248 } | 247 } |
249 | 248 |
250 // Called on the FILE thread to update the path of the reservation associated | 249 // Called on the FILE thread to update the path of the reservation associated |
251 // with |key| to |new_path|. | 250 // with |key| to |new_path|. |
252 void UpdateReservation(ReservationKey key, const base::FilePath& new_path) { | 251 void UpdateReservation(ReservationKey key, const base::FilePath& new_path) { |
253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
254 DCHECK(g_reservation_map != NULL); | 253 DCHECK(g_reservation_map != NULL); |
255 ReservationMap::iterator iter = g_reservation_map->find(key); | 254 ReservationMap::iterator iter = g_reservation_map->find(key); |
256 if (iter != g_reservation_map->end()) { | 255 if (iter != g_reservation_map->end()) { |
257 iter->second = new_path; | 256 iter->second = new_path; |
(...skipping 12 matching lines...) Expand all Loading... |
270 DCHECK(g_reservation_map != NULL); | 269 DCHECK(g_reservation_map != NULL); |
271 DCHECK(ContainsKey(*g_reservation_map, key)); | 270 DCHECK(ContainsKey(*g_reservation_map, key)); |
272 g_reservation_map->erase(key); | 271 g_reservation_map->erase(key); |
273 if (g_reservation_map->size() == 0) { | 272 if (g_reservation_map->size() == 0) { |
274 // No more reservations. Delete map. | 273 // No more reservations. Delete map. |
275 delete g_reservation_map; | 274 delete g_reservation_map; |
276 g_reservation_map = NULL; | 275 g_reservation_map = NULL; |
277 } | 276 } |
278 } | 277 } |
279 | 278 |
| 279 void RunGetReservedPathCallback( |
| 280 const DownloadPathReservationTracker::ReservedPathCallback& callback, |
| 281 const base::FilePath* reserved_path, |
| 282 bool verified) { |
| 283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 284 callback.Run(*reserved_path, verified); |
| 285 } |
| 286 |
280 DownloadItemObserver::DownloadItemObserver(DownloadItem* download_item) | 287 DownloadItemObserver::DownloadItemObserver(DownloadItem* download_item) |
281 : download_item_(download_item), | 288 : download_item_(download_item), |
282 last_target_path_(download_item->GetTargetFilePath()) { | 289 last_target_path_(download_item->GetTargetFilePath()) { |
283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
284 download_item_->AddObserver(this); | 291 download_item_->AddObserver(this); |
285 } | 292 } |
286 | 293 |
287 DownloadItemObserver::~DownloadItemObserver() { | 294 DownloadItemObserver::~DownloadItemObserver() { |
288 download_item_->RemoveObserver(this); | 295 download_item_->RemoveObserver(this); |
289 } | 296 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 const base::FilePath& default_path, | 349 const base::FilePath& default_path, |
343 bool create_directory, | 350 bool create_directory, |
344 FilenameConflictAction conflict_action, | 351 FilenameConflictAction conflict_action, |
345 const ReservedPathCallback& callback) { | 352 const ReservedPathCallback& callback) { |
346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
347 // Attach an observer to the download item so that we know when the target | 354 // Attach an observer to the download item so that we know when the target |
348 // path changes and/or the download is no longer active. | 355 // path changes and/or the download is no longer active. |
349 new DownloadItemObserver(download_item); | 356 new DownloadItemObserver(download_item); |
350 // DownloadItemObserver deletes itself. | 357 // DownloadItemObserver deletes itself. |
351 | 358 |
352 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind( | 359 base::FilePath* reserved_path = new base::FilePath; |
353 &CreateReservation, | 360 BrowserThread::PostTaskAndReplyWithResult( |
354 download_item, | 361 BrowserThread::FILE, |
355 target_path, | 362 FROM_HERE, |
356 default_path, | 363 base::Bind(&CreateReservation, |
357 create_directory, | 364 download_item, |
358 conflict_action, | 365 target_path, |
359 callback)); | 366 default_path, |
| 367 create_directory, |
| 368 conflict_action, |
| 369 reserved_path), |
| 370 base::Bind(&RunGetReservedPathCallback, |
| 371 callback, |
| 372 base::Owned(reserved_path))); |
360 } | 373 } |
361 | 374 |
362 // static | 375 // static |
363 bool DownloadPathReservationTracker::IsPathInUseForTesting( | 376 bool DownloadPathReservationTracker::IsPathInUseForTesting( |
364 const base::FilePath& path) { | 377 const base::FilePath& path) { |
365 return IsPathInUse(path); | 378 return IsPathInUse(path); |
366 } | 379 } |
OLD | NEW |