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

Side by Side Diff: chrome/browser/file_select_helper.cc

Issue 634833003: mac: Zip packages when they are selected by the file opener. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments from avi. Created 6 years, 2 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
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/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
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 (auto& file_path : paths)
66 base::DeleteFile(file_path, true);
Lei Zhang 2014/10/09 18:41:54 Recursive deletion is scary. Do you really need to
erikchen 2014/10/09 23:33:35 Got rid of the recursive deletion.
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
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 #else
147 NotifyRenderViewHostAndEnd(files);
148 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
137 } 149 }
138 150
139 void FileSelectHelper::MultiFilesSelected( 151 void FileSelectHelper::MultiFilesSelected(
140 const std::vector<base::FilePath>& files, 152 const std::vector<base::FilePath>& files,
141 void* params) { 153 void* params) {
142 std::vector<ui::SelectedFileInfo> selected_files = 154 std::vector<ui::SelectedFileInfo> selected_files =
143 FilePathListToSelectedFileInfoList(files); 155 FilePathListToSelectedFileInfoList(files);
144 156
145 MultiFilesSelectedWithExtraInfo(selected_files, params); 157 MultiFilesSelectedWithExtraInfo(selected_files, params);
146 } 158 }
147 159
148 void FileSelectHelper::MultiFilesSelectedWithExtraInfo( 160 void FileSelectHelper::MultiFilesSelectedWithExtraInfo(
149 const std::vector<ui::SelectedFileInfo>& files, 161 const std::vector<ui::SelectedFileInfo>& files,
150 void* params) { 162 void* params) {
151 if (!files.empty()) 163 if (!files.empty())
152 profile_->set_last_selected_directory(files[0].file_path.DirName()); 164 profile_->set_last_selected_directory(files[0].file_path.DirName());
153 if (!render_view_host_)
154 return;
155 165
156 NotifyRenderViewHost(render_view_host_, files, dialog_mode_); 166 #if defined(OS_MACOSX) && !defined(OS_IOS)
157 167 content::BrowserThread::PostTask(
158 // No members should be accessed from here on. 168 content::BrowserThread::FILE_USER_BLOCKING,
159 RunFileChooserEnd(); 169 FROM_HERE,
170 base::Bind(&FileSelectHelper::ProcessSelectedFilesMac, this, files));
171 #else
172 NotifyRenderViewHostAndEnd(files);
173 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
160 } 174 }
161 175
162 void FileSelectHelper::FileSelectionCanceled(void* params) { 176 void FileSelectHelper::FileSelectionCanceled(void* params) {
163 if (!render_view_host_) 177 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 } 178 }
175 179
176 void FileSelectHelper::StartNewEnumeration(const base::FilePath& path, 180 void FileSelectHelper::StartNewEnumeration(const base::FilePath& path,
177 int request_id, 181 int request_id,
178 RenderViewHost* render_view_host) { 182 RenderViewHost* render_view_host) {
179 scoped_ptr<ActiveDirectoryEnumeration> entry(new ActiveDirectoryEnumeration); 183 scoped_ptr<ActiveDirectoryEnumeration> entry(new ActiveDirectoryEnumeration);
180 entry->rvh_ = render_view_host; 184 entry->rvh_ = render_view_host;
181 entry->delegate_.reset(new DirectoryListerDispatchDelegate(this, request_id)); 185 entry->delegate_.reset(new DirectoryListerDispatchDelegate(this, request_id));
182 entry->lister_.reset(new net::DirectoryLister(path, 186 entry->lister_.reset(new net::DirectoryLister(path,
183 true, 187 true,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 FilePathListToSelectedFileInfoList(entry->results_); 225 FilePathListToSelectedFileInfoList(entry->results_);
222 226
223 if (id == kFileSelectEnumerationId) 227 if (id == kFileSelectEnumerationId)
224 NotifyRenderViewHost(entry->rvh_, selected_files, dialog_mode_); 228 NotifyRenderViewHost(entry->rvh_, selected_files, dialog_mode_);
225 else 229 else
226 entry->rvh_->DirectoryEnumerationFinished(id, entry->results_); 230 entry->rvh_->DirectoryEnumerationFinished(id, entry->results_);
227 231
228 EnumerateDirectoryEnd(); 232 EnumerateDirectoryEnd();
229 } 233 }
230 234
235 void FileSelectHelper::NotifyRenderViewHostAndEnd(
236 const std::vector<ui::SelectedFileInfo>& files) {
237 if (render_view_host_)
238 NotifyRenderViewHost(render_view_host_, files, dialog_mode_);
239
240 // No members should be accessed from here on.
241 RunFileChooserEnd();
242 }
243
244 void FileSelectHelper::DeleteTemporaryFiles() {
245 BrowserThread::PostTask(BrowserThread::FILE,
246 FROM_HERE,
247 base::Bind(&DeleteFiles, temporary_files_));
248 temporary_files_.clear();
249 }
250
231 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> 251 scoped_ptr<ui::SelectFileDialog::FileTypeInfo>
232 FileSelectHelper::GetFileTypesFromAcceptType( 252 FileSelectHelper::GetFileTypesFromAcceptType(
233 const std::vector<base::string16>& accept_types) { 253 const std::vector<base::string16>& accept_types) {
234 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type( 254 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type(
235 new ui::SelectFileDialog::FileTypeInfo()); 255 new ui::SelectFileDialog::FileTypeInfo());
236 if (accept_types.empty()) 256 if (accept_types.empty())
237 return base_file_type.Pass(); 257 return base_file_type.Pass();
238 258
239 // Create FileTypeInfo and pre-allocate for the first extension list. 259 // Create FileTypeInfo and pre-allocate for the first extension list.
240 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> file_type( 260 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> file_type(
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 } 339 }
320 340
321 void FileSelectHelper::RunFileChooser(RenderViewHost* render_view_host, 341 void FileSelectHelper::RunFileChooser(RenderViewHost* render_view_host,
322 content::WebContents* web_contents, 342 content::WebContents* web_contents,
323 const FileChooserParams& params) { 343 const FileChooserParams& params) {
324 DCHECK(!render_view_host_); 344 DCHECK(!render_view_host_);
325 DCHECK(!web_contents_); 345 DCHECK(!web_contents_);
326 render_view_host_ = render_view_host; 346 render_view_host_ = render_view_host;
327 web_contents_ = web_contents; 347 web_contents_ = web_contents;
328 notification_registrar_.RemoveAll(); 348 notification_registrar_.RemoveAll();
349 notification_registrar_.Add(this,
350 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
351 content::Source<WebContents>(web_contents_));
329 notification_registrar_.Add( 352 notification_registrar_.Add(
330 this, content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, 353 this,
354 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
331 content::Source<RenderWidgetHost>(render_view_host_)); 355 content::Source<RenderWidgetHost>(render_view_host_));
332 notification_registrar_.Add( 356 notification_registrar_.Add(
333 this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 357 this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
334 content::Source<WebContents>(web_contents_)); 358 content::Source<WebContents>(web_contents_));
335 359
336 BrowserThread::PostTask( 360 BrowserThread::PostTask(
337 BrowserThread::FILE, FROM_HERE, 361 BrowserThread::FILE, FROM_HERE,
338 base::Bind(&FileSelectHelper::RunFileChooserOnFileThread, this, params)); 362 base::Bind(&FileSelectHelper::RunFileChooserOnFileThread, this, params));
339 363
340 // Because this class returns notifications to the RenderViewHost, it is 364 // Because this class returns notifications to the RenderViewHost, it is
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 NULL); 441 NULL);
418 #endif 442 #endif
419 443
420 select_file_types_.reset(); 444 select_file_types_.reset();
421 } 445 }
422 446
423 // This method is called when we receive the last callback from the file 447 // 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 448 // chooser dialog. Perform any cleanup and release the reference we added
425 // in RunFileChooser(). 449 // in RunFileChooser().
426 void FileSelectHelper::RunFileChooserEnd() { 450 void FileSelectHelper::RunFileChooserEnd() {
451 // If there are temporary files, then this instance needs to stick around
452 // until web_contents_ is destroyed, so that this instance can delete the
453 // temporary files.
454 if (!temporary_files_.empty())
455 return;
456
427 render_view_host_ = NULL; 457 render_view_host_ = NULL;
428 web_contents_ = NULL; 458 web_contents_ = NULL;
429 Release(); 459 Release();
430 } 460 }
431 461
432 void FileSelectHelper::EnumerateDirectory(int request_id, 462 void FileSelectHelper::EnumerateDirectory(int request_id,
433 RenderViewHost* render_view_host, 463 RenderViewHost* render_view_host,
434 const base::FilePath& path) { 464 const base::FilePath& path) {
435 465
436 // Because this class returns notifications to the RenderViewHost, it is 466 // Because this class returns notifications to the RenderViewHost, it is
(...skipping 19 matching lines...) Expand all
456 case content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: { 486 case content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: {
457 DCHECK(content::Source<RenderWidgetHost>(source).ptr() == 487 DCHECK(content::Source<RenderWidgetHost>(source).ptr() ==
458 render_view_host_); 488 render_view_host_);
459 render_view_host_ = NULL; 489 render_view_host_ = NULL;
460 break; 490 break;
461 } 491 }
462 492
463 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { 493 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
464 DCHECK(content::Source<WebContents>(source).ptr() == web_contents_); 494 DCHECK(content::Source<WebContents>(source).ptr() == web_contents_);
465 web_contents_ = NULL; 495 web_contents_ = NULL;
496 }
497
498 // Intentional fall through.
499 case content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED:
500 if (!temporary_files_.empty()) {
501 DeleteTemporaryFiles();
502
503 // Now that the temporary files have been scheduled for deletion, there
504 // is no longer any reason to keep this instance around.
505 Release();
506 }
507
466 break; 508 break;
467 }
468 509
469 default: 510 default:
470 NOTREACHED(); 511 NOTREACHED();
471 } 512 }
472 } 513 }
473 514
474 // static 515 // static
475 bool FileSelectHelper::IsAcceptTypeValid(const std::string& accept_type) { 516 bool FileSelectHelper::IsAcceptTypeValid(const std::string& accept_type) {
476 // TODO(raymes): This only does some basic checks, extend to test more cases. 517 // 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 518 // 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). 519 // of an extension or a "/" in the case of a MIME type).
479 std::string unused; 520 std::string unused;
480 if (accept_type.length() <= 1 || 521 if (accept_type.length() <= 1 ||
481 base::StringToLowerASCII(accept_type) != accept_type || 522 base::StringToLowerASCII(accept_type) != accept_type ||
482 base::TrimWhitespaceASCII(accept_type, base::TRIM_ALL, &unused) != 523 base::TrimWhitespaceASCII(accept_type, base::TRIM_ALL, &unused) !=
483 base::TRIM_NONE) { 524 base::TRIM_NONE) {
484 return false; 525 return false;
485 } 526 }
486 return true; 527 return true;
487 } 528 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698