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/extensions/api/file_system/file_system_api.h" | 5 #include "chrome/browser/extensions/api/file_system/file_system_api.h" |
6 | 6 |
| 7 #include "apps/saved_files_service.h" |
7 #include "base/bind.h" | 8 #include "base/bind.h" |
8 #include "base/file_util.h" | 9 #include "base/file_util.h" |
9 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/path_service.h" | 12 #include "base/path_service.h" |
12 #include "base/string_util.h" | 13 #include "base/string_util.h" |
13 #include "base/strings/sys_string_conversions.h" | 14 #include "base/strings/sys_string_conversions.h" |
14 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
15 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" | 16 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" |
16 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
(...skipping 23 matching lines...) Expand all Loading... |
40 | 41 |
41 #if defined(OS_MACOSX) | 42 #if defined(OS_MACOSX) |
42 #include <CoreFoundation/CoreFoundation.h> | 43 #include <CoreFoundation/CoreFoundation.h> |
43 #include "base/mac/foundation_util.h" | 44 #include "base/mac/foundation_util.h" |
44 #endif | 45 #endif |
45 | 46 |
46 #if defined(OS_CHROMEOS) | 47 #if defined(OS_CHROMEOS) |
47 #include "chrome/browser/chromeos/drive/file_system_util.h" | 48 #include "chrome/browser/chromeos/drive/file_system_util.h" |
48 #endif | 49 #endif |
49 | 50 |
| 51 using apps::SavedFileEntry; |
| 52 using apps::SavedFilesService; |
50 using fileapi::IsolatedContext; | 53 using fileapi::IsolatedContext; |
51 | 54 |
52 const char kInvalidParameters[] = "Invalid parameters"; | 55 const char kInvalidParameters[] = "Invalid parameters"; |
53 const char kSecurityError[] = "Security error"; | 56 const char kSecurityError[] = "Security error"; |
54 const char kInvalidCallingPage[] = "Invalid calling page. This function can't " | 57 const char kInvalidCallingPage[] = "Invalid calling page. This function can't " |
55 "be called from a background page."; | 58 "be called from a background page."; |
56 const char kUserCancelled[] = "User cancelled"; | 59 const char kUserCancelled[] = "User cancelled"; |
57 const char kWritableFileError[] = "Invalid file for writing"; | 60 const char kWritableFileError[] = "Invalid file for writing"; |
58 const char kRequiresFileSystemWriteError[] = | 61 const char kRequiresFileSystemWriteError[] = |
59 "Operation requires fileSystem.write permission"; | 62 "Operation requires fileSystem.write permission"; |
| 63 const char kUnknownIdError[] = "Unknown id"; |
60 | 64 |
61 namespace file_system = extensions::api::file_system; | 65 namespace file_system = extensions::api::file_system; |
62 namespace ChooseEntry = file_system::ChooseEntry; | 66 namespace ChooseEntry = file_system::ChooseEntry; |
63 | 67 |
64 namespace { | 68 namespace { |
65 | 69 |
66 #if defined(OS_MACOSX) | 70 #if defined(OS_MACOSX) |
67 // Retrieves the localized display name for the base name of the given path. | 71 // Retrieves the localized display name for the base name of the given path. |
68 // If the path is not localized, this will just return the base name. | 72 // If the path is not localized, this will just return the base name. |
69 std::string GetDisplayBaseName(const base::FilePath& path) { | 73 std::string GetDisplayBaseName(const base::FilePath& path) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 return display_path; | 137 return display_path; |
134 #endif | 138 #endif |
135 return source_path; | 139 return source_path; |
136 } | 140 } |
137 #endif // defined(OS_MACOSX) | 141 #endif // defined(OS_MACOSX) |
138 | 142 |
139 bool g_skip_picker_for_test = false; | 143 bool g_skip_picker_for_test = false; |
140 bool g_use_suggested_path_for_test = false; | 144 bool g_use_suggested_path_for_test = false; |
141 base::FilePath* g_path_to_be_picked_for_test; | 145 base::FilePath* g_path_to_be_picked_for_test; |
142 | 146 |
143 bool GetFilePathOfFileEntry(const std::string& filesystem_name, | 147 bool GetFileSystemAndPathOfFileEntry( |
144 const std::string& filesystem_path, | 148 const std::string& filesystem_name, |
145 const content::RenderViewHost* render_view_host, | 149 const std::string& filesystem_path, |
146 base::FilePath* file_path, | 150 const content::RenderViewHost* render_view_host, |
147 std::string* error) { | 151 std::string* filesystem_id, |
148 std::string filesystem_id; | 152 base::FilePath* file_path, |
149 if (!fileapi::CrackIsolatedFileSystemName(filesystem_name, &filesystem_id)) { | 153 std::string* error) { |
| 154 if (!fileapi::CrackIsolatedFileSystemName(filesystem_name, filesystem_id)) { |
150 *error = kInvalidParameters; | 155 *error = kInvalidParameters; |
151 return false; | 156 return false; |
152 } | 157 } |
153 | 158 |
154 // Only return the display path if the process has read access to the | 159 // Only return the display path if the process has read access to the |
155 // filesystem. | 160 // filesystem. |
156 content::ChildProcessSecurityPolicy* policy = | 161 content::ChildProcessSecurityPolicy* policy = |
157 content::ChildProcessSecurityPolicy::GetInstance(); | 162 content::ChildProcessSecurityPolicy::GetInstance(); |
158 if (!policy->CanReadFileSystem(render_view_host->GetProcess()->GetID(), | 163 if (!policy->CanReadFileSystem(render_view_host->GetProcess()->GetID(), |
159 filesystem_id)) { | 164 *filesystem_id)) { |
160 *error = kSecurityError; | 165 *error = kSecurityError; |
161 return false; | 166 return false; |
162 } | 167 } |
163 | 168 |
164 IsolatedContext* context = IsolatedContext::GetInstance(); | 169 IsolatedContext* context = IsolatedContext::GetInstance(); |
165 base::FilePath relative_path = | 170 base::FilePath relative_path = |
166 base::FilePath::FromUTF8Unsafe(filesystem_path); | 171 base::FilePath::FromUTF8Unsafe(filesystem_path); |
167 base::FilePath virtual_path = context->CreateVirtualRootPath(filesystem_id) | 172 base::FilePath virtual_path = context->CreateVirtualRootPath(*filesystem_id) |
168 .Append(relative_path); | 173 .Append(relative_path); |
169 if (!context->CrackVirtualPath(virtual_path, | 174 if (!context->CrackVirtualPath(virtual_path, |
170 &filesystem_id, | 175 filesystem_id, |
171 NULL, | 176 NULL, |
172 file_path)) { | 177 file_path)) { |
173 *error = kInvalidParameters; | 178 *error = kInvalidParameters; |
174 return false; | 179 return false; |
175 } | 180 } |
176 | 181 |
177 return true; | 182 return true; |
178 } | 183 } |
179 | 184 |
| 185 bool GetFilePathOfFileEntry(const std::string& filesystem_name, |
| 186 const std::string& filesystem_path, |
| 187 const content::RenderViewHost* render_view_host, |
| 188 base::FilePath* file_path, |
| 189 std::string* error) { |
| 190 std::string filesystem_id; |
| 191 return GetFileSystemAndPathOfFileEntry(filesystem_name, |
| 192 filesystem_path, |
| 193 render_view_host, |
| 194 &filesystem_id, |
| 195 file_path, |
| 196 error); |
| 197 } |
| 198 |
180 bool DoCheckWritableFile(const base::FilePath& path) { | 199 bool DoCheckWritableFile(const base::FilePath& path) { |
181 // Don't allow links. | 200 // Don't allow links. |
182 if (file_util::PathExists(path) && file_util::IsLink(path)) | 201 if (file_util::PathExists(path) && file_util::IsLink(path)) |
183 return false; | 202 return false; |
184 | 203 |
185 // Create the file if it doesn't already exist. | 204 // Create the file if it doesn't already exist. |
186 base::PlatformFileError error = base::PLATFORM_FILE_OK; | 205 base::PlatformFileError error = base::PLATFORM_FILE_OK; |
187 int creation_flags = base::PLATFORM_FILE_CREATE | | 206 int creation_flags = base::PLATFORM_FILE_CREATE | |
188 base::PLATFORM_FILE_READ | | 207 base::PLATFORM_FILE_READ | |
189 base::PLATFORM_FILE_WRITE; | 208 base::PLATFORM_FILE_WRITE; |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 base::Bind(&CheckRemoteWritableFile, on_success, on_failure)); | 338 base::Bind(&CheckRemoteWritableFile, on_success, on_failure)); |
320 return; | 339 return; |
321 } | 340 } |
322 #endif | 341 #endif |
323 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, | 342 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, |
324 base::Bind(&CheckLocalWritableFile, path, on_success, on_failure)); | 343 base::Bind(&CheckLocalWritableFile, path, on_success, on_failure)); |
325 } | 344 } |
326 | 345 |
327 void FileSystemEntryFunction::RegisterFileSystemAndSendResponse( | 346 void FileSystemEntryFunction::RegisterFileSystemAndSendResponse( |
328 const base::FilePath& path, EntryType entry_type) { | 347 const base::FilePath& path, EntryType entry_type) { |
| 348 RegisterFileSystemAndSendResponseWithIdOverride(path, entry_type, ""); |
| 349 } |
| 350 |
| 351 void FileSystemEntryFunction::RegisterFileSystemAndSendResponseWithIdOverride( |
| 352 const base::FilePath& path, EntryType entry_type, const std::string& id) { |
329 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 353 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
330 | 354 |
331 fileapi::IsolatedContext* isolated_context = | 355 fileapi::IsolatedContext* isolated_context = |
332 fileapi::IsolatedContext::GetInstance(); | 356 fileapi::IsolatedContext::GetInstance(); |
333 DCHECK(isolated_context); | 357 DCHECK(isolated_context); |
334 | 358 |
335 bool writable = entry_type == WRITABLE; | 359 bool writable = entry_type == WRITABLE; |
336 extensions::app_file_handler_util::GrantedFileEntry file_entry = | 360 extensions::app_file_handler_util::GrantedFileEntry file_entry = |
337 extensions::app_file_handler_util::CreateFileEntry(profile(), | 361 extensions::app_file_handler_util::CreateFileEntry(profile(), |
338 GetExtension()->id(), render_view_host_->GetProcess()->GetID(), path, | 362 GetExtension()->id(), render_view_host_->GetProcess()->GetID(), path, |
339 writable); | 363 writable); |
340 | 364 |
341 DictionaryValue* dict = new DictionaryValue(); | 365 DictionaryValue* dict = new DictionaryValue(); |
342 SetResult(dict); | 366 SetResult(dict); |
343 dict->SetString("fileSystemId", file_entry.filesystem_id); | 367 dict->SetString("fileSystemId", file_entry.filesystem_id); |
344 dict->SetString("baseName", file_entry.registered_name); | 368 dict->SetString("baseName", file_entry.registered_name); |
345 dict->SetString("id", file_entry.id); | 369 if (id.empty()) |
| 370 dict->SetString("id", file_entry.id); |
| 371 else |
| 372 dict->SetString("id", id); |
346 | 373 |
347 SendResponse(true); | 374 SendResponse(true); |
348 } | 375 } |
349 | 376 |
350 void FileSystemEntryFunction::HandleWritableFileError() { | 377 void FileSystemEntryFunction::HandleWritableFileError() { |
351 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 378 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
352 error_ = kWritableFileError; | 379 error_ = kWritableFileError; |
353 SendResponse(false); | 380 SendResponse(false); |
354 } | 381 } |
355 | 382 |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 FROM_HERE, | 721 FROM_HERE, |
695 base::Bind( | 722 base::Bind( |
696 &FileSystemChooseEntryFunction::SetInitialPathOnFileThread, this, | 723 &FileSystemChooseEntryFunction::SetInitialPathOnFileThread, this, |
697 suggested_name, previous_path), | 724 suggested_name, previous_path), |
698 base::Bind( | 725 base::Bind( |
699 &FileSystemChooseEntryFunction::ShowPicker, this, file_type_info, | 726 &FileSystemChooseEntryFunction::ShowPicker, this, file_type_info, |
700 picker_type, entry_type)); | 727 picker_type, entry_type)); |
701 return true; | 728 return true; |
702 } | 729 } |
703 | 730 |
| 731 bool FileSystemRetainEntryFunction::RunImpl() { |
| 732 std::string entry_id; |
| 733 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &entry_id)); |
| 734 SavedFilesService* saved_files_service = SavedFilesService::Get(profile()); |
| 735 // Add the file to the retain list if it is not already on there. |
| 736 if (!saved_files_service->IsRetained(extension_->id(), entry_id) && |
| 737 !RetainFileEntry(entry_id)) { |
| 738 return false; |
| 739 } |
| 740 saved_files_service->MoveEntryToFrontOfQueue(extension_->id(), entry_id); |
| 741 return true; |
| 742 } |
| 743 |
| 744 bool FileSystemRetainEntryFunction::RetainFileEntry( |
| 745 const std::string& entry_id) { |
| 746 std::string filesystem_name; |
| 747 std::string filesystem_path; |
| 748 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &filesystem_name)); |
| 749 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &filesystem_path)); |
| 750 std::string filesystem_id; |
| 751 base::FilePath path; |
| 752 if (!GetFileSystemAndPathOfFileEntry(filesystem_name, |
| 753 filesystem_path, |
| 754 render_view_host_, |
| 755 &filesystem_id, |
| 756 &path, |
| 757 &error_)) { |
| 758 return false; |
| 759 } |
| 760 |
| 761 content::ChildProcessSecurityPolicy* policy = |
| 762 content::ChildProcessSecurityPolicy::GetInstance(); |
| 763 bool is_writable = policy->CanReadWriteFileSystem( |
| 764 render_view_host_->GetProcess()->GetID(), filesystem_id); |
| 765 SavedFilesService::Get(profile())->RetainFileEntry( |
| 766 extension_->id(), entry_id, path, is_writable); |
| 767 return true; |
| 768 } |
| 769 |
| 770 bool FileSystemIsRestorableFunction::RunImpl() { |
| 771 std::string entry_id; |
| 772 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &entry_id)); |
| 773 SetResult(new base::FundamentalValue(SavedFilesService::Get( |
| 774 profile())->IsRetained(extension_->id(), entry_id))); |
| 775 return true; |
| 776 } |
| 777 |
| 778 bool FileSystemRestoreEntryFunction::RunImpl() { |
| 779 std::string entry_id; |
| 780 bool needs_new_entry; |
| 781 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &entry_id)); |
| 782 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &needs_new_entry)); |
| 783 SavedFileEntry file_entry; |
| 784 if (!SavedFilesService::Get(profile())->GetFileEntry( |
| 785 extension_->id(), entry_id, &file_entry)) { |
| 786 error_ = kUnknownIdError; |
| 787 return false; |
| 788 } |
| 789 SavedFilesService::Get(profile())->MoveEntryToFrontOfQueue( |
| 790 extension_->id(), entry_id); |
| 791 |
| 792 // Only create a new file entry if the renderer requests one. |
| 793 // |needs_new_entry| will be false if the renderer already has an Entry for |
| 794 // |entry_id|. |
| 795 if (needs_new_entry) { |
| 796 RegisterFileSystemAndSendResponseWithIdOverride( |
| 797 file_entry.path, |
| 798 file_entry.writable ? WRITABLE : READ_ONLY, |
| 799 file_entry.id); |
| 800 } |
| 801 return true; |
| 802 } |
| 803 |
704 } // namespace extensions | 804 } // namespace extensions |
OLD | NEW |