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

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: Addressed hidehiko's comments. 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 if (iter->second.inflight_request_id != kInvalidWatcherRequestId) {
hidehiko 2017/03/14 16:56:13 I do not think you need individual condition here.
Shuhei Takahashi 2017/03/14 18:36:50 I agree.
125 path_to_watcher_id_.erase(iter); 143 // There is an in-flight request. Remove the entry to cancel it.
126 if (watcher_id < 0) { 144 path_to_watcher_data_.erase(iter);
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); 145 callback.Run(base::File::FILE_OK);
130 return; 146 return;
131 } 147 }
148 int64_t watcher_id = iter->second.id;
149 path_to_watcher_data_.erase(iter);
150 if (watcher_id == kInvalidWatcherId) {
151 // This is an invalid watcher. No need to send a request to the remote
152 // service.
153 callback.Run(base::File::FILE_OK);
154 return;
155 }
132 file_system_operation_runner_util::RemoveWatcherOnIOThread( 156 file_system_operation_runner_util::RemoveWatcherOnIOThread(
133 watcher_id, 157 watcher_id,
134 base::Bind(&ArcDocumentsProviderRoot::OnWatcherRemoved, 158 base::Bind(&ArcDocumentsProviderRoot::OnWatcherRemoved,
135 weak_ptr_factory_.GetWeakPtr(), callback)); 159 weak_ptr_factory_.GetWeakPtr(), callback));
136 } 160 }
137 161
138 void ArcDocumentsProviderRoot::ResolveToContentUrl( 162 void ArcDocumentsProviderRoot::ResolveToContentUrl(
139 const base::FilePath& path, 163 const base::FilePath& path,
140 const ResolveToContentUrlCallback& callback) { 164 const ResolveToContentUrlCallback& callback) {
141 DCHECK_CURRENTLY_ON(BrowserThread::IO); 165 DCHECK_CURRENTLY_ON(BrowserThread::IO);
142 ResolveToDocumentId( 166 ResolveToDocumentId(
143 path, 167 path,
144 base::Bind(&ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId, 168 base::Bind(&ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId,
145 weak_ptr_factory_.GetWeakPtr(), callback)); 169 weak_ptr_factory_.GetWeakPtr(), callback));
146 } 170 }
147 171
148 void ArcDocumentsProviderRoot::OnWatchersCleared() { 172 void ArcDocumentsProviderRoot::OnWatchersCleared() {
149 DCHECK_CURRENTLY_ON(BrowserThread::IO); 173 DCHECK_CURRENTLY_ON(BrowserThread::IO);
150 // Mark all watchers orphan. 174 // Mark all watchers invalid.
151 for (auto& entry : path_to_watcher_id_) 175 for (auto& entry : path_to_watcher_data_)
152 entry.second = -1; 176 entry.second = kInvalidWatcherData;
153 } 177 }
154 178
155 void ArcDocumentsProviderRoot::GetFileInfoWithDocumentId( 179 void ArcDocumentsProviderRoot::GetFileInfoWithDocumentId(
156 const GetFileInfoCallback& callback, 180 const GetFileInfoCallback& callback,
157 const std::string& document_id) { 181 const std::string& document_id) {
158 DCHECK_CURRENTLY_ON(BrowserThread::IO); 182 DCHECK_CURRENTLY_ON(BrowserThread::IO);
159 if (document_id.empty()) { 183 if (document_id.empty()) {
160 callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info()); 184 callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info());
161 return; 185 return;
162 } 186 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 for (const auto& pair : mapping) { 249 for (const auto& pair : mapping) {
226 entry_list.emplace_back(pair.first, pair.second.is_directory 250 entry_list.emplace_back(pair.first, pair.second.is_directory
227 ? storage::DirectoryEntry::DIRECTORY 251 ? storage::DirectoryEntry::DIRECTORY
228 : storage::DirectoryEntry::FILE); 252 : storage::DirectoryEntry::FILE);
229 } 253 }
230 callback.Run(base::File::FILE_OK, entry_list, false /* has_more */); 254 callback.Run(base::File::FILE_OK, entry_list, false /* has_more */);
231 } 255 }
232 256
233 void ArcDocumentsProviderRoot::AddWatcherWithDocumentId( 257 void ArcDocumentsProviderRoot::AddWatcherWithDocumentId(
234 const base::FilePath& path, 258 const base::FilePath& path,
259 uint64_t watcher_request_id,
235 const WatcherCallback& watcher_callback, 260 const WatcherCallback& watcher_callback,
236 const StatusCallback& callback,
237 const std::string& document_id) { 261 const std::string& document_id) {
238 DCHECK_CURRENTLY_ON(BrowserThread::IO); 262 DCHECK_CURRENTLY_ON(BrowserThread::IO);
263
264 if (IsWatcherInflightRequestCanceled(path, watcher_request_id))
265 return;
266
239 if (document_id.empty()) { 267 if (document_id.empty()) {
240 callback.Run(base::File::FILE_ERROR_NOT_FOUND); 268 DCHECK(path_to_watcher_data_.count(path));
269 path_to_watcher_data_[path] = kInvalidWatcherData;
241 return; 270 return;
242 } 271 }
272
243 // Start observing ArcFileSystemOperationRunner if we have not. 273 // Start observing ArcFileSystemOperationRunner if we have not.
244 if (!observer_wrapper_) { 274 if (!observer_wrapper_) {
245 observer_wrapper_ = 275 observer_wrapper_ =
246 new file_system_operation_runner_util::ObserverIOThreadWrapper(this); 276 new file_system_operation_runner_util::ObserverIOThreadWrapper(this);
247 file_system_operation_runner_util::AddObserverOnIOThread(observer_wrapper_); 277 file_system_operation_runner_util::AddObserverOnIOThread(observer_wrapper_);
248 } 278 }
279
249 file_system_operation_runner_util::AddWatcherOnIOThread( 280 file_system_operation_runner_util::AddWatcherOnIOThread(
250 authority_, document_id, watcher_callback, 281 authority_, document_id, watcher_callback,
251 base::Bind(&ArcDocumentsProviderRoot::OnWatcherAdded, 282 base::Bind(&ArcDocumentsProviderRoot::OnWatcherAdded,
252 weak_ptr_factory_.GetWeakPtr(), path, callback)); 283 weak_ptr_factory_.GetWeakPtr(), path, watcher_request_id));
253 } 284 }
254 285
255 void ArcDocumentsProviderRoot::OnWatcherAdded(const base::FilePath& path, 286 void ArcDocumentsProviderRoot::OnWatcherAdded(const base::FilePath& path,
256 const StatusCallback& callback, 287 uint64_t watcher_request_id,
257 int64_t watcher_id) { 288 int64_t watcher_id) {
258 DCHECK_CURRENTLY_ON(BrowserThread::IO); 289 DCHECK_CURRENTLY_ON(BrowserThread::IO);
259 if (watcher_id < 0) { 290
260 callback.Run(base::File::FILE_ERROR_FAILED); 291 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( 292 file_system_operation_runner_util::RemoveWatcherOnIOThread(
267 watcher_id, 293 watcher_id,
268 base::Bind(&ArcDocumentsProviderRoot::OnWatcherAddedButRemoved, 294 base::Bind(&ArcDocumentsProviderRoot::OnWatcherAddedButRemoved,
269 weak_ptr_factory_.GetWeakPtr(), callback)); 295 weak_ptr_factory_.GetWeakPtr()));
270 return; 296 return;
271 } 297 }
272 path_to_watcher_id_.insert(std::make_pair(path, watcher_id)); 298
273 callback.Run(base::File::FILE_OK); 299 DCHECK(path_to_watcher_data_.count(path));
300 path_to_watcher_data_[path] =
301 WatcherData{watcher_id < 0 ? kInvalidWatcherId : watcher_id,
302 kInvalidWatcherRequestId};
274 } 303 }
275 304
276 void ArcDocumentsProviderRoot::OnWatcherAddedButRemoved( 305 void ArcDocumentsProviderRoot::OnWatcherAddedButRemoved(bool success) {
277 const StatusCallback& callback,
278 bool success) {
279 DCHECK_CURRENTLY_ON(BrowserThread::IO); 306 DCHECK_CURRENTLY_ON(BrowserThread::IO);
280 callback.Run(base::File::FILE_ERROR_FAILED); 307 // Ignore |success|.
281 } 308 }
282 309
283 void ArcDocumentsProviderRoot::OnWatcherRemoved(const StatusCallback& callback, 310 void ArcDocumentsProviderRoot::OnWatcherRemoved(const StatusCallback& callback,
284 bool success) { 311 bool success) {
285 DCHECK_CURRENTLY_ON(BrowserThread::IO); 312 DCHECK_CURRENTLY_ON(BrowserThread::IO);
286 callback.Run(success ? base::File::FILE_OK : base::File::FILE_ERROR_FAILED); 313 callback.Run(success ? base::File::FILE_OK : base::File::FILE_ERROR_FAILED);
287 } 314 }
288 315
316 bool ArcDocumentsProviderRoot::IsWatcherInflightRequestCanceled(
317 const base::FilePath& path,
318 uint64_t watcher_request_id) const {
319 auto iter = path_to_watcher_data_.find(path);
320 return (iter == path_to_watcher_data_.end() ||
321 iter->second.inflight_request_id != watcher_request_id);
322 }
323
289 void ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId( 324 void ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId(
290 const ResolveToContentUrlCallback& callback, 325 const ResolveToContentUrlCallback& callback,
291 const std::string& document_id) { 326 const std::string& document_id) {
292 DCHECK_CURRENTLY_ON(BrowserThread::IO); 327 DCHECK_CURRENTLY_ON(BrowserThread::IO);
293 if (document_id.empty()) { 328 if (document_id.empty()) {
294 callback.Run(GURL()); 329 callback.Run(GURL());
295 return; 330 return;
296 } 331 }
297 callback.Run(BuildDocumentUrl(authority_, document_id)); 332 callback.Run(BuildDocumentUrl(authority_, document_id));
298 } 333 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 430
396 mapping[filename] = 431 mapping[filename] =
397 ThinDocument{document->document_id, 432 ThinDocument{document->document_id,
398 document->mime_type == kAndroidDirectoryMimeType}; 433 document->mime_type == kAndroidDirectoryMimeType};
399 } 434 }
400 435
401 callback.Run(base::File::FILE_OK, std::move(mapping)); 436 callback.Run(base::File::FILE_OK, std::move(mapping));
402 } 437 }
403 438
404 } // namespace arc 439 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698