1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// found in the LICENSE file.
4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
52385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <string>
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/logging.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_sync_context.h"
132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/syncable_file_system_operation.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/sync_file_system/sync_file_system_service.h"
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/sync_file_system/sync_file_system_service_factory.h"
162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/public/browser/notification_service.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/file_stream_reader.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_stream_writer.h"
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation.h"
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h"
24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using content::BrowserThread;
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace sync_file_system {
28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace {
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool CalledOnUIThread() {
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Ensure that these methods are called on the UI thread, except for unittests
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // where a UI thread might not have been created.
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return BrowserThread::CurrentlyOn(BrowserThread::UI) ||
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         !BrowserThread::IsMessageLoopValid(BrowserThread::UI);
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)SyncFileSystemBackend::ProfileHolder::ProfileHolder(Profile* profile)
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : profile_(profile) {
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(CalledOnUIThread());
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  registrar_.Add(this,
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 chrome::NOTIFICATION_PROFILE_DESTROYED,
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 content::Source<Profile>(profile_));
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SyncFileSystemBackend::ProfileHolder::Observe(
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int type,
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const content::NotificationSource& source,
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const content::NotificationDetails& details) {
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(CalledOnUIThread());
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED, type);
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK_EQ(profile_, content::Source<Profile>(source).ptr());
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  profile_ = NULL;
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  registrar_.RemoveAll();
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)Profile* SyncFileSystemBackend::ProfileHolder::GetProfile() {
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(CalledOnUIThread());
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return profile_;
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)SyncFileSystemBackend::SyncFileSystemBackend(Profile* profile)
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : context_(NULL),
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      skip_initialize_syncfs_service_for_testing_(false) {
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(CalledOnUIThread());
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (profile)
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    profile_holder_.reset(new ProfileHolder(profile));
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Register the service name here to enable to crack an URL on SyncFileSystem
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // even if SyncFileSystemService has not started yet.
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RegisterSyncableFileSystem();
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)SyncFileSystemBackend::~SyncFileSystemBackend() {
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (change_tracker_) {
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    GetDelegate()->file_task_runner()->DeleteSoon(
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        FROM_HERE, change_tracker_.release());
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (profile_holder_ && !CalledOnUIThread()) {
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    BrowserThread::DeleteSoon(
8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        BrowserThread::UI, FROM_HERE, profile_holder_.release());
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)SyncFileSystemBackend* SyncFileSystemBackend::CreateForTesting() {
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(CalledOnUIThread());
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SyncFileSystemBackend* backend = new SyncFileSystemBackend(NULL);
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  backend->skip_initialize_syncfs_service_for_testing_ = true;
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return backend;
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool SyncFileSystemBackend::CanHandleType(storage::FileSystemType type) const {
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return type == storage::kFileSystemTypeSyncable ||
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)         type == storage::kFileSystemTypeSyncableForInternalSync;
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void SyncFileSystemBackend::Initialize(storage::FileSystemContext* context) {
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(context);
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(!context_);
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  context_ = context;
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::SandboxFileSystemBackendDelegate* delegate = GetDelegate();
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  delegate->RegisterQuotaUpdateObserver(storage::kFileSystemTypeSyncable);
1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  delegate->RegisterQuotaUpdateObserver(
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeSyncableForInternalSync);
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void SyncFileSystemBackend::ResolveURL(const storage::FileSystemURL& url,
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::OpenFileSystemMode mode,
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       const OpenFileSystemCallback& callback) {
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(CanHandleType(url.type()));
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (skip_initialize_syncfs_service_for_testing_) {
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    GetDelegate()->OpenFileSystem(url.origin(),
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  url.type(),
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  mode,
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  callback,
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  GetSyncableFileSystemRootURI(url.origin()));
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // It is safe to pass Unretained(this) since |context_| owns it.
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SyncStatusCallback initialize_callback =
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&SyncFileSystemBackend::DidInitializeSyncFileSystemService,
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this),
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 make_scoped_refptr(context_),
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 url.origin(),
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 url.type(),
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 mode,
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 callback);
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  InitializeSyncFileSystemService(url.origin(), initialize_callback);
136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::AsyncFileUtil* SyncFileSystemBackend::GetAsyncFileUtil(
13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemType type) {
14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return GetDelegate()->file_util();
141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistorage::WatcherManager* SyncFileSystemBackend::GetWatcherManager(
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    storage::FileSystemType type) {
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return NULL;
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::CopyOrMoveFileValidatorFactory*
149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)SyncFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemType type,
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error* error_code) {
152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(error_code);
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *error_code = base::File::FILE_OK;
154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return NULL;
155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::FileSystemOperation* SyncFileSystemBackend::CreateFileSystemOperation(
15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemContext* context,
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error* error_code) const {
161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(CanHandleType(url.type()));
162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(context);
163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(error_code);
164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<storage::FileSystemOperationContext> operation_context =
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetDelegate()->CreateFileSystemOperationContext(url, context, error_code);
1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!operation_context)
1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (url.type() == storage::kFileSystemTypeSyncableForInternalSync) {
17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return storage::FileSystemOperation::Create(
172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        url, context, operation_context.Pass());
173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return new SyncableFileSystemOperation(
176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      url, context, operation_context.Pass());
177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool SyncFileSystemBackend::SupportsStreaming(
18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url) const {
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return false;
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool SyncFileSystemBackend::HasInplaceCopyImplementation(
18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemType type) const {
18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return false;
18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_ptr<storage::FileStreamReader>
190a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)SyncFileSystemBackend::CreateFileStreamReader(
19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    int64 offset,
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int64 max_bytes_to_read,
194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const base::Time& expected_modification_time,
19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemContext* context) const {
196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(CanHandleType(url.type()));
19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return GetDelegate()->CreateFileStreamReader(
1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      url, offset, expected_modification_time, context);
199a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_ptr<storage::FileStreamWriter>
202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)SyncFileSystemBackend::CreateFileStreamWriter(
20303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    int64 offset,
20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemContext* context) const {
206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(CanHandleType(url.type()));
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return GetDelegate()->CreateFileStreamWriter(
20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      url, offset, context, storage::kFileSystemTypeSyncableForInternalSync);
209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
210a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::FileSystemQuotaUtil* SyncFileSystemBackend::GetQuotaUtil() {
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return GetDelegate();
213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
214a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst storage::UpdateObserverList* SyncFileSystemBackend::GetUpdateObservers(
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    storage::FileSystemType type) const {
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return GetDelegate()->GetUpdateObservers(type);
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst storage::ChangeObserverList* SyncFileSystemBackend::GetChangeObservers(
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    storage::FileSystemType type) const {
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return GetDelegate()->GetChangeObservers(type);
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst storage::AccessObserverList* SyncFileSystemBackend::GetAccessObservers(
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    storage::FileSystemType type) const {
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return GetDelegate()->GetAccessObservers(type);
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)SyncFileSystemBackend* SyncFileSystemBackend::GetBackend(
23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemContext* file_system_context) {
233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(file_system_context);
234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return static_cast<SyncFileSystemBackend*>(
235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      file_system_context->GetFileSystemBackend(
23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          storage::kFileSystemTypeSyncable));
237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void SyncFileSystemBackend::SetLocalFileChangeTracker(
240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    scoped_ptr<LocalFileChangeTracker> tracker) {
241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(!change_tracker_);
242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(tracker);
243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  change_tracker_ = tracker.Pass();
244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::SandboxFileSystemBackendDelegate* delegate = GetDelegate();
24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  delegate->AddFileUpdateObserver(storage::kFileSystemTypeSyncable,
24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                  change_tracker_.get(),
24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                  delegate->file_task_runner());
24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  delegate->AddFileChangeObserver(storage::kFileSystemTypeSyncable,
25003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                  change_tracker_.get(),
25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                  delegate->file_task_runner());
252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void SyncFileSystemBackend::set_sync_context(
255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    LocalFileSyncContext* sync_context) {
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!sync_context_.get());
257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  sync_context_ = sync_context;
258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::SandboxFileSystemBackendDelegate* SyncFileSystemBackend::GetDelegate()
26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const {
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(context_);
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(context_->sandbox_delegate());
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return context_->sandbox_delegate();
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SyncFileSystemBackend::InitializeSyncFileSystemService(
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& origin_url,
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const SyncStatusCallback& callback) {
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Repost to switch from IO thread to UI thread.
27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // It is safe to pass Unretained(this) (see comments in OpenFileSystem()).
27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    BrowserThread::PostTask(
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        BrowserThread::UI, FROM_HERE,
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::Bind(&SyncFileSystemBackend::InitializeSyncFileSystemService,
27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   base::Unretained(this), origin_url, callback));
27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!profile_holder_->GetProfile()) {
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Profile was destroyed.
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    callback.Run(SYNC_FILE_ERROR_FAILED);
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SyncFileSystemService* service = SyncFileSystemServiceFactory::GetForProfile(
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          profile_holder_->GetProfile());
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(service);
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  service->InitializeForApp(context_, origin_url, callback);
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SyncFileSystemBackend::DidInitializeSyncFileSystemService(
29403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemContext* context,
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& origin_url,
29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemType type,
29703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::OpenFileSystemMode mode,
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const OpenFileSystemCallback& callback,
29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    SyncStatusCode status) {
30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Repost to switch from UI thread to IO thread.
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // It is safe to pass Unretained(this) since |context| owns it.
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    BrowserThread::PostTask(
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        BrowserThread::IO, FROM_HERE,
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::Bind(&SyncFileSystemBackend::DidInitializeSyncFileSystemService,
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   base::Unretained(this), make_scoped_refptr(context),
30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   origin_url, type, mode, callback, status));
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (status != sync_file_system::SYNC_STATUS_OK) {
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    callback.Run(GURL(), std::string(),
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 SyncStatusCodeToFileError(status));
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback.Run(GetSyncableFileSystemRootURI(origin_url),
319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               GetFileSystemName(origin_url, type),
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               base::File::FILE_OK);
32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace sync_file_system
324