Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync_file_system / syncable_file_system_util.cc
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
17 using fileapi::ExternalMountPoints;
18 using fileapi::FileSystemContext;
19 using fileapi::FileSystemURL;
20
21 namespace sync_file_system {
22
23 namespace {
24
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";
30
31 // A command switch to enable V2 Sync FileSystem.
32 const char kEnableSyncFileSystemV2[] = "enable-syncfs-v2";
33
34 // A command switch to specify comma-separated app IDs to enable V2 Sync
35 // FileSystem.
36 const char kSyncFileSystemV2Whitelist[] = "syncfs-v2-whitelist";
37
38 const char kSyncableMountName[] = "syncfs";
39 const char kSyncableMountNameForInternalSync[] = "syncfs-internal";
40
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");
45
46 // Flags to enable features for testing.
47 bool g_is_directory_operation_enabled = false;
48 bool g_is_syncfs_v2_enabled = false;
49
50 }  // namespace
51
52 void RegisterSyncableFileSystem() {
53   ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
54       kSyncableMountName,
55       fileapi::kFileSystemTypeSyncable,
56       fileapi::FileSystemMountOption(),
57       base::FilePath());
58   ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
59       kSyncableMountNameForInternalSync,
60       fileapi::kFileSystemTypeSyncableForInternalSync,
61       fileapi::FileSystemMountOption(),
62       base::FilePath());
63 }
64
65 void RevokeSyncableFileSystem() {
66   ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
67       kSyncableMountName);
68   ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
69       kSyncableMountNameForInternalSync);
70 }
71
72 GURL GetSyncableFileSystemRootURI(const GURL& origin) {
73   return GURL(fileapi::GetExternalFileSystemRootURIString(
74       origin, kSyncableMountName));
75 }
76
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));
82
83   return ExternalMountPoints::GetSystemInstance()->CreateExternalFileSystemURL(
84       origin, kSyncableMountName, path_for_url);
85 }
86
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,
93       syncable_url.path());
94 }
95
96 bool SerializeSyncableFileSystemURL(const FileSystemURL& url,
97                                     std::string* serialized_url) {
98   if (!url.is_valid() || url.type() != fileapi::kFileSystemTypeSyncable)
99     return false;
100   *serialized_url =
101       GetSyncableFileSystemRootURI(url.origin()).spec() +
102       url.path().AsUTF8Unsafe();
103   return true;
104 }
105
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
111
112   FileSystemURL deserialized =
113       ExternalMountPoints::GetSystemInstance()->CrackURL(GURL(serialized_url));
114   if (!deserialized.is_valid() ||
115       deserialized.type() != fileapi::kFileSystemTypeSyncable) {
116     return false;
117   }
118
119   *url = deserialized;
120   return true;
121 }
122
123 void SetEnableSyncFSDirectoryOperation(bool flag) {
124   g_is_directory_operation_enabled = flag;
125 }
126
127 bool IsSyncFSDirectoryOperationEnabled() {
128   return IsSyncFSDirectoryOperationEnabled(GURL());
129 }
130
131 bool IsSyncFSDirectoryOperationEnabled(const GURL& origin) {
132   return g_is_directory_operation_enabled ||
133       CommandLine::ForCurrentProcess()->HasSwitch(
134           kEnableSyncFSDirectoryOperation) ||
135       IsV2EnabledForOrigin(origin);
136 }
137
138 bool IsV2Enabled() {
139   return g_is_syncfs_v2_enabled ||
140         CommandLine::ForCurrentProcess()->HasSwitch(kEnableSyncFileSystemV2);
141 }
142
143 bool IsV2EnabledForOrigin(const GURL& origin) {
144   if (IsV2Enabled())
145     return true;
146
147   // Spark release channel.
148   if (origin.host() == "kcjgcakhgelcejampmijgkjkadfcncjl")
149     return true;
150   // Spark dev channel.
151   if (origin.host() == "pnoffddplpippgcfjdhbmhkofpnaalpg")
152     return true;
153
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)
159       return false;
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])
164         return true;
165     }
166   }
167
168   return false;
169 }
170
171 base::FilePath GetSyncFileSystemDir(const base::FilePath& profile_base_dir) {
172   if (IsV2Enabled())
173     return profile_base_dir.Append(kSyncFileSystemDir);
174   if (IsSyncFSDirectoryOperationEnabled())
175     return profile_base_dir.Append(kSyncFileSystemDirDev);
176   return profile_base_dir.Append(kSyncFileSystemDir);
177 }
178
179 ScopedEnableSyncFSDirectoryOperation::ScopedEnableSyncFSDirectoryOperation() {
180   was_enabled_ = IsSyncFSDirectoryOperationEnabled(GURL());
181   SetEnableSyncFSDirectoryOperation(true);
182 }
183
184 ScopedEnableSyncFSDirectoryOperation::~ScopedEnableSyncFSDirectoryOperation() {
185   DCHECK(IsSyncFSDirectoryOperationEnabled(GURL()));
186   SetEnableSyncFSDirectoryOperation(was_enabled_);
187 }
188
189 ScopedEnableSyncFSV2::ScopedEnableSyncFSV2() {
190   was_enabled_ = IsV2Enabled();
191   g_is_syncfs_v2_enabled = true;
192 }
193
194 ScopedEnableSyncFSV2::~ScopedEnableSyncFSV2() {
195   DCHECK(IsV2Enabled());
196   g_is_syncfs_v2_enabled = was_enabled_;
197 }
198
199 void RunSoon(const tracked_objects::Location& from_here,
200              const base::Closure& callback) {
201   base::MessageLoop::current()->PostTask(from_here, callback);
202 }
203
204 }  // namespace sync_file_system