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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
78 struct FileSelectHelper::ActiveDirectoryEnumeration { | 78 struct FileSelectHelper::ActiveDirectoryEnumeration { |
79 ActiveDirectoryEnumeration() : rvh_(NULL) {} | 79 ActiveDirectoryEnumeration() : rvh_(NULL) {} |
80 | 80 |
81 scoped_ptr<DirectoryListerDispatchDelegate> delegate_; | 81 scoped_ptr<DirectoryListerDispatchDelegate> delegate_; |
82 scoped_ptr<net::DirectoryLister> lister_; | 82 scoped_ptr<net::DirectoryLister> lister_; |
83 RenderViewHost* rvh_; | 83 RenderViewHost* rvh_; |
84 std::vector<base::FilePath> results_; | 84 std::vector<base::FilePath> results_; |
85 }; | 85 }; |
86 | 86 |
87 FileSelectHelper::FileSelectHelper(Profile* profile) | 87 FileSelectHelper::FileSelectHelper(Profile* profile) |
88 : profile_(profile), | 88 : content::WebContentsObserver(), |
Lei Zhang
2015/05/11 19:52:58
Is this necessary?
lazyboy
2015/05/11 20:41:55
It's not, I've removed invoking default constructo
| |
89 profile_(profile), | |
89 render_view_host_(NULL), | 90 render_view_host_(NULL), |
90 web_contents_(NULL), | 91 web_contents_(NULL), |
91 select_file_dialog_(), | 92 select_file_dialog_(), |
92 select_file_types_(), | 93 select_file_types_(), |
93 dialog_type_(ui::SelectFileDialog::SELECT_OPEN_FILE), | 94 dialog_type_(ui::SelectFileDialog::SELECT_OPEN_FILE), |
94 dialog_mode_(FileChooserParams::Open) { | 95 dialog_mode_(FileChooserParams::Open) { |
95 } | 96 } |
96 | 97 |
97 FileSelectHelper::~FileSelectHelper() { | 98 FileSelectHelper::~FileSelectHelper() { |
98 // There may be pending file dialogs, we need to tell them that we've gone | 99 // There may be pending file dialogs, we need to tell them that we've gone |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
285 RunFileChooserEnd(); | 286 RunFileChooserEnd(); |
286 } | 287 } |
287 | 288 |
288 void FileSelectHelper::DeleteTemporaryFiles() { | 289 void FileSelectHelper::DeleteTemporaryFiles() { |
289 BrowserThread::PostTask(BrowserThread::FILE, | 290 BrowserThread::PostTask(BrowserThread::FILE, |
290 FROM_HERE, | 291 FROM_HERE, |
291 base::Bind(&DeleteFiles, temporary_files_)); | 292 base::Bind(&DeleteFiles, temporary_files_)); |
292 temporary_files_.clear(); | 293 temporary_files_.clear(); |
293 } | 294 } |
294 | 295 |
296 void FileSelectHelper::CleanUpOnRenderViewHostChange() { | |
297 if (!temporary_files_.empty()) { | |
298 DeleteTemporaryFiles(); | |
299 | |
300 // Now that the temporary files have been scheduled for deletion, there | |
301 // is no longer any reason to keep this instance around. | |
302 Release(); | |
303 } | |
304 } | |
305 | |
295 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> | 306 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> |
296 FileSelectHelper::GetFileTypesFromAcceptType( | 307 FileSelectHelper::GetFileTypesFromAcceptType( |
297 const std::vector<base::string16>& accept_types) { | 308 const std::vector<base::string16>& accept_types) { |
298 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type( | 309 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type( |
299 new ui::SelectFileDialog::FileTypeInfo()); | 310 new ui::SelectFileDialog::FileTypeInfo()); |
300 if (accept_types.empty()) | 311 if (accept_types.empty()) |
301 return base_file_type.Pass(); | 312 return base_file_type.Pass(); |
302 | 313 |
303 // Create FileTypeInfo and pre-allocate for the first extension list. | 314 // Create FileTypeInfo and pre-allocate for the first extension list. |
304 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> file_type( | 315 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> file_type( |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
383 } | 394 } |
384 | 395 |
385 void FileSelectHelper::RunFileChooser(RenderViewHost* render_view_host, | 396 void FileSelectHelper::RunFileChooser(RenderViewHost* render_view_host, |
386 content::WebContents* web_contents, | 397 content::WebContents* web_contents, |
387 const FileChooserParams& params) { | 398 const FileChooserParams& params) { |
388 DCHECK(!render_view_host_); | 399 DCHECK(!render_view_host_); |
389 DCHECK(!web_contents_); | 400 DCHECK(!web_contents_); |
390 render_view_host_ = render_view_host; | 401 render_view_host_ = render_view_host; |
391 web_contents_ = web_contents; | 402 web_contents_ = web_contents; |
392 notification_registrar_.RemoveAll(); | 403 notification_registrar_.RemoveAll(); |
393 notification_registrar_.Add(this, | 404 content::WebContentsObserver::Observe(web_contents_); |
394 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, | |
395 content::Source<WebContents>(web_contents_)); | |
396 notification_registrar_.Add( | 405 notification_registrar_.Add( |
397 this, | 406 this, |
398 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, | 407 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, |
399 content::Source<RenderWidgetHost>(render_view_host_)); | 408 content::Source<RenderWidgetHost>(render_view_host_)); |
400 notification_registrar_.Add( | |
401 this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | |
402 content::Source<WebContents>(web_contents_)); | |
403 | 409 |
404 BrowserThread::PostTask( | 410 BrowserThread::PostTask( |
405 BrowserThread::FILE, FROM_HERE, | 411 BrowserThread::FILE, FROM_HERE, |
406 base::Bind(&FileSelectHelper::RunFileChooserOnFileThread, this, params)); | 412 base::Bind(&FileSelectHelper::RunFileChooserOnFileThread, this, params)); |
407 | 413 |
408 // Because this class returns notifications to the RenderViewHost, it is | 414 // Because this class returns notifications to the RenderViewHost, it is |
409 // difficult for callers to know how long to keep a reference to this | 415 // difficult for callers to know how long to keep a reference to this |
410 // instance. We AddRef() here to keep the instance alive after we return | 416 // instance. We AddRef() here to keep the instance alive after we return |
411 // to the caller, until the last callback is received from the file dialog. | 417 // to the caller, until the last callback is received from the file dialog. |
412 // At that point, we must call RunFileChooserEnd(). | 418 // At that point, we must call RunFileChooserEnd(). |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
527 void FileSelectHelper::Observe(int type, | 533 void FileSelectHelper::Observe(int type, |
528 const content::NotificationSource& source, | 534 const content::NotificationSource& source, |
529 const content::NotificationDetails& details) { | 535 const content::NotificationDetails& details) { |
530 switch (type) { | 536 switch (type) { |
531 case content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: { | 537 case content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: { |
532 DCHECK(content::Source<RenderWidgetHost>(source).ptr() == | 538 DCHECK(content::Source<RenderWidgetHost>(source).ptr() == |
533 render_view_host_); | 539 render_view_host_); |
534 render_view_host_ = NULL; | 540 render_view_host_ = NULL; |
535 break; | 541 break; |
536 } | 542 } |
537 | |
538 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { | |
539 DCHECK(content::Source<WebContents>(source).ptr() == web_contents_); | |
540 web_contents_ = NULL; | |
541 } | |
542 | |
543 // Intentional fall through. | |
544 case content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED: | |
545 if (!temporary_files_.empty()) { | |
546 DeleteTemporaryFiles(); | |
547 | |
548 // Now that the temporary files have been scheduled for deletion, there | |
549 // is no longer any reason to keep this instance around. | |
550 Release(); | |
551 } | |
552 | |
553 break; | |
554 | |
555 default: | 543 default: |
556 NOTREACHED(); | 544 NOTREACHED(); |
557 } | 545 } |
558 } | 546 } |
559 | 547 |
548 void FileSelectHelper::RenderViewHostChanged(RenderViewHost* old_host, | |
549 RenderViewHost* new_host) { | |
550 CleanUpOnRenderViewHostChange(); | |
551 } | |
552 | |
553 void FileSelectHelper::WebContentsDestroyed() { | |
554 web_contents_ = nullptr; | |
555 CleanUpOnRenderViewHostChange(); | |
556 } | |
557 | |
560 // static | 558 // static |
561 bool FileSelectHelper::IsAcceptTypeValid(const std::string& accept_type) { | 559 bool FileSelectHelper::IsAcceptTypeValid(const std::string& accept_type) { |
562 // TODO(raymes): This only does some basic checks, extend to test more cases. | 560 // TODO(raymes): This only does some basic checks, extend to test more cases. |
563 // A 1 character accept type will always be invalid (either a "." in the case | 561 // A 1 character accept type will always be invalid (either a "." in the case |
564 // of an extension or a "/" in the case of a MIME type). | 562 // of an extension or a "/" in the case of a MIME type). |
565 std::string unused; | 563 std::string unused; |
566 if (accept_type.length() <= 1 || | 564 if (accept_type.length() <= 1 || |
567 base::StringToLowerASCII(accept_type) != accept_type || | 565 base::StringToLowerASCII(accept_type) != accept_type || |
568 base::TrimWhitespaceASCII(accept_type, base::TRIM_ALL, &unused) != | 566 base::TrimWhitespaceASCII(accept_type, base::TRIM_ALL, &unused) != |
569 base::TRIM_NONE) { | 567 base::TRIM_NONE) { |
570 return false; | 568 return false; |
571 } | 569 } |
572 return true; | 570 return true; |
573 } | 571 } |
OLD | NEW |