OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" | 5 #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "chrome/browser/chrome_notification_types.h" | |
8 #include "chrome/browser/sync_file_system/local/local_file_change_tracker.h" | 9 #include "chrome/browser/sync_file_system/local/local_file_change_tracker.h" |
9 #include "chrome/browser/sync_file_system/local/local_file_sync_context.h" | 10 #include "chrome/browser/sync_file_system/local/local_file_sync_context.h" |
10 #include "chrome/browser/sync_file_system/local/syncable_file_system_operation.h " | 11 #include "chrome/browser/sync_file_system/local/syncable_file_system_operation.h " |
12 #include "chrome/browser/sync_file_system/sync_file_system_service.h" | |
13 #include "chrome/browser/sync_file_system/sync_file_system_service_factory.h" | |
11 #include "chrome/browser/sync_file_system/syncable_file_system_util.h" | 14 #include "chrome/browser/sync_file_system/syncable_file_system_util.h" |
15 #include "content/public/browser/browser_thread.h" | |
16 #include "content/public/browser/notification_service.h" | |
12 #include "webkit/browser/fileapi/file_system_context.h" | 17 #include "webkit/browser/fileapi/file_system_context.h" |
13 #include "webkit/browser/fileapi/file_system_file_stream_reader.h" | 18 #include "webkit/browser/fileapi/file_system_file_stream_reader.h" |
14 #include "webkit/browser/fileapi/file_system_operation_impl.h" | 19 #include "webkit/browser/fileapi/file_system_operation_impl.h" |
15 #include "webkit/browser/fileapi/sandbox_file_stream_writer.h" | 20 #include "webkit/browser/fileapi/sandbox_file_stream_writer.h" |
16 #include "webkit/browser/fileapi/sandbox_quota_observer.h" | 21 #include "webkit/browser/fileapi/sandbox_quota_observer.h" |
17 #include "webkit/common/fileapi/file_system_util.h" | 22 #include "webkit/common/fileapi/file_system_util.h" |
18 | 23 |
24 using content::BrowserThread; | |
25 | |
19 namespace sync_file_system { | 26 namespace sync_file_system { |
20 | 27 |
21 SyncFileSystemBackend::SyncFileSystemBackend() | 28 namespace { |
22 : delegate_(NULL) { | 29 |
30 bool CalledOnUIThread() { | |
31 // Ensure that these methods are called on the UI thread, except for unittests | |
32 // where a UI thread might not have been created. | |
33 return BrowserThread::CurrentlyOn(BrowserThread::UI) || | |
34 !BrowserThread::IsMessageLoopValid(BrowserThread::UI); | |
35 } | |
36 | |
37 } // namespace | |
38 | |
39 SyncFileSystemBackend::ProfileHolder::ProfileHolder(Profile* profile) | |
40 : profile_(profile) { | |
41 DCHECK(CalledOnUIThread()); | |
42 registrar_.Add(this, | |
43 chrome::NOTIFICATION_PROFILE_DESTROYED, | |
44 content::NotificationService::AllSources()); | |
kinuko
2013/08/28 11:24:45
content::Source<Profile>(profile_) ?
nhiroki
2013/08/29 04:31:34
Done.
| |
45 } | |
46 | |
47 void SyncFileSystemBackend::ProfileHolder::Observe( | |
48 int type, | |
49 const content::NotificationSource& source, | |
50 const content::NotificationDetails& details) { | |
51 DCHECK(CalledOnUIThread()); | |
52 switch (type) { | |
53 case chrome::NOTIFICATION_PROFILE_DESTROYED: { | |
kinuko
2013/08/28 11:24:45
nit: maybe DCHECK_EQ(chrome::NOTIFICATION_PROFILE_
nhiroki
2013/08/29 04:31:34
Replaced with DCHECK_EQ(...).
Sorry, I couldn't g
kinuko
2013/08/29 08:28:21
d'oh, I think I wanted to say no switch/case.
| |
54 Profile* profile = content::Source<Profile>(source).ptr(); | |
kinuko
2013/08/28 11:24:45
nit: probably you don't need store it to a temp va
nhiroki
2013/08/29 04:31:34
Done.
| |
55 if (profile_ == profile) | |
56 profile_ = NULL; | |
kinuko
2013/08/28 11:24:45
I think here this can remove itself from the regis
nhiroki
2013/08/29 04:31:34
Done.
| |
57 break; | |
58 } | |
59 } | |
60 } | |
61 | |
62 Profile* SyncFileSystemBackend::ProfileHolder::GetProfile() { | |
63 DCHECK(CalledOnUIThread()); | |
64 return profile_; | |
65 } | |
66 | |
67 SyncFileSystemBackend::SyncFileSystemBackend(Profile* profile) | |
68 : context_(NULL), | |
69 skip_initialize_syncfs_service_for_testing_(false) { | |
70 DCHECK(CalledOnUIThread()); | |
71 if (profile) | |
72 profile_holder_.reset(new ProfileHolder(profile)); | |
23 } | 73 } |
24 | 74 |
25 SyncFileSystemBackend::~SyncFileSystemBackend() { | 75 SyncFileSystemBackend::~SyncFileSystemBackend() { |
26 if (change_tracker_) { | 76 if (change_tracker_) { |
27 delegate_->file_task_runner()->DeleteSoon( | 77 GetDelegate()->file_task_runner()->DeleteSoon( |
28 FROM_HERE, change_tracker_.release()); | 78 FROM_HERE, change_tracker_.release()); |
29 } | 79 } |
80 | |
81 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
kinuko
2013/08/28 11:24:45
Also check profile_holder_ is not null?
nhiroki
2013/08/29 04:31:34
Done.
| |
82 BrowserThread::DeleteSoon( | |
83 BrowserThread::UI, FROM_HERE, profile_holder_.release()); | |
84 } | |
30 } | 85 } |
31 | 86 |
87 // static | |
88 SyncFileSystemBackend* SyncFileSystemBackend::CreateForTesting() { | |
89 DCHECK(CalledOnUIThread()); | |
90 SyncFileSystemBackend* backend = new SyncFileSystemBackend(NULL); | |
91 backend->skip_initialize_syncfs_service_for_testing_ = true; | |
92 return backend; | |
93 } | |
94 | |
32 bool SyncFileSystemBackend::CanHandleType( | 95 bool SyncFileSystemBackend::CanHandleType( |
33 fileapi::FileSystemType type) const { | 96 fileapi::FileSystemType type) const { |
34 return type == fileapi::kFileSystemTypeSyncable || | 97 return type == fileapi::kFileSystemTypeSyncable || |
35 type == fileapi::kFileSystemTypeSyncableForInternalSync; | 98 type == fileapi::kFileSystemTypeSyncableForInternalSync; |
36 } | 99 } |
37 | 100 |
38 void SyncFileSystemBackend::Initialize(fileapi::FileSystemContext* context) { | 101 void SyncFileSystemBackend::Initialize(fileapi::FileSystemContext* context) { |
39 DCHECK(context); | 102 DCHECK(context); |
40 DCHECK(!delegate_); | 103 DCHECK(!context_); |
41 delegate_ = context->sandbox_delegate(); | 104 context_ = context; |
42 | 105 |
43 delegate_->AddFileUpdateObserver( | 106 fileapi::SandboxFileSystemBackendDelegate* delegate = GetDelegate(); |
107 delegate->AddFileUpdateObserver( | |
44 fileapi::kFileSystemTypeSyncable, | 108 fileapi::kFileSystemTypeSyncable, |
45 delegate_->quota_observer(), | 109 delegate->quota_observer(), |
46 delegate_->file_task_runner()); | 110 delegate->file_task_runner()); |
47 delegate_->AddFileUpdateObserver( | 111 delegate->AddFileUpdateObserver( |
48 fileapi::kFileSystemTypeSyncableForInternalSync, | 112 fileapi::kFileSystemTypeSyncableForInternalSync, |
49 delegate_->quota_observer(), | 113 delegate->quota_observer(), |
50 delegate_->file_task_runner()); | 114 delegate->file_task_runner()); |
51 } | 115 } |
52 | 116 |
53 void SyncFileSystemBackend::OpenFileSystem( | 117 void SyncFileSystemBackend::OpenFileSystem( |
54 const GURL& origin_url, | 118 const GURL& origin_url, |
55 fileapi::FileSystemType type, | 119 fileapi::FileSystemType type, |
56 fileapi::OpenFileSystemMode mode, | 120 fileapi::OpenFileSystemMode mode, |
57 const OpenFileSystemCallback& callback) { | 121 const OpenFileSystemCallback& callback) { |
58 DCHECK(CanHandleType(type)); | 122 DCHECK(CanHandleType(type)); |
59 DCHECK(delegate_); | 123 |
60 delegate_->OpenFileSystem(origin_url, type, mode, callback, | 124 if (skip_initialize_syncfs_service_for_testing_) { |
61 GetSyncableFileSystemRootURI(origin_url)); | 125 GetDelegate()->OpenFileSystem(origin_url, type, mode, callback, |
126 GetSyncableFileSystemRootURI(origin_url)); | |
127 return; | |
128 } | |
129 | |
130 SyncStatusCallback initialize_callback = | |
131 base::Bind(&SyncFileSystemBackend::DidInitializeSyncFileSystemService, | |
132 base::Unretained(this), origin_url, type, mode, callback); | |
kinuko
2013/08/28 11:24:45
Why we use Unretained here (and else)?
nhiroki
2013/08/29 04:31:34
Hmm... yes, we have to manage lifetime of SyncFile
| |
133 InitializeSyncFileSystemService(origin_url, initialize_callback); | |
62 } | 134 } |
63 | 135 |
64 fileapi::FileSystemFileUtil* SyncFileSystemBackend::GetFileUtil( | 136 fileapi::FileSystemFileUtil* SyncFileSystemBackend::GetFileUtil( |
65 fileapi::FileSystemType type) { | 137 fileapi::FileSystemType type) { |
66 DCHECK(delegate_); | 138 return GetDelegate()->sync_file_util(); |
67 return delegate_->sync_file_util(); | |
68 } | 139 } |
69 | 140 |
70 fileapi::AsyncFileUtil* SyncFileSystemBackend::GetAsyncFileUtil( | 141 fileapi::AsyncFileUtil* SyncFileSystemBackend::GetAsyncFileUtil( |
71 fileapi::FileSystemType type) { | 142 fileapi::FileSystemType type) { |
72 DCHECK(delegate_); | 143 return GetDelegate()->file_util(); |
73 return delegate_->file_util(); | |
74 } | 144 } |
75 | 145 |
76 fileapi::CopyOrMoveFileValidatorFactory* | 146 fileapi::CopyOrMoveFileValidatorFactory* |
77 SyncFileSystemBackend::GetCopyOrMoveFileValidatorFactory( | 147 SyncFileSystemBackend::GetCopyOrMoveFileValidatorFactory( |
78 fileapi::FileSystemType type, | 148 fileapi::FileSystemType type, |
79 base::PlatformFileError* error_code) { | 149 base::PlatformFileError* error_code) { |
80 DCHECK(error_code); | 150 DCHECK(error_code); |
81 *error_code = base::PLATFORM_FILE_OK; | 151 *error_code = base::PLATFORM_FILE_OK; |
82 return NULL; | 152 return NULL; |
83 } | 153 } |
84 | 154 |
85 fileapi::FileSystemOperation* | 155 fileapi::FileSystemOperation* |
86 SyncFileSystemBackend::CreateFileSystemOperation( | 156 SyncFileSystemBackend::CreateFileSystemOperation( |
87 const fileapi::FileSystemURL& url, | 157 const fileapi::FileSystemURL& url, |
88 fileapi::FileSystemContext* context, | 158 fileapi::FileSystemContext* context, |
89 base::PlatformFileError* error_code) const { | 159 base::PlatformFileError* error_code) const { |
90 DCHECK(CanHandleType(url.type())); | 160 DCHECK(CanHandleType(url.type())); |
91 DCHECK(context); | 161 DCHECK(context); |
92 DCHECK(error_code); | 162 DCHECK(error_code); |
93 | 163 |
94 DCHECK(delegate_); | |
95 scoped_ptr<fileapi::FileSystemOperationContext> operation_context = | 164 scoped_ptr<fileapi::FileSystemOperationContext> operation_context = |
96 delegate_->CreateFileSystemOperationContext(url, context, error_code); | 165 GetDelegate()->CreateFileSystemOperationContext(url, context, error_code); |
97 if (!operation_context) | 166 if (!operation_context) |
98 return NULL; | 167 return NULL; |
99 | 168 |
100 if (url.type() == fileapi::kFileSystemTypeSyncableForInternalSync) { | 169 if (url.type() == fileapi::kFileSystemTypeSyncableForInternalSync) { |
101 return new fileapi::FileSystemOperationImpl( | 170 return new fileapi::FileSystemOperationImpl( |
102 url, context, operation_context.Pass()); | 171 url, context, operation_context.Pass()); |
103 } | 172 } |
104 | 173 |
105 return new SyncableFileSystemOperation( | 174 return new SyncableFileSystemOperation( |
106 url, context, operation_context.Pass()); | 175 url, context, operation_context.Pass()); |
107 } | 176 } |
108 | 177 |
109 scoped_ptr<webkit_blob::FileStreamReader> | 178 scoped_ptr<webkit_blob::FileStreamReader> |
110 SyncFileSystemBackend::CreateFileStreamReader( | 179 SyncFileSystemBackend::CreateFileStreamReader( |
111 const fileapi::FileSystemURL& url, | 180 const fileapi::FileSystemURL& url, |
112 int64 offset, | 181 int64 offset, |
113 const base::Time& expected_modification_time, | 182 const base::Time& expected_modification_time, |
114 fileapi::FileSystemContext* context) const { | 183 fileapi::FileSystemContext* context) const { |
115 DCHECK(CanHandleType(url.type())); | 184 DCHECK(CanHandleType(url.type())); |
116 DCHECK(delegate_); | 185 return GetDelegate()->CreateFileStreamReader( |
117 return delegate_->CreateFileStreamReader( | |
118 url, offset, expected_modification_time, context); | 186 url, offset, expected_modification_time, context); |
119 } | 187 } |
120 | 188 |
121 scoped_ptr<fileapi::FileStreamWriter> | 189 scoped_ptr<fileapi::FileStreamWriter> |
122 SyncFileSystemBackend::CreateFileStreamWriter( | 190 SyncFileSystemBackend::CreateFileStreamWriter( |
123 const fileapi::FileSystemURL& url, | 191 const fileapi::FileSystemURL& url, |
124 int64 offset, | 192 int64 offset, |
125 fileapi::FileSystemContext* context) const { | 193 fileapi::FileSystemContext* context) const { |
126 DCHECK(CanHandleType(url.type())); | 194 DCHECK(CanHandleType(url.type())); |
127 DCHECK(delegate_); | 195 return GetDelegate()->CreateFileStreamWriter( |
128 return delegate_->CreateFileStreamWriter( | |
129 url, offset, context, fileapi::kFileSystemTypeSyncableForInternalSync); | 196 url, offset, context, fileapi::kFileSystemTypeSyncableForInternalSync); |
130 } | 197 } |
131 | 198 |
132 fileapi::FileSystemQuotaUtil* SyncFileSystemBackend::GetQuotaUtil() { | 199 fileapi::FileSystemQuotaUtil* SyncFileSystemBackend::GetQuotaUtil() { |
133 return delegate_; | 200 return GetDelegate(); |
134 } | 201 } |
135 | 202 |
136 // static | 203 // static |
137 SyncFileSystemBackend* SyncFileSystemBackend::GetBackend( | 204 SyncFileSystemBackend* SyncFileSystemBackend::GetBackend( |
138 const fileapi::FileSystemContext* file_system_context) { | 205 const fileapi::FileSystemContext* file_system_context) { |
139 DCHECK(file_system_context); | 206 DCHECK(file_system_context); |
140 return static_cast<SyncFileSystemBackend*>( | 207 return static_cast<SyncFileSystemBackend*>( |
141 file_system_context->GetFileSystemBackend( | 208 file_system_context->GetFileSystemBackend( |
142 fileapi::kFileSystemTypeSyncable)); | 209 fileapi::kFileSystemTypeSyncable)); |
143 } | 210 } |
144 | 211 |
145 void SyncFileSystemBackend::SetLocalFileChangeTracker( | 212 void SyncFileSystemBackend::SetLocalFileChangeTracker( |
146 scoped_ptr<LocalFileChangeTracker> tracker) { | 213 scoped_ptr<LocalFileChangeTracker> tracker) { |
147 DCHECK(!change_tracker_); | 214 DCHECK(!change_tracker_); |
148 DCHECK(tracker); | 215 DCHECK(tracker); |
149 change_tracker_ = tracker.Pass(); | 216 change_tracker_ = tracker.Pass(); |
150 | 217 |
151 DCHECK(delegate_); | 218 fileapi::SandboxFileSystemBackendDelegate* delegate = GetDelegate(); |
152 delegate_->AddFileUpdateObserver( | 219 delegate->AddFileUpdateObserver( |
153 fileapi::kFileSystemTypeSyncable, | 220 fileapi::kFileSystemTypeSyncable, |
154 change_tracker_.get(), | 221 change_tracker_.get(), |
155 delegate_->file_task_runner()); | 222 delegate->file_task_runner()); |
156 delegate_->AddFileChangeObserver( | 223 delegate->AddFileChangeObserver( |
157 fileapi::kFileSystemTypeSyncable, | 224 fileapi::kFileSystemTypeSyncable, |
158 change_tracker_.get(), | 225 change_tracker_.get(), |
159 delegate_->file_task_runner()); | 226 delegate->file_task_runner()); |
160 } | 227 } |
161 | 228 |
162 void SyncFileSystemBackend::set_sync_context( | 229 void SyncFileSystemBackend::set_sync_context( |
163 LocalFileSyncContext* sync_context) { | 230 LocalFileSyncContext* sync_context) { |
164 DCHECK(!sync_context_); | 231 DCHECK(!sync_context_); |
165 sync_context_ = sync_context; | 232 sync_context_ = sync_context; |
166 } | 233 } |
167 | 234 |
235 fileapi::SandboxFileSystemBackendDelegate* | |
236 SyncFileSystemBackend::GetDelegate() const { | |
237 DCHECK(context_); | |
238 DCHECK(context_->sandbox_delegate()); | |
239 return context_->sandbox_delegate(); | |
240 } | |
241 | |
242 void SyncFileSystemBackend::InitializeSyncFileSystemService( | |
243 const GURL& origin_url, | |
244 const SyncStatusCallback& callback) { | |
245 // Repost to switch from IO thread to UI thread. | |
246 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | |
247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
248 BrowserThread::PostTask( | |
249 BrowserThread::UI, FROM_HERE, | |
250 base::Bind(&SyncFileSystemBackend::InitializeSyncFileSystemService, | |
251 base::Unretained(this), origin_url, callback)); | |
252 return; | |
253 } | |
254 | |
255 if (!profile_holder_->GetProfile()) { | |
256 // Profile was destroyed. | |
257 callback.Run(SYNC_FILE_ERROR_FAILED); | |
258 return; | |
259 } | |
260 | |
261 SyncFileSystemService* service = SyncFileSystemServiceFactory::GetForProfile( | |
262 profile_holder_->GetProfile()); | |
263 DCHECK(service); | |
264 service->InitializeForApp(context_, origin_url, callback); | |
265 } | |
266 | |
267 void SyncFileSystemBackend::DidInitializeSyncFileSystemService( | |
268 const GURL& origin_url, | |
269 fileapi::FileSystemType type, | |
270 fileapi::OpenFileSystemMode mode, | |
271 const OpenFileSystemCallback& callback, | |
272 SyncStatusCode status) { | |
273 // Repost to switch from UI thread to IO thread. | |
274 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | |
275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
276 BrowserThread::PostTask( | |
277 BrowserThread::IO, FROM_HERE, | |
278 base::Bind(&SyncFileSystemBackend::DidInitializeSyncFileSystemService, | |
279 base::Unretained(this), | |
280 origin_url, type, mode, callback, status)); | |
281 return; | |
282 } | |
283 | |
284 if (status != sync_file_system::SYNC_STATUS_OK) { | |
285 callback.Run(GURL(), std::string(), | |
286 SyncStatusCodeToPlatformFileError(status)); | |
287 return; | |
288 } | |
289 | |
290 GetDelegate()->OpenFileSystem(origin_url, type, mode, callback, | |
291 GetSyncableFileSystemRootURI(origin_url)); | |
292 } | |
293 | |
168 } // namespace sync_file_system | 294 } // namespace sync_file_system |
OLD | NEW |