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/file_select_helper.h" | 5 #include "chrome/browser/file_select_helper.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 std::vector<ui::SelectedFileInfo> FilePathListToSelectedFileInfoList( | 54 std::vector<ui::SelectedFileInfo> FilePathListToSelectedFileInfoList( |
55 const std::vector<base::FilePath>& paths) { | 55 const std::vector<base::FilePath>& paths) { |
56 std::vector<ui::SelectedFileInfo> selected_files; | 56 std::vector<ui::SelectedFileInfo> selected_files; |
57 for (size_t i = 0; i < paths.size(); ++i) { | 57 for (size_t i = 0; i < paths.size(); ++i) { |
58 selected_files.push_back( | 58 selected_files.push_back( |
59 ui::SelectedFileInfo(paths[i], paths[i])); | 59 ui::SelectedFileInfo(paths[i], paths[i])); |
60 } | 60 } |
61 return selected_files; | 61 return selected_files; |
62 } | 62 } |
63 | 63 |
64 void DeleteFiles(const std::vector<base::FilePath>& paths) { | |
65 for (base::FilePath file_path : paths) | |
Avi (use Gerrit)
2014/10/08 00:17:32
auto& perhaps?
erikchen
2014/10/08 20:14:43
Done.
| |
66 base::DeleteFile(file_path, true); | |
67 } | |
68 | |
64 } // namespace | 69 } // namespace |
65 | 70 |
66 struct FileSelectHelper::ActiveDirectoryEnumeration { | 71 struct FileSelectHelper::ActiveDirectoryEnumeration { |
67 ActiveDirectoryEnumeration() : rvh_(NULL) {} | 72 ActiveDirectoryEnumeration() : rvh_(NULL) {} |
68 | 73 |
69 scoped_ptr<DirectoryListerDispatchDelegate> delegate_; | 74 scoped_ptr<DirectoryListerDispatchDelegate> delegate_; |
70 scoped_ptr<net::DirectoryLister> lister_; | 75 scoped_ptr<net::DirectoryLister> lister_; |
71 RenderViewHost* rvh_; | 76 RenderViewHost* rvh_; |
72 std::vector<base::FilePath> results_; | 77 std::vector<base::FilePath> results_; |
73 }; | 78 }; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
110 | 115 |
111 void FileSelectHelper::FileSelected(const base::FilePath& path, | 116 void FileSelectHelper::FileSelected(const base::FilePath& path, |
112 int index, void* params) { | 117 int index, void* params) { |
113 FileSelectedWithExtraInfo(ui::SelectedFileInfo(path, path), index, params); | 118 FileSelectedWithExtraInfo(ui::SelectedFileInfo(path, path), index, params); |
114 } | 119 } |
115 | 120 |
116 void FileSelectHelper::FileSelectedWithExtraInfo( | 121 void FileSelectHelper::FileSelectedWithExtraInfo( |
117 const ui::SelectedFileInfo& file, | 122 const ui::SelectedFileInfo& file, |
118 int index, | 123 int index, |
119 void* params) { | 124 void* params) { |
120 if (!render_view_host_) | 125 profile_->set_last_selected_directory(file.file_path.DirName()); |
126 | |
127 if (!render_view_host_) { | |
128 RunFileChooserEnd(); | |
121 return; | 129 return; |
122 | 130 } |
123 profile_->set_last_selected_directory(file.file_path.DirName()); | |
124 | 131 |
125 const base::FilePath& path = file.local_path; | 132 const base::FilePath& path = file.local_path; |
126 if (dialog_type_ == ui::SelectFileDialog::SELECT_UPLOAD_FOLDER) { | 133 if (dialog_type_ == ui::SelectFileDialog::SELECT_UPLOAD_FOLDER) { |
127 StartNewEnumeration(path, kFileSelectEnumerationId, render_view_host_); | 134 StartNewEnumeration(path, kFileSelectEnumerationId, render_view_host_); |
128 return; | 135 return; |
129 } | 136 } |
130 | 137 |
131 std::vector<ui::SelectedFileInfo> files; | 138 std::vector<ui::SelectedFileInfo> files; |
132 files.push_back(file); | 139 files.push_back(file); |
133 NotifyRenderViewHost(render_view_host_, files, dialog_mode_); | |
134 | 140 |
135 // No members should be accessed from here on. | 141 #if defined(OS_MACOSX) && !defined(OS_IOS) |
136 RunFileChooserEnd(); | 142 content::BrowserThread::PostTask( |
143 content::BrowserThread::FILE_USER_BLOCKING, | |
144 FROM_HERE, | |
145 base::Bind(&FileSelectHelper::ProcessSelectedFilesMac, this, files)); | |
146 return; | |
147 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | |
148 | |
149 NotifyRenderViewHostAndEnd(files); | |
137 } | 150 } |
138 | 151 |
139 void FileSelectHelper::MultiFilesSelected( | 152 void FileSelectHelper::MultiFilesSelected( |
140 const std::vector<base::FilePath>& files, | 153 const std::vector<base::FilePath>& files, |
141 void* params) { | 154 void* params) { |
142 std::vector<ui::SelectedFileInfo> selected_files = | 155 std::vector<ui::SelectedFileInfo> selected_files = |
143 FilePathListToSelectedFileInfoList(files); | 156 FilePathListToSelectedFileInfoList(files); |
144 | 157 |
145 MultiFilesSelectedWithExtraInfo(selected_files, params); | 158 MultiFilesSelectedWithExtraInfo(selected_files, params); |
146 } | 159 } |
147 | 160 |
148 void FileSelectHelper::MultiFilesSelectedWithExtraInfo( | 161 void FileSelectHelper::MultiFilesSelectedWithExtraInfo( |
149 const std::vector<ui::SelectedFileInfo>& files, | 162 const std::vector<ui::SelectedFileInfo>& files, |
150 void* params) { | 163 void* params) { |
151 if (!files.empty()) | 164 if (!files.empty()) |
152 profile_->set_last_selected_directory(files[0].file_path.DirName()); | 165 profile_->set_last_selected_directory(files[0].file_path.DirName()); |
153 if (!render_view_host_) | |
154 return; | |
155 | 166 |
156 NotifyRenderViewHost(render_view_host_, files, dialog_mode_); | 167 #if defined(OS_MACOSX) && !defined(OS_IOS) |
168 content::BrowserThread::PostTask( | |
169 content::BrowserThread::FILE_USER_BLOCKING, | |
170 FROM_HERE, | |
171 base::Bind(&FileSelectHelper::ProcessSelectedFilesMac, this, files)); | |
172 return; | |
173 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | |
157 | 174 |
158 // No members should be accessed from here on. | 175 NotifyRenderViewHostAndEnd(files); |
Avi (use Gerrit)
2014/10/08 00:17:32
Might as well put this into an #else.
erikchen
2014/10/08 20:14:43
Done.
| |
159 RunFileChooserEnd(); | |
160 } | 176 } |
161 | 177 |
162 void FileSelectHelper::FileSelectionCanceled(void* params) { | 178 void FileSelectHelper::FileSelectionCanceled(void* params) { |
163 if (!render_view_host_) | 179 NotifyRenderViewHostAndEnd(std::vector<ui::SelectedFileInfo>()); |
164 return; | |
165 | |
166 // If the user cancels choosing a file to upload we pass back an | |
167 // empty vector. | |
168 NotifyRenderViewHost( | |
169 render_view_host_, std::vector<ui::SelectedFileInfo>(), | |
170 dialog_mode_); | |
171 | |
172 // No members should be accessed from here on. | |
173 RunFileChooserEnd(); | |
174 } | 180 } |
175 | 181 |
176 void FileSelectHelper::StartNewEnumeration(const base::FilePath& path, | 182 void FileSelectHelper::StartNewEnumeration(const base::FilePath& path, |
177 int request_id, | 183 int request_id, |
178 RenderViewHost* render_view_host) { | 184 RenderViewHost* render_view_host) { |
179 scoped_ptr<ActiveDirectoryEnumeration> entry(new ActiveDirectoryEnumeration); | 185 scoped_ptr<ActiveDirectoryEnumeration> entry(new ActiveDirectoryEnumeration); |
180 entry->rvh_ = render_view_host; | 186 entry->rvh_ = render_view_host; |
181 entry->delegate_.reset(new DirectoryListerDispatchDelegate(this, request_id)); | 187 entry->delegate_.reset(new DirectoryListerDispatchDelegate(this, request_id)); |
182 entry->lister_.reset(new net::DirectoryLister(path, | 188 entry->lister_.reset(new net::DirectoryLister(path, |
183 true, | 189 true, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 FilePathListToSelectedFileInfoList(entry->results_); | 227 FilePathListToSelectedFileInfoList(entry->results_); |
222 | 228 |
223 if (id == kFileSelectEnumerationId) | 229 if (id == kFileSelectEnumerationId) |
224 NotifyRenderViewHost(entry->rvh_, selected_files, dialog_mode_); | 230 NotifyRenderViewHost(entry->rvh_, selected_files, dialog_mode_); |
225 else | 231 else |
226 entry->rvh_->DirectoryEnumerationFinished(id, entry->results_); | 232 entry->rvh_->DirectoryEnumerationFinished(id, entry->results_); |
227 | 233 |
228 EnumerateDirectoryEnd(); | 234 EnumerateDirectoryEnd(); |
229 } | 235 } |
230 | 236 |
237 void FileSelectHelper::NotifyRenderViewHostAndEnd( | |
238 const std::vector<ui::SelectedFileInfo>& files) { | |
239 if (render_view_host_) | |
240 NotifyRenderViewHost(render_view_host_, files, dialog_mode_); | |
241 | |
242 // No members should be accessed from here on. | |
243 RunFileChooserEnd(); | |
244 } | |
245 | |
246 void FileSelectHelper::DeleteTemporaryFiles() { | |
247 BrowserThread::PostTask(BrowserThread::FILE, | |
248 FROM_HERE, | |
249 base::Bind(&DeleteFiles, temporary_files_)); | |
250 temporary_files_.clear(); | |
251 } | |
252 | |
231 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> | 253 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> |
232 FileSelectHelper::GetFileTypesFromAcceptType( | 254 FileSelectHelper::GetFileTypesFromAcceptType( |
233 const std::vector<base::string16>& accept_types) { | 255 const std::vector<base::string16>& accept_types) { |
234 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type( | 256 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type( |
235 new ui::SelectFileDialog::FileTypeInfo()); | 257 new ui::SelectFileDialog::FileTypeInfo()); |
236 if (accept_types.empty()) | 258 if (accept_types.empty()) |
237 return base_file_type.Pass(); | 259 return base_file_type.Pass(); |
238 | 260 |
239 // Create FileTypeInfo and pre-allocate for the first extension list. | 261 // Create FileTypeInfo and pre-allocate for the first extension list. |
240 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> file_type( | 262 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> file_type( |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 NULL); | 439 NULL); |
418 #endif | 440 #endif |
419 | 441 |
420 select_file_types_.reset(); | 442 select_file_types_.reset(); |
421 } | 443 } |
422 | 444 |
423 // This method is called when we receive the last callback from the file | 445 // This method is called when we receive the last callback from the file |
424 // chooser dialog. Perform any cleanup and release the reference we added | 446 // chooser dialog. Perform any cleanup and release the reference we added |
425 // in RunFileChooser(). | 447 // in RunFileChooser(). |
426 void FileSelectHelper::RunFileChooserEnd() { | 448 void FileSelectHelper::RunFileChooserEnd() { |
449 // If there are temporary files, then this instance needs to stick around | |
450 // until web_contents_ is destroyed, so that this instance can delete the | |
451 // temporary files. | |
452 if (!temporary_files_.empty()) | |
453 return; | |
454 | |
427 render_view_host_ = NULL; | 455 render_view_host_ = NULL; |
428 web_contents_ = NULL; | 456 web_contents_ = NULL; |
429 Release(); | 457 Release(); |
430 } | 458 } |
431 | 459 |
432 void FileSelectHelper::EnumerateDirectory(int request_id, | 460 void FileSelectHelper::EnumerateDirectory(int request_id, |
433 RenderViewHost* render_view_host, | 461 RenderViewHost* render_view_host, |
434 const base::FilePath& path) { | 462 const base::FilePath& path) { |
435 | 463 |
436 // Because this class returns notifications to the RenderViewHost, it is | 464 // Because this class returns notifications to the RenderViewHost, it is |
(...skipping 19 matching lines...) Expand all Loading... | |
456 case content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: { | 484 case content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: { |
457 DCHECK(content::Source<RenderWidgetHost>(source).ptr() == | 485 DCHECK(content::Source<RenderWidgetHost>(source).ptr() == |
458 render_view_host_); | 486 render_view_host_); |
459 render_view_host_ = NULL; | 487 render_view_host_ = NULL; |
460 break; | 488 break; |
461 } | 489 } |
462 | 490 |
463 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { | 491 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { |
464 DCHECK(content::Source<WebContents>(source).ptr() == web_contents_); | 492 DCHECK(content::Source<WebContents>(source).ptr() == web_contents_); |
465 web_contents_ = NULL; | 493 web_contents_ = NULL; |
494 | |
495 if (!temporary_files_.empty()) { | |
496 DeleteTemporaryFiles(); | |
497 | |
498 // Now that the temporary files have been scheduled for deletion, there | |
499 // is no longer any reason to keep this instance around. | |
500 Release(); | |
501 } | |
Avi (use Gerrit)
2014/10/08 00:17:32
So if there was zipping that happened, those tempo
erikchen
2014/10/08 20:14:43
Sure. In the updated CL, the notification NOTIFICA
| |
502 | |
466 break; | 503 break; |
467 } | 504 } |
468 | 505 |
469 default: | 506 default: |
470 NOTREACHED(); | 507 NOTREACHED(); |
471 } | 508 } |
472 } | 509 } |
473 | 510 |
474 // static | 511 // static |
475 bool FileSelectHelper::IsAcceptTypeValid(const std::string& accept_type) { | 512 bool FileSelectHelper::IsAcceptTypeValid(const std::string& accept_type) { |
476 // TODO(raymes): This only does some basic checks, extend to test more cases. | 513 // TODO(raymes): This only does some basic checks, extend to test more cases. |
477 // A 1 character accept type will always be invalid (either a "." in the case | 514 // A 1 character accept type will always be invalid (either a "." in the case |
478 // of an extension or a "/" in the case of a MIME type). | 515 // of an extension or a "/" in the case of a MIME type). |
479 std::string unused; | 516 std::string unused; |
480 if (accept_type.length() <= 1 || | 517 if (accept_type.length() <= 1 || |
481 base::StringToLowerASCII(accept_type) != accept_type || | 518 base::StringToLowerASCII(accept_type) != accept_type || |
482 base::TrimWhitespaceASCII(accept_type, base::TRIM_ALL, &unused) != | 519 base::TrimWhitespaceASCII(accept_type, base::TRIM_ALL, &unused) != |
483 base::TRIM_NONE) { | 520 base::TRIM_NONE) { |
484 return false; | 521 return false; |
485 } | 522 } |
486 return true; | 523 return true; |
487 } | 524 } |
OLD | NEW |