Chromium Code Reviews| Index: chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h |
| diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h |
| index fd8f8807e3b3ac777b6b68b4a91e35f4d1777311..031518912ba9e649f85d387ed5979b5dc81e5f0a 100644 |
| --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h |
| +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h |
| @@ -5,6 +5,8 @@ |
| #ifndef CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_H_ |
| #define CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_H_ |
| +#include <stdint.h> |
| + |
| #include <map> |
| #include <string> |
| #include <vector> |
| @@ -16,6 +18,7 @@ |
| #include "base/optional.h" |
| #include "components/arc/common/file_system.mojom.h" |
| #include "storage/browser/fileapi/async_file_util.h" |
| +#include "storage/browser/fileapi/watcher_manager.h" |
| class GURL; |
| @@ -30,6 +33,9 @@ class ArcDocumentsProviderRoot { |
| public: |
| using GetFileInfoCallback = storage::AsyncFileUtil::GetFileInfoCallback; |
| using ReadDirectoryCallback = storage::AsyncFileUtil::ReadDirectoryCallback; |
| + using ChangeType = storage::WatcherManager::ChangeType; |
| + using WatcherCallback = base::Callback<void(ChangeType type)>; |
| + using StatusCallback = base::Callback<void(base::File::Error error)>; |
| using ResolveToContentUrlCallback = |
| base::Callback<void(const GURL& content_url)>; |
| @@ -46,6 +52,49 @@ class ArcDocumentsProviderRoot { |
| void ReadDirectory(const base::FilePath& path, |
| const ReadDirectoryCallback& callback); |
| + // Installs a document watcher. |
| + // |
| + // It is not allowed to install multiple watchers at the same file path; |
| + // if attempted, duplicated requests will fail. |
| + // |
| + // Currently, watchers can be installed only on directories, and only |
| + // directory content changes are notified. |
| + // |
| + // NOTES ABOUT CORRECTNESS AND CONSISTENCY: |
| + // |
| + // Document watchers are not always correct and they may miss some updates or |
| + // even notify incorrect update events for several reasons, such as: |
| + // |
| + // - Racy file system operations. |
|
hidehiko
2017/02/23 12:10:54
Could you add a simple racy operations as an examp
Shuhei Takahashi
2017/03/02 07:06:01
Sure, added more examples.
Also I added mention o
|
| + // - Broken DocumentsProviders. |
| + // - Duplicated file name handling in this class. |
| + // |
| + // However, consistency of installed watchers is guaranteed. That is, after |
| + // a watcher is installed on a file path X, an attempt to uninstall a watcher |
| + // at X will always success (unless it is automatically uninstalled by |
| + // a DELETED event). |
| + // |
| + // Unfortunately it is too difficult (or maybe theoretically impossible) to |
| + // implement a perfect Android document watcher which never misses document |
| + // updates. So the current implementation gives up correctness, but instead |
| + // focuses on following two goals: |
| + // |
| + // 1. Keep the implementation simple, rather than trying hard to catch |
| + // race conditions or minor cases. Even if we return wrong results, the |
| + // worst consequence is just that users do not see the latest contents |
| + // until they refresh UI. |
| + // |
| + // 2. Keep consistency of installed watchers so that the caller can avoid |
| + // dangling watchers. |
| + void AddWatcher(const base::FilePath& path, |
| + const WatcherCallback& watcher_callback, |
| + const StatusCallback& callback); |
| + |
| + // Uninstalls a document watcher. |
| + // See the documentation of AddWatcher() above. |
| + void RemoveWatcher(const base::FilePath& path, |
| + const StatusCallback& callback); |
| + |
| // Resolves a file path into a content:// URL pointing to the file |
| // on DocumentsProvider. Returns URL that can be passed to |
| // ArcContentFileSystemFileSystemReader to read the content. |
| @@ -82,6 +131,17 @@ class ArcDocumentsProviderRoot { |
| base::File::Error error, |
| NameToThinDocumentMap mapping); |
| + void AddWatcherWithDocumentId(const base::FilePath& path, |
| + const WatcherCallback& watcher_callback, |
| + const StatusCallback& callback, |
| + const std::string& document_id); |
| + void AddWatcherDone(const base::FilePath& path, |
| + const StatusCallback& callback, |
| + int64_t watcher_id); |
| + void AddWatcherAborted(const StatusCallback& callback, bool success); |
| + |
| + void RemoveWatcherDone(const StatusCallback& callback, bool success); |
| + |
| void ResolveToContentUrlWithDocumentId( |
| const ResolveToContentUrlCallback& callback, |
| const std::string& document_id); |
| @@ -110,6 +170,15 @@ class ArcDocumentsProviderRoot { |
| const std::string authority_; |
| const std::string root_document_id_; |
| + |
| + // Map from a file path to a watcher ID. |
| + // |
| + // Note that we do not use a document ID as a key here to guarantee that |
| + // a watch installed by AddWatcher() can be always identified in |
| + // RemoveWatcher() with the same file path specified. |
| + // See the documentation of AddWatcher() for more details. |
| + std::map<base::FilePath, int64_t> path_to_watcher_id_; |
| + |
| base::WeakPtrFactory<ArcDocumentsProviderRoot> weak_ptr_factory_; |
| DISALLOW_COPY_AND_ASSIGN(ArcDocumentsProviderRoot); |