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

Unified 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: Assign ID to watcher requests. 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
index 6c8b936f1260af4f699518db8174efbc2b458cc8..6a65157662e298959d35312d7104c49e454c5527 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.cc
@@ -26,6 +26,15 @@ namespace arc {
namespace {
+// A special watcher ID indicating this watcher is orphaned.
+// Though we have an entry in ArcDocumentsProviderRoot, the remote
+// ArcFileSystemService does not have a corresponding watcher. This happens
+// when, for example, AddWatcher() is called for non-existent files or the
+// remote service crashes.
+// We use this value to allow RemoveWatcher() to succeed even after the remote
+// service forgets watchers.
+constexpr int64_t kOrphanWatcherId = -1;
+
// Computes a file name for a document.
// TODO(crbug.com/675868): Consolidate with the similar logic for Drive.
base::FilePath::StringType GetFileNameForDocument(
@@ -102,20 +111,35 @@ void ArcDocumentsProviderRoot::AddWatcher(
const WatcherCallback& watcher_callback,
const StatusCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (path_to_watcher_id_.count(path)) {
+ if (path_to_watcher_id_.count(path) ||
+ path_to_watcher_request_id_.count(path)) {
callback.Run(base::File::FILE_ERROR_FAILED);
return;
}
+ uint64_t watcher_request_id = next_watcher_request_id_++;
+ path_to_watcher_request_id_.insert(std::make_pair(path, watcher_request_id));
ResolveToDocumentId(
- path,
- base::Bind(&ArcDocumentsProviderRoot::AddWatcherWithDocumentId,
- weak_ptr_factory_.GetWeakPtr(), path, watcher_callback,
- callback));
+ path, base::Bind(&ArcDocumentsProviderRoot::AddWatcherWithDocumentId,
+ weak_ptr_factory_.GetWeakPtr(), path, watcher_request_id,
+ watcher_callback));
+
+ // HACK: Invoke |callback| immediately.
+ //
+ // TODO(crbug.com/698624): Remove this hack. It was introduced because Files
+ // app freezes until AddWatcher() finishes, but it should be handled in Files
+ // app rather than here.
+ callback.Run(base::File::FILE_OK);
}
void ArcDocumentsProviderRoot::RemoveWatcher(const base::FilePath& path,
const StatusCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ auto iter_request = path_to_watcher_request_id_.find(path);
+ if (iter_request != path_to_watcher_request_id_.end()) {
+ path_to_watcher_request_id_.erase(iter_request);
+ callback.Run(base::File::FILE_OK);
+ return;
+ }
auto iter = path_to_watcher_id_.find(path);
if (iter == path_to_watcher_id_.end()) {
callback.Run(base::File::FILE_ERROR_FAILED);
@@ -149,7 +173,7 @@ void ArcDocumentsProviderRoot::OnWatchersCleared() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Mark all watchers orphan.
for (auto& entry : path_to_watcher_id_)
- entry.second = -1;
+ entry.second = kOrphanWatcherId;
}
void ArcDocumentsProviderRoot::GetFileInfoWithDocumentId(
@@ -232,52 +256,56 @@ void ArcDocumentsProviderRoot::ReadDirectoryWithNameToThinDocumentMap(
void ArcDocumentsProviderRoot::AddWatcherWithDocumentId(
const base::FilePath& path,
+ uint64_t watcher_request_id,
const WatcherCallback& watcher_callback,
- const StatusCallback& callback,
const std::string& document_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ if (IsWatcherRequestCanceled(path, watcher_request_id))
+ return;
+
if (document_id.empty()) {
- callback.Run(base::File::FILE_ERROR_NOT_FOUND);
+ DCHECK(!path_to_watcher_id_.count(path));
+ path_to_watcher_id_.insert(std::make_pair(path, kOrphanWatcherId));
+ path_to_watcher_request_id_.erase(path);
return;
}
+
// Start observing ArcFileSystemOperationRunner if we have not.
if (!observer_wrapper_) {
observer_wrapper_ =
new file_system_operation_runner_util::ObserverIOThreadWrapper(this);
file_system_operation_runner_util::AddObserverOnIOThread(observer_wrapper_);
}
+
file_system_operation_runner_util::AddWatcherOnIOThread(
authority_, document_id, watcher_callback,
base::Bind(&ArcDocumentsProviderRoot::OnWatcherAdded,
- weak_ptr_factory_.GetWeakPtr(), path, callback));
+ weak_ptr_factory_.GetWeakPtr(), path, watcher_request_id));
}
void ArcDocumentsProviderRoot::OnWatcherAdded(const base::FilePath& path,
- const StatusCallback& callback,
+ uint64_t watcher_request_id,
int64_t watcher_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (watcher_id < 0) {
- callback.Run(base::File::FILE_ERROR_FAILED);
- return;
- }
- if (path_to_watcher_id_.count(path)) {
- // Multiple watchers have been installed on the same file path in a race.
- // Following the contract of WatcherManager, we reject all except the first.
+
+ if (IsWatcherRequestCanceled(path, watcher_request_id)) {
file_system_operation_runner_util::RemoveWatcherOnIOThread(
watcher_id,
base::Bind(&ArcDocumentsProviderRoot::OnWatcherAddedButRemoved,
- weak_ptr_factory_.GetWeakPtr(), callback));
+ weak_ptr_factory_.GetWeakPtr()));
return;
}
- path_to_watcher_id_.insert(std::make_pair(path, watcher_id));
- callback.Run(base::File::FILE_OK);
+
+ DCHECK(!path_to_watcher_id_.count(path));
+ path_to_watcher_id_.insert(
+ std::make_pair(path, watcher_id < 0 ? kOrphanWatcherId : watcher_id));
+ path_to_watcher_request_id_.erase(path);
}
-void ArcDocumentsProviderRoot::OnWatcherAddedButRemoved(
- const StatusCallback& callback,
- bool success) {
+void ArcDocumentsProviderRoot::OnWatcherAddedButRemoved(bool success) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- callback.Run(base::File::FILE_ERROR_FAILED);
+ // Ignore |success|.
}
void ArcDocumentsProviderRoot::OnWatcherRemoved(const StatusCallback& callback,
@@ -286,6 +314,14 @@ void ArcDocumentsProviderRoot::OnWatcherRemoved(const StatusCallback& callback,
callback.Run(success ? base::File::FILE_OK : base::File::FILE_ERROR_FAILED);
}
+bool ArcDocumentsProviderRoot::IsWatcherRequestCanceled(
+ const base::FilePath& path,
+ uint64_t watcher_request_id) {
+ auto iter = path_to_watcher_request_id_.find(path);
+ return (iter == path_to_watcher_request_id_.end() ||
+ iter->second != watcher_request_id);
+}
+
void ArcDocumentsProviderRoot::ResolveToContentUrlWithDocumentId(
const ResolveToContentUrlCallback& callback,
const std::string& document_id) {

Powered by Google App Engine
This is Rietveld 408576698