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.
5 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
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"
17 using fileapi::ExternalMountPoints;
18 using fileapi::FileSystemContext;
19 using fileapi::FileSystemURL;
21 namespace sync_file_system {
25 // A command switch to enable syncing directory operations in Sync FileSystem
26 // API. (http://crbug.com/161442)
27 // TODO(kinuko): this command-line switch should be temporary.
28 const char kEnableSyncFSDirectoryOperation[] =
29 "enable-syncfs-directory-operation";
31 // A command switch to enable V2 Sync FileSystem.
32 const char kEnableSyncFileSystemV2[] = "enable-syncfs-v2";
34 // A command switch to specify comma-separated app IDs to enable V2 Sync
36 const char kSyncFileSystemV2Whitelist[] = "syncfs-v2-whitelist";
38 const char kSyncableMountName[] = "syncfs";
39 const char kSyncableMountNameForInternalSync[] = "syncfs-internal";
41 const base::FilePath::CharType kSyncFileSystemDir[] =
42 FILE_PATH_LITERAL("Sync FileSystem");
43 const base::FilePath::CharType kSyncFileSystemDirDev[] =
44 FILE_PATH_LITERAL("Sync FileSystem Dev");
46 // Flags to enable features for testing.
47 bool g_is_directory_operation_enabled = false;
48 bool g_is_syncfs_v2_enabled = false;
52 void RegisterSyncableFileSystem() {
53 ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
55 fileapi::kFileSystemTypeSyncable,
56 fileapi::FileSystemMountOption(),
58 ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
59 kSyncableMountNameForInternalSync,
60 fileapi::kFileSystemTypeSyncableForInternalSync,
61 fileapi::FileSystemMountOption(),
65 void RevokeSyncableFileSystem() {
66 ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
68 ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
69 kSyncableMountNameForInternalSync);
72 GURL GetSyncableFileSystemRootURI(const GURL& origin) {
73 return GURL(fileapi::GetExternalFileSystemRootURIString(
74 origin, kSyncableMountName));
77 FileSystemURL CreateSyncableFileSystemURL(const GURL& origin,
78 const base::FilePath& path) {
79 base::FilePath path_for_url = path;
80 if (fileapi::VirtualPath::IsAbsolute(path.value()))
81 path_for_url = base::FilePath(path.value().substr(1));
83 return ExternalMountPoints::GetSystemInstance()->CreateExternalFileSystemURL(
84 origin, kSyncableMountName, path_for_url);
87 FileSystemURL CreateSyncableFileSystemURLForSync(
88 fileapi::FileSystemContext* file_system_context,
89 const FileSystemURL& syncable_url) {
90 return ExternalMountPoints::GetSystemInstance()->CreateExternalFileSystemURL(
91 syncable_url.origin(),
92 kSyncableMountNameForInternalSync,
96 bool SerializeSyncableFileSystemURL(const FileSystemURL& url,
97 std::string* serialized_url) {
98 if (!url.is_valid() || url.type() != fileapi::kFileSystemTypeSyncable)
101 GetSyncableFileSystemRootURI(url.origin()).spec() +
102 url.path().AsUTF8Unsafe();
106 bool DeserializeSyncableFileSystemURL(
107 const std::string& serialized_url, FileSystemURL* url) {
108 #if !defined(FILE_PATH_USES_WIN_SEPARATORS)
109 DCHECK(serialized_url.find('\\') == std::string::npos);
110 #endif // FILE_PATH_USES_WIN_SEPARATORS
112 FileSystemURL deserialized =
113 ExternalMountPoints::GetSystemInstance()->CrackURL(GURL(serialized_url));
114 if (!deserialized.is_valid() ||
115 deserialized.type() != fileapi::kFileSystemTypeSyncable) {
123 void SetEnableSyncFSDirectoryOperation(bool flag) {
124 g_is_directory_operation_enabled = flag;
127 bool IsSyncFSDirectoryOperationEnabled() {
128 return IsSyncFSDirectoryOperationEnabled(GURL());
131 bool IsSyncFSDirectoryOperationEnabled(const GURL& origin) {
132 return g_is_directory_operation_enabled ||
133 CommandLine::ForCurrentProcess()->HasSwitch(
134 kEnableSyncFSDirectoryOperation) ||
135 IsV2EnabledForOrigin(origin);
139 return g_is_syncfs_v2_enabled ||
140 CommandLine::ForCurrentProcess()->HasSwitch(kEnableSyncFileSystemV2);
143 bool IsV2EnabledForOrigin(const GURL& origin) {
147 // Spark release channel.
148 if (origin.host() == "kcjgcakhgelcejampmijgkjkadfcncjl")
150 // Spark dev channel.
151 if (origin.host() == "pnoffddplpippgcfjdhbmhkofpnaalpg")
154 CommandLine command_line = *CommandLine::ForCurrentProcess();
155 if (command_line.HasSwitch(kSyncFileSystemV2Whitelist)) {
156 std::string app_ids_string =
157 command_line.GetSwitchValueASCII(kSyncFileSystemV2Whitelist);
158 if (app_ids_string.find(origin.host()) == std::string::npos)
160 std::vector<std::string> app_ids;
161 Tokenize(app_ids_string, ",", &app_ids);
162 for (size_t i = 0; i < app_ids.size(); ++i) {
163 if (origin.host() == app_ids[i])
171 base::FilePath GetSyncFileSystemDir(const base::FilePath& profile_base_dir) {
173 return profile_base_dir.Append(kSyncFileSystemDir);
174 if (IsSyncFSDirectoryOperationEnabled())
175 return profile_base_dir.Append(kSyncFileSystemDirDev);
176 return profile_base_dir.Append(kSyncFileSystemDir);
179 ScopedEnableSyncFSDirectoryOperation::ScopedEnableSyncFSDirectoryOperation() {
180 was_enabled_ = IsSyncFSDirectoryOperationEnabled(GURL());
181 SetEnableSyncFSDirectoryOperation(true);
184 ScopedEnableSyncFSDirectoryOperation::~ScopedEnableSyncFSDirectoryOperation() {
185 DCHECK(IsSyncFSDirectoryOperationEnabled(GURL()));
186 SetEnableSyncFSDirectoryOperation(was_enabled_);
189 ScopedEnableSyncFSV2::ScopedEnableSyncFSV2() {
190 was_enabled_ = IsV2Enabled();
191 g_is_syncfs_v2_enabled = true;
194 ScopedEnableSyncFSV2::~ScopedEnableSyncFSV2() {
195 DCHECK(IsV2Enabled());
196 g_is_syncfs_v2_enabled = was_enabled_;
199 void RunSoon(const tracked_objects::Location& from_here,
200 const base::Closure& callback) {
201 base::MessageLoop::current()->PostTask(from_here, callback);
204 } // namespace sync_file_system