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

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

Issue 2726373002: mediaview: Hack to avoid Files app to freeze soon after login. (Closed)
Patch Set: Remove unnecessary branch. 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"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 extension) == possible_extensions.end()) { 58 extension) == possible_extensions.end()) {
59 filename = 59 filename =
60 base::FilePath(filename).AddExtension(possible_extensions[0]).value(); 60 base::FilePath(filename).AddExtension(possible_extensions[0]).value();
61 } 61 }
62 62
63 return filename; 63 return filename;
64 } 64 }
65 65
66 } // namespace 66 } // namespace
67 67
68 // static
69 const int64_t ArcDocumentsProviderRoot::kInvalidWatcherId = -1;
70 // static
71 const uint64_t ArcDocumentsProviderRoot::kInvalidWatcherRequestId = 0;
72 // static
73 const ArcDocumentsProviderRoot::WatcherData
74 ArcDocumentsProviderRoot::kInvalidWatcherData = {kInvalidWatcherId,
75 kInvalidWatcherRequestId};
76
68 ArcDocumentsProviderRoot::ArcDocumentsProviderRoot( 77 ArcDocumentsProviderRoot::ArcDocumentsProviderRoot(
69 const std::string& authority, 78 const std::string& authority,
70 const std::string& root_document_id) 79 const std::string& root_document_id)
71 : authority_(authority), 80 : authority_(authority),
72 root_document_id_(root_document_id), 81 root_document_id_(root_document_id),
73 weak_ptr_factory_(this) {} 82 weak_ptr_factory_(this) {}
74 83
75 ArcDocumentsProviderRoot::~ArcDocumentsProviderRoot() { 84 ArcDocumentsProviderRoot::~ArcDocumentsProviderRoot() {
76 DCHECK_CURRENTLY_ON(BrowserThread::IO); 85 DCHECK_CURRENTLY_ON(BrowserThread::IO);
77 if (observer_wrapper_) 86 if (observer_wrapper_)
(...skipping 17 matching lines...) Expand all
95 ResolveToDocumentId( 104 ResolveToDocumentId(
96 path, base::Bind(&ArcDocumentsProviderRoot::ReadDirectoryWithDocumentId, 105 path, base::Bind(&ArcDocumentsProviderRoot::ReadDirectoryWithDocumentId,
97 weak_ptr_factory_.GetWeakPtr(), callback)); 106 weak_ptr_factory_.GetWeakPtr(), callback));
98 } 107 }
99 108
100 void ArcDocumentsProviderRoot::AddWatcher( 109 void ArcDocumentsProviderRoot::AddWatcher(
101 const base::FilePath& path, 110 const base::FilePath& path,
102 const WatcherCallback& watcher_callback, 111 const WatcherCallback& watcher_callback,
103 const StatusCallback& callback) { 112 const StatusCallback& callback) {
104 DCHECK_CURRENTLY_ON(BrowserThread::IO); 113 DCHECK_CURRENTLY_ON(BrowserThread::IO);
105 if (path_to_watcher_id_.count(path)) { 114 if (path_to_watcher_data_.count(path)) {
106 callback.Run(base::File::FILE_ERROR_FAILED); 115 callback.Run(base::File::FILE_ERROR_FAILED);
107 return; 116 return;
108 } 117 }
118 uint64_t watcher_request_id = next_watcher_request_id_++;
119 path_to_watcher_data_.insert(
120 std::make_pair(path, WatcherData{kInvalidWatcherId, watcher_request_id}));
109 ResolveToDocumentId( 121 ResolveToDocumentId(
110 path, 122 path, base::Bind(&ArcDocumentsProviderRoot::AddWatcherWithDocumentId,
111 base::Bind(&ArcDocumentsProviderRoot::AddWatcherWithDocumentId, 123 weak_ptr_factory_.GetWeakPtr(), path, watcher_request_id,
112 weak_ptr_factory_.GetWeakPtr(), path, watcher_callback, 124 watcher_callback));
113 callback)); 125
126 // HACK: Invoke |callback| immediately.
127 //
128 // TODO(crbug.com/698624): Remove this hack. It was introduced because Files
129 // app freezes until AddWatcher() finishes, but it should be handled in Files
130 // app rather than here.
131 callback.Run(base::File::FILE_OK);
114 } 132 }
115 133
116 void ArcDocumentsProviderRoot::RemoveWatcher(const base::FilePath& path, 134 void ArcDocumentsProviderRoot::RemoveWatcher(const base::FilePath& path,
117 const StatusCallback& callback) { 135 const StatusCallback& callback) {
118 DCHECK_CURRENTLY_ON(BrowserThread::IO); 136 DCHECK_CURRENTLY_ON(BrowserThread::IO);
119 auto iter = path_to_watcher_id_.find(path); 137 auto iter = path_to_watcher_data_.find(path);
120 if (iter == path_to_watcher_id_.end()) { 138 if (iter == path_to_watcher_data_.end()) {
121 callback.Run(base::File::FILE_ERROR_FAILED); 139 callback.Run(base::File::FILE_ERROR_FAILED);
122 return; 140 return;
123 } 141 }
124 int64_t watcher_id = iter->second; 142 int64_t watcher_id = iter->second.id;
125 path_to_watcher_id_.erase(iter); 143 path_to_watcher_data_.erase(iter);
126 if (watcher_id < 0) { 144 if (watcher_id == kInvalidWatcherId) {
127 // This is an orphan watcher. Just remove an entry from 145 // This is an invalid watcher. No need to send a request to the remote
128 // |path_to_watcher_id_| and return success. 146 // service.
129 callback.Run(base::File::FILE_OK); 147 callback.Run(base::File::FILE_OK);
130 return; 148 return;
131 } 149 }
132 file_system_operation_runner_util::RemoveWatcherOnIOThread( 150 file_system_operation_runner_util::RemoveWatcherOnIOThread(
133 watcher_id, 151 watcher_id,
134 base::Bind(&ArcDocumentsProviderRoot::OnWatcherRemoved, 152 base::Bind(&ArcDocumentsProviderRoot::OnWatcherRemoved,
135 weak_ptr_factory_.GetWeakPtr(), callback)); 153 weak_ptr_factory_.GetWeakPtr(), callback));
136 } 154 }
137 155
138 void ArcDocumentsProviderRoot::ResolveToContentUrl( 156 void ArcDocumentsProviderRoot::ResolveToContentUrl(
139 const base::FilePath& path, 157 const base::FilePath& path,
140 const ResolveToContentUrlCallback& callback) { 158 const ResolveToContentUrlCallback& callback) {
141 DCHECK_CURRENTLY_ON(BrowserThread::IO); 159 DCHECK_CURRENTLY_ON(BrowserThread::IO);
142 ResolveToDocumentId( 160 ResolveToDocumentId(
143 path, 161 path,
144 base::Bind(&ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId, 162 base::Bind(&ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId,
145 weak_ptr_factory_.GetWeakPtr(), callback)); 163 weak_ptr_factory_.GetWeakPtr(), callback));
146 } 164 }
147 165
148 void ArcDocumentsProviderRoot::OnWatchersCleared() { 166 void ArcDocumentsProviderRoot::OnWatchersCleared() {
149 DCHECK_CURRENTLY_ON(BrowserThread::IO); 167 DCHECK_CURRENTLY_ON(BrowserThread::IO);
150 // Mark all watchers orphan. 168 // Mark all watchers invalid.
151 for (auto& entry : path_to_watcher_id_) 169 for (auto& entry : path_to_watcher_data_)
152 entry.second = -1; 170 entry.second = kInvalidWatcherData;
153 } 171 }
154 172
155 void ArcDocumentsProviderRoot::GetFileInfoWithDocumentId( 173 void ArcDocumentsProviderRoot::GetFileInfoWithDocumentId(
156 const GetFileInfoCallback& callback, 174 const GetFileInfoCallback& callback,
157 const std::string& document_id) { 175 const std::string& document_id) {
158 DCHECK_CURRENTLY_ON(BrowserThread::IO); 176 DCHECK_CURRENTLY_ON(BrowserThread::IO);
159 if (document_id.empty()) { 177 if (document_id.empty()) {
160 callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info()); 178 callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info());
161 return; 179 return;
162 } 180 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 for (const auto& pair : mapping) { 243 for (const auto& pair : mapping) {
226 entry_list.emplace_back(pair.first, pair.second.is_directory 244 entry_list.emplace_back(pair.first, pair.second.is_directory
227 ? storage::DirectoryEntry::DIRECTORY 245 ? storage::DirectoryEntry::DIRECTORY
228 : storage::DirectoryEntry::FILE); 246 : storage::DirectoryEntry::FILE);
229 } 247 }
230 callback.Run(base::File::FILE_OK, entry_list, false /* has_more */); 248 callback.Run(base::File::FILE_OK, entry_list, false /* has_more */);
231 } 249 }
232 250
233 void ArcDocumentsProviderRoot::AddWatcherWithDocumentId( 251 void ArcDocumentsProviderRoot::AddWatcherWithDocumentId(
234 const base::FilePath& path, 252 const base::FilePath& path,
253 uint64_t watcher_request_id,
235 const WatcherCallback& watcher_callback, 254 const WatcherCallback& watcher_callback,
236 const StatusCallback& callback,
237 const std::string& document_id) { 255 const std::string& document_id) {
238 DCHECK_CURRENTLY_ON(BrowserThread::IO); 256 DCHECK_CURRENTLY_ON(BrowserThread::IO);
257
258 if (IsWatcherInflightRequestCanceled(path, watcher_request_id))
259 return;
260
239 if (document_id.empty()) { 261 if (document_id.empty()) {
240 callback.Run(base::File::FILE_ERROR_NOT_FOUND); 262 DCHECK(path_to_watcher_data_.count(path));
263 path_to_watcher_data_[path] = kInvalidWatcherData;
241 return; 264 return;
242 } 265 }
266
243 // Start observing ArcFileSystemOperationRunner if we have not. 267 // Start observing ArcFileSystemOperationRunner if we have not.
244 if (!observer_wrapper_) { 268 if (!observer_wrapper_) {
245 observer_wrapper_ = 269 observer_wrapper_ =
246 new file_system_operation_runner_util::ObserverIOThreadWrapper(this); 270 new file_system_operation_runner_util::ObserverIOThreadWrapper(this);
247 file_system_operation_runner_util::AddObserverOnIOThread(observer_wrapper_); 271 file_system_operation_runner_util::AddObserverOnIOThread(observer_wrapper_);
248 } 272 }
273
249 file_system_operation_runner_util::AddWatcherOnIOThread( 274 file_system_operation_runner_util::AddWatcherOnIOThread(
250 authority_, document_id, watcher_callback, 275 authority_, document_id, watcher_callback,
251 base::Bind(&ArcDocumentsProviderRoot::OnWatcherAdded, 276 base::Bind(&ArcDocumentsProviderRoot::OnWatcherAdded,
252 weak_ptr_factory_.GetWeakPtr(), path, callback)); 277 weak_ptr_factory_.GetWeakPtr(), path, watcher_request_id));
253 } 278 }
254 279
255 void ArcDocumentsProviderRoot::OnWatcherAdded(const base::FilePath& path, 280 void ArcDocumentsProviderRoot::OnWatcherAdded(const base::FilePath& path,
256 const StatusCallback& callback, 281 uint64_t watcher_request_id,
257 int64_t watcher_id) { 282 int64_t watcher_id) {
258 DCHECK_CURRENTLY_ON(BrowserThread::IO); 283 DCHECK_CURRENTLY_ON(BrowserThread::IO);
259 if (watcher_id < 0) { 284
260 callback.Run(base::File::FILE_ERROR_FAILED); 285 if (IsWatcherInflightRequestCanceled(path, watcher_request_id)) {
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( 286 file_system_operation_runner_util::RemoveWatcherOnIOThread(
267 watcher_id, 287 watcher_id,
268 base::Bind(&ArcDocumentsProviderRoot::OnWatcherAddedButRemoved, 288 base::Bind(&ArcDocumentsProviderRoot::OnWatcherAddedButRemoved,
269 weak_ptr_factory_.GetWeakPtr(), callback)); 289 weak_ptr_factory_.GetWeakPtr()));
270 return; 290 return;
271 } 291 }
272 path_to_watcher_id_.insert(std::make_pair(path, watcher_id)); 292
273 callback.Run(base::File::FILE_OK); 293 DCHECK(path_to_watcher_data_.count(path));
294 path_to_watcher_data_[path] =
295 WatcherData{watcher_id < 0 ? kInvalidWatcherId : watcher_id,
296 kInvalidWatcherRequestId};
274 } 297 }
275 298
276 void ArcDocumentsProviderRoot::OnWatcherAddedButRemoved( 299 void ArcDocumentsProviderRoot::OnWatcherAddedButRemoved(bool success) {
277 const StatusCallback& callback,
278 bool success) {
279 DCHECK_CURRENTLY_ON(BrowserThread::IO); 300 DCHECK_CURRENTLY_ON(BrowserThread::IO);
280 callback.Run(base::File::FILE_ERROR_FAILED); 301 // Ignore |success|.
281 } 302 }
282 303
283 void ArcDocumentsProviderRoot::OnWatcherRemoved(const StatusCallback& callback, 304 void ArcDocumentsProviderRoot::OnWatcherRemoved(const StatusCallback& callback,
284 bool success) { 305 bool success) {
285 DCHECK_CURRENTLY_ON(BrowserThread::IO); 306 DCHECK_CURRENTLY_ON(BrowserThread::IO);
286 callback.Run(success ? base::File::FILE_OK : base::File::FILE_ERROR_FAILED); 307 callback.Run(success ? base::File::FILE_OK : base::File::FILE_ERROR_FAILED);
287 } 308 }
288 309
310 bool ArcDocumentsProviderRoot::IsWatcherInflightRequestCanceled(
311 const base::FilePath& path,
312 uint64_t watcher_request_id) const {
313 auto iter = path_to_watcher_data_.find(path);
314 return (iter == path_to_watcher_data_.end() ||
315 iter->second.inflight_request_id != watcher_request_id);
316 }
317
289 void ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId( 318 void ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId(
290 const ResolveToContentUrlCallback& callback, 319 const ResolveToContentUrlCallback& callback,
291 const std::string& document_id) { 320 const std::string& document_id) {
292 DCHECK_CURRENTLY_ON(BrowserThread::IO); 321 DCHECK_CURRENTLY_ON(BrowserThread::IO);
293 if (document_id.empty()) { 322 if (document_id.empty()) {
294 callback.Run(GURL()); 323 callback.Run(GURL());
295 return; 324 return;
296 } 325 }
297 callback.Run(BuildDocumentUrl(authority_, document_id)); 326 callback.Run(BuildDocumentUrl(authority_, document_id));
298 } 327 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 424
396 mapping[filename] = 425 mapping[filename] =
397 ThinDocument{document->document_id, 426 ThinDocument{document->document_id,
398 document->mime_type == kAndroidDirectoryMimeType}; 427 document->mime_type == kAndroidDirectoryMimeType};
399 } 428 }
400 429
401 callback.Run(base::File::FILE_OK, std::move(mapping)); 430 callback.Run(base::File::FILE_OK, std::move(mapping));
402 } 431 }
403 432
404 } // namespace arc 433 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698