15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/file_select_helper.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <utility> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/platform_util.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/chrome_select_file_policy.h" 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/file_chooser_params.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/mime_util.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/shell_dialogs/selected_file_info.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::FileChooserParams; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderWidgetHost; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There is only one file-selection happening at any given time, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// so we allocate an enumeration ID for that purpose. All IDs from 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the renderer must start at 0 and increase. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kFileSelectEnumerationId = -1; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NotifyRenderViewHost(RenderViewHost* render_view_host, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ui::SelectedFileInfo>& files, 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileChooserParams::Mode dialog_mode) { 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch render_view_host->FilesSelectedInChooser(files, dialog_mode); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts a list of FilePaths to a list of ui::SelectedFileInfo. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<ui::SelectedFileInfo> FilePathListToSelectedFileInfoList( 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<base::FilePath>& paths) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ui::SelectedFileInfo> selected_files; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < paths.size(); ++i) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_files.push_back( 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SelectedFileInfo(paths[i], paths[i])); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return selected_files; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct FileSelectHelper::ActiveDirectoryEnumeration { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ActiveDirectoryEnumeration() : rvh_(NULL) {} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DirectoryListerDispatchDelegate> delegate_; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<net::DirectoryLister> lister_; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHost* rvh_; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath> results_; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSelectHelper::FileSelectHelper(Profile* profile) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile), 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_host_(NULL), 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_contents_(NULL), 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_dialog_(), 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_types_(), 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dialog_type_(ui::SelectFileDialog::SELECT_OPEN_FILE), 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dialog_mode_(FileChooserParams::Open) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSelectHelper::~FileSelectHelper() { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There may be pending file dialogs, we need to tell them that we've gone 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // away so they don't try and call back to us. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (select_file_dialog_.get()) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_dialog_->ListenerDestroyed(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop any pending directory enumeration, prevent a callback, and free 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allocated memory. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, ActiveDirectoryEnumeration*>::iterator iter; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (iter = directory_enumerations_.begin(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != directory_enumerations_.end(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter->second->lister_.reset(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete iter->second; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::DirectoryListerDispatchDelegate::OnListFile( 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::DirectoryLister::DirectoryListerData& data) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_->OnListFile(id_, data); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::DirectoryListerDispatchDelegate::OnListDone(int error) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_->OnListDone(id_, error); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileSelectHelper::FileSelected(const base::FilePath& path, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index, void* params) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSelectedWithExtraInfo(ui::SelectedFileInfo(path, path), index, params); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::FileSelectedWithExtraInfo( 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::SelectedFileInfo& file, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* params) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!render_view_host_) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->set_last_selected_directory(file.file_path.DirName()); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path = file.local_path; 126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (dialog_type_ == ui::SelectFileDialog::SELECT_UPLOAD_FOLDER) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartNewEnumeration(path, kFileSelectEnumerationId, render_view_host_); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ui::SelectedFileInfo> files; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.push_back(file); 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NotifyRenderViewHost(render_view_host_, files, dialog_mode_); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No members should be accessed from here on. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunFileChooserEnd(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileSelectHelper::MultiFilesSelected( 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<base::FilePath>& files, 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* params) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ui::SelectedFileInfo> selected_files = 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePathListToSelectedFileInfoList(files); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MultiFilesSelectedWithExtraInfo(selected_files, params); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::MultiFilesSelectedWithExtraInfo( 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ui::SelectedFileInfo>& files, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* params) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!files.empty()) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->set_last_selected_directory(files[0].file_path.DirName()); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!render_view_host_) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NotifyRenderViewHost(render_view_host_, files, dialog_mode_); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No members should be accessed from here on. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunFileChooserEnd(); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::FileSelectionCanceled(void* params) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!render_view_host_) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the user cancels choosing a file to upload we pass back an 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // empty vector. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyRenderViewHost( 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_host_, std::vector<ui::SelectedFileInfo>(), 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dialog_mode_); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No members should be accessed from here on. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunFileChooserEnd(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileSelectHelper::StartNewEnumeration(const base::FilePath& path, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int request_id, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHost* render_view_host) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ActiveDirectoryEnumeration> entry(new ActiveDirectoryEnumeration); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->rvh_ = render_view_host; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->delegate_.reset(new DirectoryListerDispatchDelegate(this, request_id)); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->lister_.reset(new net::DirectoryLister(path, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::DirectoryLister::NO_SORT, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->delegate_.get())); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry->lister_->Start()) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_id == kFileSelectEnumerationId) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSelectionCanceled(NULL); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_host->DirectoryEnumerationFinished(request_id, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->results_); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory_enumerations_[request_id] = entry.release(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::OnListFile( 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int id, 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::DirectoryLister::DirectoryListerData& data) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ActiveDirectoryEnumeration* entry = directory_enumerations_[id]; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Directory upload only cares about files. 203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (data.info.IsDirectory()) 204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 205effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 206effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch entry->results_.push_back(data.path); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::OnListDone(int id, int error) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This entry needs to be cleaned up when this function is done. 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ActiveDirectoryEnumeration> entry(directory_enumerations_[id]); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directory_enumerations_.erase(id); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry->rvh_) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSelectionCanceled(NULL); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ui::SelectedFileInfo> selected_files = 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePathListToSelectedFileInfoList(entry->results_); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id == kFileSelectEnumerationId) 2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NotifyRenderViewHost(entry->rvh_, selected_files, dialog_mode_); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->rvh_->DirectoryEnumerationFinished(id, entry->results_); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumerateDirectoryEnd(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<ui::SelectFileDialog::FileTypeInfo> 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSelectHelper::GetFileTypesFromAcceptType( 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<base::string16>& accept_types) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type( 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ui::SelectFileDialog::FileTypeInfo()); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (accept_types.empty()) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base_file_type.Pass(); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create FileTypeInfo and pre-allocate for the first extension list. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ui::SelectFileDialog::FileTypeInfo> file_type( 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ui::SelectFileDialog::FileTypeInfo(*base_file_type)); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type->include_all_files = true; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type->extensions.resize(1); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath::StringType>* extensions = 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &file_type->extensions.back(); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the corresponding extensions. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int valid_type_count = 0; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int description_id = 0; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < accept_types.size(); ++i) { 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string ascii_type = base::UTF16ToASCII(accept_types[i]); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsAcceptTypeValid(ascii_type)) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t old_extension_size = extensions->size(); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ascii_type[0] == '.') { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the type starts with a period it is assumed to be a file extension 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so we just have to add it to the list. 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath::StringType ext(ascii_type.begin(), ascii_type.end()); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions->push_back(ext.substr(1)); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ascii_type == "image/*") 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) description_id = IDS_IMAGE_FILES; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (ascii_type == "audio/*") 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) description_id = IDS_AUDIO_FILES; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (ascii_type == "video/*") 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) description_id = IDS_VIDEO_FILES; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::GetExtensionsForMimeType(ascii_type, extensions); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extensions->size() > old_extension_size) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valid_type_count++; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If no valid extension is added, bail out. 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (valid_type_count == 0) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base_file_type.Pass(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use a generic description "Custom Files" if either of the following is 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // true: 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1) There're multiple types specified, like "audio/*,video/*" 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2) There're multiple extensions for a MIME type without parameter, like 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "ehtml,shtml,htm,html" for "text/html". On Windows, the select file 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dialog uses the first extension in the list to form the description, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // like "EHTML Files". This is not what we want. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (valid_type_count > 1 || 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (valid_type_count == 1 && description_id == 0 && extensions->size() > 1)) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) description_id = IDS_CUSTOM_FILES; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (description_id) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type->extension_description_overrides.push_back( 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(description_id)); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file_type.Pass(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::RunFileChooser(content::WebContents* tab, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileChooserParams& params) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext()); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FileSelectHelper will keep itself alive until it sends the result message. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<FileSelectHelper> file_select_helper( 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new FileSelectHelper(profile)); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_select_helper->RunFileChooser(tab->GetRenderViewHost(), tab, params); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::EnumerateDirectory(content::WebContents* tab, 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int request_id, 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext()); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FileSelectHelper will keep itself alive until it sends the result message. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<FileSelectHelper> file_select_helper( 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new FileSelectHelper(profile)); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_select_helper->EnumerateDirectory( 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_id, tab->GetRenderViewHost(), path); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::RunFileChooser(RenderViewHost* render_view_host, 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents, 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileChooserParams& params) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!render_view_host_); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!web_contents_); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_host_ = render_view_host; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_contents_ = web_contents; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.RemoveAll(); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.Add( 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<RenderWidgetHost>(render_view_host_)); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.Add( 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<WebContents>(web_contents_)); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::FILE, FROM_HERE, 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&FileSelectHelper::RunFileChooserOnFileThread, this, params)); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Because this class returns notifications to the RenderViewHost, it is 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // difficult for callers to know how long to keep a reference to this 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instance. We AddRef() here to keep the instance alive after we return 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the caller, until the last callback is received from the file dialog. 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At that point, we must call RunFileChooserEnd(). 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRef(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::RunFileChooserOnFileThread( 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileChooserParams& params) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_types_ = GetFileTypesFromAcceptType(params.accept_types); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&FileSelectHelper::RunFileChooserOnUIThread, this, params)); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::RunFileChooserOnUIThread( 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileChooserParams& params) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!render_view_host_ || !web_contents_) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the renderer was destroyed before we started, just cancel the 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // operation. 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunFileChooserEnd(); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_dialog_ = ui::SelectFileDialog::Create( 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, new ChromeSelectFilePolicy(web_contents_)); 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!select_file_dialog_.get()) 36923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dialog_mode_ = params.mode; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (params.mode) { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FileChooserParams::Open: 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FileChooserParams::OpenMultiple: 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case FileChooserParams::UploadFolder: 380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) dialog_type_ = ui::SelectFileDialog::SELECT_UPLOAD_FOLDER; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FileChooserParams::Save: 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_type_ = ui::SelectFileDialog::SELECT_SAVEAS_FILE; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prevent warning. 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath default_file_name = params.default_file_name.IsAbsolute() ? 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.default_file_name : 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->last_selected_directory().Append(params.default_file_name); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::NativeWindow owning_window = 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) platform_util::GetTopLevel(render_view_host_->GetView()->GetNativeView()); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Android needs the original MIME types and an additional capture value. 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::pair<std::vector<base::string16>, bool> accept_types = 4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::make_pair(params.accept_types, params.capture); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_dialog_->SelectFile( 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialog_type_, 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.title, 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_file_name, 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_types_.get(), 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) select_file_types_.get() && !select_file_types_->extensions.empty() 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ? 1 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : 0, // 1-based index of default extension to show. 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath::StringType(), 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owning_window, 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &accept_types); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) select_file_types_.reset(); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This method is called when we receive the last callback from the file 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// chooser dialog. Perform any cleanup and release the reference we added 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in RunFileChooser(). 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::RunFileChooserEnd() { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_host_ = NULL; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_contents_ = NULL; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::EnumerateDirectory(int request_id, 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHost* render_view_host, 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path) { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Because this class returns notifications to the RenderViewHost, it is 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // difficult for callers to know how long to keep a reference to this 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instance. We AddRef() here to keep the instance alive after we return 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the caller, until the last callback is received from the enumeration 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // code. At that point, we must call EnumerateDirectoryEnd(). 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRef(); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartNewEnumeration(path, request_id, render_view_host); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This method is called when we receive the last callback from the enumeration 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// code. Perform any cleanup and release the reference we added in 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// EnumerateDirectory(). 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::EnumerateDirectoryEnd() { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileSelectHelper::Observe(int type, 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED: { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::Source<RenderWidgetHost>(source).ptr() == 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_host_); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_host_ = NULL; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(content::Source<WebContents>(source).ptr() == web_contents_); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_contents_ = NULL; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileSelectHelper::IsAcceptTypeValid(const std::string& accept_type) { 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(raymes): This only does some basic checks, extend to test more cases. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A 1 character accept type will always be invalid (either a "." in the case 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of an extension or a "/" in the case of a MIME type). 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string unused; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (accept_type.length() <= 1 || 4816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::StringToLowerASCII(accept_type) != accept_type || 482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TrimWhitespaceASCII(accept_type, base::TRIM_ALL, &unused) != 483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TRIM_NONE) { 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 488