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 #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_PATH_RESERVATION_TRACKER_H_ | 5 #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_PATH_RESERVATION_TRACKER_H_ |
6 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_PATH_RESERVATION_TRACKER_H_ | 6 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_PATH_RESERVATION_TRACKER_H_ |
7 | 7 |
8 #include <map> | |
9 | |
10 #include "base/callback_forward.h" | 8 #include "base/callback_forward.h" |
11 #include "base/file_path.h" | |
12 #include "base/lazy_instance.h" | |
13 #include "content/public/browser/download_id.h" | |
14 | 9 |
15 // DownloadPathReservationTracker: Track download paths that are in use by | 10 // DownloadPathReservationTracker: Track download paths that are in use by |
16 // active downloads. | 11 // active downloads. |
17 // | 12 // |
18 // Chrome attempts to uniquify filenames that are assigned to downloads in order | 13 // Chrome attempts to uniquify filenames that are assigned to downloads in order |
19 // to avoid overwriting files that already exist on the file system. Downloads | 14 // to avoid overwriting files that already exist on the file system. Downloads |
20 // that are considered potentially dangerous use random intermediate filenames. | 15 // that are considered potentially dangerous use random intermediate filenames. |
21 // Therefore only considering files that exist on the filesystem is | 16 // Therefore only considering files that exist on the filesystem is |
22 // insufficient. This class tracks files that are assigned to active downloads | 17 // insufficient. This class tracks files that are assigned to active downloads |
23 // so that uniquification can take those into account as well. | 18 // so that uniquification can take those into account as well. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 // path of the |download_item| appropriately. | 60 // path of the |download_item| appropriately. |
66 // | 61 // |
67 // Note: The current implementation doesn't look at symlinks/mount points. E.g.: | 62 // Note: The current implementation doesn't look at symlinks/mount points. E.g.: |
68 // It considers 'foo/bar/x.pdf' and 'foo/baz/x.pdf' to be two different paths, | 63 // It considers 'foo/bar/x.pdf' and 'foo/baz/x.pdf' to be two different paths, |
69 // even though 'bar' might be a symlink to 'baz'. | 64 // even though 'bar' might be a symlink to 'baz'. |
70 | 65 |
71 namespace content { | 66 namespace content { |
72 class DownloadItem; | 67 class DownloadItem; |
73 } | 68 } |
74 | 69 |
| 70 class FilePath; |
| 71 |
75 // Issues and tracks download paths that are in use by the download system. When | 72 // Issues and tracks download paths that are in use by the download system. When |
76 // a target path is set for a download, this object tracks the path and the | 73 // a target path is set for a download, this object tracks the path and the |
77 // associated download item so that subsequent downloads can avoid using the | 74 // associated download item so that subsequent downloads can avoid using the |
78 // same path. All non-static methods must be invoked on the FILE thread. | 75 // same path. |
79 class DownloadPathReservationTracker { | 76 class DownloadPathReservationTracker { |
80 public: | 77 public: |
81 // Callback used with |GetReservedPath|. |target_path| specifies the target | 78 // Callback used with |GetReservedPath|. |target_path| specifies the target |
82 // path for the download. |target_path_verified| is true if all of the | 79 // path for the download. |target_path_verified| is true if all of the |
83 // following is true: | 80 // following is true: |
84 // - |requested_target_path| (passed into GetReservedPath()) was writeable. | 81 // - |requested_target_path| (passed into GetReservedPath()) was writeable. |
85 // - |target_path| was verified as being unique if uniqueness was | 82 // - |target_path| was verified as being unique if uniqueness was |
86 // required. | 83 // required. |
87 // | 84 // |
88 // If |requested_target_path| was not writeable, then the parent directory of | 85 // If |requested_target_path| was not writeable, then the parent directory of |
89 // |target_path| may be different from that of |requested_target_path|. | 86 // |target_path| may be different from that of |requested_target_path|. |
90 typedef base::Callback<void(const FilePath& target_path, | 87 typedef base::Callback<void(const FilePath& target_path, |
91 bool target_path_verified)> ReservedPathCallback; | 88 bool target_path_verified)> ReservedPathCallback; |
92 | 89 |
93 // The largest index for the uniquification suffix that we will try while | 90 // The largest index for the uniquification suffix that we will try while |
94 // attempting to come up with a unique path. | 91 // attempting to come up with a unique path. |
95 static const int kMaxUniqueFiles = 100; | 92 static const int kMaxUniqueFiles = 100; |
96 | 93 |
97 // Called on the UI thread to request a download path reservation. Begins | 94 // Called on the UI thread to request a download path reservation. Begins |
98 // observing |download_item| and invokes ReserveInternal() on the FILE thread | 95 // observing |download_item| and initiates creating a reservation on the FILE |
99 // to create the path reservation. Will not modify any state of | 96 // thread. Will not modify any state of |download_item|. |
100 // |download_item|. | |
101 // | 97 // |
102 // |default_download_path| is the user's default download path. If this | 98 // |default_download_path| is the user's default download path. If this |
103 // directory does not exist and is the parent directory of | 99 // directory does not exist and is the parent directory of |
104 // |requested_target_path|, the directory will be created. | 100 // |requested_target_path|, the directory will be created. |
105 static void GetReservedPath(content::DownloadItem& download_item, | 101 static void GetReservedPath(content::DownloadItem& download_item, |
106 const FilePath& requested_target_path, | 102 const FilePath& requested_target_path, |
107 const FilePath& default_download_path, | 103 const FilePath& default_download_path, |
108 bool should_uniquify_path, | 104 bool should_uniquify_path, |
109 const ReservedPathCallback& callback); | 105 const ReservedPathCallback& callback); |
110 | 106 |
111 private: | 107 // Returns true if |path| is in use by an existing path reservation. Should |
112 friend class DownloadPathReservationTrackerTest; | 108 // only be called on the FILE thread. Currently only used by tests. |
113 friend struct base::DefaultLazyInstanceTraits<DownloadPathReservationTracker>; | 109 static bool IsPathInUseForTesting(const FilePath& path); |
114 | |
115 typedef std::map<content::DownloadId, FilePath> ReservationMap; | |
116 | |
117 DownloadPathReservationTracker(); | |
118 ~DownloadPathReservationTracker(); | |
119 | |
120 // Called on the FILE thread to reserve a download path. This method: | |
121 // - Creates directory |default_download_path| if it doesn't exist. | |
122 // - Verifies that the parent directory of |suggested_path| exists and is | |
123 // writeable. | |
124 // - Uniquifies |suggested_path| if |should_uniquify_path| is true. | |
125 // - Schedules |callback| on the UI thread with the reserved path and a flag | |
126 // indicating whether the returned path has been successfully verified. | |
127 void ReserveInternal(content::DownloadId download_id, | |
128 const FilePath& suggested_path, | |
129 const FilePath& default_download_path, | |
130 bool should_uniquify_path, | |
131 const ReservedPathCallback& callback); | |
132 | |
133 // Returns true if the given path is in use by any path reservation or the | |
134 // file system. Called on the FILE thread. | |
135 bool IsPathInUse(const FilePath& path) const; | |
136 | |
137 // Called on the FILE thread to update the path of the reservation associated | |
138 // with |download_id| to |new_path|. | |
139 void Update(content::DownloadId download_id, const FilePath& new_path); | |
140 | |
141 // Called on the FILE thread to remove the path reservation associated with | |
142 // |download_id|. | |
143 void Revoke(content::DownloadId download_id); | |
144 | |
145 // Get a pointer to the browser global instace of this object. Called on the | |
146 // UI thread. | |
147 static DownloadPathReservationTracker* GetInstance(); | |
148 | |
149 ReservationMap reservations_; | |
150 | |
151 DISALLOW_COPY_AND_ASSIGN(DownloadPathReservationTracker); | |
152 }; | 110 }; |
153 | 111 |
154 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_PATH_RESERVATION_TRACKER_H_ | 112 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_PATH_RESERVATION_TRACKER_H_ |
OLD | NEW |