1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef WEBKIT_FILEAPI_OBFUSCATED_FILE_UTIL_H_
6 #define WEBKIT_FILEAPI_OBFUSCATED_FILE_UTIL_H_
12 #include "base/file_path.h"
13 #include "base/file_util_proxy.h"
14 #include "base/platform_file.h"
15 #include "base/timer.h"
16 #include "webkit/blob/shareable_file_reference.h"
17 #include "webkit/fileapi/file_system_directory_database.h"
18 #include "webkit/fileapi/file_system_file_util.h"
19 #include "webkit/fileapi/file_system_origin_database.h"
20 #include "webkit/fileapi/file_system_types.h"
21 #include "webkit/fileapi/file_system_url.h"
22 #include "webkit/fileapi/fileapi_export.h"
25 struct PlatformFileInfo
;
33 class FileSystemOperationContext
;
35 // The overall implementation philosophy of this class is that partial failures
36 // should leave us with an intact database; we'd prefer to leak the occasional
37 // backing file than have a database entry whose backing file is missing. When
38 // doing FSCK operations, if you find a loose backing file with no reference,
39 // you may safely delete it.
41 // This class must be deleted on the FILE thread, because that's where
42 // DropDatabases needs to be called.
43 class FILEAPI_EXPORT_PRIVATE ObfuscatedFileUtil
: public FileSystemFileUtil
{
45 // Origin enumerator interface.
46 // An instance of this interface is assumed to be called on the file thread.
47 class AbstractOriginEnumerator
{
49 virtual ~AbstractOriginEnumerator() {}
51 // Returns the next origin. Returns empty if there are no more origins.
52 virtual GURL
Next() = 0;
54 // Returns the current origin's information.
55 virtual bool HasFileSystemType(FileSystemType type
) const = 0;
58 explicit ObfuscatedFileUtil(const FilePath
& file_system_directory
);
59 virtual ~ObfuscatedFileUtil();
61 // FileSystemFileUtil overrides.
62 virtual base::PlatformFileError
CreateOrOpen(
63 FileSystemOperationContext
* context
,
64 const FileSystemURL
& url
,
66 base::PlatformFile
* file_handle
,
67 bool* created
) OVERRIDE
;
68 virtual PlatformFileError
Close(
69 FileSystemOperationContext
* context
,
70 PlatformFile file
) OVERRIDE
;
71 virtual base::PlatformFileError
EnsureFileExists(
72 FileSystemOperationContext
* context
,
73 const FileSystemURL
& url
, bool* created
) OVERRIDE
;
74 virtual base::PlatformFileError
CreateDirectory(
75 FileSystemOperationContext
* context
,
76 const FileSystemURL
& url
,
78 bool recursive
) OVERRIDE
;
79 virtual base::PlatformFileError
GetFileInfo(
80 FileSystemOperationContext
* context
,
81 const FileSystemURL
& url
,
82 base::PlatformFileInfo
* file_info
,
83 FilePath
* platform_file
) OVERRIDE
;
84 virtual AbstractFileEnumerator
* CreateFileEnumerator(
85 FileSystemOperationContext
* context
,
86 const FileSystemURL
& root_url
,
87 bool recursive
) OVERRIDE
;
88 virtual base::PlatformFileError
GetLocalFilePath(
89 FileSystemOperationContext
* context
,
90 const FileSystemURL
& file_system_url
,
91 FilePath
* local_path
) OVERRIDE
;
92 virtual base::PlatformFileError
Touch(
93 FileSystemOperationContext
* context
,
94 const FileSystemURL
& url
,
95 const base::Time
& last_access_time
,
96 const base::Time
& last_modified_time
) OVERRIDE
;
97 virtual base::PlatformFileError
Truncate(
98 FileSystemOperationContext
* context
,
99 const FileSystemURL
& url
,
100 int64 length
) OVERRIDE
;
101 virtual bool IsDirectoryEmpty(
102 FileSystemOperationContext
* context
,
103 const FileSystemURL
& url
) OVERRIDE
;
104 virtual base::PlatformFileError
CopyOrMoveFile(
105 FileSystemOperationContext
* context
,
106 const FileSystemURL
& src_url
,
107 const FileSystemURL
& dest_url
,
109 virtual PlatformFileError
CopyInForeignFile(
110 FileSystemOperationContext
* context
,
111 const FilePath
& src_file_path
,
112 const FileSystemURL
& dest_url
) OVERRIDE
;
113 virtual base::PlatformFileError
DeleteFile(
114 FileSystemOperationContext
* context
,
115 const FileSystemURL
& url
) OVERRIDE
;
116 virtual base::PlatformFileError
DeleteSingleDirectory(
117 FileSystemOperationContext
* context
,
118 const FileSystemURL
& url
) OVERRIDE
;
119 virtual base::PlatformFileError
CreateSnapshotFile(
120 FileSystemOperationContext
* context
,
121 const FileSystemURL
& url
,
122 base::PlatformFileInfo
* file_info
,
123 FilePath
* platform_path
,
124 SnapshotFilePolicy
* policy
) OVERRIDE
;
126 // Gets the topmost directory specific to this origin and type. This will
127 // contain both the directory database's files and all the backing file
129 // Returns an empty path if the directory is undefined (e.g. because |type|
130 // is invalid). If the directory is defined, it will be returned, even if
131 // there is a file system error (e.g. the directory doesn't exist on disk and
132 // |create| is false). Callers should always check |error_code| to make sure
133 // the returned path is usable.
134 FilePath
GetDirectoryForOriginAndType(
138 base::PlatformFileError
* error_code
);
140 // Deletes the topmost directory specific to this origin and type. This will
141 // delete its directory database.
142 bool DeleteDirectoryForOriginAndType(const GURL
& origin
, FileSystemType type
);
144 // This will migrate a filesystem from the old passthrough sandbox into the
145 // new obfuscated one. It won't obfuscate the old filenames [it will maintain
146 // the old structure, but move it to a new root], but any new files created
147 // will go into the new standard locations. This will be completely
148 // transparent to the user. This migration is atomic in that it won't alter
149 // the source data until it's done, and that will be with a single directory
150 // move [the directory with the unguessable name will move into the new
151 // filesystem storage directory]. However, if this fails partway through, it
152 // might leave a seemingly-valid database for this origin. When it starts up,
153 // it will clear any such database, just in case.
154 bool MigrateFromOldSandbox(
155 const GURL
& origin
, FileSystemType type
, const FilePath
& root
);
157 // TODO(ericu): This doesn't really feel like it belongs in this class.
158 // The previous version lives in FileSystemPathManager, but perhaps
159 // SandboxMountPointProvider would be better?
160 static FilePath::StringType
GetDirectoryNameForType(FileSystemType type
);
162 // This method and all methods of its returned class must be called only on
163 // the FILE thread. The caller is responsible for deleting the returned
165 AbstractOriginEnumerator
* CreateOriginEnumerator();
167 // Deletes a directory database from the database list in the ObfuscatedFSFU
168 // and destroys the database on the disk.
169 bool DestroyDirectoryDatabase(const GURL
& origin
, FileSystemType type
);
171 // Computes a cost for storing a given file in the obfuscated FSFU.
172 // As the cost of a file is independent of the cost of its parent directories,
173 // this ignores all but the BaseName of the supplied path. In order to
174 // compute the cost of adding a multi-segment directory recursively, call this
175 // on each path segment and add the results.
176 static int64
ComputeFilePathCost(const FilePath
& path
);
179 typedef FileSystemDirectoryDatabase::FileId FileId
;
180 typedef FileSystemDirectoryDatabase::FileInfo FileInfo
;
182 friend class ObfuscatedFileEnumerator
;
184 base::PlatformFileError
GetFileInfoInternal(
185 FileSystemDirectoryDatabase
* db
,
186 FileSystemOperationContext
* context
,
190 FileInfo
* local_info
,
191 base::PlatformFileInfo
* file_info
,
192 FilePath
* platform_file_path
);
194 // Creates a new file, both the underlying backing file and the entry in the
195 // database. |dest_file_info| is an in-out parameter. Supply the name and
196 // parent_id; data_path is ignored. On success, data_path will
197 // always be set to the relative path [from the root of the type-specific
198 // filesystem directory] of a NEW backing file, and handle, if supplied, will
199 // hold open PlatformFile for the backing file, which the caller is
200 // responsible for closing. If you supply a path in |source_path|, it will be
201 // used as a source from which to COPY data.
202 // Caveat: do not supply handle if you're also supplying a data path. It was
203 // easier not to support this, and no code has needed it so far, so it will
204 // DCHECK and handle will hold base::kInvalidPlatformFileValue.
205 base::PlatformFileError
CreateFile(
206 FileSystemOperationContext
* context
,
207 const FilePath
& source_file_path
,
208 const GURL
& dest_origin
,
209 FileSystemType dest_type
,
210 FileInfo
* dest_file_info
,
212 base::PlatformFile
* handle
);
214 // This converts from a relative path [as is stored in the FileInfo.data_path
215 // field] to an absolute platform path that can be given to the native
217 FilePath
DataPathToLocalPath(
220 const FilePath
& data_file_path
);
222 // This returns NULL if |create| flag is false and a filesystem does not
223 // exist for the given |origin_url| and |type|.
224 // For read operations |create| should be false.
225 FileSystemDirectoryDatabase
* GetDirectoryDatabase(
226 const GURL
& origin_url
, FileSystemType type
, bool create
);
228 // Gets the topmost directory specific to this origin. This will
229 // contain both the filesystem type subdirectories.
230 FilePath
GetDirectoryForOrigin(const GURL
& origin
,
232 base::PlatformFileError
* error_code
);
234 void InvalidateUsageCache(FileSystemOperationContext
* context
,
236 FileSystemType type
);
239 void DropDatabases();
240 bool InitOriginDatabase(bool create
);
242 base::PlatformFileError
GenerateNewLocalPath(
243 FileSystemDirectoryDatabase
* db
,
244 FileSystemOperationContext
* context
,
247 FilePath
* local_path
);
249 typedef std::map
<std::string
, FileSystemDirectoryDatabase
*> DirectoryMap
;
250 DirectoryMap directories_
;
251 scoped_ptr
<FileSystemOriginDatabase
> origin_database_
;
252 FilePath file_system_directory_
;
253 base::OneShotTimer
<ObfuscatedFileUtil
> timer_
;
255 DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileUtil
);
258 } // namespace fileapi
260 #endif // WEBKIT_FILEAPI_OBFUSCATED_FILE_UTIL_H_