Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 #ifndef CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_H_ | 5 #ifndef CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_H_ |
| 6 #define CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_H_ | 6 #define CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | |
| 9 | |
| 8 #include <map> | 10 #include <map> |
| 9 #include <string> | 11 #include <string> |
| 10 #include <vector> | 12 #include <vector> |
| 11 | 13 |
| 12 #include "base/callback_forward.h" | 14 #include "base/callback_forward.h" |
| 13 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
| 14 #include "base/macros.h" | 16 #include "base/macros.h" |
| 15 #include "base/memory/weak_ptr.h" | 17 #include "base/memory/weak_ptr.h" |
| 16 #include "base/optional.h" | 18 #include "base/optional.h" |
| 17 #include "components/arc/common/file_system.mojom.h" | 19 #include "components/arc/common/file_system.mojom.h" |
| 18 #include "storage/browser/fileapi/async_file_util.h" | 20 #include "storage/browser/fileapi/async_file_util.h" |
| 21 #include "storage/browser/fileapi/watcher_manager.h" | |
| 19 | 22 |
| 20 class GURL; | 23 class GURL; |
| 21 | 24 |
| 22 namespace arc { | 25 namespace arc { |
| 23 | 26 |
| 24 // Represents a file system root in Android Documents Provider. | 27 // Represents a file system root in Android Documents Provider. |
| 25 // | 28 // |
| 26 // All methods must be called on the IO thread. | 29 // All methods must be called on the IO thread. |
| 27 // If this object is deleted while there are in-flight operations, callbacks | 30 // If this object is deleted while there are in-flight operations, callbacks |
| 28 // for those operations will be never called. | 31 // for those operations will be never called. |
| 29 class ArcDocumentsProviderRoot { | 32 class ArcDocumentsProviderRoot { |
| 30 public: | 33 public: |
| 31 using GetFileInfoCallback = storage::AsyncFileUtil::GetFileInfoCallback; | 34 using GetFileInfoCallback = storage::AsyncFileUtil::GetFileInfoCallback; |
| 32 using ReadDirectoryCallback = storage::AsyncFileUtil::ReadDirectoryCallback; | 35 using ReadDirectoryCallback = storage::AsyncFileUtil::ReadDirectoryCallback; |
| 36 using ChangeType = storage::WatcherManager::ChangeType; | |
| 37 using WatcherCallback = base::Callback<void(ChangeType type)>; | |
| 38 using StatusCallback = base::Callback<void(base::File::Error error)>; | |
| 33 using ResolveToContentUrlCallback = | 39 using ResolveToContentUrlCallback = |
| 34 base::Callback<void(const GURL& content_url)>; | 40 base::Callback<void(const GURL& content_url)>; |
| 35 | 41 |
| 36 ArcDocumentsProviderRoot(const std::string& authority, | 42 ArcDocumentsProviderRoot(const std::string& authority, |
| 37 const std::string& root_document_id); | 43 const std::string& root_document_id); |
| 38 ~ArcDocumentsProviderRoot(); | 44 ~ArcDocumentsProviderRoot(); |
| 39 | 45 |
| 40 // Queries information of a file just like AsyncFileUtil.GetFileInfo(). | 46 // Queries information of a file just like AsyncFileUtil.GetFileInfo(). |
| 41 void GetFileInfo(const base::FilePath& path, | 47 void GetFileInfo(const base::FilePath& path, |
| 42 const GetFileInfoCallback& callback); | 48 const GetFileInfoCallback& callback); |
| 43 | 49 |
| 44 // Queries a list of files under a directory just like | 50 // Queries a list of files under a directory just like |
| 45 // AsyncFileUtil.ReadDirectory(). | 51 // AsyncFileUtil.ReadDirectory(). |
| 46 void ReadDirectory(const base::FilePath& path, | 52 void ReadDirectory(const base::FilePath& path, |
| 47 const ReadDirectoryCallback& callback); | 53 const ReadDirectoryCallback& callback); |
| 48 | 54 |
| 55 // Installs a document watcher. | |
| 56 // | |
| 57 // It is not allowed to install multiple watchers at the same file path; | |
| 58 // if attempted, duplicated requests will fail. | |
| 59 // | |
| 60 // Currently, watchers can be installed only on directories, and only | |
| 61 // directory content changes are notified. | |
| 62 // | |
| 63 // NOTES ABOUT CORRECTNESS AND CONSISTENCY: | |
| 64 // | |
| 65 // Document watchers are not always correct and they may miss some updates or | |
| 66 // even notify incorrect update events for several reasons, such as: | |
| 67 // | |
| 68 // - 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
| |
| 69 // - Broken DocumentsProviders. | |
| 70 // - Duplicated file name handling in this class. | |
| 71 // | |
| 72 // However, consistency of installed watchers is guaranteed. That is, after | |
| 73 // a watcher is installed on a file path X, an attempt to uninstall a watcher | |
| 74 // at X will always success (unless it is automatically uninstalled by | |
| 75 // a DELETED event). | |
| 76 // | |
| 77 // Unfortunately it is too difficult (or maybe theoretically impossible) to | |
| 78 // implement a perfect Android document watcher which never misses document | |
| 79 // updates. So the current implementation gives up correctness, but instead | |
| 80 // focuses on following two goals: | |
| 81 // | |
| 82 // 1. Keep the implementation simple, rather than trying hard to catch | |
| 83 // race conditions or minor cases. Even if we return wrong results, the | |
| 84 // worst consequence is just that users do not see the latest contents | |
| 85 // until they refresh UI. | |
| 86 // | |
| 87 // 2. Keep consistency of installed watchers so that the caller can avoid | |
| 88 // dangling watchers. | |
| 89 void AddWatcher(const base::FilePath& path, | |
| 90 const WatcherCallback& watcher_callback, | |
| 91 const StatusCallback& callback); | |
| 92 | |
| 93 // Uninstalls a document watcher. | |
| 94 // See the documentation of AddWatcher() above. | |
| 95 void RemoveWatcher(const base::FilePath& path, | |
| 96 const StatusCallback& callback); | |
| 97 | |
| 49 // Resolves a file path into a content:// URL pointing to the file | 98 // Resolves a file path into a content:// URL pointing to the file |
| 50 // on DocumentsProvider. Returns URL that can be passed to | 99 // on DocumentsProvider. Returns URL that can be passed to |
| 51 // ArcContentFileSystemFileSystemReader to read the content. | 100 // ArcContentFileSystemFileSystemReader to read the content. |
| 52 // On errors, an invalid GURL is returned. | 101 // On errors, an invalid GURL is returned. |
| 53 void ResolveToContentUrl(const base::FilePath& path, | 102 void ResolveToContentUrl(const base::FilePath& path, |
| 54 const ResolveToContentUrlCallback& callback); | 103 const ResolveToContentUrlCallback& callback); |
| 55 | 104 |
| 56 private: | 105 private: |
| 57 // Thin representation of a document in documents provider. | 106 // Thin representation of a document in documents provider. |
| 58 struct ThinDocument { | 107 struct ThinDocument { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 75 void GetFileInfoWithDocument(const GetFileInfoCallback& callback, | 124 void GetFileInfoWithDocument(const GetFileInfoCallback& callback, |
| 76 mojom::DocumentPtr document); | 125 mojom::DocumentPtr document); |
| 77 | 126 |
| 78 void ReadDirectoryWithDocumentId(const ReadDirectoryCallback& callback, | 127 void ReadDirectoryWithDocumentId(const ReadDirectoryCallback& callback, |
| 79 const std::string& document_id); | 128 const std::string& document_id); |
| 80 void ReadDirectoryWithNameToThinDocumentMap( | 129 void ReadDirectoryWithNameToThinDocumentMap( |
| 81 const ReadDirectoryCallback& callback, | 130 const ReadDirectoryCallback& callback, |
| 82 base::File::Error error, | 131 base::File::Error error, |
| 83 NameToThinDocumentMap mapping); | 132 NameToThinDocumentMap mapping); |
| 84 | 133 |
| 134 void AddWatcherWithDocumentId(const base::FilePath& path, | |
| 135 const WatcherCallback& watcher_callback, | |
| 136 const StatusCallback& callback, | |
| 137 const std::string& document_id); | |
| 138 void AddWatcherDone(const base::FilePath& path, | |
| 139 const StatusCallback& callback, | |
| 140 int64_t watcher_id); | |
| 141 void AddWatcherAborted(const StatusCallback& callback, bool success); | |
| 142 | |
| 143 void RemoveWatcherDone(const StatusCallback& callback, bool success); | |
| 144 | |
| 85 void ResolveToContentUrlWithDocumentId( | 145 void ResolveToContentUrlWithDocumentId( |
| 86 const ResolveToContentUrlCallback& callback, | 146 const ResolveToContentUrlCallback& callback, |
| 87 const std::string& document_id); | 147 const std::string& document_id); |
| 88 | 148 |
| 89 // Resolves |path| to a document ID. Failures are indicated by an empty | 149 // Resolves |path| to a document ID. Failures are indicated by an empty |
| 90 // document ID. | 150 // document ID. |
| 91 void ResolveToDocumentId(const base::FilePath& path, | 151 void ResolveToDocumentId(const base::FilePath& path, |
| 92 const ResolveToDocumentIdCallback& callback); | 152 const ResolveToDocumentIdCallback& callback); |
| 93 void ResolveToDocumentIdRecursively( | 153 void ResolveToDocumentIdRecursively( |
| 94 const std::string& document_id, | 154 const std::string& document_id, |
| 95 const std::vector<base::FilePath::StringType>& components, | 155 const std::vector<base::FilePath::StringType>& components, |
| 96 const ResolveToDocumentIdCallback& callback); | 156 const ResolveToDocumentIdCallback& callback); |
| 97 void ResolveToDocumentIdRecursivelyWithNameToThinDocumentMap( | 157 void ResolveToDocumentIdRecursivelyWithNameToThinDocumentMap( |
| 98 const std::vector<base::FilePath::StringType>& components, | 158 const std::vector<base::FilePath::StringType>& components, |
| 99 const ResolveToDocumentIdCallback& callback, | 159 const ResolveToDocumentIdCallback& callback, |
| 100 base::File::Error error, | 160 base::File::Error error, |
| 101 NameToThinDocumentMap mapping); | 161 NameToThinDocumentMap mapping); |
| 102 | 162 |
| 103 // Enumerates child documents of a directory specified by |document_id|. | 163 // Enumerates child documents of a directory specified by |document_id|. |
| 104 // The result is returned as a NameToThinDocumentMap. | 164 // The result is returned as a NameToThinDocumentMap. |
| 105 void ReadDirectoryInternal(const std::string& document_id, | 165 void ReadDirectoryInternal(const std::string& document_id, |
| 106 const ReadDirectoryInternalCallback& callback); | 166 const ReadDirectoryInternalCallback& callback); |
| 107 void ReadDirectoryInternalWithChildDocuments( | 167 void ReadDirectoryInternalWithChildDocuments( |
| 108 const ReadDirectoryInternalCallback& callback, | 168 const ReadDirectoryInternalCallback& callback, |
| 109 base::Optional<std::vector<mojom::DocumentPtr>> maybe_children); | 169 base::Optional<std::vector<mojom::DocumentPtr>> maybe_children); |
| 110 | 170 |
| 111 const std::string authority_; | 171 const std::string authority_; |
| 112 const std::string root_document_id_; | 172 const std::string root_document_id_; |
| 173 | |
| 174 // Map from a file path to a watcher ID. | |
| 175 // | |
| 176 // Note that we do not use a document ID as a key here to guarantee that | |
| 177 // a watch installed by AddWatcher() can be always identified in | |
| 178 // RemoveWatcher() with the same file path specified. | |
| 179 // See the documentation of AddWatcher() for more details. | |
| 180 std::map<base::FilePath, int64_t> path_to_watcher_id_; | |
| 181 | |
| 113 base::WeakPtrFactory<ArcDocumentsProviderRoot> weak_ptr_factory_; | 182 base::WeakPtrFactory<ArcDocumentsProviderRoot> weak_ptr_factory_; |
| 114 | 183 |
| 115 DISALLOW_COPY_AND_ASSIGN(ArcDocumentsProviderRoot); | 184 DISALLOW_COPY_AND_ASSIGN(ArcDocumentsProviderRoot); |
| 116 }; | 185 }; |
| 117 | 186 |
| 118 } // namespace arc | 187 } // namespace arc |
| 119 | 188 |
| 120 #endif // CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_H_ | 189 #endif // CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_H_ |
| OLD | NEW |