| 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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 RunFileChooserEnd(); | 285 RunFileChooserEnd(); |
| 286 } | 286 } |
| 287 | 287 |
| 288 void FileSelectHelper::DeleteTemporaryFiles() { | 288 void FileSelectHelper::DeleteTemporaryFiles() { |
| 289 BrowserThread::PostTask(BrowserThread::FILE, | 289 BrowserThread::PostTask(BrowserThread::FILE, |
| 290 FROM_HERE, | 290 FROM_HERE, |
| 291 base::Bind(&DeleteFiles, temporary_files_)); | 291 base::Bind(&DeleteFiles, temporary_files_)); |
| 292 temporary_files_.clear(); | 292 temporary_files_.clear(); |
| 293 } | 293 } |
| 294 | 294 |
| 295 void FileSelectHelper::CleanUpOnRenderViewHostChange() { |
| 296 if (!temporary_files_.empty()) { |
| 297 DeleteTemporaryFiles(); |
| 298 |
| 299 // Now that the temporary files have been scheduled for deletion, there |
| 300 // is no longer any reason to keep this instance around. |
| 301 Release(); |
| 302 } |
| 303 } |
| 304 |
| 295 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> | 305 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> |
| 296 FileSelectHelper::GetFileTypesFromAcceptType( | 306 FileSelectHelper::GetFileTypesFromAcceptType( |
| 297 const std::vector<base::string16>& accept_types) { | 307 const std::vector<base::string16>& accept_types) { |
| 298 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type( | 308 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type( |
| 299 new ui::SelectFileDialog::FileTypeInfo()); | 309 new ui::SelectFileDialog::FileTypeInfo()); |
| 300 if (accept_types.empty()) | 310 if (accept_types.empty()) |
| 301 return base_file_type.Pass(); | 311 return base_file_type.Pass(); |
| 302 | 312 |
| 303 // Create FileTypeInfo and pre-allocate for the first extension list. | 313 // Create FileTypeInfo and pre-allocate for the first extension list. |
| 304 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> file_type( | 314 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> file_type( |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 } | 393 } |
| 384 | 394 |
| 385 void FileSelectHelper::RunFileChooser(RenderViewHost* render_view_host, | 395 void FileSelectHelper::RunFileChooser(RenderViewHost* render_view_host, |
| 386 content::WebContents* web_contents, | 396 content::WebContents* web_contents, |
| 387 const FileChooserParams& params) { | 397 const FileChooserParams& params) { |
| 388 DCHECK(!render_view_host_); | 398 DCHECK(!render_view_host_); |
| 389 DCHECK(!web_contents_); | 399 DCHECK(!web_contents_); |
| 390 render_view_host_ = render_view_host; | 400 render_view_host_ = render_view_host; |
| 391 web_contents_ = web_contents; | 401 web_contents_ = web_contents; |
| 392 notification_registrar_.RemoveAll(); | 402 notification_registrar_.RemoveAll(); |
| 393 notification_registrar_.Add(this, | 403 content::WebContentsObserver::Observe(web_contents_); |
| 394 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, | |
| 395 content::Source<WebContents>(web_contents_)); | |
| 396 notification_registrar_.Add( | 404 notification_registrar_.Add( |
| 397 this, | 405 this, |
| 398 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, | 406 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, |
| 399 content::Source<RenderWidgetHost>(render_view_host_)); | 407 content::Source<RenderWidgetHost>(render_view_host_)); |
| 400 notification_registrar_.Add( | |
| 401 this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | |
| 402 content::Source<WebContents>(web_contents_)); | |
| 403 | 408 |
| 404 BrowserThread::PostTask( | 409 BrowserThread::PostTask( |
| 405 BrowserThread::FILE, FROM_HERE, | 410 BrowserThread::FILE, FROM_HERE, |
| 406 base::Bind(&FileSelectHelper::RunFileChooserOnFileThread, this, params)); | 411 base::Bind(&FileSelectHelper::RunFileChooserOnFileThread, this, params)); |
| 407 | 412 |
| 408 // Because this class returns notifications to the RenderViewHost, it is | 413 // Because this class returns notifications to the RenderViewHost, it is |
| 409 // difficult for callers to know how long to keep a reference to this | 414 // 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 | 415 // 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. | 416 // to the caller, until the last callback is received from the file dialog. |
| 412 // At that point, we must call RunFileChooserEnd(). | 417 // 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, | 532 void FileSelectHelper::Observe(int type, |
| 528 const content::NotificationSource& source, | 533 const content::NotificationSource& source, |
| 529 const content::NotificationDetails& details) { | 534 const content::NotificationDetails& details) { |
| 530 switch (type) { | 535 switch (type) { |
| 531 case content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: { | 536 case content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: { |
| 532 DCHECK(content::Source<RenderWidgetHost>(source).ptr() == | 537 DCHECK(content::Source<RenderWidgetHost>(source).ptr() == |
| 533 render_view_host_); | 538 render_view_host_); |
| 534 render_view_host_ = NULL; | 539 render_view_host_ = NULL; |
| 535 break; | 540 break; |
| 536 } | 541 } |
| 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: | 542 default: |
| 556 NOTREACHED(); | 543 NOTREACHED(); |
| 557 } | 544 } |
| 558 } | 545 } |
| 559 | 546 |
| 547 void FileSelectHelper::RenderViewHostChanged(RenderViewHost* old_host, |
| 548 RenderViewHost* new_host) { |
| 549 CleanUpOnRenderViewHostChange(); |
| 550 } |
| 551 |
| 552 void FileSelectHelper::WebContentsDestroyed() { |
| 553 web_contents_ = nullptr; |
| 554 CleanUpOnRenderViewHostChange(); |
| 555 } |
| 556 |
| 560 // static | 557 // static |
| 561 bool FileSelectHelper::IsAcceptTypeValid(const std::string& accept_type) { | 558 bool FileSelectHelper::IsAcceptTypeValid(const std::string& accept_type) { |
| 562 // TODO(raymes): This only does some basic checks, extend to test more cases. | 559 // 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 | 560 // 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). | 561 // of an extension or a "/" in the case of a MIME type). |
| 565 std::string unused; | 562 std::string unused; |
| 566 if (accept_type.length() <= 1 || | 563 if (accept_type.length() <= 1 || |
| 567 base::StringToLowerASCII(accept_type) != accept_type || | 564 base::StringToLowerASCII(accept_type) != accept_type || |
| 568 base::TrimWhitespaceASCII(accept_type, base::TRIM_ALL, &unused) != | 565 base::TrimWhitespaceASCII(accept_type, base::TRIM_ALL, &unused) != |
| 569 base::TRIM_NONE) { | 566 base::TRIM_NONE) { |
| 570 return false; | 567 return false; |
| 571 } | 568 } |
| 572 return true; | 569 return true; |
| 573 } | 570 } |
| OLD | NEW |