Index: chrome/browser/extensions/api/file_system/file_system_api.cc |
diff --git a/chrome/browser/extensions/api/file_system/file_system_api.cc b/chrome/browser/extensions/api/file_system/file_system_api.cc |
index be3d9bd20df38d2326e754d0c04ee62b5cbdc4ff..5c1649807ed810c6b4908eca09398c86d9679bc3 100644 |
--- a/chrome/browser/extensions/api/file_system/file_system_api.cc |
+++ b/chrome/browser/extensions/api/file_system/file_system_api.cc |
@@ -4,6 +4,7 @@ |
#include "chrome/browser/extensions/api/file_system/file_system_api.h" |
+#include "apps/saved_files_service.h" |
#include "base/bind.h" |
#include "base/file_util.h" |
#include "base/files/file_path.h" |
@@ -47,6 +48,8 @@ |
#include "chrome/browser/chromeos/drive/file_system_util.h" |
#endif |
+using apps::SavedFileEntry; |
+using apps::SavedFilesService; |
using fileapi::IsolatedContext; |
const char kInvalidParameters[] = "Invalid parameters"; |
@@ -57,6 +60,7 @@ const char kUserCancelled[] = "User cancelled"; |
const char kWritableFileError[] = "Invalid file for writing"; |
const char kRequiresFileSystemWriteError[] = |
"Operation requires fileSystem.write permission"; |
+const char kUnknownIdError[] = "Unknown id"; |
namespace file_system = extensions::api::file_system; |
namespace ChooseEntry = file_system::ChooseEntry; |
@@ -140,13 +144,14 @@ bool g_skip_picker_for_test = false; |
bool g_use_suggested_path_for_test = false; |
base::FilePath* g_path_to_be_picked_for_test; |
-bool GetFilePathOfFileEntry(const std::string& filesystem_name, |
- const std::string& filesystem_path, |
- const content::RenderViewHost* render_view_host, |
- base::FilePath* file_path, |
- std::string* error) { |
- std::string filesystem_id; |
- if (!fileapi::CrackIsolatedFileSystemName(filesystem_name, &filesystem_id)) { |
+bool GetFileSystemAndPathOfFileEntry( |
+ const std::string& filesystem_name, |
+ const std::string& filesystem_path, |
+ const content::RenderViewHost* render_view_host, |
+ std::string* filesystem_id, |
+ base::FilePath* file_path, |
+ std::string* error) { |
+ if (!fileapi::CrackIsolatedFileSystemName(filesystem_name, filesystem_id)) { |
*error = kInvalidParameters; |
return false; |
} |
@@ -156,7 +161,7 @@ bool GetFilePathOfFileEntry(const std::string& filesystem_name, |
content::ChildProcessSecurityPolicy* policy = |
content::ChildProcessSecurityPolicy::GetInstance(); |
if (!policy->CanReadFileSystem(render_view_host->GetProcess()->GetID(), |
- filesystem_id)) { |
+ *filesystem_id)) { |
*error = kSecurityError; |
return false; |
} |
@@ -164,10 +169,10 @@ bool GetFilePathOfFileEntry(const std::string& filesystem_name, |
IsolatedContext* context = IsolatedContext::GetInstance(); |
base::FilePath relative_path = |
base::FilePath::FromUTF8Unsafe(filesystem_path); |
- base::FilePath virtual_path = context->CreateVirtualRootPath(filesystem_id) |
+ base::FilePath virtual_path = context->CreateVirtualRootPath(*filesystem_id) |
.Append(relative_path); |
if (!context->CrackVirtualPath(virtual_path, |
- &filesystem_id, |
+ filesystem_id, |
NULL, |
file_path)) { |
*error = kInvalidParameters; |
@@ -177,6 +182,20 @@ bool GetFilePathOfFileEntry(const std::string& filesystem_name, |
return true; |
} |
+bool GetFilePathOfFileEntry(const std::string& filesystem_name, |
+ const std::string& filesystem_path, |
+ const content::RenderViewHost* render_view_host, |
+ base::FilePath* file_path, |
+ std::string* error) { |
+ std::string filesystem_id; |
+ return GetFileSystemAndPathOfFileEntry(filesystem_name, |
+ filesystem_path, |
+ render_view_host, |
+ &filesystem_id, |
+ file_path, |
+ error); |
+} |
+ |
bool DoCheckWritableFile(const base::FilePath& path) { |
// Don't allow links. |
if (file_util::PathExists(path) && file_util::IsLink(path)) |
@@ -326,6 +345,11 @@ void FileSystemEntryFunction::CheckWritableFile(const base::FilePath& path) { |
void FileSystemEntryFunction::RegisterFileSystemAndSendResponse( |
const base::FilePath& path, EntryType entry_type) { |
+ RegisterFileSystemAndSendResponseWithIdOverride(path, entry_type, ""); |
+} |
+ |
+void FileSystemEntryFunction::RegisterFileSystemAndSendResponseWithIdOverride( |
+ const base::FilePath& path, EntryType entry_type, const std::string& id) { |
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
fileapi::IsolatedContext* isolated_context = |
@@ -342,7 +366,10 @@ void FileSystemEntryFunction::RegisterFileSystemAndSendResponse( |
SetResult(dict); |
dict->SetString("fileSystemId", file_entry.filesystem_id); |
dict->SetString("baseName", file_entry.registered_name); |
- dict->SetString("id", file_entry.id); |
+ if (id.empty()) |
+ dict->SetString("id", file_entry.id); |
+ else |
+ dict->SetString("id", id); |
SendResponse(true); |
} |
@@ -701,4 +728,77 @@ bool FileSystemChooseEntryFunction::RunImpl() { |
return true; |
} |
+bool FileSystemRetainEntryFunction::RunImpl() { |
+ std::string entry_id; |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &entry_id)); |
+ SavedFilesService* saved_files_service = SavedFilesService::Get(profile()); |
+ // Add the file to the retain list if it is not already on there. |
+ if (!saved_files_service->IsRetained(extension_->id(), entry_id) && |
+ !RetainFileEntry(entry_id)) { |
+ return false; |
+ } |
+ saved_files_service->MoveEntryToFrontOfQueue(extension_->id(), entry_id); |
+ return true; |
+} |
+ |
+bool FileSystemRetainEntryFunction::RetainFileEntry( |
+ const std::string& entry_id) { |
+ std::string filesystem_name; |
+ std::string filesystem_path; |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &filesystem_name)); |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &filesystem_path)); |
+ std::string filesystem_id; |
+ base::FilePath path; |
+ if (!GetFileSystemAndPathOfFileEntry(filesystem_name, |
+ filesystem_path, |
+ render_view_host_, |
+ &filesystem_id, |
+ &path, |
+ &error_)) { |
+ return false; |
+ } |
+ |
+ content::ChildProcessSecurityPolicy* policy = |
+ content::ChildProcessSecurityPolicy::GetInstance(); |
+ bool is_writable = policy->CanReadWriteFileSystem( |
+ render_view_host_->GetProcess()->GetID(), filesystem_id); |
+ SavedFilesService::Get(profile())->RetainFileEntry( |
+ extension_->id(), entry_id, path, is_writable); |
+ return true; |
+} |
+ |
+bool FileSystemIsRestorableFunction::RunImpl() { |
+ std::string entry_id; |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &entry_id)); |
+ SetResult(new base::FundamentalValue(SavedFilesService::Get( |
+ profile())->IsRetained(extension_->id(), entry_id))); |
+ return true; |
+} |
+ |
+bool FileSystemRestoreEntryFunction::RunImpl() { |
+ std::string entry_id; |
+ bool needs_new_entry; |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &entry_id)); |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &needs_new_entry)); |
+ SavedFileEntry file_entry; |
+ if (!SavedFilesService::Get(profile())->GetFileEntry( |
+ extension_->id(), entry_id, &file_entry)) { |
+ error_ = kUnknownIdError; |
+ return false; |
+ } |
+ SavedFilesService::Get(profile())->MoveEntryToFrontOfQueue( |
+ extension_->id(), entry_id); |
+ |
+ // Only create a new file entry if the renderer requests one. |
+ // |needs_new_entry| will be false if the renderer already has an Entry for |
+ // |entry_id|. |
+ if (needs_new_entry) { |
+ RegisterFileSystemAndSendResponseWithIdOverride( |
+ file_entry.path, |
+ file_entry.writable ? WRITABLE : READ_ONLY, |
+ file_entry.id); |
+ } |
+ return true; |
+} |
+ |
} // namespace extensions |