summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsatorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-02 04:29:32 +0000
committersatorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-02 04:29:32 +0000
commit587c68abad8fc27f7e47fff5fc58c673d440ef28 (patch)
tree4b90e76c67a2fa329d1fe695107662c7cfdd232e
parent7bc7d290d9ca82e8102568ec20e4e0f37dd85255 (diff)
downloadchromium_src-587c68abad8fc27f7e47fff5fc58c673d440ef28.zip
chromium_src-587c68abad8fc27f7e47fff5fc58c673d440ef28.tar.gz
chromium_src-587c68abad8fc27f7e47fff5fc58c673d440ef28.tar.bz2
file_manager: Move file system related API functions to separate files
This is a reland of crrev.com/215194 which was reverted in crrev.com/215195 This is part of an effort to split file_browser_private_api.cc BUG=257918 TEST=none R=hashimoto@chromium.org Review URL: https://codereview.chromium.org/21704002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215204 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc608
-rw-r--r--chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h190
-rw-r--r--chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc600
-rw-r--r--chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h218
-rw-r--r--chrome/chrome_browser_chromeos.gypi2
5 files changed, 829 insertions, 789 deletions
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc b/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc
index 126933e..a6f1f90 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc
@@ -4,207 +4,41 @@
#include "chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h"
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/types.h>
-#include <utime.h>
-
#include <map>
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/logging.h"
-#include "base/memory/scoped_vector.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "base/time/time.h"
#include "base/values.h"
-#include "chrome/browser/chromeos/drive/drive.pb.h"
#include "chrome/browser/chromeos/drive/drive_integration_service.h"
-#include "chrome/browser/chromeos/drive/file_system_interface.h"
-#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/drive/logging.h"
#include "chrome/browser/chromeos/extensions/file_manager/file_browser_private_api_factory.h"
-#include "chrome/browser/chromeos/extensions/file_manager/file_handler_util.h"
#include "chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.h"
-#include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h"
#include "chrome/browser/chromeos/extensions/file_manager/private_api_dialog.h"
#include "chrome/browser/chromeos/extensions/file_manager/private_api_drive.h"
+#include "chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h"
#include "chrome/browser/chromeos/extensions/file_manager/private_api_mount.h"
#include "chrome/browser/chromeos/extensions/file_manager/private_api_strings.h"
#include "chrome/browser/chromeos/extensions/file_manager/private_api_tasks.h"
#include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
#include "chrome/browser/chromeos/extensions/file_manager/zip_file_creator.h"
-#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
#include "chrome/browser/extensions/extension_function_registry.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/google_apis/gdata_wapi_parser.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/common/extensions/api/file_browser_handlers/file_browser_handler.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/extension_icon_set.h"
-#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
#include "chrome/common/pref_names.h"
-#include "chromeos/disks/disk_mount_manager.h"
-#include "content/public/browser/child_process_security_policy.h"
-#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/storage_partition.h"
#include "content/public/common/page_zoom.h"
-#include "net/base/escape.h"
-#include "net/base/network_change_notifier.h"
-#include "ui/shell_dialogs/selected_file_info.h"
#include "url/gurl.h"
-#include "webkit/browser/fileapi/file_system_context.h"
-#include "webkit/browser/fileapi/file_system_file_util.h"
-#include "webkit/browser/fileapi/file_system_operation_context.h"
-#include "webkit/browser/fileapi/file_system_url.h"
-#include "webkit/common/fileapi/file_system_types.h"
-#include "webkit/common/fileapi/file_system_util.h"
-
-using extensions::app_file_handler_util::FindFileHandlersForFiles;
-using extensions::app_file_handler_util::PathAndMimeTypeSet;
-using chromeos::disks::DiskMountManager;
-using content::BrowserContext;
-using content::BrowserThread;
-using content::ChildProcessSecurityPolicy;
-using content::WebContents;
-using extensions::Extension;
+
using extensions::ZipFileCreator;
-using fileapi::FileSystemURL;
namespace file_manager {
-namespace {
-
-// Error messages.
-const char kFileError[] = "File error %d";
-
-const DiskMountManager::Disk* GetVolumeAsDisk(const std::string& mount_path) {
- DiskMountManager* disk_mount_manager = DiskMountManager::GetInstance();
-
- DiskMountManager::MountPointMap::const_iterator mount_point_it =
- disk_mount_manager->mount_points().find(mount_path);
- if (mount_point_it == disk_mount_manager->mount_points().end())
- return NULL;
-
- const DiskMountManager::Disk* disk = disk_mount_manager->FindDiskBySourcePath(
- mount_point_it->second.source_path);
-
- return (disk && disk->is_hidden()) ? NULL : disk;
-}
-
-base::DictionaryValue* CreateValueFromDisk(
- Profile* profile,
- const std::string& extension_id,
- const DiskMountManager::Disk* volume) {
- base::DictionaryValue* volume_info = new base::DictionaryValue();
-
- std::string mount_path;
- if (!volume->mount_path().empty()) {
- base::FilePath relative_mount_path;
- file_manager_util::ConvertFileToRelativeFileSystemPath(
- profile, extension_id, base::FilePath(volume->mount_path()),
- &relative_mount_path);
- mount_path = relative_mount_path.value();
- }
-
- volume_info->SetString("devicePath", volume->device_path());
- volume_info->SetString("mountPath", mount_path);
- volume_info->SetString("systemPath", volume->system_path());
- volume_info->SetString("filePath", volume->file_path());
- volume_info->SetString("deviceLabel", volume->device_label());
- volume_info->SetString("driveLabel", volume->drive_label());
- volume_info->SetString("deviceType",
- DiskMountManager::DeviceTypeToString(volume->device_type()));
- volume_info->SetDouble("totalSize",
- static_cast<double>(volume->total_size_in_bytes()));
- volume_info->SetBoolean("isParent", volume->is_parent());
- volume_info->SetBoolean("isReadOnly", volume->is_read_only());
- volume_info->SetBoolean("hasMedia", volume->has_media());
- volume_info->SetBoolean("isOnBootDevice", volume->on_boot_device());
-
- return volume_info;
-}
-
-// Sets permissions for the Drive mount point so Files.app can access files
-// in the mount point directory. It's safe to call this function even if
-// Drive is disabled by the setting (i.e. prefs::kDisableDrive is true).
-void SetDriveMountPointPermissions(
- Profile* profile,
- const std::string& extension_id,
- content::RenderViewHost* render_view_host) {
- if (!render_view_host ||
- !render_view_host->GetSiteInstance() || !render_view_host->GetProcess()) {
- return;
- }
-
- content::SiteInstance* site_instance = render_view_host->GetSiteInstance();
- fileapi::ExternalFileSystemBackend* backend =
- BrowserContext::GetStoragePartition(profile, site_instance)->
- GetFileSystemContext()->external_backend();
- if (!backend)
- return;
-
- const base::FilePath mount_point = drive::util::GetDriveMountPointPath();
- // Grant R/W permissions to drive 'folder'. File API layer still
- // expects this to be satisfied.
- ChildProcessSecurityPolicy::GetInstance()->GrantCreateReadWriteFile(
- render_view_host->GetProcess()->GetID(), mount_point);
-
- base::FilePath mount_point_virtual;
- if (backend->GetVirtualPath(mount_point, &mount_point_virtual))
- backend->GrantFileAccessToExtension(extension_id, mount_point_virtual);
-}
-
-// Retrieves total and remaining available size on |mount_path|.
-void GetSizeStatsOnBlockingPool(const std::string& mount_path,
- uint64* total_size,
- uint64* remaining_size) {
- struct statvfs stat = {}; // Zero-clear
- if (HANDLE_EINTR(statvfs(mount_path.c_str(), &stat)) == 0) {
- *total_size =
- static_cast<uint64>(stat.f_blocks) * stat.f_frsize;
- *remaining_size =
- static_cast<uint64>(stat.f_bfree) * stat.f_frsize;
- }
-}
-
-// Retrieves the maximum file name length of the file system of |path|.
-// Returns 0 if it could not be queried.
-size_t GetFileNameMaxLengthOnBlockingPool(const std::string& path) {
- struct statvfs stat = {};
- if (statvfs(path.c_str(), &stat) != 0) {
- // The filesystem seems not supporting statvfs(). Assume it to be a commonly
- // used bound 255, and log the failure.
- LOG(ERROR) << "Cannot statvfs() the name length limit for: " << path;
- return 255;
- }
- return stat.f_namemax;
-}
-
-// Sets last modified date.
-bool SetLastModifiedOnBlockingPool(const base::FilePath& local_path,
- time_t timestamp) {
- if (local_path.empty())
- return false;
-
- struct stat stat_buffer;
- if (stat(local_path.value().c_str(), &stat_buffer) != 0)
- return false;
-
- struct utimbuf times;
- times.actime = stat_buffer.st_atime;
- times.modtime = timestamp;
- return utime(local_path.value().c_str(), &times) == 0;
-}
-
-} // namespace
FileBrowserPrivateAPI::FileBrowserPrivateAPI(Profile* profile)
: event_router_(new FileManagerEventRouter(profile)) {
@@ -242,18 +76,21 @@ FileBrowserPrivateAPI::FileBrowserPrivateAPI(Profile* profile)
// Hundreds of strings for the file manager.
registry->RegisterFunction<GetStringsFunction>();
- registry->RegisterFunction<LogoutUserFunction>();
- registry->RegisterFunction<GetVolumeMetadataFunction>();
+ // File system related functions.
registry->RegisterFunction<RequestFileSystemFunction>();
registry->RegisterFunction<AddFileWatchFunction>();
registry->RegisterFunction<RemoveFileWatchFunction>();
+ registry->RegisterFunction<SetLastModifiedFunction>();
registry->RegisterFunction<GetSizeStatsFunction>();
+ registry->RegisterFunction<GetVolumeMetadataFunction>();
+ registry->RegisterFunction<ValidatePathNameLengthFunction>();
registry->RegisterFunction<FormatDeviceFunction>();
+
+ // Misc functions.
+ registry->RegisterFunction<LogoutUserFunction>();
registry->RegisterFunction<GetPreferencesFunction>();
registry->RegisterFunction<SetPreferencesFunction>();
- registry->RegisterFunction<SetLastModifiedFunction>();
registry->RegisterFunction<ZipSelectionFunction>();
- registry->RegisterFunction<ValidatePathNameLengthFunction>();
registry->RegisterFunction<ZoomFunction>();
event_router_->ObserveFileSystemEvents();
}
@@ -281,385 +118,6 @@ bool LogoutUserFunction::RunImpl() {
return true;
}
-RequestFileSystemFunction::RequestFileSystemFunction() {
-}
-
-RequestFileSystemFunction::~RequestFileSystemFunction() {
-}
-
-void RequestFileSystemFunction::DidOpenFileSystem(
- scoped_refptr<fileapi::FileSystemContext> file_system_context,
- base::PlatformFileError result,
- const std::string& name,
- const GURL& root_path) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (result != base::PLATFORM_FILE_OK) {
- DidFail(result);
- return;
- }
-
- // RenderViewHost may have gone while the task is posted asynchronously.
- if (!render_view_host()) {
- DidFail(base::PLATFORM_FILE_ERROR_FAILED);
- return;
- }
-
- // Set up file permission access.
- const int child_id = render_view_host()->GetProcess()->GetID();
- if (!SetupFileSystemAccessPermissions(file_system_context,
- child_id,
- GetExtension())) {
- DidFail(base::PLATFORM_FILE_ERROR_SECURITY);
- return;
- }
-
- // Set permissions for the Drive mount point immediately when we kick of
- // first instance of file manager. The actual mount event will be sent to
- // UI only when we perform proper authentication.
- //
- // Note that we call this function even when Drive is disabled by the
- // setting. Otherwise, we need to call this when the setting is changed at
- // a later time, which complicates the code.
- SetDriveMountPointPermissions(profile_, extension_id(), render_view_host());
-
- DictionaryValue* dict = new DictionaryValue();
- SetResult(dict);
- dict->SetString("name", name);
- dict->SetString("path", root_path.spec());
- dict->SetInteger("error", drive::FILE_ERROR_OK);
- SendResponse(true);
-}
-
-void RequestFileSystemFunction::DidFail(
- base::PlatformFileError error_code) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- error_ = base::StringPrintf(kFileError, static_cast<int>(error_code));
- SendResponse(false);
-}
-
-bool RequestFileSystemFunction::SetupFileSystemAccessPermissions(
- scoped_refptr<fileapi::FileSystemContext> file_system_context,
- int child_id,
- scoped_refptr<const extensions::Extension> extension) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (!extension.get())
- return false;
-
- // Make sure that only component extension can access the entire
- // local file system.
- if (extension_->location() != extensions::Manifest::COMPONENT) {
- NOTREACHED() << "Private method access by non-component extension "
- << extension->id();
- return false;
- }
-
- fileapi::ExternalFileSystemBackend* backend =
- file_system_context->external_backend();
- if (!backend)
- return false;
-
- // Grant full access to File API from this component extension.
- backend->GrantFullAccessToExtension(extension_->id());
-
- // Grant R/W file permissions to the renderer hosting component
- // extension for all paths exposed by our local file system backend.
- std::vector<base::FilePath> root_dirs = backend->GetRootDirectories();
- for (size_t i = 0; i < root_dirs.size(); ++i) {
- ChildProcessSecurityPolicy::GetInstance()->GrantCreateReadWriteFile(
- child_id, root_dirs[i]);
- }
- return true;
-}
-
-bool RequestFileSystemFunction::RunImpl() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (!dispatcher() || !render_view_host() || !render_view_host()->GetProcess())
- return false;
-
- set_log_on_completion(true);
-
- content::SiteInstance* site_instance = render_view_host()->GetSiteInstance();
- scoped_refptr<fileapi::FileSystemContext> file_system_context =
- BrowserContext::GetStoragePartition(profile_, site_instance)->
- GetFileSystemContext();
-
- const GURL origin_url = source_url_.GetOrigin();
- file_system_context->OpenFileSystem(
- origin_url,
- fileapi::kFileSystemTypeExternal,
- fileapi::OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT,
- base::Bind(&RequestFileSystemFunction::DidOpenFileSystem,
- this,
- file_system_context));
- return true;
-}
-
-FileWatchFunctionBase::FileWatchFunctionBase() {
-}
-
-FileWatchFunctionBase::~FileWatchFunctionBase() {
-}
-
-void FileWatchFunctionBase::Respond(bool success) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- SetResult(Value::CreateBooleanValue(success));
- SendResponse(success);
-}
-
-bool FileWatchFunctionBase::RunImpl() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (!render_view_host() || !render_view_host()->GetProcess())
- return false;
-
- // First param is url of a file to watch.
- std::string url;
- if (!args_->GetString(0, &url) || url.empty())
- return false;
-
- content::SiteInstance* site_instance = render_view_host()->GetSiteInstance();
- scoped_refptr<fileapi::FileSystemContext> file_system_context =
- BrowserContext::GetStoragePartition(profile(), site_instance)->
- GetFileSystemContext();
-
- FileSystemURL file_watch_url = file_system_context->CrackURL(GURL(url));
- base::FilePath local_path = file_watch_url.path();
- base::FilePath virtual_path = file_watch_url.virtual_path();
- if (local_path.empty()) {
- Respond(false);
- return true;
- }
- PerformFileWatchOperation(local_path, virtual_path, extension_id());
-
- return true;
-}
-
-AddFileWatchFunction::AddFileWatchFunction() {
-}
-
-AddFileWatchFunction::~AddFileWatchFunction() {
-}
-
-void AddFileWatchFunction::PerformFileWatchOperation(
- const base::FilePath& local_path,
- const base::FilePath& virtual_path,
- const std::string& extension_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- FileManagerEventRouter* event_router =
- FileBrowserPrivateAPI::Get(profile_)->event_router();
- event_router->AddFileWatch(
- local_path,
- virtual_path,
- extension_id,
- base::Bind(&AddFileWatchFunction::Respond, this));
-}
-
-RemoveFileWatchFunction::RemoveFileWatchFunction() {
-}
-
-RemoveFileWatchFunction::~RemoveFileWatchFunction() {
-}
-
-void RemoveFileWatchFunction::PerformFileWatchOperation(
- const base::FilePath& local_path,
- const base::FilePath& unused,
- const std::string& extension_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- FileManagerEventRouter* event_router =
- FileBrowserPrivateAPI::Get(profile_)->event_router();
- event_router->RemoveFileWatch(local_path, extension_id);
- Respond(true);
-}
-
-SetLastModifiedFunction::SetLastModifiedFunction() {
-}
-
-SetLastModifiedFunction::~SetLastModifiedFunction() {
-}
-
-bool SetLastModifiedFunction::RunImpl() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- if (args_->GetSize() != 2) {
- return false;
- }
-
- std::string file_url;
- if (!args_->GetString(0, &file_url))
- return false;
-
- std::string timestamp;
- if (!args_->GetString(1, &timestamp))
- return false;
-
- base::FilePath local_path = GetLocalPathFromURL(
- render_view_host(), profile(), GURL(file_url));
-
- base::PostTaskAndReplyWithResult(
- BrowserThread::GetBlockingPool(),
- FROM_HERE,
- base::Bind(&SetLastModifiedOnBlockingPool,
- local_path,
- strtoul(timestamp.c_str(), NULL, 0)),
- base::Bind(&SetLastModifiedFunction::SendResponse,
- this));
- return true;
-}
-
-GetSizeStatsFunction::GetSizeStatsFunction() {
-}
-
-GetSizeStatsFunction::~GetSizeStatsFunction() {
-}
-
-bool GetSizeStatsFunction::RunImpl() {
- if (args_->GetSize() != 1) {
- return false;
- }
-
- std::string mount_url;
- if (!args_->GetString(0, &mount_url))
- return false;
-
- base::FilePath file_path = GetLocalPathFromURL(
- render_view_host(), profile(), GURL(mount_url));
- if (file_path.empty())
- return false;
-
- if (file_path == drive::util::GetDriveMountPointPath()) {
- drive::DriveIntegrationService* integration_service =
- drive::DriveIntegrationServiceFactory::GetForProfile(profile_);
- // |integration_service| is NULL if Drive is disabled.
- if (!integration_service) {
- // If stats couldn't be gotten for drive, result should be left
- // undefined. See comments in GetDriveAvailableSpaceCallback().
- SendResponse(true);
- return true;
- }
-
- drive::FileSystemInterface* file_system =
- integration_service->file_system();
-
- file_system->GetAvailableSpace(
- base::Bind(&GetSizeStatsFunction::GetDriveAvailableSpaceCallback,
- this));
-
- } else {
- uint64* total_size = new uint64(0);
- uint64* remaining_size = new uint64(0);
- BrowserThread::PostBlockingPoolTaskAndReply(
- FROM_HERE,
- base::Bind(&GetSizeStatsOnBlockingPool,
- file_path.value(),
- total_size,
- remaining_size),
- base::Bind(&GetSizeStatsFunction::GetSizeStatsCallback,
- this,
- base::Owned(total_size),
- base::Owned(remaining_size)));
- }
- return true;
-}
-
-void GetSizeStatsFunction::GetDriveAvailableSpaceCallback(
- drive::FileError error,
- int64 bytes_total,
- int64 bytes_used) {
- if (error == drive::FILE_ERROR_OK) {
- const uint64 bytes_total_unsigned = bytes_total;
- const uint64 bytes_remaining_unsigned = bytes_total - bytes_used;
- GetSizeStatsCallback(&bytes_total_unsigned,
- &bytes_remaining_unsigned);
- } else {
- // If stats couldn't be gotten for drive, result should be left undefined.
- SendResponse(true);
- }
-}
-
-void GetSizeStatsFunction::GetSizeStatsCallback(
- const uint64* total_size,
- const uint64* remaining_size) {
- base::DictionaryValue* sizes = new base::DictionaryValue();
- SetResult(sizes);
-
- sizes->SetDouble("totalSize", static_cast<double>(*total_size));
- sizes->SetDouble("remainingSize", static_cast<double>(*remaining_size));
-
- SendResponse(true);
-}
-
-FormatDeviceFunction::FormatDeviceFunction() {
-}
-
-FormatDeviceFunction::~FormatDeviceFunction() {
-}
-
-bool FormatDeviceFunction::RunImpl() {
- if (args_->GetSize() != 1) {
- return false;
- }
-
- std::string volume_file_url;
- if (!args_->GetString(0, &volume_file_url)) {
- NOTREACHED();
- return false;
- }
-
- base::FilePath file_path = GetLocalPathFromURL(
- render_view_host(), profile(), GURL(volume_file_url));
- if (file_path.empty())
- return false;
-
- DiskMountManager::GetInstance()->FormatMountedDevice(file_path.value());
- SendResponse(true);
- return true;
-}
-
-GetVolumeMetadataFunction::GetVolumeMetadataFunction() {
-}
-
-GetVolumeMetadataFunction::~GetVolumeMetadataFunction() {
-}
-
-bool GetVolumeMetadataFunction::RunImpl() {
- if (args_->GetSize() != 1) {
- error_ = "Invalid argument count";
- return false;
- }
-
- std::string volume_mount_url;
- if (!args_->GetString(0, &volume_mount_url)) {
- NOTREACHED();
- return false;
- }
-
- base::FilePath file_path = GetLocalPathFromURL(
- render_view_host(), profile(), GURL(volume_mount_url));
- if (file_path.empty()) {
- error_ = "Invalid mount path.";
- return false;
- }
-
- results_.reset();
-
- const DiskMountManager::Disk* volume = GetVolumeAsDisk(file_path.value());
- if (volume) {
- DictionaryValue* volume_info =
- CreateValueFromDisk(profile_, extension_->id(), volume);
- SetResult(volume_info);
- }
-
- SendResponse(true);
- return true;
-}
-
GetPreferencesFunction::GetPreferencesFunction() {
}
@@ -803,54 +261,6 @@ void ZipSelectionFunction::OnZipDone(bool success) {
Release();
}
-ValidatePathNameLengthFunction::ValidatePathNameLengthFunction() {
-}
-
-ValidatePathNameLengthFunction::~ValidatePathNameLengthFunction() {
-}
-
-bool ValidatePathNameLengthFunction::RunImpl() {
- std::string parent_url;
- if (!args_->GetString(0, &parent_url))
- return false;
-
- std::string name;
- if (!args_->GetString(1, &name))
- return false;
-
- content::SiteInstance* site_instance = render_view_host()->GetSiteInstance();
- scoped_refptr<fileapi::FileSystemContext> file_system_context =
- BrowserContext::GetStoragePartition(profile(), site_instance)->
- GetFileSystemContext();
- fileapi::FileSystemURL filesystem_url(
- file_system_context->CrackURL(GURL(parent_url)));
- if (!chromeos::FileSystemBackend::CanHandleURL(filesystem_url))
- return false;
-
- // No explicit limit on the length of Drive file names.
- if (filesystem_url.type() == fileapi::kFileSystemTypeDrive) {
- SetResult(new base::FundamentalValue(true));
- SendResponse(true);
- return true;
- }
-
- base::PostTaskAndReplyWithResult(
- BrowserThread::GetBlockingPool(),
- FROM_HERE,
- base::Bind(&GetFileNameMaxLengthOnBlockingPool,
- filesystem_url.path().AsUTF8Unsafe()),
- base::Bind(&ValidatePathNameLengthFunction::OnFilePathLimitRetrieved,
- this, name.size()));
- return true;
-}
-
-void ValidatePathNameLengthFunction::OnFilePathLimitRetrieved(
- size_t current_length,
- size_t max_length) {
- SetResult(new base::FundamentalValue(current_length <= max_length));
- SendResponse(true);
-}
-
ZoomFunction::ZoomFunction() {
}
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h b/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h
index af4059e..b9e929b 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h
+++ b/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h
@@ -11,10 +11,8 @@
#include <vector>
#include "base/memory/scoped_ptr.h"
-#include "base/platform_file.h"
#include "base/prefs/pref_service.h"
#include "base/time/time.h"
-#include "chrome/browser/chromeos/drive/file_errors.h"
#include "chrome/browser/chromeos/extensions/file_manager/private_api_base.h"
#include "chrome/browser/chromeos/extensions/file_manager/zip_file_creator.h"
#include "chrome/browser/extensions/extension_function.h"
@@ -24,10 +22,6 @@ class FileManagerEventRouter;
class GURL;
class Profile;
-namespace fileapi {
-class FileSystemContext;
-}
-
namespace file_manager {
// Manages and registers the fileBrowserPrivate API with the extension system.
@@ -66,173 +60,6 @@ class LogoutUserFunction : public SyncExtensionFunction {
virtual bool RunImpl() OVERRIDE;
};
-// Implements the chrome.fileBrowserPrivate.requestFileSystem method.
-class RequestFileSystemFunction : public LoggedAsyncExtensionFunction {
- public:
- DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.requestFileSystem",
- FILEBROWSERPRIVATE_REQUESTFILESYSTEM)
-
- RequestFileSystemFunction();
-
- protected:
- virtual ~RequestFileSystemFunction();
-
- // AsyncExtensionFunction overrides.
- virtual bool RunImpl() OVERRIDE;
-
- private:
- void RespondSuccessOnUIThread(const std::string& name,
- const GURL& root_path);
- void RespondFailedOnUIThread(base::PlatformFileError error_code);
-
- // Called when FileSystemContext::OpenFileSystem() is done.
- void DidOpenFileSystem(
- scoped_refptr<fileapi::FileSystemContext> file_system_context,
- base::PlatformFileError result,
- const std::string& name,
- const GURL& root_path);
-
- // Called when something goes wrong. Records the error to |error_| per the
- // error code and reports that the private API function failed.
- void DidFail(base::PlatformFileError error_code);
-
- // Sets up file system access permissions to the extension identified by
- // |child_id|.
- bool SetupFileSystemAccessPermissions(
- scoped_refptr<fileapi::FileSystemContext> file_system_context,
- int child_id,
- scoped_refptr<const extensions::Extension> extension);
-};
-
-// Base class for AddFileWatchFunction and RemoveFileWatchFunction. Although
-// it's called "FileWatch", the class and its sub classes are used only for
-// watching changes in directories.
-class FileWatchFunctionBase : public LoggedAsyncExtensionFunction {
- public:
- FileWatchFunctionBase();
-
- protected:
- virtual ~FileWatchFunctionBase();
-
- // Performs a file watch operation (ex. adds or removes a file watch).
- virtual void PerformFileWatchOperation(
- const base::FilePath& local_path,
- const base::FilePath& virtual_path,
- const std::string& extension_id) = 0;
-
- // AsyncExtensionFunction overrides.
- virtual bool RunImpl() OVERRIDE;
-
- // Calls SendResponse() with |success| converted to base::Value.
- void Respond(bool success);
-};
-
-// Implements the chrome.fileBrowserPrivate.addFileWatch method.
-// Starts watching changes in directories.
-class AddFileWatchFunction : public FileWatchFunctionBase {
- public:
- DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.addFileWatch",
- FILEBROWSERPRIVATE_ADDFILEWATCH)
-
- AddFileWatchFunction();
-
- protected:
- virtual ~AddFileWatchFunction();
-
- // FileWatchFunctionBase override.
- virtual void PerformFileWatchOperation(
- const base::FilePath& local_path,
- const base::FilePath& virtual_path,
- const std::string& extension_id) OVERRIDE;
-};
-
-
-// Implements the chrome.fileBrowserPrivate.removeFileWatch method.
-// Stops watching changes in directories.
-class RemoveFileWatchFunction : public FileWatchFunctionBase {
- public:
- DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.removeFileWatch",
- FILEBROWSERPRIVATE_REMOVEFILEWATCH)
-
- RemoveFileWatchFunction();
-
- protected:
- virtual ~RemoveFileWatchFunction();
-
- // FileWatchFunctionBase override.
- virtual void PerformFileWatchOperation(
- const base::FilePath& local_path,
- const base::FilePath& virtual_path,
- const std::string& extension_id) OVERRIDE;
-};
-
-// Formats Device given its mount path.
-class FormatDeviceFunction : public LoggedAsyncExtensionFunction {
- public:
- DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.formatDevice",
- FILEBROWSERPRIVATE_FORMATDEVICE)
-
- FormatDeviceFunction();
-
- protected:
- virtual ~FormatDeviceFunction();
-
- // AsyncExtensionFunction overrides.
- virtual bool RunImpl() OVERRIDE;
-};
-
-// Sets last modified date in seconds of local file
-class SetLastModifiedFunction : public LoggedAsyncExtensionFunction {
- public:
- DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.setLastModified",
- FILEBROWSERPRIVATE_SETLASTMODIFIED)
-
- SetLastModifiedFunction();
-
- protected:
- virtual ~SetLastModifiedFunction();
-
- // AsyncExtensionFunction overrides.
- virtual bool RunImpl() OVERRIDE;
-};
-
-class GetSizeStatsFunction : public LoggedAsyncExtensionFunction {
- public:
- DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.getSizeStats",
- FILEBROWSERPRIVATE_GETSIZESTATS)
-
- GetSizeStatsFunction();
-
- protected:
- virtual ~GetSizeStatsFunction();
-
- // AsyncExtensionFunction overrides.
- virtual bool RunImpl() OVERRIDE;
-
- private:
- void GetDriveAvailableSpaceCallback(drive::FileError error,
- int64 bytes_total,
- int64 bytes_used);
-
- void GetSizeStatsCallback(const uint64* total_size,
- const uint64* remaining_size);
-};
-
-// Retrieves devices meta-data. Expects volume's device path as an argument.
-class GetVolumeMetadataFunction : public LoggedAsyncExtensionFunction {
- public:
- DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.getVolumeMetadata",
- FILEBROWSERPRIVATE_GETVOLUMEMETADATA)
-
- GetVolumeMetadataFunction();
-
- protected:
- virtual ~GetVolumeMetadataFunction();
-
- // AsyncExtensionFunction overrides.
- virtual bool RunImpl() OVERRIDE;
-};
-
// Read setting value.
class GetPreferencesFunction : public SyncExtensionFunction {
public:
@@ -283,23 +110,6 @@ class ZipSelectionFunction : public LoggedAsyncExtensionFunction,
scoped_refptr<extensions::ZipFileCreator> zip_file_creator_;
};
-// Implements the chrome.fileBrowserPrivate.validatePathNameLength method.
-class ValidatePathNameLengthFunction : public LoggedAsyncExtensionFunction {
- public:
- DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.validatePathNameLength",
- FILEBROWSERPRIVATE_VALIDATEPATHNAMELENGTH)
-
- ValidatePathNameLengthFunction();
-
- protected:
- virtual ~ValidatePathNameLengthFunction();
-
- void OnFilePathLimitRetrieved(size_t current_length, size_t max_length);
-
- // AsyncExtensionFunction overrides.
- virtual bool RunImpl() OVERRIDE;
-};
-
// Changes the zoom level of the file manager by internally calling
// RenderViewHost::Zoom(). TODO(hirono): Remove this function once the zoom
// level change is supported for all apps. crbug.com/227175.
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
new file mode 100644
index 0000000..15088dc
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -0,0 +1,600 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h"
+
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/types.h>
+#include <utime.h>
+
+#include "base/posix/eintr_wrapper.h"
+#include "base/strings/stringprintf.h"
+#include "base/task_runner_util.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "chrome/browser/chromeos/drive/drive.pb.h"
+#include "chrome/browser/chromeos/drive/drive_integration_service.h"
+#include "chrome/browser/chromeos/drive/file_system_interface.h"
+#include "chrome/browser/chromeos/drive/file_system_util.h"
+#include "chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.h"
+#include "chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.h"
+#include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h"
+#include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
+#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chromeos/disks/disk_mount_manager.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/child_process_security_policy.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/storage_partition.h"
+#include "webkit/browser/fileapi/file_system_context.h"
+#include "webkit/browser/fileapi/file_system_file_util.h"
+#include "webkit/browser/fileapi/file_system_operation_context.h"
+#include "webkit/browser/fileapi/file_system_url.h"
+#include "webkit/common/fileapi/file_system_types.h"
+#include "webkit/common/fileapi/file_system_util.h"
+
+using chromeos::disks::DiskMountManager;
+using content::BrowserContext;
+using content::BrowserThread;
+using content::ChildProcessSecurityPolicy;
+using content::WebContents;
+using fileapi::FileSystemURL;
+
+namespace file_manager {
+namespace {
+
+// Error messages.
+const char kFileError[] = "File error %d";
+
+const DiskMountManager::Disk* GetVolumeAsDisk(const std::string& mount_path) {
+ DiskMountManager* disk_mount_manager = DiskMountManager::GetInstance();
+
+ DiskMountManager::MountPointMap::const_iterator mount_point_it =
+ disk_mount_manager->mount_points().find(mount_path);
+ if (mount_point_it == disk_mount_manager->mount_points().end())
+ return NULL;
+
+ const DiskMountManager::Disk* disk = disk_mount_manager->FindDiskBySourcePath(
+ mount_point_it->second.source_path);
+
+ return (disk && disk->is_hidden()) ? NULL : disk;
+}
+
+base::DictionaryValue* CreateValueFromDisk(
+ Profile* profile,
+ const std::string& extension_id,
+ const DiskMountManager::Disk* volume) {
+ base::DictionaryValue* volume_info = new base::DictionaryValue();
+
+ std::string mount_path;
+ if (!volume->mount_path().empty()) {
+ base::FilePath relative_mount_path;
+ file_manager_util::ConvertFileToRelativeFileSystemPath(
+ profile, extension_id, base::FilePath(volume->mount_path()),
+ &relative_mount_path);
+ mount_path = relative_mount_path.value();
+ }
+
+ volume_info->SetString("devicePath", volume->device_path());
+ volume_info->SetString("mountPath", mount_path);
+ volume_info->SetString("systemPath", volume->system_path());
+ volume_info->SetString("filePath", volume->file_path());
+ volume_info->SetString("deviceLabel", volume->device_label());
+ volume_info->SetString("driveLabel", volume->drive_label());
+ volume_info->SetString("deviceType",
+ DiskMountManager::DeviceTypeToString(volume->device_type()));
+ volume_info->SetDouble("totalSize",
+ static_cast<double>(volume->total_size_in_bytes()));
+ volume_info->SetBoolean("isParent", volume->is_parent());
+ volume_info->SetBoolean("isReadOnly", volume->is_read_only());
+ volume_info->SetBoolean("hasMedia", volume->has_media());
+ volume_info->SetBoolean("isOnBootDevice", volume->on_boot_device());
+
+ return volume_info;
+}
+
+// Sets permissions for the Drive mount point so Files.app can access files
+// in the mount point directory. It's safe to call this function even if
+// Drive is disabled by the setting (i.e. prefs::kDisableDrive is true).
+void SetDriveMountPointPermissions(
+ Profile* profile,
+ const std::string& extension_id,
+ content::RenderViewHost* render_view_host) {
+ if (!render_view_host ||
+ !render_view_host->GetSiteInstance() || !render_view_host->GetProcess()) {
+ return;
+ }
+
+ content::SiteInstance* site_instance = render_view_host->GetSiteInstance();
+ fileapi::ExternalFileSystemBackend* backend =
+ BrowserContext::GetStoragePartition(profile, site_instance)->
+ GetFileSystemContext()->external_backend();
+ if (!backend)
+ return;
+
+ const base::FilePath mount_point = drive::util::GetDriveMountPointPath();
+ // Grant R/W permissions to drive 'folder'. File API layer still
+ // expects this to be satisfied.
+ ChildProcessSecurityPolicy::GetInstance()->GrantCreateReadWriteFile(
+ render_view_host->GetProcess()->GetID(), mount_point);
+
+ base::FilePath mount_point_virtual;
+ if (backend->GetVirtualPath(mount_point, &mount_point_virtual))
+ backend->GrantFileAccessToExtension(extension_id, mount_point_virtual);
+}
+
+// Retrieves total and remaining available size on |mount_path|.
+void GetSizeStatsOnBlockingPool(const std::string& mount_path,
+ uint64* total_size,
+ uint64* remaining_size) {
+ struct statvfs stat = {}; // Zero-clear
+ if (HANDLE_EINTR(statvfs(mount_path.c_str(), &stat)) == 0) {
+ *total_size =
+ static_cast<uint64>(stat.f_blocks) * stat.f_frsize;
+ *remaining_size =
+ static_cast<uint64>(stat.f_bfree) * stat.f_frsize;
+ }
+}
+
+// Retrieves the maximum file name length of the file system of |path|.
+// Returns 0 if it could not be queried.
+size_t GetFileNameMaxLengthOnBlockingPool(const std::string& path) {
+ struct statvfs stat = {};
+ if (statvfs(path.c_str(), &stat) != 0) {
+ // The filesystem seems not supporting statvfs(). Assume it to be a commonly
+ // used bound 255, and log the failure.
+ LOG(ERROR) << "Cannot statvfs() the name length limit for: " << path;
+ return 255;
+ }
+ return stat.f_namemax;
+}
+
+// Sets last modified date.
+bool SetLastModifiedOnBlockingPool(const base::FilePath& local_path,
+ time_t timestamp) {
+ if (local_path.empty())
+ return false;
+
+ struct stat stat_buffer;
+ if (stat(local_path.value().c_str(), &stat_buffer) != 0)
+ return false;
+
+ struct utimbuf times;
+ times.actime = stat_buffer.st_atime;
+ times.modtime = timestamp;
+ return utime(local_path.value().c_str(), &times) == 0;
+}
+
+} // namespace
+
+RequestFileSystemFunction::RequestFileSystemFunction() {
+}
+
+RequestFileSystemFunction::~RequestFileSystemFunction() {
+}
+
+void RequestFileSystemFunction::DidOpenFileSystem(
+ scoped_refptr<fileapi::FileSystemContext> file_system_context,
+ base::PlatformFileError result,
+ const std::string& name,
+ const GURL& root_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (result != base::PLATFORM_FILE_OK) {
+ DidFail(result);
+ return;
+ }
+
+ // RenderViewHost may have gone while the task is posted asynchronously.
+ if (!render_view_host()) {
+ DidFail(base::PLATFORM_FILE_ERROR_FAILED);
+ return;
+ }
+
+ // Set up file permission access.
+ const int child_id = render_view_host()->GetProcess()->GetID();
+ if (!SetupFileSystemAccessPermissions(file_system_context,
+ child_id,
+ GetExtension())) {
+ DidFail(base::PLATFORM_FILE_ERROR_SECURITY);
+ return;
+ }
+
+ // Set permissions for the Drive mount point immediately when we kick of
+ // first instance of file manager. The actual mount event will be sent to
+ // UI only when we perform proper authentication.
+ //
+ // Note that we call this function even when Drive is disabled by the
+ // setting. Otherwise, we need to call this when the setting is changed at
+ // a later time, which complicates the code.
+ SetDriveMountPointPermissions(profile_, extension_id(), render_view_host());
+
+ DictionaryValue* dict = new DictionaryValue();
+ SetResult(dict);
+ dict->SetString("name", name);
+ dict->SetString("path", root_path.spec());
+ dict->SetInteger("error", drive::FILE_ERROR_OK);
+ SendResponse(true);
+}
+
+void RequestFileSystemFunction::DidFail(
+ base::PlatformFileError error_code) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ error_ = base::StringPrintf(kFileError, static_cast<int>(error_code));
+ SendResponse(false);
+}
+
+bool RequestFileSystemFunction::SetupFileSystemAccessPermissions(
+ scoped_refptr<fileapi::FileSystemContext> file_system_context,
+ int child_id,
+ scoped_refptr<const extensions::Extension> extension) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!extension.get())
+ return false;
+
+ // Make sure that only component extension can access the entire
+ // local file system.
+ if (extension_->location() != extensions::Manifest::COMPONENT) {
+ NOTREACHED() << "Private method access by non-component extension "
+ << extension->id();
+ return false;
+ }
+
+ fileapi::ExternalFileSystemBackend* backend =
+ file_system_context->external_backend();
+ if (!backend)
+ return false;
+
+ // Grant full access to File API from this component extension.
+ backend->GrantFullAccessToExtension(extension_->id());
+
+ // Grant R/W file permissions to the renderer hosting component
+ // extension for all paths exposed by our local file system backend.
+ std::vector<base::FilePath> root_dirs = backend->GetRootDirectories();
+ for (size_t i = 0; i < root_dirs.size(); ++i) {
+ ChildProcessSecurityPolicy::GetInstance()->GrantCreateReadWriteFile(
+ child_id, root_dirs[i]);
+ }
+ return true;
+}
+
+bool RequestFileSystemFunction::RunImpl() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!dispatcher() || !render_view_host() || !render_view_host()->GetProcess())
+ return false;
+
+ set_log_on_completion(true);
+
+ content::SiteInstance* site_instance = render_view_host()->GetSiteInstance();
+ scoped_refptr<fileapi::FileSystemContext> file_system_context =
+ BrowserContext::GetStoragePartition(profile_, site_instance)->
+ GetFileSystemContext();
+
+ const GURL origin_url = source_url_.GetOrigin();
+ file_system_context->OpenFileSystem(
+ origin_url,
+ fileapi::kFileSystemTypeExternal,
+ fileapi::OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT,
+ base::Bind(&RequestFileSystemFunction::DidOpenFileSystem,
+ this,
+ file_system_context));
+ return true;
+}
+
+FileWatchFunctionBase::FileWatchFunctionBase() {
+}
+
+FileWatchFunctionBase::~FileWatchFunctionBase() {
+}
+
+void FileWatchFunctionBase::Respond(bool success) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ SetResult(Value::CreateBooleanValue(success));
+ SendResponse(success);
+}
+
+bool FileWatchFunctionBase::RunImpl() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!render_view_host() || !render_view_host()->GetProcess())
+ return false;
+
+ // First param is url of a file to watch.
+ std::string url;
+ if (!args_->GetString(0, &url) || url.empty())
+ return false;
+
+ content::SiteInstance* site_instance = render_view_host()->GetSiteInstance();
+ scoped_refptr<fileapi::FileSystemContext> file_system_context =
+ BrowserContext::GetStoragePartition(profile(), site_instance)->
+ GetFileSystemContext();
+
+ FileSystemURL file_watch_url = file_system_context->CrackURL(GURL(url));
+ base::FilePath local_path = file_watch_url.path();
+ base::FilePath virtual_path = file_watch_url.virtual_path();
+ if (local_path.empty()) {
+ Respond(false);
+ return true;
+ }
+ PerformFileWatchOperation(local_path, virtual_path, extension_id());
+
+ return true;
+}
+
+AddFileWatchFunction::AddFileWatchFunction() {
+}
+
+AddFileWatchFunction::~AddFileWatchFunction() {
+}
+
+void AddFileWatchFunction::PerformFileWatchOperation(
+ const base::FilePath& local_path,
+ const base::FilePath& virtual_path,
+ const std::string& extension_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ FileManagerEventRouter* event_router =
+ FileBrowserPrivateAPI::Get(profile_)->event_router();
+ event_router->AddFileWatch(
+ local_path,
+ virtual_path,
+ extension_id,
+ base::Bind(&AddFileWatchFunction::Respond, this));
+}
+
+RemoveFileWatchFunction::RemoveFileWatchFunction() {
+}
+
+RemoveFileWatchFunction::~RemoveFileWatchFunction() {
+}
+
+void RemoveFileWatchFunction::PerformFileWatchOperation(
+ const base::FilePath& local_path,
+ const base::FilePath& unused,
+ const std::string& extension_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ FileManagerEventRouter* event_router =
+ FileBrowserPrivateAPI::Get(profile_)->event_router();
+ event_router->RemoveFileWatch(local_path, extension_id);
+ Respond(true);
+}
+
+SetLastModifiedFunction::SetLastModifiedFunction() {
+}
+
+SetLastModifiedFunction::~SetLastModifiedFunction() {
+}
+
+bool SetLastModifiedFunction::RunImpl() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (args_->GetSize() != 2) {
+ return false;
+ }
+
+ std::string file_url;
+ if (!args_->GetString(0, &file_url))
+ return false;
+
+ std::string timestamp;
+ if (!args_->GetString(1, &timestamp))
+ return false;
+
+ base::FilePath local_path = GetLocalPathFromURL(
+ render_view_host(), profile(), GURL(file_url));
+
+ base::PostTaskAndReplyWithResult(
+ BrowserThread::GetBlockingPool(),
+ FROM_HERE,
+ base::Bind(&SetLastModifiedOnBlockingPool,
+ local_path,
+ strtoul(timestamp.c_str(), NULL, 0)),
+ base::Bind(&SetLastModifiedFunction::SendResponse,
+ this));
+ return true;
+}
+
+GetSizeStatsFunction::GetSizeStatsFunction() {
+}
+
+GetSizeStatsFunction::~GetSizeStatsFunction() {
+}
+
+bool GetSizeStatsFunction::RunImpl() {
+ if (args_->GetSize() != 1) {
+ return false;
+ }
+
+ std::string mount_url;
+ if (!args_->GetString(0, &mount_url))
+ return false;
+
+ base::FilePath file_path = GetLocalPathFromURL(
+ render_view_host(), profile(), GURL(mount_url));
+ if (file_path.empty())
+ return false;
+
+ if (file_path == drive::util::GetDriveMountPointPath()) {
+ drive::DriveIntegrationService* integration_service =
+ drive::DriveIntegrationServiceFactory::GetForProfile(profile_);
+ // |integration_service| is NULL if Drive is disabled.
+ if (!integration_service) {
+ // If stats couldn't be gotten for drive, result should be left
+ // undefined. See comments in GetDriveAvailableSpaceCallback().
+ SendResponse(true);
+ return true;
+ }
+
+ drive::FileSystemInterface* file_system =
+ integration_service->file_system();
+
+ file_system->GetAvailableSpace(
+ base::Bind(&GetSizeStatsFunction::GetDriveAvailableSpaceCallback,
+ this));
+
+ } else {
+ uint64* total_size = new uint64(0);
+ uint64* remaining_size = new uint64(0);
+ BrowserThread::PostBlockingPoolTaskAndReply(
+ FROM_HERE,
+ base::Bind(&GetSizeStatsOnBlockingPool,
+ file_path.value(),
+ total_size,
+ remaining_size),
+ base::Bind(&GetSizeStatsFunction::GetSizeStatsCallback,
+ this,
+ base::Owned(total_size),
+ base::Owned(remaining_size)));
+ }
+ return true;
+}
+
+void GetSizeStatsFunction::GetDriveAvailableSpaceCallback(
+ drive::FileError error,
+ int64 bytes_total,
+ int64 bytes_used) {
+ if (error == drive::FILE_ERROR_OK) {
+ const uint64 bytes_total_unsigned = bytes_total;
+ const uint64 bytes_remaining_unsigned = bytes_total - bytes_used;
+ GetSizeStatsCallback(&bytes_total_unsigned,
+ &bytes_remaining_unsigned);
+ } else {
+ // If stats couldn't be gotten for drive, result should be left undefined.
+ SendResponse(true);
+ }
+}
+
+void GetSizeStatsFunction::GetSizeStatsCallback(
+ const uint64* total_size,
+ const uint64* remaining_size) {
+ base::DictionaryValue* sizes = new base::DictionaryValue();
+ SetResult(sizes);
+
+ sizes->SetDouble("totalSize", static_cast<double>(*total_size));
+ sizes->SetDouble("remainingSize", static_cast<double>(*remaining_size));
+
+ SendResponse(true);
+}
+
+GetVolumeMetadataFunction::GetVolumeMetadataFunction() {
+}
+
+GetVolumeMetadataFunction::~GetVolumeMetadataFunction() {
+}
+
+bool GetVolumeMetadataFunction::RunImpl() {
+ if (args_->GetSize() != 1) {
+ error_ = "Invalid argument count";
+ return false;
+ }
+
+ std::string volume_mount_url;
+ if (!args_->GetString(0, &volume_mount_url)) {
+ NOTREACHED();
+ return false;
+ }
+
+ base::FilePath file_path = GetLocalPathFromURL(
+ render_view_host(), profile(), GURL(volume_mount_url));
+ if (file_path.empty()) {
+ error_ = "Invalid mount path.";
+ return false;
+ }
+
+ results_.reset();
+
+ const DiskMountManager::Disk* volume = GetVolumeAsDisk(file_path.value());
+ if (volume) {
+ DictionaryValue* volume_info =
+ CreateValueFromDisk(profile_, extension_->id(), volume);
+ SetResult(volume_info);
+ }
+
+ SendResponse(true);
+ return true;
+}
+
+ValidatePathNameLengthFunction::ValidatePathNameLengthFunction() {
+}
+
+ValidatePathNameLengthFunction::~ValidatePathNameLengthFunction() {
+}
+
+bool ValidatePathNameLengthFunction::RunImpl() {
+ std::string parent_url;
+ if (!args_->GetString(0, &parent_url))
+ return false;
+
+ std::string name;
+ if (!args_->GetString(1, &name))
+ return false;
+
+ content::SiteInstance* site_instance = render_view_host()->GetSiteInstance();
+ scoped_refptr<fileapi::FileSystemContext> file_system_context =
+ BrowserContext::GetStoragePartition(profile(), site_instance)->
+ GetFileSystemContext();
+ fileapi::FileSystemURL filesystem_url(
+ file_system_context->CrackURL(GURL(parent_url)));
+ if (!chromeos::FileSystemBackend::CanHandleURL(filesystem_url))
+ return false;
+
+ // No explicit limit on the length of Drive file names.
+ if (filesystem_url.type() == fileapi::kFileSystemTypeDrive) {
+ SetResult(new base::FundamentalValue(true));
+ SendResponse(true);
+ return true;
+ }
+
+ base::PostTaskAndReplyWithResult(
+ BrowserThread::GetBlockingPool(),
+ FROM_HERE,
+ base::Bind(&GetFileNameMaxLengthOnBlockingPool,
+ filesystem_url.path().AsUTF8Unsafe()),
+ base::Bind(&ValidatePathNameLengthFunction::OnFilePathLimitRetrieved,
+ this, name.size()));
+ return true;
+}
+
+void ValidatePathNameLengthFunction::OnFilePathLimitRetrieved(
+ size_t current_length,
+ size_t max_length) {
+ SetResult(new base::FundamentalValue(current_length <= max_length));
+ SendResponse(true);
+}
+
+FormatDeviceFunction::FormatDeviceFunction() {
+}
+
+FormatDeviceFunction::~FormatDeviceFunction() {
+}
+
+bool FormatDeviceFunction::RunImpl() {
+ if (args_->GetSize() != 1) {
+ return false;
+ }
+
+ std::string volume_file_url;
+ if (!args_->GetString(0, &volume_file_url)) {
+ NOTREACHED();
+ return false;
+ }
+
+ base::FilePath file_path = GetLocalPathFromURL(
+ render_view_host(), profile(), GURL(volume_file_url));
+ if (file_path.empty())
+ return false;
+
+ DiskMountManager::GetInstance()->FormatMountedDevice(file_path.value());
+ SendResponse(true);
+ return true;
+}
+
+} // namespace file_manager
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h
new file mode 100644
index 0000000..d4e4f13
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h
@@ -0,0 +1,218 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This file provides file system related API functions.
+
+#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_FILE_SYSTEM_H_
+#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_FILE_SYSTEM_H_
+
+#include <string>
+
+#include "base/platform_file.h"
+#include "chrome/browser/chromeos/drive/file_errors.h"
+#include "chrome/browser/chromeos/extensions/file_manager/private_api_base.h"
+
+class GURL;
+
+namespace base {
+class FilePath;
+}
+
+namespace fileapi {
+class FileSystemContext;
+}
+
+namespace file_manager {
+
+// Implements the chrome.fileBrowserPrivate.requestFileSystem method.
+class RequestFileSystemFunction : public LoggedAsyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.requestFileSystem",
+ FILEBROWSERPRIVATE_REQUESTFILESYSTEM)
+
+ RequestFileSystemFunction();
+
+ protected:
+ virtual ~RequestFileSystemFunction();
+
+ // AsyncExtensionFunction overrides.
+ virtual bool RunImpl() OVERRIDE;
+
+ private:
+ void RespondSuccessOnUIThread(const std::string& name,
+ const GURL& root_path);
+ void RespondFailedOnUIThread(base::PlatformFileError error_code);
+
+ // Called when FileSystemContext::OpenFileSystem() is done.
+ void DidOpenFileSystem(
+ scoped_refptr<fileapi::FileSystemContext> file_system_context,
+ base::PlatformFileError result,
+ const std::string& name,
+ const GURL& root_path);
+
+ // Called when something goes wrong. Records the error to |error_| per the
+ // error code and reports that the private API function failed.
+ void DidFail(base::PlatformFileError error_code);
+
+ // Sets up file system access permissions to the extension identified by
+ // |child_id|.
+ bool SetupFileSystemAccessPermissions(
+ scoped_refptr<fileapi::FileSystemContext> file_system_context,
+ int child_id,
+ scoped_refptr<const extensions::Extension> extension);
+};
+
+// Base class for AddFileWatchFunction and RemoveFileWatchFunction. Although
+// it's called "FileWatch", the class and its sub classes are used only for
+// watching changes in directories.
+class FileWatchFunctionBase : public LoggedAsyncExtensionFunction {
+ public:
+ FileWatchFunctionBase();
+
+ protected:
+ virtual ~FileWatchFunctionBase();
+
+ // Performs a file watch operation (ex. adds or removes a file watch).
+ virtual void PerformFileWatchOperation(
+ const base::FilePath& local_path,
+ const base::FilePath& virtual_path,
+ const std::string& extension_id) = 0;
+
+ // AsyncExtensionFunction overrides.
+ virtual bool RunImpl() OVERRIDE;
+
+ // Calls SendResponse() with |success| converted to base::Value.
+ void Respond(bool success);
+};
+
+// Implements the chrome.fileBrowserPrivate.addFileWatch method.
+// Starts watching changes in directories.
+class AddFileWatchFunction : public FileWatchFunctionBase {
+ public:
+ DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.addFileWatch",
+ FILEBROWSERPRIVATE_ADDFILEWATCH)
+
+ AddFileWatchFunction();
+
+ protected:
+ virtual ~AddFileWatchFunction();
+
+ // FileWatchFunctionBase override.
+ virtual void PerformFileWatchOperation(
+ const base::FilePath& local_path,
+ const base::FilePath& virtual_path,
+ const std::string& extension_id) OVERRIDE;
+};
+
+
+// Implements the chrome.fileBrowserPrivate.removeFileWatch method.
+// Stops watching changes in directories.
+class RemoveFileWatchFunction : public FileWatchFunctionBase {
+ public:
+ DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.removeFileWatch",
+ FILEBROWSERPRIVATE_REMOVEFILEWATCH)
+
+ RemoveFileWatchFunction();
+
+ protected:
+ virtual ~RemoveFileWatchFunction();
+
+ // FileWatchFunctionBase override.
+ virtual void PerformFileWatchOperation(
+ const base::FilePath& local_path,
+ const base::FilePath& virtual_path,
+ const std::string& extension_id) OVERRIDE;
+};
+
+// Implements the chrome.fileBrowserPrivate.setLastModified method.
+// Sets last modified date in seconds of local file
+class SetLastModifiedFunction : public LoggedAsyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.setLastModified",
+ FILEBROWSERPRIVATE_SETLASTMODIFIED)
+
+ SetLastModifiedFunction();
+
+ protected:
+ virtual ~SetLastModifiedFunction();
+
+ // AsyncExtensionFunction overrides.
+ virtual bool RunImpl() OVERRIDE;
+};
+
+// Implements the chrome.fileBrowserPrivate.getSizeStats method.
+class GetSizeStatsFunction : public LoggedAsyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.getSizeStats",
+ FILEBROWSERPRIVATE_GETSIZESTATS)
+
+ GetSizeStatsFunction();
+
+ protected:
+ virtual ~GetSizeStatsFunction();
+
+ // AsyncExtensionFunction overrides.
+ virtual bool RunImpl() OVERRIDE;
+
+ private:
+ void GetDriveAvailableSpaceCallback(drive::FileError error,
+ int64 bytes_total,
+ int64 bytes_used);
+
+ void GetSizeStatsCallback(const uint64* total_size,
+ const uint64* remaining_size);
+};
+
+// Implements the chrome.fileBrowserPrivate.getVolumeMetadata method.
+// Retrieves devices meta-data. Expects volume's device path as an argument.
+class GetVolumeMetadataFunction : public LoggedAsyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.getVolumeMetadata",
+ FILEBROWSERPRIVATE_GETVOLUMEMETADATA)
+
+ GetVolumeMetadataFunction();
+
+ protected:
+ virtual ~GetVolumeMetadataFunction();
+
+ // AsyncExtensionFunction overrides.
+ virtual bool RunImpl() OVERRIDE;
+};
+
+// Implements the chrome.fileBrowserPrivate.validatePathNameLength method.
+class ValidatePathNameLengthFunction : public LoggedAsyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.validatePathNameLength",
+ FILEBROWSERPRIVATE_VALIDATEPATHNAMELENGTH)
+
+ ValidatePathNameLengthFunction();
+
+ protected:
+ virtual ~ValidatePathNameLengthFunction();
+
+ void OnFilePathLimitRetrieved(size_t current_length, size_t max_length);
+
+ // AsyncExtensionFunction overrides.
+ virtual bool RunImpl() OVERRIDE;
+};
+
+// Implements the chrome.fileBrowserPrivate.formatDevice method.
+// Formats Device given its mount path.
+class FormatDeviceFunction : public LoggedAsyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("fileBrowserPrivate.formatDevice",
+ FILEBROWSERPRIVATE_FORMATDEVICE)
+
+ FormatDeviceFunction();
+
+ protected:
+ virtual ~FormatDeviceFunction();
+
+ // AsyncExtensionFunction overrides.
+ virtual bool RunImpl() OVERRIDE;
+};
+
+} // namespace file_manager
+
+#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_FILE_MANAGER_PRIVATE_API_FILE_SYSTEM_H_
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index ff7274f..fb7de84 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -843,6 +843,8 @@
'browser/chromeos/extensions/file_manager/private_api_dialog.h',
'browser/chromeos/extensions/file_manager/private_api_drive.cc',
'browser/chromeos/extensions/file_manager/private_api_drive.h',
+ 'browser/chromeos/extensions/file_manager/private_api_file_system.cc',
+ 'browser/chromeos/extensions/file_manager/private_api_file_system.h',
'browser/chromeos/extensions/file_manager/private_api_mount.cc',
'browser/chromeos/extensions/file_manager/private_api_mount.h',
'browser/chromeos/extensions/file_manager/private_api_strings.cc',