syncable_file_system_util.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1// Copyright 2013 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#include "chrome/browser/sync_file_system/syncable_file_system_util.h" 6 7#include <vector> 8 9#include "base/command_line.h" 10#include "base/location.h" 11#include "base/strings/string_util.h" 12#include "webkit/browser/fileapi/external_mount_points.h" 13#include "webkit/browser/fileapi/file_observers.h" 14#include "webkit/browser/fileapi/file_system_context.h" 15#include "webkit/common/fileapi/file_system_util.h" 16 17using fileapi::ExternalMountPoints; 18using fileapi::FileSystemContext; 19using fileapi::FileSystemURL; 20 21namespace sync_file_system { 22 23namespace { 24 25// A command switch to enable V2 Sync FileSystem. 26const char kEnableSyncFileSystemV2[] = "enable-syncfs-v2"; 27 28// A command switch to specify comma-separated app IDs to enable V2 Sync 29// FileSystem. 30const char kSyncFileSystemV2Whitelist[] = "syncfs-v2-whitelist"; 31 32const char kSyncableMountName[] = "syncfs"; 33const char kSyncableMountNameForInternalSync[] = "syncfs-internal"; 34 35const base::FilePath::CharType kSyncFileSystemDir[] = 36 FILE_PATH_LITERAL("Sync FileSystem"); 37 38// Flags to enable features for testing. 39bool g_is_syncfs_v2_enabled = true; 40 41void Noop() {} 42 43} // namespace 44 45void RegisterSyncableFileSystem() { 46 ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( 47 kSyncableMountName, 48 fileapi::kFileSystemTypeSyncable, 49 fileapi::FileSystemMountOption(), 50 base::FilePath()); 51 ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( 52 kSyncableMountNameForInternalSync, 53 fileapi::kFileSystemTypeSyncableForInternalSync, 54 fileapi::FileSystemMountOption(), 55 base::FilePath()); 56} 57 58void RevokeSyncableFileSystem() { 59 ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( 60 kSyncableMountName); 61 ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( 62 kSyncableMountNameForInternalSync); 63} 64 65GURL GetSyncableFileSystemRootURI(const GURL& origin) { 66 return GURL(fileapi::GetExternalFileSystemRootURIString( 67 origin, kSyncableMountName)); 68} 69 70FileSystemURL CreateSyncableFileSystemURL(const GURL& origin, 71 const base::FilePath& path) { 72 base::FilePath path_for_url = path; 73 if (fileapi::VirtualPath::IsAbsolute(path.value())) 74 path_for_url = base::FilePath(path.value().substr(1)); 75 76 return ExternalMountPoints::GetSystemInstance()->CreateExternalFileSystemURL( 77 origin, kSyncableMountName, path_for_url); 78} 79 80FileSystemURL CreateSyncableFileSystemURLForSync( 81 fileapi::FileSystemContext* file_system_context, 82 const FileSystemURL& syncable_url) { 83 return ExternalMountPoints::GetSystemInstance()->CreateExternalFileSystemURL( 84 syncable_url.origin(), 85 kSyncableMountNameForInternalSync, 86 syncable_url.path()); 87} 88 89bool SerializeSyncableFileSystemURL(const FileSystemURL& url, 90 std::string* serialized_url) { 91 if (!url.is_valid() || url.type() != fileapi::kFileSystemTypeSyncable) 92 return false; 93 *serialized_url = 94 GetSyncableFileSystemRootURI(url.origin()).spec() + 95 url.path().AsUTF8Unsafe(); 96 return true; 97} 98 99bool DeserializeSyncableFileSystemURL( 100 const std::string& serialized_url, FileSystemURL* url) { 101#if !defined(FILE_PATH_USES_WIN_SEPARATORS) 102 DCHECK(serialized_url.find('\\') == std::string::npos); 103#endif // FILE_PATH_USES_WIN_SEPARATORS 104 105 FileSystemURL deserialized = 106 ExternalMountPoints::GetSystemInstance()->CrackURL(GURL(serialized_url)); 107 if (!deserialized.is_valid() || 108 deserialized.type() != fileapi::kFileSystemTypeSyncable) { 109 return false; 110 } 111 112 *url = deserialized; 113 return true; 114} 115 116bool IsV2Enabled() { 117 return g_is_syncfs_v2_enabled || 118 CommandLine::ForCurrentProcess()->HasSwitch(kEnableSyncFileSystemV2); 119} 120 121bool IsV2EnabledForOrigin(const GURL& origin) { 122 if (IsV2Enabled()) 123 return true; 124 125 // Spark release channel. 126 if (origin.host() == "kcjgcakhgelcejampmijgkjkadfcncjl") 127 return true; 128 // Spark dev channel. 129 if (origin.host() == "pnoffddplpippgcfjdhbmhkofpnaalpg") 130 return true; 131 132 CommandLine command_line = *CommandLine::ForCurrentProcess(); 133 if (command_line.HasSwitch(kSyncFileSystemV2Whitelist)) { 134 std::string app_ids_string = 135 command_line.GetSwitchValueASCII(kSyncFileSystemV2Whitelist); 136 if (app_ids_string.find(origin.host()) == std::string::npos) 137 return false; 138 std::vector<std::string> app_ids; 139 Tokenize(app_ids_string, ",", &app_ids); 140 for (size_t i = 0; i < app_ids.size(); ++i) { 141 if (origin.host() == app_ids[i]) 142 return true; 143 } 144 } 145 146 return false; 147} 148 149base::FilePath GetSyncFileSystemDir(const base::FilePath& profile_base_dir) { 150 if (IsV2Enabled()) 151 return profile_base_dir.Append(kSyncFileSystemDir); 152 return profile_base_dir.Append(kSyncFileSystemDir); 153} 154 155ScopedDisableSyncFSV2::ScopedDisableSyncFSV2() { 156 was_enabled_ = IsV2Enabled(); 157 g_is_syncfs_v2_enabled = false; 158} 159 160ScopedDisableSyncFSV2::~ScopedDisableSyncFSV2() { 161 DCHECK(!IsV2Enabled()); 162 g_is_syncfs_v2_enabled = was_enabled_; 163} 164 165void RunSoon(const tracked_objects::Location& from_here, 166 const base::Closure& callback) { 167 base::MessageLoop::current()->PostTask(from_here, callback); 168} 169 170base::Closure NoopClosure() { 171 return base::Bind(&Noop); 172} 173 174} // namespace sync_file_system 175