190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_CONTEXT_H_
62385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#define CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_CONTEXT_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/files/file.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_sync_status.h"
242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_callbacks.h"
252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_status_code.h"
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SingleThreadTaskRunner;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FileSystemContext;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FileSystemURL;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace leveldb {
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Env;
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class ScopedFile;
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sync_file_system {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FileChange;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LocalFileChangeTracker;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct LocalFileSyncInfo;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LocalOriginChangeObserver;
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class RootDeleteHelper;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncableFileOperationRunner;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class works as a bridge between LocalFileSyncService (which is a
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// per-profile object) and FileSystemContext's (which is a per-storage-partition
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object and may exist multiple in a profile).
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An instance of this class is shared by FileSystemContexts and outlives
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LocalFileSyncService.
592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochclass LocalFileSyncContext
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::RefCountedThreadSafe<LocalFileSyncContext>,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public LocalFileSyncStatus::Observer {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  enum SyncMode {
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SYNC_EXCLUSIVE,
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    SYNC_SNAPSHOT,
66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  };
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  typedef base::Callback<void(SyncStatusCode status,
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              const LocalFileSyncInfo& sync_file_info,
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              storage::ScopedFile snapshot)>
7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      LocalFileSyncInfoCallback;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(SyncStatusCode status,
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              bool has_pending_changes)>
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HasPendingLocalChangeCallback;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  LocalFileSyncContext(const base::FilePath& base_path,
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       leveldb::Env* env_override,
79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                       base::SingleThreadTaskRunner* ui_task_runner,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       base::SingleThreadTaskRunner* io_task_runner);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Initializes |file_system_context| for syncable file operations
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // and registers the it into the internal map.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calling this multiple times for the same file_system_context is valid.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method must be called on UI thread.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void MaybeInitializeFileSystemContext(
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const GURL& source_url,
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemContext* file_system_context,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const SyncStatusCallback& callback);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the corresponding LocalFileSyncService exits.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method must be called on UI thread.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ShutdownOnUIThread();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Picks a file for next local sync and returns it after disabling writes
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for the file.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method must be called on UI thread.
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void GetFileForLocalSync(storage::FileSystemContext* file_system_context,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const LocalFileSyncInfoCallback& callback);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(kinuko): Make this private.
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clears all pending local changes for |url|. |done_callback| is called
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // when the changes are cleared.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method must be called on UI thread.
10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void ClearChangesForURL(storage::FileSystemContext* file_system_context,
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                          const storage::FileSystemURL& url,
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          const base::Closure& done_callback);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Finalizes SnapshotSync, which must have been started by
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // PrepareForSync with SYNC_SNAPSHOT.
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Updates the on-disk dirty flag for |url| in the tracker DB.
112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // This will clear the dirty flag if |sync_finish_status| is SYNC_STATUS_OK
113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // or SYNC_STATUS_HAS_CONFLICT.
114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // |done_callback| is called when the changes are committed.
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void FinalizeSnapshotSync(storage::FileSystemContext* file_system_context,
11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                            const storage::FileSystemURL& url,
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                            SyncStatusCode sync_finish_status,
11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                            const base::Closure& done_callback);
119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Finalizes ExclusiveSync, which must have been started by
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // PrepareForSync with SYNC_EXCLUSIVE.
12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void FinalizeExclusiveSync(storage::FileSystemContext* file_system_context,
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                             const storage::FileSystemURL& url,
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                             bool clear_local_changes,
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                             const base::Closure& done_callback);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prepares for sync |url| by disabling writes on |url|.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the target |url| is being written and cannot start sync it
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returns SYNC_STATUS_WRITING status code via |callback|.
130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Otherwise returns the current change sets made on |url|.
131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If |sync_mode| is SYNC_EXCLUSIVE this leaves the target file locked.
133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // If |sync_mode| is SYNC_SNAPSHOT this creates a snapshot (if the
134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // target file is not deleted) and unlocks the file before returning.
135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // For SYNC_EXCLUSIVE, caller must call FinalizeExclusiveSync() to finalize
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // sync and unlock the file.
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // For SYNC_SNAPSHOT, caller must call FinalizeSnapshotSync() to finalize
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // sync to reset the mirrored change status and decrement writing count.
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method must be called on UI thread.
14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void PrepareForSync(storage::FileSystemContext* file_system_context,
14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                      const storage::FileSystemURL& url,
144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                      SyncMode sync_mode,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const LocalFileSyncInfoCallback& callback);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Registers |url| to wait until sync is enabled for |url|.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |on_syncable_callback| is to be called when |url| becomes syncable
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (i.e. when we have no pending writes and the file is successfully locked
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for sync).
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calling this method again while this already has another URL waiting
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for sync will overwrite the previously registered URL.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method must be called on UI thread.
15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void RegisterURLForWaitingSync(const storage::FileSystemURL& url,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const base::Closure& on_syncable_callback);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Applies a remote change.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method must be called on UI thread.
16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void ApplyRemoteChange(storage::FileSystemContext* file_system_context,
16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                         const FileChange& change,
16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                         const base::FilePath& local_path,
16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                         const storage::FileSystemURL& url,
16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                         const SyncStatusCallback& callback);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Records a fake local change in the local change tracker.
16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void RecordFakeLocalChange(storage::FileSystemContext* file_system_context,
16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                             const storage::FileSystemURL& url,
17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                             const FileChange& change,
17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                             const SyncStatusCallback& callback);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This must be called on UI thread.
17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void GetFileMetadata(storage::FileSystemContext* file_system_context,
17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                       const storage::FileSystemURL& url,
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                       const SyncFileMetadataCallback& callback);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true via |callback| if the given file |url| has local pending
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // changes.
18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void HasPendingLocalChanges(storage::FileSystemContext* file_system_context,
18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              const storage::FileSystemURL& url,
18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              const HasPendingLocalChangeCallback& callback);
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void PromoteDemotedChanges(const GURL& origin,
18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                             storage::FileSystemContext* file_system_context,
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             const base::Closure& callback);
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void UpdateChangesForOrigin(const GURL& origin,
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              const base::Closure& callback);
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // They must be called on UI thread.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddOriginChangeObserver(LocalOriginChangeObserver* observer);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveOriginChangeObserver(LocalOriginChangeObserver* observer);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OperationRunner is accessible only on IO thread.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtr<SyncableFileOperationRunner> operation_runner() const;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SyncContext is accessible only on IO thread.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LocalFileSyncStatus* sync_status() const;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For testing; override the duration to notify changes from the
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // default value.
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_mock_notify_changes_duration_in_sec(int duration) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_notify_changes_duration_in_sec_ = duration;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LocalFileSyncStatus::Observer overrides. They are called on IO thread.
20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void OnSyncEnabled(const storage::FileSystemURL& url) OVERRIDE;
20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void OnWriteEnabled(const storage::FileSystemURL& url) OVERRIDE;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef base::Callback<void(base::File::Error result)> StatusCallback;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::deque<SyncStatusCallback> StatusCallbackQueue;
21403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  typedef std::deque<storage::FileSystemURL> FileSystemURLQueue;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCountedThreadSafe<LocalFileSyncContext>;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class CannedSyncableFileSystem;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~LocalFileSyncContext();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ShutdownOnIOThread();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Starts a timer to eventually call NotifyAvailableChangesOnIOThread.
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The caller is expected to update origins_with_pending_changes_ before
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // calling this.
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void ScheduleNotifyChangesUpdatedOnIOThread(const base::Closure& callback);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by the internal timer on IO thread to notify changes to UI thread.
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void NotifyAvailableChangesOnIOThread(const base::Closure& callback);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called from NotifyAvailableChangesOnIOThread.
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void NotifyAvailableChanges(const std::set<GURL>& origins,
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              const base::Closure& callback);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper routines for MaybeInitializeFileSystemContext.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitializeFileSystemContextOnIOThread(
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& source_url,
23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemContext* file_system_context,
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const GURL& /* root */,
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const std::string& /* name */,
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::File::Error error);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SyncStatusCode InitializeChangeTrackerOnFileThread(
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<LocalFileChangeTracker>* tracker_ptr,
24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemContext* file_system_context,
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::set<GURL>* origins_with_changes);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidInitializeChangeTrackerOnIOThread(
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<LocalFileChangeTracker>* tracker_ptr,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& source_url,
24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemContext* file_system_context,
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::set<GURL>* origins_with_changes,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SyncStatusCode status);
25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void DidInitialize(const GURL& source_url,
25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     storage::FileSystemContext* file_system_context,
25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     SyncStatusCode status);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper routines for GetFileForLocalSync.
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<FileSystemURLQueue> GetNextURLsForSyncOnFileThread(
25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemContext* file_system_context);
25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void TryPrepareForLocalSync(storage::FileSystemContext* file_system_context,
25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              const LocalFileSyncInfoCallback& callback,
26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              scoped_ptr<FileSystemURLQueue> urls);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidTryPrepareForLocalSync(
26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemContext* file_system_context,
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      scoped_ptr<FileSystemURLQueue> remaining_urls,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const LocalFileSyncInfoCallback& callback,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SyncStatusCode status,
266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const LocalFileSyncInfo& sync_file_info,
26703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::ScopedFile snapshot);
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void PromoteDemotedChangesForURL(
26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemContext* file_system_context,
27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      const storage::FileSystemURL& url);
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void PromoteDemotedChangesForURLs(
27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemContext* file_system_context,
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      scoped_ptr<FileSystemURLQueue> url);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback routine for PrepareForSync and GetFileForLocalSync.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidGetWritingStatusForSync(
27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemContext* file_system_context,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SyncStatusCode status,
27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      const storage::FileSystemURL& url,
280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      SyncMode sync_mode,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const LocalFileSyncInfoCallback& callback);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Helper routine for sync/writing flag handling.
2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //
2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If |for_snapshot_sync| is true, this increments the writing counter
2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // for |url| (after clearing syncing flag), so that other sync activities
2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // won't step in while snapshot sync is ongoing.
2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // In this case FinalizeSnapshotSyncOnIOThread must be called after the
2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // snapshot sync is finished to decrement the writing counter.
29003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void ClearSyncFlagOnIOThread(const storage::FileSystemURL& url,
2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               bool for_snapshot_sync);
29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void FinalizeSnapshotSyncOnIOThread(const storage::FileSystemURL& url);
29303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
29403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void HandleRemoteDelete(storage::FileSystemContext* file_system_context,
29503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                          const storage::FileSystemURL& url,
29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                          const SyncStatusCallback& callback);
29703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void HandleRemoteAddOrUpdate(storage::FileSystemContext* file_system_context,
29803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                               const FileChange& change,
29903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                               const base::FilePath& local_path,
30003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                               const storage::FileSystemURL& url,
30103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                               const SyncStatusCallback& callback);
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void DidRemoveExistingEntryForRemoteAddOrUpdate(
30303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemContext* file_system_context,
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const FileChange& change,
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::FilePath& local_path,
30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      const storage::FileSystemURL& url,
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const SyncStatusCallback& callback,
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::File::Error error);
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback routine for ApplyRemoteChange.
31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void DidApplyRemoteChange(const storage::FileSystemURL& url,
31203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                            const SyncStatusCallback& callback_on_ui,
31303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                            base::File::Error file_error);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidGetFileMetadata(
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const SyncFileMetadataCallback& callback,
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::File::Error file_error,
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const base::File::Info& file_info);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta NotifyChangesDuration();
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void DidCreateDirectoryForCopyIn(
32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemContext* file_system_context,
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const base::FilePath& local_file_path,
32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      const storage::FileSystemURL& dest_url,
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const StatusCallback& callback,
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::File::Error error);
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const base::FilePath local_base_path_;
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  leveldb::Env* env_override_;
331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Indicates if the sync service is shutdown.
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool shutdown_on_ui_;  // Updated and referred only on UI thread.
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool shutdown_on_io_;  // Updated and referred only on IO thread.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OperationRunner. This must be accessed only on IO thread.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SyncableFileOperationRunner> operation_runner_;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keeps track of writing/syncing status.
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This must be accessed only on IO thread.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<LocalFileSyncStatus> sync_status_;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pointers to file system contexts that have been initialized for
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // synchronization (i.e. that own this instance).
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This must be accessed only on UI thread.
34903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::set<storage::FileSystemContext*> file_system_contexts_;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Accessed only on UI thread.
35203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::map<storage::FileSystemContext*, StatusCallbackQueue>
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_initialize_callbacks_;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A URL and associated callback waiting for sync is enabled.
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Accessed only on IO thread.
35703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemURL url_waiting_sync_on_io_;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure url_syncable_callback_;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used only on IO thread for available changes notifications.
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time last_notified_changes_;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::OneShotTimer<LocalFileSyncContext> > timer_on_io_;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<GURL> origins_with_pending_changes_;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Populated while root directory deletion is being handled for
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // ApplyRemoteChange(). Modified only on IO thread.
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<RootDeleteHelper> root_delete_helper_;
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObserverList<LocalOriginChangeObserver> origin_change_observers_;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mock_notify_changes_duration_in_sec_;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LocalFileSyncContext);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace sync_file_system
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_CONTEXT_H_
379