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

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

Issue 1542063003: [download] Make DownloadItemObserver be owned by DownloadItem. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove unnecessary RemoveUserData() call. Created 4 years, 12 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 // there are no more reservations. 42 // there are no more reservations.
43 // 43 //
44 // It is not an error, although undesirable, to have multiple DownloadItem*s 44 // It is not an error, although undesirable, to have multiple DownloadItem*s
45 // that are mapped to the same path. This can happen if a reservation is created 45 // that are mapped to the same path. This can happen if a reservation is created
46 // that is supposed to overwrite an existing reservation. 46 // that is supposed to overwrite an existing reservation.
47 ReservationMap* g_reservation_map = NULL; 47 ReservationMap* g_reservation_map = NULL;
48 48
49 // Observes a DownloadItem for changes to its target path and state. Updates or 49 // Observes a DownloadItem for changes to its target path and state. Updates or
50 // revokes associated download path reservations as necessary. Created, invoked 50 // revokes associated download path reservations as necessary. Created, invoked
51 // and destroyed on the UI thread. 51 // and destroyed on the UI thread.
52 class DownloadItemObserver : public DownloadItem::Observer { 52 class DownloadItemObserver : public DownloadItem::Observer,
53 public base::SupportsUserData::Data {
53 public: 54 public:
54 explicit DownloadItemObserver(DownloadItem* download_item); 55 explicit DownloadItemObserver(DownloadItem* download_item);
55 56
56 private: 57 private:
57 ~DownloadItemObserver() override; 58 ~DownloadItemObserver() override;
58 59
59 // DownloadItem::Observer 60 // DownloadItem::Observer
60 void OnDownloadUpdated(DownloadItem* download) override; 61 void OnDownloadUpdated(DownloadItem* download) override;
61 void OnDownloadDestroyed(DownloadItem* download) override; 62 void OnDownloadDestroyed(DownloadItem* download) override;
62 63
63 DownloadItem* download_item_; 64 DownloadItem* download_item_;
64 65
65 // Last known target path for the download. 66 // Last known target path for the download.
66 base::FilePath last_target_path_; 67 base::FilePath last_target_path_;
67 68
69 static const int kUserDataKey;
70
68 DISALLOW_COPY_AND_ASSIGN(DownloadItemObserver); 71 DISALLOW_COPY_AND_ASSIGN(DownloadItemObserver);
69 }; 72 };
70 73
71 // Returns true if the given path is in use by a path reservation. 74 // Returns true if the given path is in use by a path reservation.
72 bool IsPathReserved(const base::FilePath& path) { 75 bool IsPathReserved(const base::FilePath& path) {
73 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 76 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
74 // No reservation map => no reservations. 77 // No reservation map => no reservations.
75 if (g_reservation_map == NULL) 78 if (g_reservation_map == NULL)
76 return false; 79 return false;
77 // Unfortunately path normalization doesn't work reliably for non-existant 80 // Unfortunately path normalization doesn't work reliably for non-existant
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 bool create_directory, 158 bool create_directory,
156 DownloadPathReservationTracker::FilenameConflictAction conflict_action, 159 DownloadPathReservationTracker::FilenameConflictAction conflict_action,
157 base::FilePath* reserved_path) { 160 base::FilePath* reserved_path) {
158 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 161 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
159 DCHECK(suggested_path.IsAbsolute()); 162 DCHECK(suggested_path.IsAbsolute());
160 163
161 // Create a reservation map if one doesn't exist. It will be automatically 164 // Create a reservation map if one doesn't exist. It will be automatically
162 // deleted when all the reservations are revoked. 165 // deleted when all the reservations are revoked.
163 if (g_reservation_map == NULL) 166 if (g_reservation_map == NULL)
164 g_reservation_map = new ReservationMap; 167 g_reservation_map = new ReservationMap;
168 ReservationMap& reservations = *g_reservation_map;
165 169
166 ReservationMap& reservations = *g_reservation_map; 170 // Erase the reservation if it already exists. This can happen during
167 DCHECK(!ContainsKey(reservations, key)); 171 // automatic resumption where a new target determination request may be issued
172 // for a DownloadItem without an intervening transition to INTERRUPTED.
173 //
174 // Revoking and re-acquiring the reservation forces us to re-verify the claims
175 // we are making about the path.
176 reservations.erase(key);
168 177
169 base::FilePath target_path(suggested_path.NormalizePathSeparators()); 178 base::FilePath target_path(suggested_path.NormalizePathSeparators());
170 base::FilePath target_dir = target_path.DirName(); 179 base::FilePath target_dir = target_path.DirName();
171 base::FilePath filename = target_path.BaseName(); 180 base::FilePath filename = target_path.BaseName();
172 bool is_path_writeable = true; 181 bool is_path_writeable = true;
173 bool has_conflicts = false; 182 bool has_conflicts = false;
174 bool name_too_long = false; 183 bool name_too_long = false;
175 184
176 // Create target_dir if necessary and appropriate. target_dir may be the last 185 // Create target_dir if necessary and appropriate. target_dir may be the last
177 // directory that the user selected in a FilePicker; if that directory has 186 // directory that the user selected in a FilePicker; if that directory has
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 bool verified) { 291 bool verified) {
283 DCHECK_CURRENTLY_ON(BrowserThread::UI); 292 DCHECK_CURRENTLY_ON(BrowserThread::UI);
284 callback.Run(*reserved_path, verified); 293 callback.Run(*reserved_path, verified);
285 } 294 }
286 295
287 DownloadItemObserver::DownloadItemObserver(DownloadItem* download_item) 296 DownloadItemObserver::DownloadItemObserver(DownloadItem* download_item)
288 : download_item_(download_item), 297 : download_item_(download_item),
289 last_target_path_(download_item->GetTargetFilePath()) { 298 last_target_path_(download_item->GetTargetFilePath()) {
290 DCHECK_CURRENTLY_ON(BrowserThread::UI); 299 DCHECK_CURRENTLY_ON(BrowserThread::UI);
291 download_item_->AddObserver(this); 300 download_item_->AddObserver(this);
301 download_item_->SetUserData(&kUserDataKey, this);
292 } 302 }
293 303
294 DownloadItemObserver::~DownloadItemObserver() { 304 DownloadItemObserver::~DownloadItemObserver() {
295 download_item_->RemoveObserver(this); 305 download_item_->RemoveObserver(this);
306 // DownloadItemObserver is owned by DownloadItem. It should only be getting
307 // destroyed because it's being removed from the UserData pool. No need to
308 // call DownloadItem::RemoveUserData().
296 } 309 }
297 310
298 void DownloadItemObserver::OnDownloadUpdated(DownloadItem* download) { 311 void DownloadItemObserver::OnDownloadUpdated(DownloadItem* download) {
299 switch (download->GetState()) { 312 switch (download->GetState()) {
300 case DownloadItem::IN_PROGRESS: { 313 case DownloadItem::IN_PROGRESS: {
301 // Update the reservation. 314 // Update the reservation.
302 base::FilePath new_target_path = download->GetTargetFilePath(); 315 base::FilePath new_target_path = download->GetTargetFilePath();
303 if (new_target_path != last_target_path_) { 316 if (new_target_path != last_target_path_) {
304 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind( 317 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
305 &UpdateReservation, download, new_target_path)); 318 &UpdateReservation, download, new_target_path));
(...skipping 10 matching lines...) Expand all
316 case DownloadItem::CANCELLED: 329 case DownloadItem::CANCELLED:
317 // We no longer need the reservation if the download is being removed. 330 // We no longer need the reservation if the download is being removed.
318 331
319 case DownloadItem::INTERRUPTED: 332 case DownloadItem::INTERRUPTED:
320 // The download filename will need to be re-generated when the download is 333 // The download filename will need to be re-generated when the download is
321 // restarted. Holding on to the reservation now would prevent the name 334 // restarted. Holding on to the reservation now would prevent the name
322 // from being used for a subsequent retry attempt. 335 // from being used for a subsequent retry attempt.
323 336
324 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind( 337 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
325 &RevokeReservation, download)); 338 &RevokeReservation, download));
326 delete this; 339 download->RemoveUserData(&kUserDataKey);
327 break; 340 break;
328 341
329 case DownloadItem::MAX_DOWNLOAD_STATE: 342 case DownloadItem::MAX_DOWNLOAD_STATE:
330 // Compiler appeasement. 343 // Compiler appeasement.
331 NOTREACHED(); 344 NOTREACHED();
332 } 345 }
333 } 346 }
334 347
335 void DownloadItemObserver::OnDownloadDestroyed(DownloadItem* download) { 348 void DownloadItemObserver::OnDownloadDestroyed(DownloadItem* download) {
336 // Items should be COMPLETE/INTERRUPTED/CANCELLED before being destroyed. 349 // Items should be COMPLETE/INTERRUPTED/CANCELLED before being destroyed.
337 NOTREACHED(); 350 NOTREACHED();
338 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind( 351 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
339 &RevokeReservation, download)); 352 &RevokeReservation, download));
340 delete this;
341 } 353 }
342 354
355 // static
356 const int DownloadItemObserver::kUserDataKey = 0;
357
343 } // namespace 358 } // namespace
344 359
345 // static 360 // static
346 void DownloadPathReservationTracker::GetReservedPath( 361 void DownloadPathReservationTracker::GetReservedPath(
347 DownloadItem* download_item, 362 DownloadItem* download_item,
348 const base::FilePath& target_path, 363 const base::FilePath& target_path,
349 const base::FilePath& default_path, 364 const base::FilePath& default_path,
350 bool create_directory, 365 bool create_directory,
351 FilenameConflictAction conflict_action, 366 FilenameConflictAction conflict_action,
352 const ReservedPathCallback& callback) { 367 const ReservedPathCallback& callback) {
(...skipping 17 matching lines...) Expand all
370 base::Bind(&RunGetReservedPathCallback, 385 base::Bind(&RunGetReservedPathCallback,
371 callback, 386 callback,
372 base::Owned(reserved_path))); 387 base::Owned(reserved_path)));
373 } 388 }
374 389
375 // static 390 // static
376 bool DownloadPathReservationTracker::IsPathInUseForTesting( 391 bool DownloadPathReservationTracker::IsPathInUseForTesting(
377 const base::FilePath& path) { 392 const base::FilePath& path) {
378 return IsPathInUse(path); 393 return IsPathInUse(path);
379 } 394 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698