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

Unified Diff: chrome/browser/file_system/entry_watcher_service.cc

Issue 452043003: [ew] Add basic classes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Uploaded. Created 6 years, 4 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/file_system/entry_watcher_service.cc
diff --git a/chrome/browser/file_system/entry_watcher_service.cc b/chrome/browser/file_system/entry_watcher_service.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c2e4aaa763043068df815f6e57741bf692e8deef
--- /dev/null
+++ b/chrome/browser/file_system/entry_watcher_service.cc
@@ -0,0 +1,247 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/file_system/entry_watcher_service.h"
+
+#include "base/thread_task_runner_handle.h"
+#include "chrome/browser/extensions/extension_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/extensions/api/file_system.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
+#include "extensions/browser/event_router.h"
+#include "webkit/browser/fileapi/file_system_context.h"
+
+namespace {
+
+// Default implementation for dispatching an event. Can be replaced for unit
+// tests by EntryWatcherService::SetDispatchEventImplForTesting().
+void DispatchEventImpl(extensions::EventRouter* event_router,
+ const std::string& extension_id,
+ scoped_ptr<extensions::Event> event) {
+ event_router->DispatchEventToExtension(extension_id, event.Pass());
+}
+
+// Default implementation for acquiring a file system context for a specific
+// |extension_id| and |context|.
+fileapi::FileSystemContext* GetFileSystemContextImpl(
+ const std::string& extension_id,
+ content::BrowserContext* context) {
+ const GURL site =
+ extensions::util::GetSiteForExtensionId(extension_id, context);
+ return content::BrowserContext::GetStoragePartitionForSite(context, site)
+ ->GetFileSystemContext();
+}
+
+} // namespace
+
+EntryWatcherService::EntryWatcherService(content::BrowserContext* context)
+ : context_(context),
+ dispatch_event_impl_(base::Bind(&DispatchEventImpl,
+ extensions::EventRouter::Get(context))),
+ get_file_system_context_impl_(base::Bind(&GetFileSystemContextImpl)),
+ observing_(this),
+ weak_ptr_factory_(this) {
+ // TODO(mtomasz): Restore persistent watchers.
+}
+
+EntryWatcherService::~EntryWatcherService() {
+}
+
+void EntryWatcherService::SetDispatchEventImplForTesting(
+ const DispatchEventImplCallback& callback) {
+ dispatch_event_impl_ = callback;
+}
+
+void EntryWatcherService::SetGetFileSystemContextImplForTesting(
+ const GetFileSystemContextImplCallback& callback) {
+ get_file_system_context_impl_ = callback;
+}
+
+void EntryWatcherService::WatchDirectory(
+ const std::string& extension_id,
+ const fileapi::FileSystemURL& url,
+ bool recursive,
+ const fileapi::WatcherManager::StatusCallback& callback) {
+ // TODO(mtomasz): Add support for recursive watchers.
+ if (recursive) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(callback, base::File::FILE_ERROR_INVALID_OPERATION));
+ return;
+ }
+
+ fileapi::FileSystemContext* const context =
+ get_file_system_context_impl_.Run(extension_id, context_);
+ DCHECK(context);
+
+ fileapi::WatcherManager* const watcher_manager =
+ context->GetWatcherManager(url.type());
+ if (!watcher_manager) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(callback, base::File::FILE_ERROR_INVALID_OPERATION));
+ return;
+ }
+
+ watcher_manager->WatchDirectory(
+ url,
+ recursive,
+ base::Bind(&EntryWatcherService::OnWatchDirectoryCompleted,
+ weak_ptr_factory_.GetWeakPtr(),
+ extension_id,
+ url,
+ recursive,
+ callback));
+}
+
+void EntryWatcherService::UnwatchEntry(
+ const std::string& extension_id,
+ const fileapi::FileSystemURL& url,
+ const fileapi::WatcherManager::StatusCallback& callback) {
+ fileapi::FileSystemContext* const context =
+ get_file_system_context_impl_.Run(extension_id, context_);
+ DCHECK(context);
+
+ fileapi::WatcherManager* const watcher_manager =
+ context->GetWatcherManager(url.type());
+ if (!watcher_manager) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(callback, base::File::FILE_ERROR_INVALID_OPERATION));
+ return;
+ }
+
+ watcher_manager->UnwatchEntry(
+ url,
+ base::Bind(&EntryWatcherService::OnUnwatchEntryCompleted,
+ weak_ptr_factory_.GetWeakPtr(),
+ extension_id,
+ url,
+ callback));
+}
+
+std::vector<fileapi::FileSystemURL> EntryWatcherService::GetWatchedEntries(
+ const std::string& extension_id) {
+ std::vector<fileapi::FileSystemURL> result;
+ for (WatcherMap::const_iterator it = watchers_.begin(); it != watchers_.end();
+ ++it) {
+ const std::map<std::string, EntryWatcher>::const_iterator watcher_it =
+ it->second.find(extension_id);
+ if (watcher_it != it->second.end())
+ result.push_back(watcher_it->second.url);
+ }
+
+ return result;
+}
+
+void EntryWatcherService::OnEntryChanged(const fileapi::FileSystemURL& url) {
+ const WatcherMap::const_iterator it = watchers_.find(url.ToGURL());
+ DCHECK(it != watchers_.end());
+ for (std::map<std::string, EntryWatcher>::const_iterator watcher_it =
+ it->second.begin();
+ watcher_it != it->second.end();
+ ++watcher_it) {
+ const std::string& extension_id = watcher_it->first;
+ extensions::api::file_system::EntryChangedEvent event;
+ dispatch_event_impl_.Run(
+ extension_id,
+ make_scoped_ptr(new extensions::Event(
+ extensions::api::file_system::OnEntryChanged::kEventName,
+ extensions::api::file_system::OnEntryChanged::Create(event))));
+ }
+}
+
+void EntryWatcherService::OnEntryRemoved(const fileapi::FileSystemURL& url) {
+ WatcherMap::const_iterator it = watchers_.find(url.ToGURL());
+ DCHECK(it != watchers_.end());
+ for (std::map<std::string, EntryWatcher>::const_iterator watcher_it =
+ it->second.begin();
+ watcher_it != it->second.end();
+ ++watcher_it) {
+ const std::string& extension_id = watcher_it->first;
+ extensions::api::file_system::EntryRemovedEvent event;
+ dispatch_event_impl_.Run(
+ extension_id,
+ make_scoped_ptr(new extensions::Event(
+ extensions::api::file_system::OnEntryRemoved::kEventName,
+ extensions::api::file_system::OnEntryRemoved::Create(event))));
+ }
+}
+
+void EntryWatcherService::OnWatchDirectoryCompleted(
+ const std::string& extension_id,
+ const fileapi::FileSystemURL& url,
+ bool recursive,
+ const fileapi::WatcherManager::StatusCallback& callback,
+ base::File::Error result) {
+ if (result != base::File::FILE_OK) {
+ callback.Run(result);
+ return;
+ }
+
+ fileapi::FileSystemContext* const context =
+ get_file_system_context_impl_.Run(extension_id, context_);
+ DCHECK(context);
+
+ fileapi::WatcherManager* const watcher_manager =
+ context->GetWatcherManager(url.type());
+ if (!watcher_manager) {
+ callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
+ return;
+ }
+
+ // Observe the manager if not observed yet.
+ if (!observing_.IsObserving(watcher_manager))
+ observing_.Add(watcher_manager);
+
+ const GURL gurl = url.ToGURL();
+ watchers_[gurl][extension_id] =
+ EntryWatcher(url, true /* directory */, recursive);
+
+ // TODO(mtomasz): Save in preferences.
+
+ callback.Run(base::File::FILE_OK);
+}
+
+void EntryWatcherService::OnUnwatchEntryCompleted(
+ const std::string& extension_id,
+ const fileapi::FileSystemURL& url,
+ const fileapi::WatcherManager::StatusCallback& callback,
+ base::File::Error result) {
+ if (result != base::File::FILE_OK) {
+ callback.Run(result);
+ return;
+ }
+
+ DCHECK_EQ(base::File::FILE_OK, result);
benwells 2014/08/14 05:16:32 This DCHECK can be removed as well.
mtomasz 2014/08/15 05:35:57 Done.
+
+ const GURL gurl = url.ToGURL();
+ if (watchers_[gurl].erase(extension_id) == 0) {
+ callback.Run(base::File::FILE_ERROR_NOT_FOUND);
+ return;
+ }
+
+ if (watchers_[gurl].empty())
+ watchers_.erase(gurl);
+
+ // TODO(mtomasz): Save in preferences.
+
+ callback.Run(base::File::FILE_OK);
+}
+
+EntryWatcherService::EntryWatcher::EntryWatcher()
+ : directory(false), recursive(false) {
+}
+
+EntryWatcherService::EntryWatcher::EntryWatcher(
+ const fileapi::FileSystemURL& url,
+ bool directory,
+ bool recursive)
+ : url(url), directory(directory), recursive(recursive) {
+}
+
+EntryWatcherService::EntryWatcher::~EntryWatcher() {
+}
« no previous file with comments | « chrome/browser/file_system/entry_watcher_service.h ('k') | chrome/browser/file_system/entry_watcher_service_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698