1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker // This module provides a way to monitor a file or directory for changes. 6*635a8641SAndroid Build Coastguard Worker 7*635a8641SAndroid Build Coastguard Worker #ifndef BASE_FILES_FILE_PATH_WATCHER_H_ 8*635a8641SAndroid Build Coastguard Worker #define BASE_FILES_FILE_PATH_WATCHER_H_ 9*635a8641SAndroid Build Coastguard Worker 10*635a8641SAndroid Build Coastguard Worker #include <memory> 11*635a8641SAndroid Build Coastguard Worker 12*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h" 13*635a8641SAndroid Build Coastguard Worker #include "base/callback.h" 14*635a8641SAndroid Build Coastguard Worker #include "base/files/file_path.h" 15*635a8641SAndroid Build Coastguard Worker #include "base/macros.h" 16*635a8641SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h" 17*635a8641SAndroid Build Coastguard Worker #include "base/sequence_checker.h" 18*635a8641SAndroid Build Coastguard Worker #include "base/sequenced_task_runner.h" 19*635a8641SAndroid Build Coastguard Worker 20*635a8641SAndroid Build Coastguard Worker namespace base { 21*635a8641SAndroid Build Coastguard Worker 22*635a8641SAndroid Build Coastguard Worker // This class lets you register interest in changes on a FilePath. 23*635a8641SAndroid Build Coastguard Worker // The callback will get called whenever the file or directory referenced by the 24*635a8641SAndroid Build Coastguard Worker // FilePath is changed, including created or deleted. Due to limitations in the 25*635a8641SAndroid Build Coastguard Worker // underlying OS APIs, FilePathWatcher has slightly different semantics on OS X 26*635a8641SAndroid Build Coastguard Worker // than on Windows or Linux. FilePathWatcher on Linux and Windows will detect 27*635a8641SAndroid Build Coastguard Worker // modifications to files in a watched directory. FilePathWatcher on Mac will 28*635a8641SAndroid Build Coastguard Worker // detect the creation and deletion of files in a watched directory, but will 29*635a8641SAndroid Build Coastguard Worker // not detect modifications to those files. See file_path_watcher_kqueue.cc for 30*635a8641SAndroid Build Coastguard Worker // details. 31*635a8641SAndroid Build Coastguard Worker // 32*635a8641SAndroid Build Coastguard Worker // Must be destroyed on the sequence that invokes Watch(). 33*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT FilePathWatcher { 34*635a8641SAndroid Build Coastguard Worker public: 35*635a8641SAndroid Build Coastguard Worker // Callback type for Watch(). |path| points to the file that was updated, 36*635a8641SAndroid Build Coastguard Worker // and |error| is true if the platform specific code detected an error. In 37*635a8641SAndroid Build Coastguard Worker // that case, the callback won't be invoked again. 38*635a8641SAndroid Build Coastguard Worker typedef base::Callback<void(const FilePath& path, bool error)> Callback; 39*635a8641SAndroid Build Coastguard Worker 40*635a8641SAndroid Build Coastguard Worker // Used internally to encapsulate different members on different platforms. 41*635a8641SAndroid Build Coastguard Worker class PlatformDelegate { 42*635a8641SAndroid Build Coastguard Worker public: 43*635a8641SAndroid Build Coastguard Worker PlatformDelegate(); 44*635a8641SAndroid Build Coastguard Worker virtual ~PlatformDelegate(); 45*635a8641SAndroid Build Coastguard Worker 46*635a8641SAndroid Build Coastguard Worker // Start watching for the given |path| and notify |delegate| about changes. 47*635a8641SAndroid Build Coastguard Worker virtual bool Watch(const FilePath& path, 48*635a8641SAndroid Build Coastguard Worker bool recursive, 49*635a8641SAndroid Build Coastguard Worker const Callback& callback) WARN_UNUSED_RESULT = 0; 50*635a8641SAndroid Build Coastguard Worker 51*635a8641SAndroid Build Coastguard Worker // Stop watching. This is called from FilePathWatcher's dtor in order to 52*635a8641SAndroid Build Coastguard Worker // allow to shut down properly while the object is still alive. 53*635a8641SAndroid Build Coastguard Worker virtual void Cancel() = 0; 54*635a8641SAndroid Build Coastguard Worker 55*635a8641SAndroid Build Coastguard Worker protected: 56*635a8641SAndroid Build Coastguard Worker friend class FilePathWatcher; 57*635a8641SAndroid Build Coastguard Worker task_runner()58*635a8641SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner() const { 59*635a8641SAndroid Build Coastguard Worker return task_runner_; 60*635a8641SAndroid Build Coastguard Worker } 61*635a8641SAndroid Build Coastguard Worker set_task_runner(scoped_refptr<SequencedTaskRunner> runner)62*635a8641SAndroid Build Coastguard Worker void set_task_runner(scoped_refptr<SequencedTaskRunner> runner) { 63*635a8641SAndroid Build Coastguard Worker task_runner_ = std::move(runner); 64*635a8641SAndroid Build Coastguard Worker } 65*635a8641SAndroid Build Coastguard Worker 66*635a8641SAndroid Build Coastguard Worker // Must be called before the PlatformDelegate is deleted. set_cancelled()67*635a8641SAndroid Build Coastguard Worker void set_cancelled() { 68*635a8641SAndroid Build Coastguard Worker cancelled_ = true; 69*635a8641SAndroid Build Coastguard Worker } 70*635a8641SAndroid Build Coastguard Worker is_cancelled()71*635a8641SAndroid Build Coastguard Worker bool is_cancelled() const { 72*635a8641SAndroid Build Coastguard Worker return cancelled_; 73*635a8641SAndroid Build Coastguard Worker } 74*635a8641SAndroid Build Coastguard Worker 75*635a8641SAndroid Build Coastguard Worker private: 76*635a8641SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner_; 77*635a8641SAndroid Build Coastguard Worker bool cancelled_; 78*635a8641SAndroid Build Coastguard Worker 79*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(PlatformDelegate); 80*635a8641SAndroid Build Coastguard Worker }; 81*635a8641SAndroid Build Coastguard Worker 82*635a8641SAndroid Build Coastguard Worker FilePathWatcher(); 83*635a8641SAndroid Build Coastguard Worker ~FilePathWatcher(); 84*635a8641SAndroid Build Coastguard Worker 85*635a8641SAndroid Build Coastguard Worker // Returns true if the platform and OS version support recursive watches. 86*635a8641SAndroid Build Coastguard Worker static bool RecursiveWatchAvailable(); 87*635a8641SAndroid Build Coastguard Worker 88*635a8641SAndroid Build Coastguard Worker // Invokes |callback| whenever updates to |path| are detected. This should be 89*635a8641SAndroid Build Coastguard Worker // called at most once. Set |recursive| to true to watch |path| and its 90*635a8641SAndroid Build Coastguard Worker // children. The callback will be invoked on the same sequence. Returns true 91*635a8641SAndroid Build Coastguard Worker // on success. 92*635a8641SAndroid Build Coastguard Worker // 93*635a8641SAndroid Build Coastguard Worker // On POSIX, this must be called from a thread that supports 94*635a8641SAndroid Build Coastguard Worker // FileDescriptorWatcher. 95*635a8641SAndroid Build Coastguard Worker // 96*635a8641SAndroid Build Coastguard Worker // Recursive watch is not supported on all platforms and file systems. 97*635a8641SAndroid Build Coastguard Worker // Watch() will return false in the case of failure. 98*635a8641SAndroid Build Coastguard Worker bool Watch(const FilePath& path, bool recursive, const Callback& callback); 99*635a8641SAndroid Build Coastguard Worker 100*635a8641SAndroid Build Coastguard Worker private: 101*635a8641SAndroid Build Coastguard Worker std::unique_ptr<PlatformDelegate> impl_; 102*635a8641SAndroid Build Coastguard Worker 103*635a8641SAndroid Build Coastguard Worker SequenceChecker sequence_checker_; 104*635a8641SAndroid Build Coastguard Worker 105*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(FilePathWatcher); 106*635a8641SAndroid Build Coastguard Worker }; 107*635a8641SAndroid Build Coastguard Worker 108*635a8641SAndroid Build Coastguard Worker } // namespace base 109*635a8641SAndroid Build Coastguard Worker 110*635a8641SAndroid Build Coastguard Worker #endif // BASE_FILES_FILE_PATH_WATCHER_H_ 111