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

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

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
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 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h" 5 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/files/file.h" 12 #include "base/files/file.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h" 18 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h"
19 #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_u til.h"
20 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
21 #include "url/gurl.h" 20 #include "url/gurl.h"
22 21
23 using content::BrowserThread; 22 using content::BrowserThread;
24 using EntryList = storage::AsyncFileUtil::EntryList; 23 using EntryList = storage::AsyncFileUtil::EntryList;
25 24
26 namespace arc { 25 namespace arc {
27 26
28 namespace { 27 namespace {
29 28
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 67
69 ArcDocumentsProviderRoot::ArcDocumentsProviderRoot( 68 ArcDocumentsProviderRoot::ArcDocumentsProviderRoot(
70 const std::string& authority, 69 const std::string& authority,
71 const std::string& root_document_id) 70 const std::string& root_document_id)
72 : authority_(authority), 71 : authority_(authority),
73 root_document_id_(root_document_id), 72 root_document_id_(root_document_id),
74 weak_ptr_factory_(this) {} 73 weak_ptr_factory_(this) {}
75 74
76 ArcDocumentsProviderRoot::~ArcDocumentsProviderRoot() { 75 ArcDocumentsProviderRoot::~ArcDocumentsProviderRoot() {
77 DCHECK_CURRENTLY_ON(BrowserThread::IO); 76 DCHECK_CURRENTLY_ON(BrowserThread::IO);
77 if (observer_wrapper_)
78 file_system_operation_runner_util::RemoveObserverOnIOThread(
79 std::move(observer_wrapper_));
78 } 80 }
79 81
80 void ArcDocumentsProviderRoot::GetFileInfo( 82 void ArcDocumentsProviderRoot::GetFileInfo(
81 const base::FilePath& path, 83 const base::FilePath& path,
82 const GetFileInfoCallback& callback) { 84 const GetFileInfoCallback& callback) {
83 DCHECK_CURRENTLY_ON(BrowserThread::IO); 85 DCHECK_CURRENTLY_ON(BrowserThread::IO);
84 ResolveToDocumentId( 86 ResolveToDocumentId(
85 path, base::Bind(&ArcDocumentsProviderRoot::GetFileInfoWithDocumentId, 87 path, base::Bind(&ArcDocumentsProviderRoot::GetFileInfoWithDocumentId,
86 weak_ptr_factory_.GetWeakPtr(), callback)); 88 weak_ptr_factory_.GetWeakPtr(), callback));
87 } 89 }
88 90
89 void ArcDocumentsProviderRoot::ReadDirectory( 91 void ArcDocumentsProviderRoot::ReadDirectory(
90 const base::FilePath& path, 92 const base::FilePath& path,
91 const ReadDirectoryCallback& callback) { 93 const ReadDirectoryCallback& callback) {
92 DCHECK_CURRENTLY_ON(BrowserThread::IO); 94 DCHECK_CURRENTLY_ON(BrowserThread::IO);
93 ResolveToDocumentId( 95 ResolveToDocumentId(
94 path, base::Bind(&ArcDocumentsProviderRoot::ReadDirectoryWithDocumentId, 96 path, base::Bind(&ArcDocumentsProviderRoot::ReadDirectoryWithDocumentId,
95 weak_ptr_factory_.GetWeakPtr(), callback)); 97 weak_ptr_factory_.GetWeakPtr(), callback));
96 } 98 }
97 99
100 void ArcDocumentsProviderRoot::AddWatcher(
101 const base::FilePath& path,
102 const WatcherCallback& watcher_callback,
103 const StatusCallback& callback) {
104 DCHECK_CURRENTLY_ON(BrowserThread::IO);
105 if (path_to_watcher_id_.count(path)) {
106 callback.Run(base::File::FILE_ERROR_FAILED);
107 return;
108 }
109 ResolveToDocumentId(
110 path,
111 base::Bind(&ArcDocumentsProviderRoot::AddWatcherWithDocumentId,
112 weak_ptr_factory_.GetWeakPtr(), path, watcher_callback,
113 callback));
114 }
115
116 void ArcDocumentsProviderRoot::RemoveWatcher(const base::FilePath& path,
117 const StatusCallback& callback) {
118 DCHECK_CURRENTLY_ON(BrowserThread::IO);
119 auto iter = path_to_watcher_id_.find(path);
120 if (iter == path_to_watcher_id_.end()) {
121 callback.Run(base::File::FILE_ERROR_FAILED);
122 return;
123 }
124 int64_t watcher_id = iter->second;
125 path_to_watcher_id_.erase(iter);
126 if (watcher_id < 0) {
127 // This is an orphan watcher. Just remove an entry from
128 // |path_to_watcher_id_| and return success.
129 callback.Run(base::File::FILE_OK);
130 return;
131 }
132 file_system_operation_runner_util::RemoveWatcherOnIOThread(
133 watcher_id,
134 base::Bind(&ArcDocumentsProviderRoot::OnWatcherRemoved,
135 weak_ptr_factory_.GetWeakPtr(), callback));
136 }
137
98 void ArcDocumentsProviderRoot::ResolveToContentUrl( 138 void ArcDocumentsProviderRoot::ResolveToContentUrl(
99 const base::FilePath& path, 139 const base::FilePath& path,
100 const ResolveToContentUrlCallback& callback) { 140 const ResolveToContentUrlCallback& callback) {
101 DCHECK_CURRENTLY_ON(BrowserThread::IO); 141 DCHECK_CURRENTLY_ON(BrowserThread::IO);
102 ResolveToDocumentId( 142 ResolveToDocumentId(
103 path, 143 path,
104 base::Bind(&ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId, 144 base::Bind(&ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId,
105 weak_ptr_factory_.GetWeakPtr(), callback)); 145 weak_ptr_factory_.GetWeakPtr(), callback));
106 } 146 }
107 147
148 void ArcDocumentsProviderRoot::OnWatchersCleared() {
149 DCHECK_CURRENTLY_ON(BrowserThread::IO);
150 // Mark all watchers orphan.
151 for (auto& entry : path_to_watcher_id_)
152 entry.second = -1;
153 }
154
108 void ArcDocumentsProviderRoot::GetFileInfoWithDocumentId( 155 void ArcDocumentsProviderRoot::GetFileInfoWithDocumentId(
109 const GetFileInfoCallback& callback, 156 const GetFileInfoCallback& callback,
110 const std::string& document_id) { 157 const std::string& document_id) {
158 DCHECK_CURRENTLY_ON(BrowserThread::IO);
111 if (document_id.empty()) { 159 if (document_id.empty()) {
112 callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info()); 160 callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info());
113 return; 161 return;
114 } 162 }
115 // Specially handle the root directory since Files app does not update the 163 // Specially handle the root directory since Files app does not update the
116 // list of file systems (left pane) until all volumes respond to GetMetadata 164 // list of file systems (left pane) until all volumes respond to GetMetadata
117 // requests to root directories. 165 // requests to root directories.
118 if (document_id == root_document_id_) { 166 if (document_id == root_document_id_) {
119 base::File::Info info; 167 base::File::Info info;
120 info.size = -1; 168 info.size = -1;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 } 223 }
176 EntryList entry_list; 224 EntryList entry_list;
177 for (const auto& pair : mapping) { 225 for (const auto& pair : mapping) {
178 entry_list.emplace_back(pair.first, pair.second.is_directory 226 entry_list.emplace_back(pair.first, pair.second.is_directory
179 ? storage::DirectoryEntry::DIRECTORY 227 ? storage::DirectoryEntry::DIRECTORY
180 : storage::DirectoryEntry::FILE); 228 : storage::DirectoryEntry::FILE);
181 } 229 }
182 callback.Run(base::File::FILE_OK, entry_list, false /* has_more */); 230 callback.Run(base::File::FILE_OK, entry_list, false /* has_more */);
183 } 231 }
184 232
233 void ArcDocumentsProviderRoot::AddWatcherWithDocumentId(
234 const base::FilePath& path,
235 const WatcherCallback& watcher_callback,
236 const StatusCallback& callback,
237 const std::string& document_id) {
238 DCHECK_CURRENTLY_ON(BrowserThread::IO);
239 if (document_id.empty()) {
240 callback.Run(base::File::FILE_ERROR_NOT_FOUND);
241 return;
242 }
243 // Start observing ArcFileSystemOperationRunner if we have not.
244 if (!observer_wrapper_) {
245 observer_wrapper_ =
246 new file_system_operation_runner_util::ObserverIOThreadWrapper(this);
247 file_system_operation_runner_util::AddObserverOnIOThread(observer_wrapper_);
248 }
249 file_system_operation_runner_util::AddWatcherOnIOThread(
250 authority_, document_id, watcher_callback,
251 base::Bind(&ArcDocumentsProviderRoot::OnWatcherAdded,
252 weak_ptr_factory_.GetWeakPtr(), path, callback));
253 }
254
255 void ArcDocumentsProviderRoot::OnWatcherAdded(const base::FilePath& path,
256 const StatusCallback& callback,
257 int64_t watcher_id) {
258 DCHECK_CURRENTLY_ON(BrowserThread::IO);
259 if (watcher_id < 0) {
260 callback.Run(base::File::FILE_ERROR_FAILED);
261 return;
262 }
263 if (path_to_watcher_id_.count(path)) {
264 // Multiple watchers have been installed on the same file path in a race.
265 // Following the contract of WatcherManager, we reject all except the first.
266 file_system_operation_runner_util::RemoveWatcherOnIOThread(
267 watcher_id,
268 base::Bind(&ArcDocumentsProviderRoot::OnWatcherAddedButRemoved,
269 weak_ptr_factory_.GetWeakPtr(), callback));
270 return;
271 }
272 path_to_watcher_id_.insert(std::make_pair(path, watcher_id));
273 callback.Run(base::File::FILE_OK);
274 }
275
276 void ArcDocumentsProviderRoot::OnWatcherAddedButRemoved(
277 const StatusCallback& callback,
278 bool success) {
279 DCHECK_CURRENTLY_ON(BrowserThread::IO);
280 callback.Run(base::File::FILE_ERROR_FAILED);
281 }
282
283 void ArcDocumentsProviderRoot::OnWatcherRemoved(const StatusCallback& callback,
284 bool success) {
285 DCHECK_CURRENTLY_ON(BrowserThread::IO);
286 callback.Run(success ? base::File::FILE_OK : base::File::FILE_ERROR_FAILED);
287 }
288
185 void ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId( 289 void ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId(
186 const ResolveToContentUrlCallback& callback, 290 const ResolveToContentUrlCallback& callback,
187 const std::string& document_id) { 291 const std::string& document_id) {
188 DCHECK_CURRENTLY_ON(BrowserThread::IO); 292 DCHECK_CURRENTLY_ON(BrowserThread::IO);
189 if (document_id.empty()) { 293 if (document_id.empty()) {
190 callback.Run(GURL()); 294 callback.Run(GURL());
191 return; 295 return;
192 } 296 }
193 callback.Run(BuildDocumentUrl(authority_, document_id)); 297 callback.Run(BuildDocumentUrl(authority_, document_id));
194 } 298 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 395
292 mapping[filename] = 396 mapping[filename] =
293 ThinDocument{document->document_id, 397 ThinDocument{document->document_id,
294 document->mime_type == kAndroidDirectoryMimeType}; 398 document->mime_type == kAndroidDirectoryMimeType};
295 } 399 }
296 400
297 callback.Run(base::File::FILE_OK, std::move(mapping)); 401 callback.Run(base::File::FILE_OK, std::move(mapping));
298 } 402 }
299 403
300 } // namespace arc 404 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698