Support cross-filesystem operations in FileSystem API
https://bugs.webkit.org/show_bug.cgi?id=84135

Reviewed by David Levin.

Source/WebCore:

Currently we pass Entry's fullPath to AsyncFileSystem layer where
we convert the given path to filesystem URL which includes origin and
filesystem type information, but in that way we cannot handle
cross-filesystem operations (e.g. cross-filesystem copy and move)
well since we end up with always attaching the source filesystem's
origin and type information for argument paths.

This patch does:
- change AsyncFileSystem's operation methods not to take entry paths
  but complete filesystem URLs.
- move type and rootURL information from AsyncFileSystem instance into
  DOMFileSystemBase instance (platform layer to Modules/filesystem layer)
- move filesystem-type related code in AsyncFileSystemChromium.cpp into
  DOMFileSystemChromium.cpp, which implements chromioum-specific
  DOMFileSystem code.
- move platform/FileSystemType.h into Modules/filesystem/FileSystemType.h.
- adding FileSystemType.h entry to build files (e.g. WebCore.gypi, WebCore.xcodeproj etc)

Test: fast/filesystem/cross-filesystem-op.html

* Modules/filesystem/DOMFileSystem.cpp:
(WebCore::DOMFileSystem::create):
(WebCore::DOMFileSystem::DOMFileSystem):
(WebCore::DOMFileSystem::createWriter):
(WebCore::DOMFileSystem::createFile):
* Modules/filesystem/DOMFileSystem.h:
* Modules/filesystem/DOMFileSystemBase.cpp:
(WebCore::DOMFileSystemBase::DOMFileSystemBase):
(WebCore::DOMFileSystemBase::createFileSystemURL): Added as an internal
implementation of Entry.toURL().
(WebCore::DOMFileSystemBase::getMetadata):
(WebCore::verifyAndGetDestinationPathForCopyOrMove):
(WebCore::DOMFileSystemBase::move):
(WebCore::DOMFileSystemBase::copy):
(WebCore::DOMFileSystemBase::remove):
(WebCore::DOMFileSystemBase::removeRecursively):
(WebCore::DOMFileSystemBase::getParent):
(WebCore::DOMFileSystemBase::getFile):
(WebCore::DOMFileSystemBase::getDirectory):
(WebCore::DOMFileSystemBase::readDirectory):
* Modules/filesystem/DOMFileSystemBase.h: Changed to make each
DOMFileSystemBase instance have filesystem type and rootURL (they were
held by AsyncFileSystem previously)
(WebCore::DOMFileSystemBase::create): Changed to take additional parameters.
(WebCore::DOMFileSystemBase::type): Added.(Moved from AsyncFileSystem::type)
(WebCore::DOMFileSystemBase::rootURL): Added.(Moved from AsyncFileSystem::rootURL).
* Modules/filesystem/DOMFileSystemSync.cpp:
(WebCore::DOMFileSystemSync::create):
(WebCore::DOMFileSystemSync::DOMFileSystemSync):
(WebCore::DOMFileSystemSync::createFile):
(WebCore::DOMFileSystemSync::createWriter):
* Modules/filesystem/DOMFileSystemSync.h:
(WebCore::DOMFileSystemSync::create):
* Modules/filesystem/DOMWindowFileSystem.cpp:
(WebCore::DOMWindowFileSystem::webkitRequestFileSystem):
(WebCore::DOMWindowFileSystem::webkitResolveLocalFileSystemURL):
* Modules/filesystem/EntryBase.cpp:
(WebCore::EntryBase::toURL):
* Modules/filesystem/FileSystemCallbacks.cpp:
(WebCore::FileSystemCallbacks::create):
(WebCore::FileSystemCallbacks::FileSystemCallbacks):
(WebCore::FileSystemCallbacks::didOpenFileSystem):
(WebCore::ResolveURICallbacks::create):
(WebCore::ResolveURICallbacks::ResolveURICallbacks):
(WebCore::ResolveURICallbacks::didOpenFileSystem):
* Modules/filesystem/FileSystemCallbacks.h:
(FileSystemCallbacks):
(ResolveURICallbacks):
* Modules/filesystem/FileSystemType.h: Renamed from Source/WebCore/platform/FileSystemType.h.
* Modules/filesystem/LocalFileSystem.cpp:
(WebCore::openFileSystem):
(WebCore::LocalFileSystem::readFileSystem):
(WebCore::LocalFileSystem::requestFileSystem):
* Modules/filesystem/LocalFileSystem.h:
* Modules/filesystem/WorkerContextFileSystem.cpp:
(WebCore::WorkerContextFileSystem::webkitRequestFileSystem):
(WebCore::WorkerContextFileSystem::webkitRequestFileSystemSync):
(WebCore::WorkerContextFileSystem::webkitResolveLocalFileSystemURL):
(WebCore::WorkerContextFileSystem::webkitResolveLocalFileSystemSyncURL):
* Modules/filesystem/chromium/DOMFileSystemChromium.cpp: Added for chromium-specific
implementation. Almost all of the code is moved from AsyncFileSystemChromium.
(WebCore::DOMFileSystemBase::isValidType):
(WebCore::DOMFileSystemBase::crackFileSystemURL):
(WebCore::DOMFileSystemBase::supportsToURL):
(WebCore::DOMFileSystemBase::createFileSystemURL):
(WebCore::DOMFileSystemChromium::createIsolatedFileSystem):
* Modules/filesystem/chromium/DOMFileSystemChromium.h: Added.
* Modules/filesystem/chromium/DataTransferItemFileSystemChromium.cpp:
(WebCore::DataTransferItemFileSystem::webkitGetAsEntry):
* Modules/filesystem/chromium/DraggedIsolatedFileSystem.cpp:
(WebCore::DraggedIsolatedFileSystem::getDOMFileSystem):
* WebCore.gypi:
* platform/AsyncFileSystem.cpp:
(WebCore::AsyncFileSystem::openFileSystem):
* platform/AsyncFileSystem.h:
(AsyncFileSystem):
(WebCore::AsyncFileSystem::AsyncFileSystem):
* platform/AsyncFileSystemCallbacks.h:
(WebCore::AsyncFileSystemCallbacks::didOpenFileSystem):
* platform/blackberry/AsyncFileSystemBlackBerry.cpp:
(WebCore::AsyncFileSystem::create):
(WebCore::AsyncFileSystem::openFileSystem):
(WebCore::AsyncFileSystemBlackBerry::AsyncFileSystemBlackBerry):
(WebCore::AsyncFileSystemBlackBerry::move):
(WebCore::AsyncFileSystemBlackBerry::copy):
(WebCore::AsyncFileSystemBlackBerry::remove):
(WebCore::AsyncFileSystemBlackBerry::removeRecursively):
(WebCore::AsyncFileSystemBlackBerry::readMetadata):
(WebCore::AsyncFileSystemBlackBerry::createFile):
(WebCore::AsyncFileSystemBlackBerry::createDirectory):
(WebCore::AsyncFileSystemBlackBerry::fileExists):
(WebCore::AsyncFileSystemBlackBerry::directoryExists):
(WebCore::AsyncFileSystemBlackBerry::readDirectory):
(WebCore::AsyncFileSystemBlackBerry::createWriter):
(WebCore::AsyncFileSystemBlackBerry::createSnapshotFileAndReadMetadata):
* platform/blackberry/AsyncFileSystemBlackBerry.h:
* platform/chromium/PlatformSupport.h:
* platform/gtk/AsyncFileSystemGtk.cpp:
(WebCore::AsyncFileSystem::create):
(WebCore::AsyncFileSystem::openFileSystem):
(WebCore::AsyncFileSystemGtk::AsyncFileSystemGtk):
(WebCore::AsyncFileSystemGtk::move):
(WebCore::AsyncFileSystemGtk::copy):
(WebCore::AsyncFileSystemGtk::remove):
(WebCore::AsyncFileSystemGtk::removeRecursively):
(WebCore::AsyncFileSystemGtk::readMetadata):
(WebCore::AsyncFileSystemGtk::createFile):
(WebCore::AsyncFileSystemGtk::createDirectory):
(WebCore::AsyncFileSystemGtk::fileExists):
(WebCore::AsyncFileSystemGtk::directoryExists):
(WebCore::AsyncFileSystemGtk::readDirectory):
(WebCore::AsyncFileSystemGtk::createWriter):
* platform/gtk/AsyncFileSystemGtk.h:

* GNUmakefile.list.am: Added FileSystemType.h.
* WebCore.gypi: Added FileSystemType.h.
* WebCore.vcproj/WebCore.vcproj: Added FileSystemType.h.
* WebCore.xcodeproj/project.pbxproj: Added FileSystemType.h.

Source/WebKit/chromium:

Currently we pass Entry's fullPath to AsyncFileSystem layer where
we convert the given path to filesystem URL which includes origin and
filesystem type information, but in that way we cannot handle
cross-filesystem operations (e.g. cross-filesystem copy and move)
well since we end up with always attaching the source filesystem's
origin and type information for argument paths.

This patch does:
- move filesystem-type related code out of AsyncFileSystemChromium.cpp
  (moving into DOMFileSystemChromium.cpp)
- change AsyncFileSystemChromium's methods implementation not to take
  entry paths but complete filesystem URLs.

* src/AsyncFileSystemChromium.cpp:
(WebCore::AsyncFileSystemChromium::AsyncFileSystemChromium):
(WebCore::AsyncFileSystemChromium::move):
(WebCore::AsyncFileSystemChromium::copy):
(WebCore::AsyncFileSystemChromium::remove):
(WebCore::AsyncFileSystemChromium::removeRecursively):
(WebCore::AsyncFileSystemChromium::readMetadata):
(WebCore::AsyncFileSystemChromium::createFile):
(WebCore::AsyncFileSystemChromium::createDirectory):
(WebCore::AsyncFileSystemChromium::fileExists):
(WebCore::AsyncFileSystemChromium::directoryExists):
(WebCore::AsyncFileSystemChromium::readDirectory):
(WebCore::AsyncFileSystemChromium::createWriter):
(WebCore::AsyncFileSystemChromium::createSnapshotFileAndReadMetadata):
* src/AsyncFileSystemChromium.h:
(WebCore::AsyncFileSystemChromium::create):
(AsyncFileSystemChromium):
* src/LocalFileSystemChromium.cpp:
(WebCore::openFileSystemHelper):
* src/PlatformSupport.cpp:
(WebCore::PlatformSupport::createAsyncFileSystem):
* src/WebFileSystemCallbacksImpl.cpp:
(WebKit::WebFileSystemCallbacksImpl::WebFileSystemCallbacksImpl):
(WebKit::WebFileSystemCallbacksImpl::didOpenFileSystem):
* src/WebFileSystemCallbacksImpl.h:
(WebFileSystemCallbacksImpl):
* src/WebFrameImpl.cpp:
(WebKit::WebFrameImpl::createFileSystem):
(WebKit::WebFrameImpl::createFileEntry):
* src/WorkerAsyncFileSystemChromium.cpp:
(WebCore::WorkerAsyncFileSystemChromium::WorkerAsyncFileSystemChromium):
(WebCore::WorkerAsyncFileSystemChromium::move):
(WebCore::WorkerAsyncFileSystemChromium::copy):
(WebCore::WorkerAsyncFileSystemChromium::remove):
(WebCore::WorkerAsyncFileSystemChromium::removeRecursively):
(WebCore::WorkerAsyncFileSystemChromium::readMetadata):
(WebCore::WorkerAsyncFileSystemChromium::createFile):
(WebCore::WorkerAsyncFileSystemChromium::createDirectory):
(WebCore::WorkerAsyncFileSystemChromium::fileExists):
(WebCore::WorkerAsyncFileSystemChromium::directoryExists):
(WebCore::WorkerAsyncFileSystemChromium::readDirectory):
(WebCore::WorkerAsyncFileSystemChromium::createWriter):
(WebCore::WorkerAsyncFileSystemChromium::createSnapshotFileAndReadMetadata):
* src/WorkerAsyncFileSystemChromium.h:
(WebCore::WorkerAsyncFileSystemChromium::create):
(WorkerAsyncFileSystemChromium):

LayoutTests:

* fast/filesystem/cross-filesystem-op-expected.txt: Added.
* fast/filesystem/cross-filesystem-op.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@116388 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/platform/AsyncFileSystem.h b/Source/WebCore/platform/AsyncFileSystem.h
index 6832979..6e53a9a 100644
--- a/Source/WebCore/platform/AsyncFileSystem.h
+++ b/Source/WebCore/platform/AsyncFileSystem.h
@@ -51,106 +51,86 @@
 public:
     virtual ~AsyncFileSystem() { }
 
-    // Path prefixes that are used in the filesystem URLs (that can be obtained by toURL()).
-    // http://www.w3.org/TR/file-system-api/#widl-Entry-toURL
-    static const char persistentPathPrefix[];
-    static const size_t persistentPathPrefixLength;
-    static const char temporaryPathPrefix[];
-    static const size_t temporaryPathPrefixLength;
-
     virtual void stop() { }
     virtual bool hasPendingActivity() { return false; }
 
     static bool isAvailable();
 
-    static bool isValidType(FileSystemType);
-
-    static bool crackFileSystemURL(const KURL&, FileSystemType&, String& filePath);
-
-    virtual KURL toURL(const String& originString, const String& fullPath) const = 0;
-
     // Subclass must implement this if it supports synchronous operations.
     // This should return false if there are no pending operations.
     virtual bool waitForOperationToComplete() { return false; }
 
     // Creates and returns a new platform-specific AsyncFileSystem instance if the platform has its own implementation.
-    static PassOwnPtr<AsyncFileSystem> create(FileSystemType);
+    static PassOwnPtr<AsyncFileSystem> create();
 
     // Opens a new file system. The create parameter specifies whether or not to create the path if it does not already exists.
-    static void openFileSystem(const String& basePath, const String& storageIdentifier, FileSystemType, bool create, PassOwnPtr<AsyncFileSystemCallbacks>);
+    static void openFileSystem(const String& basePath, const String& storageIdentifier, bool create, PassOwnPtr<AsyncFileSystemCallbacks>);
 
     // Moves a file or directory from srcPath to destPath.
     // AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully.
     // AsyncFileSystemCallbacks::didFail() is called otherwise.
-    virtual void move(const String& srcPath, const String& destPath, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+    virtual void move(const KURL& srcPath, const KURL& destPath, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
 
     // Copies a file or directory from srcPath to destPath.
     // AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully.
     // AsyncFileSystemCallbacks::didFail() is called otherwise.
-    virtual void copy(const String& srcPath, const String& destPath, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+    virtual void copy(const KURL& srcPath, const KURL& destPath, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
 
     // Deletes a file or directory at a given path.
     // It is an error to try to remove a directory that is not empty.
     // AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully.
     // AsyncFileSystemCallbacks::didFail() is called otherwise.
-    virtual void remove(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+    virtual void remove(const KURL& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
 
     // Recursively deletes a directory at a given path.
     // AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully.
     // AsyncFileSystemCallbacks::didFail() is called otherwise.
-    virtual void removeRecursively(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+    virtual void removeRecursively(const KURL& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
 
     // Retrieves the metadata information of the file or directory at a given path.
     // AsyncFileSystemCallbacks::didReadMetadata() is called when the operation is completed successfully.
     // AsyncFileSystemCallbacks::didFail() is called otherwise.
-    virtual void readMetadata(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+    virtual void readMetadata(const KURL& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
 
     // Creates a file at a given path.  If exclusive flag is true, it fails if the path already exists.
     // AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully.
     // AsyncFileSystemCallbacks::didFail() is called otherwise.
-    virtual void createFile(const String& path, bool exclusive, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+    virtual void createFile(const KURL& path, bool exclusive, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
 
     // Creates a directory at a given path.  If exclusive flag is true, it fails if the path already exists.
     // AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully.
     // AsyncFileSystemCallbacks::didFail() is called otherwise.
-    virtual void createDirectory(const String& path, bool exclusive, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+    virtual void createDirectory(const KURL& path, bool exclusive, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
 
     // Checks if a file exists at a given path.
     // AsyncFileSystemCallbacks::didSucceed() is called if the file exists.
     // AsyncFileSystemCallbacks::didFail() is called otherwise.
-    virtual void fileExists(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+    virtual void fileExists(const KURL& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
 
     // Checks if a directory exists at a given path.
     // AsyncFileSystemCallbacks::didSucceed() is called if the directory exists.
     // AsyncFileSystemCallbacks::didFail() is called otherwise.
-    virtual void directoryExists(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+    virtual void directoryExists(const KURL& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
 
     // Reads directory entries of a given directory at path.
     // AsyncFileSystemCallbacks::didReadDirectoryEntry() is called when each directory entry is called. AsyncFileSystemCallbacks::didReadDirectoryEntries() is called after a chunk of directory entries have been read.
     // AsyncFileSystemCallbacks::didFail() is when there is an error.
-    virtual void readDirectory(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+    virtual void readDirectory(const KURL& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
 
     // Creates an AsyncFileWriter for a given file path.
     // AsyncFileSystemCallbacks::didCreateFileWriter() is called when an AsyncFileWriter is created successfully.
     // AsyncFileSystemCallbacks::didFail() is called otherwise.
-    virtual void createWriter(AsyncFileWriterClient* client, const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+    virtual void createWriter(AsyncFileWriterClient*, const KURL& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
 
     // Creates a snapshot file and read its metadata for a new File object.
     // In local filesystem cases the backend may simply return the metadata of the file itself (as well as readMetadata does),
     // while in remote filesystem case the backend may download the file into a temporary snapshot file and return the metadata of the temporary file.
     // AsyncFileSystemCallbacks::didReadMetadata() is called when the metadata for the snapshot file is successfully returned.
     // AsyncFileSystemCallbacks::didFail() is called otherwise.
-    virtual void createSnapshotFileAndReadMetadata(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
-
-    FileSystemType type() const { return m_type; }
+    virtual void createSnapshotFileAndReadMetadata(const KURL& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
 
 protected:
-    AsyncFileSystem(FileSystemType type)
-        : m_type(type)
-    {
-    }
-
-    FileSystemType m_type;
+    AsyncFileSystem() { }
 };
 
 } // namespace WebCore