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