Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h

Issue 2731883002: mediaview: Support watchers in ArcDocumentsProviderRoot. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
17 #include "base/memory/ref_counted.h"
15 #include "base/memory/weak_ptr.h" 18 #include "base/memory/weak_ptr.h"
16 #include "base/optional.h" 19 #include "base/optional.h"
20 #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h "
21 #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_u til.h"
17 #include "components/arc/common/file_system.mojom.h" 22 #include "components/arc/common/file_system.mojom.h"
18 #include "storage/browser/fileapi/async_file_util.h" 23 #include "storage/browser/fileapi/async_file_util.h"
24 #include "storage/browser/fileapi/watcher_manager.h"
19 25
20 class GURL; 26 class GURL;
21 27
22 namespace arc { 28 namespace arc {
23 29
24 // Represents a file system root in Android Documents Provider. 30 // Represents a file system root in Android Documents Provider.
25 // 31 //
26 // All methods must be called on the IO thread. 32 // All methods must be called on the IO thread.
27 // If this object is deleted while there are in-flight operations, callbacks 33 // If this object is deleted while there are in-flight operations, callbacks
28 // for those operations will be never called. 34 // for those operations will be never called.
29 class ArcDocumentsProviderRoot { 35 class ArcDocumentsProviderRoot : public ArcFileSystemOperationRunner::Observer {
30 public: 36 public:
31 using GetFileInfoCallback = storage::AsyncFileUtil::GetFileInfoCallback; 37 using GetFileInfoCallback = storage::AsyncFileUtil::GetFileInfoCallback;
32 using ReadDirectoryCallback = storage::AsyncFileUtil::ReadDirectoryCallback; 38 using ReadDirectoryCallback = storage::AsyncFileUtil::ReadDirectoryCallback;
39 using ChangeType = storage::WatcherManager::ChangeType;
40 using WatcherCallback = base::Callback<void(ChangeType type)>;
41 using StatusCallback = base::Callback<void(base::File::Error error)>;
33 using ResolveToContentUrlCallback = 42 using ResolveToContentUrlCallback =
34 base::Callback<void(const GURL& content_url)>; 43 base::Callback<void(const GURL& content_url)>;
35 44
36 ArcDocumentsProviderRoot(const std::string& authority, 45 ArcDocumentsProviderRoot(const std::string& authority,
37 const std::string& root_document_id); 46 const std::string& root_document_id);
38 ~ArcDocumentsProviderRoot(); 47 ~ArcDocumentsProviderRoot() override;
39 48
40 // Queries information of a file just like AsyncFileUtil.GetFileInfo(). 49 // Queries information of a file just like AsyncFileUtil.GetFileInfo().
41 void GetFileInfo(const base::FilePath& path, 50 void GetFileInfo(const base::FilePath& path,
42 const GetFileInfoCallback& callback); 51 const GetFileInfoCallback& callback);
43 52
44 // Queries a list of files under a directory just like 53 // Queries a list of files under a directory just like
45 // AsyncFileUtil.ReadDirectory(). 54 // AsyncFileUtil.ReadDirectory().
46 void ReadDirectory(const base::FilePath& path, 55 void ReadDirectory(const base::FilePath& path,
47 const ReadDirectoryCallback& callback); 56 const ReadDirectoryCallback& callback);
48 57
58 // Installs a document watcher.
59 //
60 // It is not allowed to install multiple watchers at the same file path;
61 // if attempted, duplicated requests will fail.
62 //
63 // Currently, watchers can be installed only on directories, and only
64 // directory content changes are notified. The result of installing a watcher
65 // to a non-directory in unspecified.
66 //
67 // NOTES ABOUT CORRECTNESS AND CONSISTENCY:
68 //
69 // Document watchers are not always correct and they may miss some updates or
70 // even notify incorrect update events for several reasons, such as:
71 //
72 // - Directory moves: Currently a watcher will misbehave if the watched
73 // directory is moved to another location. This is acceptable for now
74 // since we whitelist MediaDocumentsProvider only.
75 // - Duplicated file name handling in this class: The same reason as
76 // directory moves. This may happen even with MediaDocumentsProvider,
77 // but the chance will not be very high.
78 // - File system operation races: For example, an watcher can be installed
79 // to a non-directory in a race condition.
80 // - Broken DocumentsProviders: For example, we get no notification if a
81 // document provider does not call setNotificationUri().
82 //
83 // However, consistency of installed watchers is guaranteed. That is, after
84 // a watcher is installed on a file path X, an attempt to uninstall a watcher
85 // at X will always succeed.
86 //
87 // Unfortunately it is too difficult (or maybe theoretically impossible) to
88 // implement a perfect Android document watcher which never misses document
89 // updates. So the current implementation gives up correctness, but instead
90 // focuses on following two goals:
91 //
92 // 1. Keep the implementation simple, rather than trying hard to catch
93 // race conditions or minor cases. Even if we return wrong results, the
94 // worst consequence is just that users do not see the latest contents
95 // until they refresh UI.
96 //
97 // 2. Keep consistency of installed watchers so that the caller can avoid
98 // dangling watchers.
99 void AddWatcher(const base::FilePath& path,
100 const WatcherCallback& watcher_callback,
101 const StatusCallback& callback);
102
103 // Uninstalls a document watcher.
104 // See the documentation of AddWatcher() above.
105 void RemoveWatcher(const base::FilePath& path,
106 const StatusCallback& callback);
107
49 // Resolves a file path into a content:// URL pointing to the file 108 // Resolves a file path into a content:// URL pointing to the file
50 // on DocumentsProvider. Returns URL that can be passed to 109 // on DocumentsProvider. Returns URL that can be passed to
51 // ArcContentFileSystemFileSystemReader to read the content. 110 // ArcContentFileSystemFileSystemReader to read the content.
52 // On errors, an invalid GURL is returned. 111 // On errors, an invalid GURL is returned.
53 void ResolveToContentUrl(const base::FilePath& path, 112 void ResolveToContentUrl(const base::FilePath& path,
54 const ResolveToContentUrlCallback& callback); 113 const ResolveToContentUrlCallback& callback);
55 114
115 // ArcFileSystemOperationRunner::Observer overrides:
116 void OnWatchersCleared() override;
117
56 private: 118 private:
57 // Thin representation of a document in documents provider. 119 // Thin representation of a document in documents provider.
58 struct ThinDocument { 120 struct ThinDocument {
59 std::string document_id; 121 std::string document_id;
60 bool is_directory; 122 bool is_directory;
61 }; 123 };
62 124
63 // Mapping from a file name to a ThinDocument. 125 // Mapping from a file name to a ThinDocument.
64 using NameToThinDocumentMap = 126 using NameToThinDocumentMap =
65 std::map<base::FilePath::StringType, ThinDocument>; 127 std::map<base::FilePath::StringType, ThinDocument>;
66 128
67 using ResolveToDocumentIdCallback = 129 using ResolveToDocumentIdCallback =
68 base::Callback<void(const std::string& document_id)>; 130 base::Callback<void(const std::string& document_id)>;
69 using ReadDirectoryInternalCallback = 131 using ReadDirectoryInternalCallback =
70 base::Callback<void(base::File::Error error, 132 base::Callback<void(base::File::Error error,
71 NameToThinDocumentMap mapping)>; 133 NameToThinDocumentMap mapping)>;
72 134
73 void GetFileInfoWithDocumentId(const GetFileInfoCallback& callback, 135 void GetFileInfoWithDocumentId(const GetFileInfoCallback& callback,
74 const std::string& document_id); 136 const std::string& document_id);
75 void GetFileInfoWithDocument(const GetFileInfoCallback& callback, 137 void GetFileInfoWithDocument(const GetFileInfoCallback& callback,
76 mojom::DocumentPtr document); 138 mojom::DocumentPtr document);
77 139
78 void ReadDirectoryWithDocumentId(const ReadDirectoryCallback& callback, 140 void ReadDirectoryWithDocumentId(const ReadDirectoryCallback& callback,
79 const std::string& document_id); 141 const std::string& document_id);
80 void ReadDirectoryWithNameToThinDocumentMap( 142 void ReadDirectoryWithNameToThinDocumentMap(
81 const ReadDirectoryCallback& callback, 143 const ReadDirectoryCallback& callback,
82 base::File::Error error, 144 base::File::Error error,
83 NameToThinDocumentMap mapping); 145 NameToThinDocumentMap mapping);
84 146
147 void AddWatcherWithDocumentId(const base::FilePath& path,
148 const WatcherCallback& watcher_callback,
149 const StatusCallback& callback,
150 const std::string& document_id);
151 void OnWatcherAdded(const base::FilePath& path,
152 const StatusCallback& callback,
153 int64_t watcher_id);
154 void OnWatcherAddedButRemoved(const StatusCallback& callback, bool success);
155
156 void OnWatcherRemoved(const StatusCallback& callback, bool success);
157
85 void ResolveToContentUrlWithDocumentId( 158 void ResolveToContentUrlWithDocumentId(
86 const ResolveToContentUrlCallback& callback, 159 const ResolveToContentUrlCallback& callback,
87 const std::string& document_id); 160 const std::string& document_id);
88 161
89 // Resolves |path| to a document ID. Failures are indicated by an empty 162 // Resolves |path| to a document ID. Failures are indicated by an empty
90 // document ID. 163 // document ID.
91 void ResolveToDocumentId(const base::FilePath& path, 164 void ResolveToDocumentId(const base::FilePath& path,
92 const ResolveToDocumentIdCallback& callback); 165 const ResolveToDocumentIdCallback& callback);
93 void ResolveToDocumentIdRecursively( 166 void ResolveToDocumentIdRecursively(
94 const std::string& document_id, 167 const std::string& document_id,
95 const std::vector<base::FilePath::StringType>& components, 168 const std::vector<base::FilePath::StringType>& components,
96 const ResolveToDocumentIdCallback& callback); 169 const ResolveToDocumentIdCallback& callback);
97 void ResolveToDocumentIdRecursivelyWithNameToThinDocumentMap( 170 void ResolveToDocumentIdRecursivelyWithNameToThinDocumentMap(
98 const std::vector<base::FilePath::StringType>& components, 171 const std::vector<base::FilePath::StringType>& components,
99 const ResolveToDocumentIdCallback& callback, 172 const ResolveToDocumentIdCallback& callback,
100 base::File::Error error, 173 base::File::Error error,
101 NameToThinDocumentMap mapping); 174 NameToThinDocumentMap mapping);
102 175
103 // Enumerates child documents of a directory specified by |document_id|. 176 // Enumerates child documents of a directory specified by |document_id|.
104 // The result is returned as a NameToThinDocumentMap. 177 // The result is returned as a NameToThinDocumentMap.
105 void ReadDirectoryInternal(const std::string& document_id, 178 void ReadDirectoryInternal(const std::string& document_id,
106 const ReadDirectoryInternalCallback& callback); 179 const ReadDirectoryInternalCallback& callback);
107 void ReadDirectoryInternalWithChildDocuments( 180 void ReadDirectoryInternalWithChildDocuments(
108 const ReadDirectoryInternalCallback& callback, 181 const ReadDirectoryInternalCallback& callback,
109 base::Optional<std::vector<mojom::DocumentPtr>> maybe_children); 182 base::Optional<std::vector<mojom::DocumentPtr>> maybe_children);
110 183
111 const std::string authority_; 184 const std::string authority_;
112 const std::string root_document_id_; 185 const std::string root_document_id_;
186
187 // Map from a file path to a watcher ID.
188 //
189 // A watcher can be "orphan" when watchers are cleared as notified by
190 // OnWatchersCleared() callback. Such watchers are still tracked here,
191 // but they are not known by the remote service, so they are represented
192 // by the invalid watcher ID (-1).
193 //
194 // Note that we do not use a document ID as a key here to guarantee that
195 // a watch installed by AddWatcher() can be always identified in
196 // RemoveWatcher() with the same file path specified.
197 // See the documentation of AddWatcher() for more details.
198 std::map<base::FilePath, int64_t> path_to_watcher_id_;
199
200 // Can be null if this instance is not observing ArcFileSystemOperationRunner.
201 // Observation is started on the first call of AddWatcher().
202 scoped_refptr<file_system_operation_runner_util::ObserverIOThreadWrapper>
203 observer_wrapper_;
204
113 base::WeakPtrFactory<ArcDocumentsProviderRoot> weak_ptr_factory_; 205 base::WeakPtrFactory<ArcDocumentsProviderRoot> weak_ptr_factory_;
114 206
115 DISALLOW_COPY_AND_ASSIGN(ArcDocumentsProviderRoot); 207 DISALLOW_COPY_AND_ASSIGN(ArcDocumentsProviderRoot);
116 }; 208 };
117 209
118 } // namespace arc 210 } // namespace arc
119 211
120 #endif // CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_H_ 212 #endif // CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_DOCUMENTS_PROVIDER_ROOT_H_
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698