| 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 |