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

Unified Diff: chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.cc

Issue 2736603002: mediaview: Support watchers in ArcFileSystemOperationRunner. (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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.cc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.cc b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.cc
index 9e914c16f9b9ebc06ccca3ee45277ad827f8a7a1..85c094ae3b4d5b9d3d566753990ac32c45a82ae5 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
@@ -18,6 +20,23 @@ using content::BrowserThread;
namespace arc {
+namespace {
+
+// TODO(nya): Use typemaps.
+ArcFileSystemOperationRunner::ChangeType FromMojoChangeType(
+ mojom::ChangeType type) {
+ switch (type) {
+ case mojom::ChangeType::CHANGED:
+ return ArcFileSystemOperationRunner::ChangeType::CHANGED;
+ case mojom::ChangeType::DELETED:
+ return ArcFileSystemOperationRunner::ChangeType::DELETED;
+ }
+ NOTREACHED();
+ return ArcFileSystemOperationRunner::ChangeType::CHANGED;
+}
+
+} // namespace
+
// static
const char ArcFileSystemOperationRunner::kArcServiceName[] =
"arc::ArcFileSystemOperationRunner";
@@ -42,30 +61,46 @@ ArcFileSystemOperationRunner::ArcFileSystemOperationRunner(
ArcFileSystemOperationRunner::ArcFileSystemOperationRunner(
ArcBridgeService* bridge_service,
const Profile* profile,
- bool observe_events)
+ bool set_should_defer_by_events)
: ArcService(bridge_service),
profile_(profile),
- observe_events_(observe_events),
+ set_should_defer_by_events_(set_should_defer_by_events),
+ binding_(this),
weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (observe_events_) {
- ArcSessionManager::Get()->AddObserver(this);
- arc_bridge_service()->file_system()->AddObserver(this);
- OnStateChanged();
- }
+ // We need to observe FileSystemInstance even in unit tests to call Init().
+ arc_bridge_service()->file_system()->AddObserver(this);
+
+ // ArcSessionManager may not exist in unit tests.
+ auto* arc_session_manager = ArcSessionManager::Get();
+ if (arc_session_manager)
+ arc_session_manager->AddObserver(this);
+
+ OnStateChanged();
}
ArcFileSystemOperationRunner::~ArcFileSystemOperationRunner() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (observe_events_) {
- ArcSessionManager::Get()->RemoveObserver(this);
- arc_bridge_service()->file_system()->RemoveObserver(this);
- }
+ auto* arc_session_manager = ArcSessionManager::Get();
+ if (arc_session_manager)
+ arc_session_manager->RemoveObserver(this);
+
+ arc_bridge_service()->file_system()->RemoveObserver(this);
// On destruction, deferred operations are discarded.
}
+void ArcFileSystemOperationRunner::AddObserver(Observer* observer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ observer_list_.AddObserver(observer);
+}
+
+void ArcFileSystemOperationRunner::RemoveObserver(Observer* observer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ observer_list_.RemoveObserver(observer);
+}
+
void ArcFileSystemOperationRunner::GetFileSize(
const GURL& url,
const GetFileSizeCallback& callback) {
@@ -150,6 +185,78 @@ void ArcFileSystemOperationRunner::GetChildDocuments(
callback);
}
+void ArcFileSystemOperationRunner::AddWatcher(
+ const std::string& authority,
+ const std::string& document_id,
+ const WatcherCallback& watcher_callback,
+ const AddWatcherCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (should_defer_) {
+ deferred_operations_.emplace_back(
+ base::Bind(&ArcFileSystemOperationRunner::AddWatcher,
+ weak_ptr_factory_.GetWeakPtr(), authority, document_id,
+ watcher_callback, callback));
+ return;
+ }
+ auto* file_system_instance = ARC_GET_INSTANCE_FOR_METHOD(
+ arc_bridge_service()->file_system(), AddWatcher);
+ if (!file_system_instance) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ base::Bind(callback, -1));
+ return;
+ }
+ file_system_instance->AddWatcher(
+ authority, document_id,
+ base::Bind(&ArcFileSystemOperationRunner::OnWatcherAdded,
+ weak_ptr_factory_.GetWeakPtr(), watcher_callback, callback));
+}
+
+void ArcFileSystemOperationRunner::RemoveWatcher(
+ int64_t watcher_id,
+ const RemoveWatcherCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // RemoveWatcher() is never deferred since watchers do not persist across
+ // container reboots.
+ if (should_defer_) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ base::Bind(callback, false));
+ return;
+ }
+
+ // Unregister from |watcher_callbacks_| now because we will do it even if
+ // the remote method fails anyway. This is an implementation detail, so
+ // users must not assume registered callbacks are immediately invalidated.
+ auto iter = watcher_callbacks_.find(watcher_id);
+ if (iter == watcher_callbacks_.end()) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ base::Bind(callback, false));
+ return;
+ }
+ watcher_callbacks_.erase(iter);
+
+ auto* file_system_instance = ARC_GET_INSTANCE_FOR_METHOD(
+ arc_bridge_service()->file_system(), AddWatcher);
+ if (!file_system_instance) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ base::Bind(callback, false));
+ return;
+ }
+ file_system_instance->RemoveWatcher(watcher_id, callback);
+}
+
+void ArcFileSystemOperationRunner::OnDocumentChanged(int64_t watcher_id,
+ mojom::ChangeType type) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ auto iter = watcher_callbacks_.find(watcher_id);
+ if (iter == watcher_callbacks_.end()) {
+ // This may happen in a race condition with documents changes and
+ // RemoveWatcher().
+ return;
+ }
+ WatcherCallback watcher_callback = iter->second;
+ watcher_callback.Run(FromMojoChangeType(type));
+}
+
void ArcFileSystemOperationRunner::OnArcPlayStoreEnabledChanged(bool enabled) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
OnStateChanged();
@@ -157,18 +264,46 @@ void ArcFileSystemOperationRunner::OnArcPlayStoreEnabledChanged(bool enabled) {
void ArcFileSystemOperationRunner::OnInstanceReady() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ auto* file_system_instance =
+ ARC_GET_INSTANCE_FOR_METHOD(arc_bridge_service()->file_system(), Init);
+ if (file_system_instance)
+ file_system_instance->Init(binding_.CreateInterfacePtrAndBind());
OnStateChanged();
}
void ArcFileSystemOperationRunner::OnInstanceClosed() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // ArcFileSystemService and watchers are gone.
+ watcher_callbacks_.clear();
+ for (auto& observer : observer_list_)
+ observer.OnWatchersCleared();
OnStateChanged();
}
+void ArcFileSystemOperationRunner::OnWatcherAdded(
+ const WatcherCallback& watcher_callback,
+ const AddWatcherCallback& callback,
+ int64_t watcher_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (watcher_id < 0) {
+ callback.Run(-1);
+ return;
+ }
+ if (watcher_callbacks_.count(watcher_id)) {
+ NOTREACHED();
+ callback.Run(-1);
+ return;
+ }
+ watcher_callbacks_.insert(std::make_pair(watcher_id, watcher_callback));
+ callback.Run(watcher_id);
+}
+
void ArcFileSystemOperationRunner::OnStateChanged() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- SetShouldDefer(IsArcPlayStoreEnabledForProfile(profile_) &&
- !arc_bridge_service()->file_system()->has_instance());
+ if (set_should_defer_by_events_) {
+ SetShouldDefer(IsArcPlayStoreEnabledForProfile(profile_) &&
+ !arc_bridge_service()->file_system()->has_instance());
+ }
}
void ArcFileSystemOperationRunner::SetShouldDefer(bool should_defer) {

Powered by Google App Engine
This is Rietveld 408576698