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

Unified Diff: chrome/browser/chromeos/extensions/file_browser_event_router.cc

Issue 13776005: drive: Fix two instances of madness in FileBrowserEventRouter (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address comments Created 7 years, 8 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/extensions/file_browser_event_router.cc
diff --git a/chrome/browser/chromeos/extensions/file_browser_event_router.cc b/chrome/browser/chromeos/extensions/file_browser_event_router.cc
index 40b4cf76e1f816676aeec19160a1c293f1283425..91f3992c9c54c55d4c4c1ae5ce64bb987dbd5e34 100644
--- a/chrome/browser/chromeos/extensions/file_browser_event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_browser_event_router.cc
@@ -228,6 +228,23 @@ void DirectoryExistsOnUIThread(const base::FilePath& directory_path,
failure_callback));
};
+// Creates a base::FilePathWatcher and starts watching at |watch_path| with
+// |callback|. Returns NULL on failure.
+base::FilePathWatcher* CreateAndStartFilePathWatcher(
+ const base::FilePath& watch_path,
+ const base::FilePathWatcher::Callback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ DCHECK(!callback.is_null());
+
+ base::FilePathWatcher* watcher(new base::FilePathWatcher);
+ if (!watcher->Watch(watch_path, false /* recursive */, callback)) {
+ delete watcher;
+ return NULL;
+ }
+
+ return watcher;
+}
+
} // namespace
FileBrowserEventRouter::FileBrowserEventRouter(
@@ -240,12 +257,9 @@ FileBrowserEventRouter::FileBrowserEventRouter(
shift_pressed_(false) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // Bind a weak reference back to |this| to avoid memory errors in case we
- // shut down while a callback is in flight.
file_watcher_callback_ =
- base::Bind(&RelayFileWatcherCallbackToUIThread,
- base::Bind(&FileBrowserEventRouter::HandleFileWatchNotification,
- weak_factory_.GetWeakPtr()));
+ base::Bind(&FileBrowserEventRouter::HandleFileWatchNotification,
+ weak_factory_.GetWeakPtr());
// Listen for the Shift modifier's state changes.
chromeos::SystemKeyEventListener* key_event_listener =
@@ -324,11 +338,11 @@ void FileBrowserEventRouter::ObserveFileSystemEvents() {
pref_change_registrar_->Add(
prefs::kExternalStorageDisabled,
base::Bind(&FileBrowserEventRouter::OnExternalStorageDisabledChanged,
- base::Unretained(this)));
+ weak_factory_.GetWeakPtr()));
base::Closure callback =
base::Bind(&FileBrowserEventRouter::OnFileBrowserPrefsChanged,
- base::Unretained(this));
+ weak_factory_.GetWeakPtr());
pref_change_registrar_->Add(prefs::kDisableDriveOverCellular, callback);
pref_change_registrar_->Add(prefs::kDisableDriveHostedFiles, callback);
pref_change_registrar_->Add(prefs::kDisableDrive, callback);
@@ -336,13 +350,14 @@ void FileBrowserEventRouter::ObserveFileSystemEvents() {
}
// File watch setup routines.
-bool FileBrowserEventRouter::AddFileWatch(
+void FileBrowserEventRouter::AddFileWatch(
const base::FilePath& local_path,
const base::FilePath& virtual_path,
- const std::string& extension_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ const std::string& extension_id,
+ const BoolCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!callback.is_null());
- base::AutoLock lock(lock_);
base::FilePath watch_path = local_path;
bool is_remote_watch = false;
// Tweak watch path for remote sources - we need to drop leading /special
@@ -351,10 +366,7 @@ bool FileBrowserEventRouter::AddFileWatch(
if (drive::util::GetSpecialRemoteRootPath().IsParent(watch_path)) {
watch_path = drive::util::ExtractDrivePath(watch_path);
is_remote_watch = true;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&FileBrowserEventRouter::HandleRemoteUpdateRequestOnUIThread,
- this, true));
+ HandleRemoteUpdateRequestOnUIThread(true /* start */);
}
WatcherMap::iterator iter = file_watchers_.find(watch_path);
@@ -363,33 +375,29 @@ bool FileBrowserEventRouter::AddFileWatch(
watch(new FileWatcherExtensions(virtual_path,
extension_id,
is_remote_watch));
-
- if (watch->Watch(watch_path, file_watcher_callback_))
- file_watchers_[watch_path] = watch.release();
- else
- return false;
+ watch->Watch(watch_path,
+ file_watcher_callback_,
+ callback);
+ file_watchers_[watch_path] = watch.release();
} else {
iter->second->AddExtension(extension_id);
+ base::MessageLoopProxy::current()->PostTask(FROM_HERE,
+ base::Bind(callback, true));
}
- return true;
}
void FileBrowserEventRouter::RemoveFileWatch(
const base::FilePath& local_path,
const std::string& extension_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- base::AutoLock lock(lock_);
base::FilePath watch_path = local_path;
// Tweak watch path for remote sources - we need to drop leading /special
// directory from there in order to be able to pair these events with
// their change notifications.
if (drive::util::GetSpecialRemoteRootPath().IsParent(watch_path)) {
watch_path = drive::util::ExtractDrivePath(watch_path);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&FileBrowserEventRouter::HandleRemoteUpdateRequestOnUIThread,
- this, false));
+ HandleRemoteUpdateRequestOnUIThread(false /* start */);
}
WatcherMap::iterator iter = file_watchers_.find(watch_path);
if (iter == file_watchers_.end())
@@ -655,7 +663,6 @@ void FileBrowserEventRouter::HandleFileWatchNotification(
const base::FilePath& local_path, bool got_error) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- base::AutoLock lock(lock_);
WatcherMap::const_iterator iter = file_watchers_.find(local_path);
if (iter == file_watchers_.end()) {
return;
@@ -901,21 +908,29 @@ void FileBrowserEventRouter::OnFormatCompleted(
}
FileBrowserEventRouter::FileWatcherExtensions::FileWatcherExtensions(
- const base::FilePath& path, const std::string& extension_id,
+ const base::FilePath& virtual_path,
+ const std::string& extension_id,
bool is_remote_file_system)
- : ref_count_(0),
- is_remote_file_system_(is_remote_file_system) {
- if (!is_remote_file_system_)
- file_watcher_.reset(new base::FilePathWatcher());
+ : file_watcher_(NULL),
+ virtual_path_(virtual_path),
+ ref_count_(0),
+ is_remote_file_system_(is_remote_file_system),
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- virtual_path_ = path;
AddExtension(extension_id);
}
-FileBrowserEventRouter::FileWatcherExtensions::~FileWatcherExtensions() {}
+FileBrowserEventRouter::FileWatcherExtensions::~FileWatcherExtensions() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, file_watcher_);
+}
void FileBrowserEventRouter::FileWatcherExtensions::AddExtension(
const std::string& extension_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
ExtensionUsageRegistry::iterator it = extensions_.find(extension_id);
if (it != extensions_.end()) {
it->second++;
@@ -928,6 +943,8 @@ void FileBrowserEventRouter::FileWatcherExtensions::AddExtension(
void FileBrowserEventRouter::FileWatcherExtensions::RemoveExtension(
const std::string& extension_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
ExtensionUsageRegistry::iterator it = extensions_.find(extension_id);
if (it != extensions_.end()) {
@@ -949,16 +966,19 @@ void FileBrowserEventRouter::FileWatcherExtensions::RemoveExtension(
const FileBrowserEventRouter::ExtensionUsageRegistry&
FileBrowserEventRouter::FileWatcherExtensions::GetExtensions() const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return extensions_;
}
unsigned int
FileBrowserEventRouter::FileWatcherExtensions::GetRefCount() const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return ref_count_;
}
const base::FilePath&
FileBrowserEventRouter::FileWatcherExtensions::GetVirtualPath() const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return virtual_path_;
}
@@ -970,11 +990,44 @@ FileBrowserEventRouter::GetRemoteFileSystem() const {
return (system_service ? system_service->file_system() : NULL);
}
-bool FileBrowserEventRouter::FileWatcherExtensions::Watch(
- const base::FilePath& path,
- const base::FilePathWatcher::Callback& callback) {
- if (is_remote_file_system_)
- return true;
+void FileBrowserEventRouter::FileWatcherExtensions::Watch(
+ const base::FilePath& local_path,
+ const base::FilePathWatcher::Callback& file_watcher_callback,
+ const BoolCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!callback.is_null());
+ DCHECK(!file_watcher_);
- return file_watcher_->Watch(path, false, callback);
+ local_path_ = local_path; // For error message in RemoveExtension().
+
+ if (is_remote_file_system_) {
+ base::MessageLoopProxy::current()->PostTask(FROM_HERE,
+ base::Bind(callback, true));
+ return;
+ }
+
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::FILE,
+ FROM_HERE,
+ base::Bind(&CreateAndStartFilePathWatcher,
+ local_path,
+ base::Bind(&RelayFileWatcherCallbackToUIThread,
+ file_watcher_callback)),
+ base::Bind(
+ &FileBrowserEventRouter::FileWatcherExtensions::OnWatcherStarted,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
+}
+
+void FileBrowserEventRouter::FileWatcherExtensions::OnWatcherStarted(
+ const BoolCallback& callback,
+ base::FilePathWatcher* file_watcher) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (file_watcher) {
+ file_watcher_ = file_watcher;
+ callback.Run(true);
+ } else {
+ callback.Run(false);
+ }
}

Powered by Google App Engine
This is Rietveld 408576698