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

Side by Side Diff: chrome/browser/extensions/api/file_system/file_system_api.cc

Issue 14607023: Add support for persistent file access in apps. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: rebase Created 7 years, 7 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
OLDNEW
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
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
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
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
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->IsRegistered(extension_->id(), entry_id) &&
737 !RetainFileEntry(entry_id)) {
738 return false;
739 }
740 saved_files_service->EnqueueFileEntry(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())->RegisterFileEntry(
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())->IsRegistered(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 const SavedFileEntry* file_entry = SavedFilesService::Get(
784 profile())->GetFileEntry(extension_->id(), entry_id);
785 if (!file_entry) {
786 error_ = kUnknownIdError;
787 return false;
788 }
789
790 SavedFilesService::Get(profile())->EnqueueFileEntry(
791 extension_->id(), entry_id);
792
793 // Only create a new file entry if the renderer requests one.
794 // |needs_new_entry| will be false if the renderer already has an Entry for
795 // |entry_id|.
796 if (needs_new_entry) {
797 // Reuse the ID of the retained file entry so retainEntry returns the same
798 // ID that was passed to restoreEntry.
799 RegisterFileSystemAndSendResponseWithIdOverride(
800 file_entry->path,
801 file_entry->writable ? WRITABLE : READ_ONLY,
802 file_entry->id);
803 }
804 return true;
805 }
806
704 } // namespace extensions 807 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698