Commit fc18261a authored by kinaba@chromium.org's avatar kinaba@chromium.org

Implement IsNonNativeLocalPathDirectory for supporting non-local non-Drive...

Implement IsNonNativeLocalPathDirectory for supporting non-local non-Drive directory access in apps.

What the CL does is:
* Almost mechanically moves out the local function CheckIfDirectoryExists
from open_util.cc to fileapi_util.cc and just use it for the desired implementation.
* Removes Drive-specific helper code for the feature.
* Allows file_system_api test setup code to refer the info of File Manager app.
(Because the new general implementation checks the directory existence in the
permission level of the file manager, the test needs access to it.)

BUG=367028

Review URL: https://codereview.chromium.org/304373004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274173 0039d316-1c4b-4281-b951-d872f2087c98
parent 711feaa6
...@@ -89,15 +89,6 @@ DriveIntegrationService* GetIntegrationServiceByProfile(Profile* profile) { ...@@ -89,15 +89,6 @@ DriveIntegrationService* GetIntegrationServiceByProfile(Profile* profile) {
return service; return service;
} }
void CheckDirectoryExistsAfterGetResourceEntry(
const FileOperationCallback& callback,
FileError error,
scoped_ptr<ResourceEntry> entry) {
if (error == FILE_ERROR_OK && !entry->file_info().is_directory())
error = FILE_ERROR_NOT_A_DIRECTORY;
callback.Run(error);
}
} // namespace } // namespace
const base::FilePath& GetDriveGrandRootPath() { const base::FilePath& GetDriveGrandRootPath() {
...@@ -338,20 +329,6 @@ void EnsureDirectoryExists(Profile* profile, ...@@ -338,20 +329,6 @@ void EnsureDirectoryExists(Profile* profile,
} }
} }
void CheckDirectoryExists(Profile* profile,
const base::FilePath& directory,
const FileOperationCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(!callback.is_null());
FileSystemInterface* file_system = GetFileSystemByProfile(profile);
DCHECK(file_system);
file_system->GetResourceEntry(
ExtractDrivePath(directory),
base::Bind(&CheckDirectoryExistsAfterGetResourceEntry, callback));
}
void EmptyFileOperationCallback(FileError error) { void EmptyFileOperationCallback(FileError error) {
} }
......
...@@ -144,12 +144,6 @@ void PrepareWritableFileAndRun(Profile* profile, ...@@ -144,12 +144,6 @@ void PrepareWritableFileAndRun(Profile* profile,
const base::FilePath& path, const base::FilePath& path,
const PrepareWritableFileCallback& callback); const PrepareWritableFileCallback& callback);
// Checks whether a directory exists at the given Drive path |directory|.
// Must be called from UI thread. The result will be called back to |callback|.
void CheckDirectoryExists(Profile* profile,
const base::FilePath& directory,
const FileOperationCallback& callback);
// Ensures the existence of |directory| of '/special/drive/foo'. This will // Ensures the existence of |directory| of '/special/drive/foo'. This will
// create |directory| and its ancestors if they don't exist. |callback| is // create |directory| and its ancestors if they don't exist. |callback| is
// invoked after making sure that |directory| exists. |callback| should // invoked after making sure that |directory| exists. |callback| should
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/files/file.h" #include "base/files/file.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "chrome/browser/chromeos/drive/file_system_util.h" #include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/file_manager/app_id.h"
#include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
...@@ -14,6 +15,7 @@ ...@@ -14,6 +15,7 @@
#include "content/public/browser/site_instance.h" #include "content/public/browser/site_instance.h"
#include "content/public/browser/storage_partition.h" #include "content/public/browser/storage_partition.h"
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
#include "google_apis/drive/task_util.h"
#include "net/base/escape.h" #include "net/base/escape.h"
#include "url/gurl.h" #include "url/gurl.h"
#include "webkit/browser/fileapi/file_system_context.h" #include "webkit/browser/fileapi/file_system_context.h"
...@@ -211,6 +213,18 @@ void OnConvertFileDefinitionDone( ...@@ -211,6 +213,18 @@ void OnConvertFileDefinitionDone(
callback.Run(entry_definition_list->at(0)); callback.Run(entry_definition_list->at(0));
} }
// Used to implement CheckIfDirectoryExists().
void CheckIfDirectoryExistsOnIOThread(
scoped_refptr<fileapi::FileSystemContext> file_system_context,
const GURL& url,
const fileapi::FileSystemOperationRunner::StatusCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
fileapi::FileSystemURL file_system_url = file_system_context->CrackURL(url);
file_system_context->operation_runner()->DirectoryExists(
file_system_url, callback);
}
} // namespace } // namespace
EntryDefinition::EntryDefinition() { EntryDefinition::EntryDefinition() {
...@@ -328,5 +342,26 @@ void ConvertFileDefinitionToEntryDefinition( ...@@ -328,5 +342,26 @@ void ConvertFileDefinitionToEntryDefinition(
base::Bind(&OnConvertFileDefinitionDone, callback)); base::Bind(&OnConvertFileDefinitionDone, callback));
} }
void CheckIfDirectoryExists(
scoped_refptr<fileapi::FileSystemContext> file_system_context,
const GURL& url,
const fileapi::FileSystemOperationRunner::StatusCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Check the existence of directory using file system API implementation on
// behalf of the file manager app. We need to grant access beforehand.
fileapi::ExternalFileSystemBackend* backend =
file_system_context->external_backend();
DCHECK(backend);
backend->GrantFullAccessToExtension(kFileManagerAppId);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&CheckIfDirectoryExistsOnIOThread,
file_system_context,
url,
google_apis::CreateRelayCallback(callback)));
}
} // namespace util } // namespace util
} // namespace file_manager } // namespace file_manager
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/files/file.h" #include "base/files/file.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "url/gurl.h" #include "url/gurl.h"
#include "webkit/browser/fileapi/file_system_operation_runner.h"
class Profile; class Profile;
...@@ -124,6 +125,12 @@ void ConvertFileDefinitionListToEntryDefinitionList( ...@@ -124,6 +125,12 @@ void ConvertFileDefinitionListToEntryDefinitionList(
const FileDefinitionList& file_definition_list, const FileDefinitionList& file_definition_list,
const EntryDefinitionListCallback& callback); const EntryDefinitionListCallback& callback);
// Checks if a directory exists at |url|.
void CheckIfDirectoryExists(
scoped_refptr<fileapi::FileSystemContext> file_system_context,
const GURL& url,
const fileapi::FileSystemOperationRunner::StatusCallback& callback);
} // namespace util } // namespace util
} // namespace file_manager } // namespace file_manager
......
...@@ -36,11 +36,14 @@ void GetMimeTypeAfterGetResourceEntry( ...@@ -36,11 +36,14 @@ void GetMimeTypeAfterGetResourceEntry(
callback.Run(true, entry->file_specific_info().content_mime_type()); callback.Run(true, entry->file_specific_info().content_mime_type());
} }
void CheckDirectoryAfterDriveCheck(const base::Callback<void(bool)>& callback, // Helper function to converts a callback that takes boolean value to that takes
drive::FileError error) { // File::Error, by regarding FILE_OK as the only successful value.
void BoolCallbackAsFileErrorCallback(
const base::Callback<void(bool)>& callback,
base::File::Error error) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
return callback.Run(error == drive::FILE_ERROR_OK); return callback.Run(error == base::File::FILE_OK);
} }
void CheckWritableAfterDriveCheck(const base::Callback<void(bool)>& callback, void CheckWritableAfterDriveCheck(const base::Callback<void(bool)>& callback,
...@@ -65,13 +68,9 @@ bool IsUnderNonNativeLocalPath(Profile* profile, ...@@ -65,13 +68,9 @@ bool IsUnderNonNativeLocalPath(Profile* profile,
return false; return false;
} }
content::StoragePartition* partition = fileapi::FileSystemURL filesystem_url =
content::BrowserContext::GetStoragePartitionForSite( GetFileSystemContextForExtensionId(profile,
profile, kFileManagerAppId)->CrackURL(url);
extensions::util::GetSiteForExtensionId(kFileManagerAppId, profile));
fileapi::FileSystemContext* context = partition->GetFileSystemContext();
fileapi::FileSystemURL filesystem_url = context->CrackURL(url);
if (!filesystem_url.is_valid()) if (!filesystem_url.is_valid())
return false; return false;
...@@ -123,12 +122,23 @@ void IsNonNativeLocalPathDirectory( ...@@ -123,12 +122,23 @@ void IsNonNativeLocalPathDirectory(
const base::FilePath& path, const base::FilePath& path,
const base::Callback<void(bool)>& callback) { const base::Callback<void(bool)>& callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(IsUnderNonNativeLocalPath(profile, path));
// TODO(kinaba): support other types of volumes besides Drive. GURL url;
drive::util::CheckDirectoryExists( if (!util::ConvertAbsoluteFilePathToFileSystemUrl(
profile, profile, path, kFileManagerAppId, &url)) {
path, // Posting to the current thread, so that we always call back asynchronously
base::Bind(&CheckDirectoryAfterDriveCheck, callback)); // independent from whether or not the operation succeeeds.
content::BrowserThread::PostTask(content::BrowserThread::UI,
FROM_HERE,
base::Bind(callback, false));
return;
}
util::CheckIfDirectoryExists(
GetFileSystemContextForExtensionId(profile, kFileManagerAppId),
url,
base::Bind(&BoolCallbackAsFileErrorCallback, callback));
} }
void PrepareNonNativeLocalPathWritableFile( void PrepareNonNativeLocalPathWritableFile(
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include "chrome/browser/ui/simple_message_box.h" #include "chrome/browser/ui/simple_message_box.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/user_metrics.h" #include "content/public/browser/user_metrics.h"
#include "google_apis/drive/task_util.h"
#include "grit/generated_resources.h" #include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "webkit/browser/fileapi/file_system_backend.h" #include "webkit/browser/fileapi/file_system_backend.h"
...@@ -144,40 +143,6 @@ void ContinueOpenItem(Profile* profile, ...@@ -144,40 +143,6 @@ void ContinueOpenItem(Profile* profile,
} }
} }
// Used to implement CheckIfDirectoryExists().
void CheckIfDirectoryExistsOnIOThread(
scoped_refptr<fileapi::FileSystemContext> file_system_context,
const GURL& url,
const fileapi::FileSystemOperationRunner::StatusCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
fileapi::FileSystemURL file_system_url = file_system_context->CrackURL(url);
file_system_context->operation_runner()->DirectoryExists(
file_system_url, callback);
}
// Checks if a directory exists at |url|.
void CheckIfDirectoryExists(
scoped_refptr<fileapi::FileSystemContext> file_system_context,
const GURL& url,
const fileapi::FileSystemOperationRunner::StatusCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Check the existence of directory using file system API implementation on
// behalf of the file manager app. We need to grant access beforehand.
fileapi::ExternalFileSystemBackend* backend =
file_system_context->external_backend();
DCHECK(backend);
backend->GrantFullAccessToExtension(kFileManagerAppId);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&CheckIfDirectoryExistsOnIOThread,
file_system_context,
url,
google_apis::CreateRelayCallback(callback)));
}
// Converts the |given_path| passed from external callers to the form that the // Converts the |given_path| passed from external callers to the form that the
// file manager can correctly handle. It first migrates old Drive/Download // file manager can correctly handle. It first migrates old Drive/Download
// folder path to the new formats, and then converts path to filesystem URL. // folder path to the new formats, and then converts path to filesystem URL.
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "chrome/browser/chromeos/drive/test_util.h" #include "chrome/browser/chromeos/drive/test_util.h"
#include "chrome/browser/drive/fake_drive_service.h" #include "chrome/browser/drive/fake_drive_service.h"
#include "chrome/browser/extensions/api/file_system/file_system_api.h" #include "chrome/browser/extensions/api/file_system/file_system_api.h"
#include "chrome/browser/extensions/component_loader.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "google_apis/drive/test_util.h" #include "google_apis/drive/test_util.h"
...@@ -27,6 +28,7 @@ class FileSystemApiTestForDrive : public PlatformAppBrowserTest { ...@@ -27,6 +28,7 @@ class FileSystemApiTestForDrive : public PlatformAppBrowserTest {
// real DriveIntegrationService instance is created.) // real DriveIntegrationService instance is created.)
virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
PlatformAppBrowserTest::SetUpInProcessBrowserTestFixture(); PlatformAppBrowserTest::SetUpInProcessBrowserTestFixture();
extensions::ComponentLoader::EnableBackgroundExtensionsForTesting();
ASSERT_TRUE(test_cache_root_.CreateUniqueTempDir()); ASSERT_TRUE(test_cache_root_.CreateUniqueTempDir());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment