Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(456)

Side by Side Diff: chrome/browser/devtools/devtools_file_system_helper.cc

Issue 11570081: Support file system access in DevTools with isolated file system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/devtools/devtools_file_system_helper.h"
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/file_util.h"
11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/prefs/pref_service.h"
13 #include "chrome/browser/prefs/scoped_user_pref_update.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/chrome_select_file_policy.h"
16 #include "chrome/common/pref_names.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/child_process_security_policy.h"
19 #include "content/public/browser/render_process_host.h"
20 #include "content/public/browser/render_view_host.h"
21 #include "content/public/browser/web_contents.h"
22 #include "grit/generated_resources.h"
23 #include "ui/base/dialogs/select_file_dialog.h"
24 #include "ui/base/l10n/l10n_util.h"
25 #include "webkit/fileapi/isolated_context.h"
26
27 using content::BrowserThread;
28 using content::RenderViewHost;
29 using content::WebContents;
30
31 namespace {
32 const char kSecurityFileName[] = ".allow-devtools-edit";
33 }
34
35 class DevToolsFileSystemHelper::SelectFolderDialog
pfeldman 2012/12/24 19:01:03 This class is almost exactly the same as the one i
36 : public ui::SelectFileDialog::Listener,
37 public base::RefCounted<SelectFolderDialog> {
38 public:
39 explicit SelectFolderDialog(DevToolsFileSystemHelper* helper)
40 : helper_(helper) {
41 select_file_dialog_ = ui::SelectFileDialog::Create(
42 this, new ChromeSelectFilePolicy(NULL));
43 }
44
45 void ResetHelper() {
46 helper_ = NULL;
47 }
48
49 void Show() {
50 AddRef(); // Balanced in the three listener outcomes.
51 select_file_dialog_->SelectFile(ui::SelectFileDialog::SELECT_FOLDER,
52 string16(),
53 FilePath(),
54 NULL,
55 0,
56 FILE_PATH_LITERAL(""),
57 NULL,
58 NULL);
59 }
60
61 // ui::SelectFileDialog::Listener implementation.
62 virtual void FileSelected(const FilePath& path,
63 int index, void* params) {
64 if (helper_)
65 helper_->FolderSelected(path);
66 Release(); // Balanced in ::Show.
67 }
68
69 virtual void MultiFilesSelected(
70 const std::vector<FilePath>& files, void* params) {
71 Release(); // Balanced in ::Show.
72 NOTREACHED() << "Should not be able to select multiple files";
73 }
74
75 virtual void FileSelectionCanceled(void* params) {
76 if (helper_)
77 helper_->FolderSelectionCanceled();
78 Release(); // Balanced in ::Show.
79 }
80
81 private:
82 friend class base::RefCounted<SelectFolderDialog>;
83 virtual ~SelectFolderDialog() {}
84
85 scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
86 DevToolsFileSystemHelper* helper_;
87 };
88
89 DevToolsFileSystemHelper::FileSystem::FileSystem(
90 const std::string& filesystem_id,
91 const std::string& registered_name,
92 const std::string& file_system_path)
93 : filesystem_id(filesystem_id),
94 registered_name(registered_name),
95 file_system_path(file_system_path) {
96 }
97
98 DevToolsFileSystemHelper::DevToolsFileSystemHelper(
99 WebContents* web_contents,
100 Profile* profile,
101 Delegate* delegate)
102 : web_contents_(web_contents),
103 profile_(profile),
104 delegate_(delegate) {
105 }
106
107 DevToolsFileSystemHelper::~DevToolsFileSystemHelper() {
108 if (select_folder_dialog_)
109 select_folder_dialog_->ResetHelper();
110 }
111
112 namespace {
113
114 fileapi::IsolatedContext* isolated_context() {
115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
116 fileapi::IsolatedContext* isolated_context =
117 fileapi::IsolatedContext::GetInstance();
118 DCHECK(isolated_context);
119 return isolated_context;
120 }
121
122 std::string RegisterFileSystem(WebContents* web_contents,
123 const FilePath& path,
124 std::string* registered_name) {
125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
126 std::string file_system_id = isolated_context()->RegisterFileSystemForPath(
127 fileapi::kFileSystemTypeNativeLocal, path, registered_name);
128
129 content::ChildProcessSecurityPolicy* policy =
130 content::ChildProcessSecurityPolicy::GetInstance();
131 RenderViewHost* render_view_host = web_contents->GetRenderViewHost();
132 int renderer_id = render_view_host->GetProcess()->GetID();
133 policy->GrantReadWriteFileSystem(renderer_id, file_system_id);
134
135 // We only need file level access for reading FileEntries. Saving FileEntries
136 // just needs the file system to have read/write access, which is granted
137 // above if required.
138 if (!policy->CanReadFile(renderer_id, path))
139 policy->GrantReadFile(renderer_id, path);
140
141 return file_system_id;
142 }
143
144 bool CheckSecurityFileExistsInFolder(const FilePath& path) {
145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
146 FilePath security_file_path = path.Append(
147 FILE_PATH_LITERAL(kSecurityFileName));
148 return file_util::PathExists(security_file_path);
149 }
150
151 } // namespace
152
153 void DevToolsFileSystemHelper::SelectFolderAndGrantPermission() {
154 if (select_folder_dialog_)
155 select_folder_dialog_->ResetHelper();
156 select_folder_dialog_ = new SelectFolderDialog(this);
157 select_folder_dialog_->Show();
158 }
159
160 void DevToolsFileSystemHelper::FolderSelected(const FilePath& path) {
161 BrowserThread::PostTask(
162 BrowserThread::FILE, FROM_HERE,
163 base::Bind(&DevToolsFileSystemHelper::CheckSelectedPath, this, path));
164 }
165
166 void DevToolsFileSystemHelper::FolderSelectionCanceled() {
167 delegate_->FileSystemFolderSelectionCanceled();
168 }
169
170 void DevToolsFileSystemHelper::CheckSelectedPath(const FilePath& path) {
171 if (!CheckSecurityFileExistsInFolder(path)) {
172 BrowserThread::PostTask(
173 BrowserThread::UI, FROM_HERE,
174 base::Bind(&DevToolsFileSystemHelper::SelectedFileSystemForbidden,
175 this));
176 return;
177 }
178
179 BrowserThread::PostTask(
180 BrowserThread::UI, FROM_HERE,
181 base::Bind(&DevToolsFileSystemHelper::SelectedFileSystemPermitted,
182 this,
183 path));
184 }
185
186 void DevToolsFileSystemHelper::SelectedFileSystemPermitted(
187 const FilePath& path) {
188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
189 std::string registered_name;
190 std::string file_system_id = RegisterFileSystem(web_contents_,
191 path,
192 &registered_name);
193 std::string file_system_path = path.AsUTF8Unsafe();
194
195 DictionaryPrefUpdate update(profile_->GetPrefs(),
196 prefs::kDevToolsSavedFileSystemPathes);
197 DictionaryValue* file_systems_pathes_value = update.Get();
198 file_systems_pathes_value->Set(file_system_path, Value::CreateNullValue());
199
200 FileSystem file_system(file_system_id, registered_name, file_system_path);
201 delegate_->FileSystemFolderSelected(file_system);
202 }
203
204 void DevToolsFileSystemHelper::SelectedFileSystemForbidden() {
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
206 std::string error_string = l10n_util::GetStringFUTF8(
207 IDS_DEV_TOOLS_FILE_SYSTEM_SECURITY_FILE_NOT_EXISTS_MESSAGE,
208 UTF8ToUTF16(kSecurityFileName));
209 delegate_->FileSystemFolderSelectionError(error_string);
210 }
211
212 void DevToolsFileSystemHelper::RequestPermissions() {
213 const DictionaryValue* file_systems_pathes_value =
214 profile_->GetPrefs()->GetDictionary(
215 prefs::kDevToolsSavedFileSystemPathes);
216 std::vector<FilePath> saved_pathes;
217 DictionaryValue::key_iterator it = file_systems_pathes_value->begin_keys();
218 for (; it != file_systems_pathes_value->end_keys(); ++it) {
219 std::string file_system_path = *it;
220 FilePath path = FilePath::FromUTF8Unsafe(file_system_path);
221 saved_pathes.push_back(path);
222 }
223
224 BrowserThread::PostTask(
225 BrowserThread::FILE, FROM_HERE,
226 base::Bind(&DevToolsFileSystemHelper::CheckSavedPathes,
227 this,
228 saved_pathes));
229 }
230
231 void DevToolsFileSystemHelper::CheckSavedPathes(
232 const std::vector<FilePath>& file_pathes) {
233 std::vector<FilePath> permitted_pathes;
234 std::vector<FilePath>::const_iterator it;
235 for (it = file_pathes.begin(); it != file_pathes.end(); ++it) {
236 if (CheckSecurityFileExistsInFolder(*it))
237 permitted_pathes.push_back(*it);
238 }
239
240 BrowserThread::PostTask(
241 BrowserThread::UI, FROM_HERE,
242 base::Bind(&DevToolsFileSystemHelper::RegisterSavedFileSystems,
243 this,
244 permitted_pathes));
245 }
246
247 void DevToolsFileSystemHelper::RegisterSavedFileSystems(
248 const std::vector<FilePath>& file_pathes) {
249 std::vector<FileSystem> file_systems;
250 std::vector<FilePath>::const_iterator it;
251 for (it = file_pathes.begin(); it != file_pathes.end(); ++it) {
252 std::string registered_name;
253 std::string file_system_id = RegisterFileSystem(web_contents_,
254 *it,
255 &registered_name);
256 std::string file_system_path = it->AsUTF8Unsafe();
257 FileSystem file_system(file_system_id, registered_name, file_system_path);
258 file_systems.push_back(file_system);
259 }
260 delegate_->FileSystemPermissionsLoaded(file_systems);
261 }
262
263 void DevToolsFileSystemHelper::RevokePermission(
264 const std::string& file_system_path) {
265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
266 FilePath path = FilePath::FromUTF8Unsafe(file_system_path);
267 isolated_context()->RevokeFileSystemByPath(path);
268
269 DictionaryPrefUpdate update(profile_->GetPrefs(),
270 prefs::kDevToolsSavedFileSystemPathes);
271 DictionaryValue* file_systems_pathes_value = update.Get();
272 file_systems_pathes_value->RemoveWithoutPathExpansion(file_system_path, NULL);
273 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698