Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(289)

Side by Side Diff: chrome/browser/sync_file_system/local/sync_file_system_backend.cc

Issue 22810002: SyncFS: Reorder initialization sequence of SyncFileSystemService (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix lifetime management of the backend Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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::Source<Profile>(profile_));
45 }
46
47 void SyncFileSystemBackend::ProfileHolder::Observe(
48 int type,
49 const content::NotificationSource& source,
50 const content::NotificationDetails& details) {
51 DCHECK(CalledOnUIThread());
52 DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED, type);
53 DCHECK_EQ(profile_, content::Source<Profile>(source).ptr());
54 profile_ = NULL;
55 registrar_.RemoveAll();
56 }
57
58 Profile* SyncFileSystemBackend::ProfileHolder::GetProfile() {
59 DCHECK(CalledOnUIThread());
60 return profile_;
61 }
62
63 SyncFileSystemBackend::SyncFileSystemBackend(Profile* profile)
64 : context_(NULL),
65 skip_initialize_syncfs_service_for_testing_(false) {
66 DCHECK(CalledOnUIThread());
67 if (profile)
68 profile_holder_.reset(new ProfileHolder(profile));
23 } 69 }
24 70
25 SyncFileSystemBackend::~SyncFileSystemBackend() { 71 SyncFileSystemBackend::~SyncFileSystemBackend() {
26 if (change_tracker_) { 72 if (change_tracker_) {
27 delegate_->file_task_runner()->DeleteSoon( 73 GetDelegate()->file_task_runner()->DeleteSoon(
28 FROM_HERE, change_tracker_.release()); 74 FROM_HERE, change_tracker_.release());
29 } 75 }
76
77 if (profile_holder_ && !BrowserThread::CurrentlyOn(BrowserThread::UI)) {
kinuko 2013/08/29 08:28:21 CurrentlyOn -> CalledOnUIThread ? (We may leak in
nhiroki 2013/08/29 08:43:35 Done.
78 BrowserThread::DeleteSoon(
79 BrowserThread::UI, FROM_HERE, profile_holder_.release());
80 }
30 } 81 }
31 82
83 // static
84 SyncFileSystemBackend* SyncFileSystemBackend::CreateForTesting() {
85 DCHECK(CalledOnUIThread());
86 SyncFileSystemBackend* backend = new SyncFileSystemBackend(NULL);
87 backend->skip_initialize_syncfs_service_for_testing_ = true;
88 return backend;
89 }
90
32 bool SyncFileSystemBackend::CanHandleType( 91 bool SyncFileSystemBackend::CanHandleType(
33 fileapi::FileSystemType type) const { 92 fileapi::FileSystemType type) const {
34 return type == fileapi::kFileSystemTypeSyncable || 93 return type == fileapi::kFileSystemTypeSyncable ||
35 type == fileapi::kFileSystemTypeSyncableForInternalSync; 94 type == fileapi::kFileSystemTypeSyncableForInternalSync;
36 } 95 }
37 96
38 void SyncFileSystemBackend::Initialize(fileapi::FileSystemContext* context) { 97 void SyncFileSystemBackend::Initialize(fileapi::FileSystemContext* context) {
39 DCHECK(context); 98 DCHECK(context);
40 DCHECK(!delegate_); 99 DCHECK(!context_);
41 delegate_ = context->sandbox_delegate(); 100 context_ = context;
42 101
43 delegate_->AddFileUpdateObserver( 102 fileapi::SandboxFileSystemBackendDelegate* delegate = GetDelegate();
103 delegate->AddFileUpdateObserver(
44 fileapi::kFileSystemTypeSyncable, 104 fileapi::kFileSystemTypeSyncable,
45 delegate_->quota_observer(), 105 delegate->quota_observer(),
46 delegate_->file_task_runner()); 106 delegate->file_task_runner());
47 delegate_->AddFileUpdateObserver( 107 delegate->AddFileUpdateObserver(
48 fileapi::kFileSystemTypeSyncableForInternalSync, 108 fileapi::kFileSystemTypeSyncableForInternalSync,
49 delegate_->quota_observer(), 109 delegate->quota_observer(),
50 delegate_->file_task_runner()); 110 delegate->file_task_runner());
51 } 111 }
52 112
53 void SyncFileSystemBackend::OpenFileSystem( 113 void SyncFileSystemBackend::OpenFileSystem(
54 const GURL& origin_url, 114 const GURL& origin_url,
55 fileapi::FileSystemType type, 115 fileapi::FileSystemType type,
56 fileapi::OpenFileSystemMode mode, 116 fileapi::OpenFileSystemMode mode,
57 const OpenFileSystemCallback& callback) { 117 const OpenFileSystemCallback& callback) {
58 DCHECK(CanHandleType(type)); 118 DCHECK(CanHandleType(type));
59 DCHECK(delegate_); 119
60 delegate_->OpenFileSystem(origin_url, type, mode, callback, 120 if (skip_initialize_syncfs_service_for_testing_) {
61 GetSyncableFileSystemRootURI(origin_url)); 121 GetDelegate()->OpenFileSystem(origin_url, type, mode, callback,
122 GetSyncableFileSystemRootURI(origin_url));
123 return;
124 }
125
126 // It is safe to pass Unretained(this) since |context_| owns it.
127 SyncStatusCallback initialize_callback =
128 base::Bind(&SyncFileSystemBackend::DidInitializeSyncFileSystemService,
129 base::Unretained(this), make_scoped_refptr(context_),
130 origin_url, type, mode, callback);
131 InitializeSyncFileSystemService(origin_url, initialize_callback);
62 } 132 }
63 133
64 fileapi::FileSystemFileUtil* SyncFileSystemBackend::GetFileUtil( 134 fileapi::FileSystemFileUtil* SyncFileSystemBackend::GetFileUtil(
65 fileapi::FileSystemType type) { 135 fileapi::FileSystemType type) {
66 DCHECK(delegate_); 136 return GetDelegate()->sync_file_util();
67 return delegate_->sync_file_util();
68 } 137 }
69 138
70 fileapi::AsyncFileUtil* SyncFileSystemBackend::GetAsyncFileUtil( 139 fileapi::AsyncFileUtil* SyncFileSystemBackend::GetAsyncFileUtil(
71 fileapi::FileSystemType type) { 140 fileapi::FileSystemType type) {
72 DCHECK(delegate_); 141 return GetDelegate()->file_util();
73 return delegate_->file_util();
74 } 142 }
75 143
76 fileapi::CopyOrMoveFileValidatorFactory* 144 fileapi::CopyOrMoveFileValidatorFactory*
77 SyncFileSystemBackend::GetCopyOrMoveFileValidatorFactory( 145 SyncFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
78 fileapi::FileSystemType type, 146 fileapi::FileSystemType type,
79 base::PlatformFileError* error_code) { 147 base::PlatformFileError* error_code) {
80 DCHECK(error_code); 148 DCHECK(error_code);
81 *error_code = base::PLATFORM_FILE_OK; 149 *error_code = base::PLATFORM_FILE_OK;
82 return NULL; 150 return NULL;
83 } 151 }
84 152
85 fileapi::FileSystemOperation* 153 fileapi::FileSystemOperation*
86 SyncFileSystemBackend::CreateFileSystemOperation( 154 SyncFileSystemBackend::CreateFileSystemOperation(
87 const fileapi::FileSystemURL& url, 155 const fileapi::FileSystemURL& url,
88 fileapi::FileSystemContext* context, 156 fileapi::FileSystemContext* context,
89 base::PlatformFileError* error_code) const { 157 base::PlatformFileError* error_code) const {
90 DCHECK(CanHandleType(url.type())); 158 DCHECK(CanHandleType(url.type()));
91 DCHECK(context); 159 DCHECK(context);
92 DCHECK(error_code); 160 DCHECK(error_code);
93 161
94 DCHECK(delegate_);
95 scoped_ptr<fileapi::FileSystemOperationContext> operation_context = 162 scoped_ptr<fileapi::FileSystemOperationContext> operation_context =
96 delegate_->CreateFileSystemOperationContext(url, context, error_code); 163 GetDelegate()->CreateFileSystemOperationContext(url, context, error_code);
97 if (!operation_context) 164 if (!operation_context)
98 return NULL; 165 return NULL;
99 166
100 if (url.type() == fileapi::kFileSystemTypeSyncableForInternalSync) { 167 if (url.type() == fileapi::kFileSystemTypeSyncableForInternalSync) {
101 return new fileapi::FileSystemOperationImpl( 168 return new fileapi::FileSystemOperationImpl(
102 url, context, operation_context.Pass()); 169 url, context, operation_context.Pass());
103 } 170 }
104 171
105 return new SyncableFileSystemOperation( 172 return new SyncableFileSystemOperation(
106 url, context, operation_context.Pass()); 173 url, context, operation_context.Pass());
107 } 174 }
108 175
109 scoped_ptr<webkit_blob::FileStreamReader> 176 scoped_ptr<webkit_blob::FileStreamReader>
110 SyncFileSystemBackend::CreateFileStreamReader( 177 SyncFileSystemBackend::CreateFileStreamReader(
111 const fileapi::FileSystemURL& url, 178 const fileapi::FileSystemURL& url,
112 int64 offset, 179 int64 offset,
113 const base::Time& expected_modification_time, 180 const base::Time& expected_modification_time,
114 fileapi::FileSystemContext* context) const { 181 fileapi::FileSystemContext* context) const {
115 DCHECK(CanHandleType(url.type())); 182 DCHECK(CanHandleType(url.type()));
116 DCHECK(delegate_); 183 return GetDelegate()->CreateFileStreamReader(
117 return delegate_->CreateFileStreamReader(
118 url, offset, expected_modification_time, context); 184 url, offset, expected_modification_time, context);
119 } 185 }
120 186
121 scoped_ptr<fileapi::FileStreamWriter> 187 scoped_ptr<fileapi::FileStreamWriter>
122 SyncFileSystemBackend::CreateFileStreamWriter( 188 SyncFileSystemBackend::CreateFileStreamWriter(
123 const fileapi::FileSystemURL& url, 189 const fileapi::FileSystemURL& url,
124 int64 offset, 190 int64 offset,
125 fileapi::FileSystemContext* context) const { 191 fileapi::FileSystemContext* context) const {
126 DCHECK(CanHandleType(url.type())); 192 DCHECK(CanHandleType(url.type()));
127 DCHECK(delegate_); 193 return GetDelegate()->CreateFileStreamWriter(
128 return delegate_->CreateFileStreamWriter(
129 url, offset, context, fileapi::kFileSystemTypeSyncableForInternalSync); 194 url, offset, context, fileapi::kFileSystemTypeSyncableForInternalSync);
130 } 195 }
131 196
132 fileapi::FileSystemQuotaUtil* SyncFileSystemBackend::GetQuotaUtil() { 197 fileapi::FileSystemQuotaUtil* SyncFileSystemBackend::GetQuotaUtil() {
133 return delegate_; 198 return GetDelegate();
134 } 199 }
135 200
136 // static 201 // static
137 SyncFileSystemBackend* SyncFileSystemBackend::GetBackend( 202 SyncFileSystemBackend* SyncFileSystemBackend::GetBackend(
138 const fileapi::FileSystemContext* file_system_context) { 203 const fileapi::FileSystemContext* file_system_context) {
139 DCHECK(file_system_context); 204 DCHECK(file_system_context);
140 return static_cast<SyncFileSystemBackend*>( 205 return static_cast<SyncFileSystemBackend*>(
141 file_system_context->GetFileSystemBackend( 206 file_system_context->GetFileSystemBackend(
142 fileapi::kFileSystemTypeSyncable)); 207 fileapi::kFileSystemTypeSyncable));
143 } 208 }
144 209
145 void SyncFileSystemBackend::SetLocalFileChangeTracker( 210 void SyncFileSystemBackend::SetLocalFileChangeTracker(
146 scoped_ptr<LocalFileChangeTracker> tracker) { 211 scoped_ptr<LocalFileChangeTracker> tracker) {
147 DCHECK(!change_tracker_); 212 DCHECK(!change_tracker_);
148 DCHECK(tracker); 213 DCHECK(tracker);
149 change_tracker_ = tracker.Pass(); 214 change_tracker_ = tracker.Pass();
150 215
151 DCHECK(delegate_); 216 fileapi::SandboxFileSystemBackendDelegate* delegate = GetDelegate();
152 delegate_->AddFileUpdateObserver( 217 delegate->AddFileUpdateObserver(
153 fileapi::kFileSystemTypeSyncable, 218 fileapi::kFileSystemTypeSyncable,
154 change_tracker_.get(), 219 change_tracker_.get(),
155 delegate_->file_task_runner()); 220 delegate->file_task_runner());
156 delegate_->AddFileChangeObserver( 221 delegate->AddFileChangeObserver(
157 fileapi::kFileSystemTypeSyncable, 222 fileapi::kFileSystemTypeSyncable,
158 change_tracker_.get(), 223 change_tracker_.get(),
159 delegate_->file_task_runner()); 224 delegate->file_task_runner());
160 } 225 }
161 226
162 void SyncFileSystemBackend::set_sync_context( 227 void SyncFileSystemBackend::set_sync_context(
163 LocalFileSyncContext* sync_context) { 228 LocalFileSyncContext* sync_context) {
164 DCHECK(!sync_context_); 229 DCHECK(!sync_context_);
165 sync_context_ = sync_context; 230 sync_context_ = sync_context;
166 } 231 }
167 232
233 fileapi::SandboxFileSystemBackendDelegate*
234 SyncFileSystemBackend::GetDelegate() const {
235 DCHECK(context_);
236 DCHECK(context_->sandbox_delegate());
237 return context_->sandbox_delegate();
238 }
239
240 void SyncFileSystemBackend::InitializeSyncFileSystemService(
241 const GURL& origin_url,
242 const SyncStatusCallback& callback) {
243 // Repost to switch from IO thread to UI thread.
244 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
246 // It is safe to pass Unretained(this) (see comments in OpenFileSystem()).
247 BrowserThread::PostTask(
248 BrowserThread::UI, FROM_HERE,
249 base::Bind(&SyncFileSystemBackend::InitializeSyncFileSystemService,
250 base::Unretained(this), origin_url, callback));
251 return;
252 }
253
254 if (!profile_holder_->GetProfile()) {
255 // Profile was destroyed.
256 callback.Run(SYNC_FILE_ERROR_FAILED);
257 return;
258 }
259
260 SyncFileSystemService* service = SyncFileSystemServiceFactory::GetForProfile(
261 profile_holder_->GetProfile());
262 DCHECK(service);
263 service->InitializeForApp(context_, origin_url, callback);
264 }
265
266 void SyncFileSystemBackend::DidInitializeSyncFileSystemService(
267 fileapi::FileSystemContext* context,
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 // It is safe to pass Unretained(this) since |context| owns it.
277 BrowserThread::PostTask(
278 BrowserThread::IO, FROM_HERE,
279 base::Bind(&SyncFileSystemBackend::DidInitializeSyncFileSystemService,
280 base::Unretained(this), make_scoped_refptr(context),
281 origin_url, type, mode, callback, status));
282 return;
283 }
284
285 if (status != sync_file_system::SYNC_STATUS_OK) {
286 callback.Run(GURL(), std::string(),
287 SyncStatusCodeToPlatformFileError(status));
288 return;
289 }
290
291 GetDelegate()->OpenFileSystem(origin_url, type, mode, callback,
292 GetSyncableFileSystemRootURI(origin_url));
293 }
294
168 } // namespace sync_file_system 295 } // namespace sync_file_system
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698