file_system_util.h revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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.
4
5#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_UTIL_H_
6#define CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_UTIL_H_
7
8#include <string>
9
10#include "base/callback_forward.h"
11#include "base/platform_file.h"
12#include "chrome/browser/chromeos/drive/drive.pb.h"
13#include "chrome/browser/chromeos/drive/file_errors.h"
14#include "chrome/browser/google_apis/gdata_errorcode.h"
15#include "googleurl/src/gurl.h"
16
17class Profile;
18
19namespace base {
20class FilePath;
21}
22
23namespace fileapi {
24class FileSystemURL;
25}
26
27namespace drive {
28
29class PlatformFileInfoProto;
30
31namespace util {
32
33// Path constants.
34
35// The extension for dirty files. The file names look like
36// "<resource-id>.local".
37const base::FilePath::CharType kLocallyModifiedFileExtension[] =
38    FILE_PATH_LITERAL("local");
39// The extension for mounted files. The file names look like
40// "<resource-id>.<md5>.mounted".
41const base::FilePath::CharType kMountedArchiveFileExtension[] =
42    FILE_PATH_LITERAL("mounted");
43const base::FilePath::CharType kWildCard[] =
44    FILE_PATH_LITERAL("*");
45// The path is used for creating a symlink in "pinned" directory for a file
46// which is not yet fetched.
47const base::FilePath::CharType kSymLinkToDevNull[] =
48    FILE_PATH_LITERAL("/dev/null");
49
50// Special resource IDs introduced to manage pseudo directory tree locally.
51// These strings are supposed to be different from any resource ID used on the
52// server, and are never sent to the server. Practical resource IDs used so far
53// have only alphabets/numbers ([a-zA-Z0-9]) and ':'.
54// Hence '<' and '>' around the directory name have been added to make them
55// different from normal server-side IDs.
56const char kDriveGrandRootSpecialResourceId[] = "<drive>";
57
58const char kDriveOtherDirSpecialResourceId[] = "<other>";
59
60// The directory names used for the Google Drive file system tree. These names
61// are used in URLs for the file manager, hence user-visible.
62const base::FilePath::CharType kDriveGrandRootDirName[] =
63    FILE_PATH_LITERAL("drive");
64
65const base::FilePath::CharType kDriveMyDriveRootDirName[] =
66    FILE_PATH_LITERAL("root");
67
68const base::FilePath::CharType kDriveOtherDirName[] =
69    FILE_PATH_LITERAL("other");
70
71const base::FilePath::CharType kDriveMyDriveRootPath[] =
72    FILE_PATH_LITERAL("drive/root");
73
74const base::FilePath::CharType kDriveOtherDirPath[] =
75    FILE_PATH_LITERAL("drive/other");
76
77// Returns the path of the top root of the pseudo tree.
78const base::FilePath& GetDriveGrandRootPath();
79
80// Returns the path of the directory representing "My Drive".
81const base::FilePath& GetDriveMyDriveRootPath();
82
83// Returns the path of the directory representing entries other than "My Drive".
84const base::FilePath& GetDriveOtherDirPath();
85
86// Returns the Drive mount point path, which looks like "/special/drive".
87const base::FilePath& GetDriveMountPointPath();
88
89// Checks if the resource ID is a special one, which is effective only in our
90// implementation and is not supposed to be sent to the server.
91bool IsSpecialResourceId(const std::string& resource_id);
92
93// Returns a ResourceEntry for "/drive/root" directory.
94ResourceEntry CreateMyDriveRootEntry(const std::string& root_resource_id);
95
96// Returns a ResourceEntry for "/drive/other" directory.
97ResourceEntry CreateOtherDirEntry();
98
99// Returns the Drive mount path as string.
100const std::string& GetDriveMountPointPathAsString();
101
102// Returns the 'local' root of remote file system as "/special".
103const base::FilePath& GetSpecialRemoteRootPath();
104
105// Returns the gdata file resource url formatted as "drive:<path>"
106GURL FilePathToDriveURL(const base::FilePath& path);
107
108// Converts a drive: URL back to a path that can be passed to FileSystem.
109base::FilePath DriveURLToFilePath(const GURL& url);
110
111// Overwrites |url| with a Drive URL when appropriate.
112void MaybeSetDriveURL(Profile* profile, const base::FilePath& path, GURL* url);
113
114// Returns true if the given path is under the Drive mount point.
115bool IsUnderDriveMountPoint(const base::FilePath& path);
116
117// Returns true if the given path is under the Drive mount point and needs to be
118// migrated to the new namespace. http://crbug.com/174233.
119bool NeedsNamespaceMigration(const base::FilePath& path);
120
121// Returns new FilePath with a namespace "root" inserted at the 3rd component.
122// e.g. "/special/drive/root/dir" for "/special/drive/dir".
123// NeedsNamespaceMigration(path) should be true (after the TODOs are resolved).
124base::FilePath ConvertToMyDriveNamespace(const base::FilePath& path);
125
126// Extracts the Drive path from the given path located under the Drive mount
127// point. Returns an empty path if |path| is not under the Drive mount point.
128// Examples: ExtractDrivePath("/special/drive/foo.txt") => "drive/foo.txt"
129base::FilePath ExtractDrivePath(const base::FilePath& path);
130
131// Extracts the Drive path (e.g., "drive/foo.txt") from the filesystem URL.
132// Returns an empty path if |url| does not point under Drive mount point.
133base::FilePath ExtractDrivePathFromFileSystemUrl(
134    const fileapi::FileSystemURL& url);
135
136// Escapes a file name in Drive cache.
137// Replaces percent ('%'), period ('.') and slash ('/') with %XX (hex)
138std::string EscapeCacheFileName(const std::string& filename);
139
140// Unescapes a file path in Drive cache.
141// This is the inverse of EscapeCacheFileName.
142std::string UnescapeCacheFileName(const std::string& filename);
143
144// Escapes forward slashes from file names with magic unicode character
145// \u2215 pretty much looks the same in UI.
146std::string EscapeUtf8FileName(const std::string& input);
147
148// Extracts resource_id out of edit url.
149std::string ExtractResourceIdFromUrl(const GURL& url);
150
151// Gets the cache root path (i.e. <user_profile_dir>/GCache/v1) from the
152// profile.
153base::FilePath GetCacheRootPath(Profile* profile);
154
155// Extracts resource_id, md5, and extra_extension from cache path.
156// Case 1: Pinned and outgoing symlinks only have resource_id.
157// Example: path="/user/GCache/v1/pinned/pdf:a1b2" =>
158//          resource_id="pdf:a1b2", md5="", extra_extension="";
159// Case 2: Normal files have both resource_id and md5.
160// Example: path="/user/GCache/v1/tmp/pdf:a1b2.01234567" =>
161//          resource_id="pdf:a1b2", md5="01234567", extra_extension="";
162// Case 3: Mounted files have all three parts.
163// Example: path="/user/GCache/v1/persistent/pdf:a1b2.01234567.mounted" =>
164//          resource_id="pdf:a1b2", md5="01234567", extra_extension="mounted".
165void ParseCacheFilePath(const base::FilePath& path,
166                        std::string* resource_id,
167                        std::string* md5,
168                        std::string* extra_extension);
169
170// Callback type for PrepareWritablebase::FilePathAndRun.
171typedef base::Callback<void (FileError, const base::FilePath& path)>
172    OpenFileCallback;
173
174// Invokes |callback| on blocking thread pool, after converting virtual |path|
175// string like "/special/drive/foo.txt" to the concrete local cache file path.
176// After |callback| returns, the written content is synchronized to the server.
177//
178// If |path| is not a Drive path, it is regarded as a local path and no path
179// conversion takes place.
180//
181// Must be called from UI thread.
182void PrepareWritableFileAndRun(Profile* profile,
183                               const base::FilePath& path,
184                               const OpenFileCallback& callback);
185
186// Ensures the existence of |directory| of '/special/drive/foo'.  This will
187// create |directory| and its ancestors if they don't exist.  |callback| is
188// invoked after making sure that |directory| exists.  |callback| should
189// interpret error codes of either FILE_ERROR_OK or FILE_ERROR_EXISTS as
190// indicating that |directory| now exists.
191//
192// If |directory| is not a Drive path, it won't check the existence and just
193// runs |callback|.
194//
195// Must be called from UI/IO thread.
196void EnsureDirectoryExists(Profile* profile,
197                           const base::FilePath& directory,
198                           const FileOperationCallback& callback);
199
200// Converts GData error code into file platform error code.
201FileError GDataToFileError(google_apis::GDataErrorCode status);
202
203// Converts the resource entry to the platform file.
204void ConvertResourceEntryToPlatformFileInfo(
205    const PlatformFileInfoProto& entry,
206    base::PlatformFileInfo* file_info);
207
208// Converts the platform file info to the resource entry.
209void ConvertPlatformFileInfoToResourceEntry(
210    const base::PlatformFileInfo& file_info,
211    PlatformFileInfoProto* entry);
212
213// Does nothing with |error|. Used with functions taking FileOperationCallback.
214void EmptyFileOperationCallback(FileError error);
215
216// Helper to destroy objects which needs Destroy() to be called on destruction.
217struct DestroyHelper {
218  template<typename T>
219  void operator()(T* object) const {
220    if (object)
221      object->Destroy();
222  }
223};
224
225}  // namespace util
226}  // namespace drive
227
228#endif  // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_UTIL_H_
229