| 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 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/files/file_enumerator.h" | 11 #include "base/files/file_enumerator.h" |
| 12 #include "base/platform_file.h" | |
| 13 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
| 14 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 15 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 16 #include "chrome/browser/platform_util.h" | 15 #include "chrome/browser/platform_util.h" |
| 17 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
| 18 #include "chrome/browser/ui/browser.h" | 17 #include "chrome/browser/ui/browser.h" |
| 19 #include "chrome/browser/ui/browser_list.h" | 18 #include "chrome/browser/ui/browser_list.h" |
| 20 #include "chrome/browser/ui/chrome_select_file_policy.h" | 19 #include "chrome/browser/ui/chrome_select_file_policy.h" |
| 21 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
| 22 #include "content/public/browser/notification_details.h" | 21 #include "content/public/browser/notification_details.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 39 | 38 |
| 40 namespace { | 39 namespace { |
| 41 | 40 |
| 42 // There is only one file-selection happening at any given time, | 41 // There is only one file-selection happening at any given time, |
| 43 // so we allocate an enumeration ID for that purpose. All IDs from | 42 // so we allocate an enumeration ID for that purpose. All IDs from |
| 44 // the renderer must start at 0 and increase. | 43 // the renderer must start at 0 and increase. |
| 45 const int kFileSelectEnumerationId = -1; | 44 const int kFileSelectEnumerationId = -1; |
| 46 | 45 |
| 47 void NotifyRenderViewHost(RenderViewHost* render_view_host, | 46 void NotifyRenderViewHost(RenderViewHost* render_view_host, |
| 48 const std::vector<ui::SelectedFileInfo>& files, | 47 const std::vector<ui::SelectedFileInfo>& files, |
| 49 ui::SelectFileDialog::Type dialog_type) { | 48 FileChooserParams::Mode dialog_mode) { |
| 50 const int kReadFilePermissions = | 49 render_view_host->FilesSelectedInChooser(files, dialog_mode); |
| 51 base::PLATFORM_FILE_OPEN | | |
| 52 base::PLATFORM_FILE_READ | | |
| 53 base::PLATFORM_FILE_EXCLUSIVE_READ | | |
| 54 base::PLATFORM_FILE_ASYNC; | |
| 55 | |
| 56 const int kWriteFilePermissions = | |
| 57 base::PLATFORM_FILE_CREATE | | |
| 58 base::PLATFORM_FILE_CREATE_ALWAYS | | |
| 59 base::PLATFORM_FILE_OPEN | | |
| 60 base::PLATFORM_FILE_OPEN_ALWAYS | | |
| 61 base::PLATFORM_FILE_OPEN_TRUNCATED | | |
| 62 base::PLATFORM_FILE_WRITE | | |
| 63 base::PLATFORM_FILE_WRITE_ATTRIBUTES | | |
| 64 base::PLATFORM_FILE_ASYNC; | |
| 65 | |
| 66 int permissions = kReadFilePermissions; | |
| 67 if (dialog_type == ui::SelectFileDialog::SELECT_SAVEAS_FILE) | |
| 68 permissions = kWriteFilePermissions; | |
| 69 render_view_host->FilesSelectedInChooser(files, permissions); | |
| 70 } | 50 } |
| 71 | 51 |
| 72 // Converts a list of FilePaths to a list of ui::SelectedFileInfo. | 52 // Converts a list of FilePaths to a list of ui::SelectedFileInfo. |
| 73 std::vector<ui::SelectedFileInfo> FilePathListToSelectedFileInfoList( | 53 std::vector<ui::SelectedFileInfo> FilePathListToSelectedFileInfoList( |
| 74 const std::vector<base::FilePath>& paths) { | 54 const std::vector<base::FilePath>& paths) { |
| 75 std::vector<ui::SelectedFileInfo> selected_files; | 55 std::vector<ui::SelectedFileInfo> selected_files; |
| 76 for (size_t i = 0; i < paths.size(); ++i) { | 56 for (size_t i = 0; i < paths.size(); ++i) { |
| 77 selected_files.push_back( | 57 selected_files.push_back( |
| 78 ui::SelectedFileInfo(paths[i], paths[i])); | 58 ui::SelectedFileInfo(paths[i], paths[i])); |
| 79 } | 59 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 90 RenderViewHost* rvh_; | 70 RenderViewHost* rvh_; |
| 91 std::vector<base::FilePath> results_; | 71 std::vector<base::FilePath> results_; |
| 92 }; | 72 }; |
| 93 | 73 |
| 94 FileSelectHelper::FileSelectHelper(Profile* profile) | 74 FileSelectHelper::FileSelectHelper(Profile* profile) |
| 95 : profile_(profile), | 75 : profile_(profile), |
| 96 render_view_host_(NULL), | 76 render_view_host_(NULL), |
| 97 web_contents_(NULL), | 77 web_contents_(NULL), |
| 98 select_file_dialog_(), | 78 select_file_dialog_(), |
| 99 select_file_types_(), | 79 select_file_types_(), |
| 100 dialog_type_(ui::SelectFileDialog::SELECT_OPEN_FILE) { | 80 dialog_type_(ui::SelectFileDialog::SELECT_OPEN_FILE), |
| 81 dialog_mode_(FileChooserParams::Open) { |
| 101 } | 82 } |
| 102 | 83 |
| 103 FileSelectHelper::~FileSelectHelper() { | 84 FileSelectHelper::~FileSelectHelper() { |
| 104 // There may be pending file dialogs, we need to tell them that we've gone | 85 // There may be pending file dialogs, we need to tell them that we've gone |
| 105 // away so they don't try and call back to us. | 86 // away so they don't try and call back to us. |
| 106 if (select_file_dialog_.get()) | 87 if (select_file_dialog_.get()) |
| 107 select_file_dialog_->ListenerDestroyed(); | 88 select_file_dialog_->ListenerDestroyed(); |
| 108 | 89 |
| 109 // Stop any pending directory enumeration, prevent a callback, and free | 90 // Stop any pending directory enumeration, prevent a callback, and free |
| 110 // allocated memory. | 91 // allocated memory. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 141 profile_->set_last_selected_directory(file.file_path.DirName()); | 122 profile_->set_last_selected_directory(file.file_path.DirName()); |
| 142 | 123 |
| 143 const base::FilePath& path = file.local_path; | 124 const base::FilePath& path = file.local_path; |
| 144 if (dialog_type_ == ui::SelectFileDialog::SELECT_FOLDER) { | 125 if (dialog_type_ == ui::SelectFileDialog::SELECT_FOLDER) { |
| 145 StartNewEnumeration(path, kFileSelectEnumerationId, render_view_host_); | 126 StartNewEnumeration(path, kFileSelectEnumerationId, render_view_host_); |
| 146 return; | 127 return; |
| 147 } | 128 } |
| 148 | 129 |
| 149 std::vector<ui::SelectedFileInfo> files; | 130 std::vector<ui::SelectedFileInfo> files; |
| 150 files.push_back(file); | 131 files.push_back(file); |
| 151 NotifyRenderViewHost(render_view_host_, files, dialog_type_); | 132 NotifyRenderViewHost(render_view_host_, files, dialog_mode_); |
| 152 | 133 |
| 153 // No members should be accessed from here on. | 134 // No members should be accessed from here on. |
| 154 RunFileChooserEnd(); | 135 RunFileChooserEnd(); |
| 155 } | 136 } |
| 156 | 137 |
| 157 void FileSelectHelper::MultiFilesSelected( | 138 void FileSelectHelper::MultiFilesSelected( |
| 158 const std::vector<base::FilePath>& files, | 139 const std::vector<base::FilePath>& files, |
| 159 void* params) { | 140 void* params) { |
| 160 std::vector<ui::SelectedFileInfo> selected_files = | 141 std::vector<ui::SelectedFileInfo> selected_files = |
| 161 FilePathListToSelectedFileInfoList(files); | 142 FilePathListToSelectedFileInfoList(files); |
| 162 | 143 |
| 163 MultiFilesSelectedWithExtraInfo(selected_files, params); | 144 MultiFilesSelectedWithExtraInfo(selected_files, params); |
| 164 } | 145 } |
| 165 | 146 |
| 166 void FileSelectHelper::MultiFilesSelectedWithExtraInfo( | 147 void FileSelectHelper::MultiFilesSelectedWithExtraInfo( |
| 167 const std::vector<ui::SelectedFileInfo>& files, | 148 const std::vector<ui::SelectedFileInfo>& files, |
| 168 void* params) { | 149 void* params) { |
| 169 if (!files.empty()) | 150 if (!files.empty()) |
| 170 profile_->set_last_selected_directory(files[0].file_path.DirName()); | 151 profile_->set_last_selected_directory(files[0].file_path.DirName()); |
| 171 if (!render_view_host_) | 152 if (!render_view_host_) |
| 172 return; | 153 return; |
| 173 | 154 |
| 174 NotifyRenderViewHost(render_view_host_, files, dialog_type_); | 155 NotifyRenderViewHost(render_view_host_, files, dialog_mode_); |
| 175 | 156 |
| 176 // No members should be accessed from here on. | 157 // No members should be accessed from here on. |
| 177 RunFileChooserEnd(); | 158 RunFileChooserEnd(); |
| 178 } | 159 } |
| 179 | 160 |
| 180 void FileSelectHelper::FileSelectionCanceled(void* params) { | 161 void FileSelectHelper::FileSelectionCanceled(void* params) { |
| 181 if (!render_view_host_) | 162 if (!render_view_host_) |
| 182 return; | 163 return; |
| 183 | 164 |
| 184 // If the user cancels choosing a file to upload we pass back an | 165 // If the user cancels choosing a file to upload we pass back an |
| 185 // empty vector. | 166 // empty vector. |
| 186 NotifyRenderViewHost( | 167 NotifyRenderViewHost( |
| 187 render_view_host_, std::vector<ui::SelectedFileInfo>(), | 168 render_view_host_, std::vector<ui::SelectedFileInfo>(), |
| 188 dialog_type_); | 169 dialog_mode_); |
| 189 | 170 |
| 190 // No members should be accessed from here on. | 171 // No members should be accessed from here on. |
| 191 RunFileChooserEnd(); | 172 RunFileChooserEnd(); |
| 192 } | 173 } |
| 193 | 174 |
| 194 void FileSelectHelper::StartNewEnumeration(const base::FilePath& path, | 175 void FileSelectHelper::StartNewEnumeration(const base::FilePath& path, |
| 195 int request_id, | 176 int request_id, |
| 196 RenderViewHost* render_view_host) { | 177 RenderViewHost* render_view_host) { |
| 197 scoped_ptr<ActiveDirectoryEnumeration> entry(new ActiveDirectoryEnumeration); | 178 scoped_ptr<ActiveDirectoryEnumeration> entry(new ActiveDirectoryEnumeration); |
| 198 entry->rvh_ = render_view_host; | 179 entry->rvh_ = render_view_host; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 return; | 215 return; |
| 235 if (error) { | 216 if (error) { |
| 236 FileSelectionCanceled(NULL); | 217 FileSelectionCanceled(NULL); |
| 237 return; | 218 return; |
| 238 } | 219 } |
| 239 | 220 |
| 240 std::vector<ui::SelectedFileInfo> selected_files = | 221 std::vector<ui::SelectedFileInfo> selected_files = |
| 241 FilePathListToSelectedFileInfoList(entry->results_); | 222 FilePathListToSelectedFileInfoList(entry->results_); |
| 242 | 223 |
| 243 if (id == kFileSelectEnumerationId) | 224 if (id == kFileSelectEnumerationId) |
| 244 NotifyRenderViewHost(entry->rvh_, selected_files, dialog_type_); | 225 NotifyRenderViewHost(entry->rvh_, selected_files, dialog_mode_); |
| 245 else | 226 else |
| 246 entry->rvh_->DirectoryEnumerationFinished(id, entry->results_); | 227 entry->rvh_->DirectoryEnumerationFinished(id, entry->results_); |
| 247 | 228 |
| 248 EnumerateDirectoryEnd(); | 229 EnumerateDirectoryEnd(); |
| 249 } | 230 } |
| 250 | 231 |
| 251 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> | 232 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> |
| 252 FileSelectHelper::GetFileTypesFromAcceptType( | 233 FileSelectHelper::GetFileTypesFromAcceptType( |
| 253 const std::vector<string16>& accept_types) { | 234 const std::vector<string16>& accept_types) { |
| 254 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type( | 235 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type( |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 if (!render_view_host_ || !web_contents_) { | 361 if (!render_view_host_ || !web_contents_) { |
| 381 // If the renderer was destroyed before we started, just cancel the | 362 // If the renderer was destroyed before we started, just cancel the |
| 382 // operation. | 363 // operation. |
| 383 RunFileChooserEnd(); | 364 RunFileChooserEnd(); |
| 384 return; | 365 return; |
| 385 } | 366 } |
| 386 | 367 |
| 387 select_file_dialog_ = ui::SelectFileDialog::Create( | 368 select_file_dialog_ = ui::SelectFileDialog::Create( |
| 388 this, new ChromeSelectFilePolicy(web_contents_)); | 369 this, new ChromeSelectFilePolicy(web_contents_)); |
| 389 | 370 |
| 371 dialog_mode_ = params.mode; |
| 390 switch (params.mode) { | 372 switch (params.mode) { |
| 391 case FileChooserParams::Open: | 373 case FileChooserParams::Open: |
| 392 dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE; | 374 dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE; |
| 393 break; | 375 break; |
| 394 case FileChooserParams::OpenMultiple: | 376 case FileChooserParams::OpenMultiple: |
| 395 dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE; | 377 dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE; |
| 396 break; | 378 break; |
| 397 case FileChooserParams::OpenFolder: | 379 case FileChooserParams::OpenFolder: |
| 398 dialog_type_ = ui::SelectFileDialog::SELECT_FOLDER; | 380 dialog_type_ = ui::SelectFileDialog::SELECT_FOLDER; |
| 399 break; | 381 break; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 // A 1 character accept type will always be invalid (either a "." in the case | 477 // A 1 character accept type will always be invalid (either a "." in the case |
| 496 // of an extension or a "/" in the case of a MIME type). | 478 // of an extension or a "/" in the case of a MIME type). |
| 497 std::string unused; | 479 std::string unused; |
| 498 if (accept_type.length() <= 1 || | 480 if (accept_type.length() <= 1 || |
| 499 StringToLowerASCII(accept_type) != accept_type || | 481 StringToLowerASCII(accept_type) != accept_type || |
| 500 TrimWhitespaceASCII(accept_type, TRIM_ALL, &unused) != TRIM_NONE) { | 482 TrimWhitespaceASCII(accept_type, TRIM_ALL, &unused) != TRIM_NONE) { |
| 501 return false; | 483 return false; |
| 502 } | 484 } |
| 503 return true; | 485 return true; |
| 504 } | 486 } |
| OLD | NEW |