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 |