OLD | NEW |
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.h" | 5 #include "chrome/browser/download/download_file.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "build/build_config.h" | 8 #include "build/build_config.h" |
| 9 #include "chrome/browser/chrome_thread.h" |
9 #include "chrome/browser/download/download_manager.h" | 10 #include "chrome/browser/download/download_manager.h" |
10 #include "chrome/browser/download/download_util.h" | 11 #include "chrome/browser/download/download_util.h" |
11 #include "chrome/browser/history/download_types.h" | 12 #include "chrome/browser/history/download_types.h" |
12 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
13 | 14 |
14 #if defined(OS_WIN) | 15 #if defined(OS_WIN) |
15 #include "app/win_util.h" | 16 #include "app/win_util.h" |
16 #include "chrome/common/win_safe_util.h" | 17 #include "chrome/common/win_safe_util.h" |
17 #elif defined(OS_MACOSX) | 18 #elif defined(OS_MACOSX) |
18 #include "chrome/browser/cocoa/file_metadata.h" | 19 #include "chrome/browser/cocoa/file_metadata.h" |
19 #endif | 20 #endif |
20 | 21 |
21 DownloadFile::DownloadFile(const DownloadCreateInfo* info) | 22 DownloadFile::DownloadFile(const DownloadCreateInfo* info) |
22 : file_stream_(info->save_info.file_stream), | 23 : file_stream_(info->save_info.file_stream), |
23 source_url_(info->url), | 24 source_url_(info->url), |
24 referrer_url_(info->referrer_url), | 25 referrer_url_(info->referrer_url), |
25 id_(info->download_id), | 26 id_(info->download_id), |
26 child_id_(info->child_id), | 27 child_id_(info->child_id), |
27 render_view_id_(info->render_view_id), | |
28 request_id_(info->request_id), | 28 request_id_(info->request_id), |
29 bytes_so_far_(0), | |
30 full_path_(info->save_info.file_path), | 29 full_path_(info->save_info.file_path), |
31 path_renamed_(false), | 30 path_renamed_(false), |
32 in_progress_(true), | 31 dont_sleep_(true) { |
33 dont_sleep_(true), | 32 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
34 save_info_(info->save_info) { | |
35 } | 33 } |
36 | 34 |
37 DownloadFile::~DownloadFile() { | 35 DownloadFile::~DownloadFile() { |
| 36 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
38 Close(); | 37 Close(); |
39 } | 38 } |
40 | 39 |
41 bool DownloadFile::Initialize() { | 40 bool DownloadFile::Initialize() { |
| 41 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
42 if (!full_path_.empty() || | 42 if (!full_path_.empty() || |
43 download_util::CreateTemporaryFileForDownload(&full_path_)) | 43 download_util::CreateTemporaryFileForDownload(&full_path_)) |
44 return Open(); | 44 return Open(); |
45 return false; | 45 return false; |
46 } | 46 } |
47 | 47 |
48 bool DownloadFile::AppendDataToFile(const char* data, int data_len) { | 48 bool DownloadFile::AppendDataToFile(const char* data, size_t data_len) { |
49 if (file_stream_.get()) { | 49 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
50 // FIXME bug 595247: handle errors on file writes. | 50 |
51 size_t written = file_stream_->Write(data, data_len, NULL); | 51 if (!file_stream_.get()) |
52 bytes_so_far_ += written; | 52 return false; |
53 return true; | 53 |
54 } | 54 // FIXME bug 595247: handle errors on file writes. |
55 return false; | 55 size_t written = file_stream_->Write(data, data_len, NULL); |
| 56 return (written == data_len); |
56 } | 57 } |
57 | 58 |
58 void DownloadFile::Cancel() { | 59 void DownloadFile::Cancel() { |
| 60 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
59 Close(); | 61 Close(); |
60 if (!full_path_.empty()) | 62 if (!full_path_.empty()) |
61 file_util::Delete(full_path_, false); | 63 file_util::Delete(full_path_, false); |
62 } | 64 } |
63 | 65 |
64 // The UI has provided us with our finalized name. | 66 // The UI has provided us with our finalized name. |
65 bool DownloadFile::Rename(const FilePath& new_path) { | 67 bool DownloadFile::Rename(const FilePath& new_path) { |
| 68 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
| 69 |
| 70 // Save the information whether the download is in progress because |
| 71 // it will be overwritten by closing the file. |
| 72 bool saved_in_progress = in_progress(); |
| 73 |
66 // If the new path is same as the old one, there is no need to perform the | 74 // If the new path is same as the old one, there is no need to perform the |
67 // following renaming logic. | 75 // following renaming logic. |
68 if (new_path == full_path_) { | 76 if (new_path == full_path_) { |
69 path_renamed_ = true; | 77 path_renamed_ = true; |
70 | 78 |
71 // Don't close the file if we're not done (finished or canceled). | 79 // Don't close the file if we're not done (finished or canceled). |
72 if (!in_progress_) | 80 if (!saved_in_progress) |
73 Close(); | 81 Close(); |
74 | 82 |
75 return true; | 83 return true; |
76 } | 84 } |
77 | 85 |
78 Close(); | 86 Close(); |
79 | 87 |
80 #if defined(OS_WIN) | 88 #if defined(OS_WIN) |
81 // We cannot rename because rename will keep the same security descriptor | 89 // We cannot rename because rename will keep the same security descriptor |
82 // on the destination file. We want to recreate the security descriptor | 90 // on the destination file. We want to recreate the security descriptor |
(...skipping 19 matching lines...) Expand all Loading... |
102 | 110 |
103 if (stat_succeeded) | 111 if (stat_succeeded) |
104 chmod(new_path.value().c_str(), st.st_mode); | 112 chmod(new_path.value().c_str(), st.st_mode); |
105 } | 113 } |
106 #endif | 114 #endif |
107 | 115 |
108 full_path_ = new_path; | 116 full_path_ = new_path; |
109 path_renamed_ = true; | 117 path_renamed_ = true; |
110 | 118 |
111 // We don't need to re-open the file if we're done (finished or canceled). | 119 // We don't need to re-open the file if we're done (finished or canceled). |
112 if (!in_progress_) | 120 if (!saved_in_progress) |
113 return true; | 121 return true; |
114 | 122 |
115 if (!Open()) | 123 if (!Open()) |
116 return false; | 124 return false; |
117 | 125 |
118 // Move to the end of the new file. | 126 // Move to the end of the new file. |
119 if (file_stream_->Seek(net::FROM_END, 0) < 0) | 127 if (file_stream_->Seek(net::FROM_END, 0) < 0) |
120 return false; | 128 return false; |
121 | 129 |
122 return true; | 130 return true; |
123 } | 131 } |
124 | 132 |
| 133 void DownloadFile::Finish() { |
| 134 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
| 135 Close(); |
| 136 } |
| 137 |
125 void DownloadFile::Close() { | 138 void DownloadFile::Close() { |
| 139 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
126 if (file_stream_.get()) { | 140 if (file_stream_.get()) { |
127 #if defined(OS_CHROMEOS) | 141 #if defined(OS_CHROMEOS) |
128 // Currently we don't really care about the return value, since if it fails | 142 // Currently we don't really care about the return value, since if it fails |
129 // theres not much we can do. But we might in the future. | 143 // theres not much we can do. But we might in the future. |
130 file_stream_->Flush(); | 144 file_stream_->Flush(); |
131 #endif | 145 #endif |
132 file_stream_->Close(); | 146 file_stream_->Close(); |
133 file_stream_.reset(); | 147 file_stream_.reset(); |
134 } | 148 } |
135 } | 149 } |
136 | 150 |
137 bool DownloadFile::Open() { | 151 bool DownloadFile::Open() { |
| 152 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
138 DCHECK(!full_path_.empty()); | 153 DCHECK(!full_path_.empty()); |
139 | 154 |
140 // Create a new file steram if it is not provided. | 155 // Create a new file steram if it is not provided. |
141 if (!file_stream_.get()) { | 156 if (!file_stream_.get()) { |
142 file_stream_.reset(new net::FileStream); | 157 file_stream_.reset(new net::FileStream); |
143 if (file_stream_->Open(full_path_, | 158 if (file_stream_->Open(full_path_, |
144 base::PLATFORM_FILE_OPEN_ALWAYS | | 159 base::PLATFORM_FILE_OPEN_ALWAYS | |
145 base::PLATFORM_FILE_WRITE) != net::OK) { | 160 base::PLATFORM_FILE_WRITE) != net::OK) { |
146 file_stream_.reset(); | 161 file_stream_.reset(); |
147 return false; | 162 return false; |
148 } | 163 } |
149 } | 164 } |
150 | 165 |
151 #if defined(OS_WIN) | 166 #if defined(OS_WIN) |
152 AnnotateWithSourceInformation(); | 167 AnnotateWithSourceInformation(); |
153 #endif | 168 #endif |
154 return true; | 169 return true; |
155 } | 170 } |
156 | 171 |
157 void DownloadFile::AnnotateWithSourceInformation() { | 172 void DownloadFile::AnnotateWithSourceInformation() { |
| 173 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
158 #if defined(OS_WIN) | 174 #if defined(OS_WIN) |
159 // Sets the Zone to tell Windows that this file comes from the internet. | 175 // Sets the Zone to tell Windows that this file comes from the internet. |
160 // We ignore the return value because a failure is not fatal. | 176 // We ignore the return value because a failure is not fatal. |
161 win_util::SetInternetZoneIdentifier(full_path_); | 177 win_util::SetInternetZoneIdentifier(full_path_); |
162 #elif defined(OS_MACOSX) | 178 #elif defined(OS_MACOSX) |
163 file_metadata::AddQuarantineMetadataToFile(full_path_, source_url_, | 179 file_metadata::AddQuarantineMetadataToFile(full_path_, source_url_, |
164 referrer_url_); | 180 referrer_url_); |
165 file_metadata::AddOriginMetadataToFile(full_path_, source_url_, | 181 file_metadata::AddOriginMetadataToFile(full_path_, source_url_, |
166 referrer_url_); | 182 referrer_url_); |
167 #endif | 183 #endif |
168 } | 184 } |
| 185 |
| 186 void DownloadFile::CancelDownloadRequest(ResourceDispatcherHost* rdh) { |
| 187 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
| 188 ChromeThread::PostTask( |
| 189 ChromeThread::IO, FROM_HERE, |
| 190 NewRunnableFunction(&download_util::CancelDownloadRequest, |
| 191 rdh, |
| 192 child_id_, |
| 193 request_id_)); |
| 194 } |
OLD | NEW |