blob: 6f72071978c2368d93eccf31589ad199cfba97a1 [file] [log] [blame]
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01001// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ben Murdoch2385ea32013-08-06 11:01:04 +01005#include "chrome/browser/chromeos/extensions/file_manager/file_watcher.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01006
7#include "base/bind.h"
8#include "base/message_loop/message_loop_proxy.h"
9#include "chrome/browser/google_apis/task_util.h"
10#include "content/public/browser/browser_thread.h"
11
12using content::BrowserThread;
13
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010014namespace file_manager {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010015namespace {
16
17// Creates a base::FilePathWatcher and starts watching at |watch_path| with
18// |callback|. Returns NULL on failure.
19base::FilePathWatcher* CreateAndStartFilePathWatcher(
20 const base::FilePath& watch_path,
21 const base::FilePathWatcher::Callback& callback) {
22 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
23 DCHECK(!callback.is_null());
24
25 scoped_ptr<base::FilePathWatcher> watcher(new base::FilePathWatcher);
26 if (!watcher->Watch(watch_path, false /* recursive */, callback))
27 return NULL;
28
29 return watcher.release();
30}
31
32} // namespace
33
Ben Murdochbb1529c2013-08-08 10:24:53 +010034FileWatcher::FileWatcher(const base::FilePath& virtual_path)
Ben Murdoch2385ea32013-08-06 11:01:04 +010035 : local_file_watcher_(NULL),
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010036 virtual_path_(virtual_path),
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010037 weak_ptr_factory_(this) {
38 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010039}
40
Ben Murdoch2385ea32013-08-06 11:01:04 +010041FileWatcher::~FileWatcher() {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010042 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
43
Ben Murdoch2385ea32013-08-06 11:01:04 +010044 BrowserThread::DeleteSoon(BrowserThread::FILE,
45 FROM_HERE,
46 local_file_watcher_);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010047}
48
Ben Murdoch2385ea32013-08-06 11:01:04 +010049void FileWatcher::AddExtension(const std::string& extension_id) {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010050 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
51
52 extensions_[extension_id]++;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010053}
54
Ben Murdoch2385ea32013-08-06 11:01:04 +010055void FileWatcher::RemoveExtension(const std::string& extension_id) {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010056 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
57
Ben Murdochbb1529c2013-08-08 10:24:53 +010058 ExtensionCountMap::iterator it = extensions_.find(extension_id);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010059 if (it == extensions_.end()) {
60 LOG(ERROR) << " Extension [" << extension_id
Ben Murdochbb1529c2013-08-08 10:24:53 +010061 << "] tries to unsubscribe from folder ["
62 << virtual_path_.value()
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010063 << "] it isn't subscribed";
64 return;
65 }
66
67 // If entry found - decrease it's count and remove if necessary
Ben Murdochbb1529c2013-08-08 10:24:53 +010068 --it->second;
69 if (it->second == 0)
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010070 extensions_.erase(it);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010071}
72
Ben Murdochbb1529c2013-08-08 10:24:53 +010073std::vector<std::string> FileWatcher::GetExtensionIds() const {
74 std::vector<std::string> extension_ids;
75 for (ExtensionCountMap::const_iterator iter = extensions_.begin();
76 iter != extensions_.end(); ++iter) {
77 extension_ids.push_back(iter->first);
78 }
79 return extension_ids;
80}
81
82void FileWatcher::WatchLocalFile(
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010083 const base::FilePath& local_path,
84 const base::FilePathWatcher::Callback& file_watcher_callback,
85 const BoolCallback& callback) {
86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
87 DCHECK(!callback.is_null());
Ben Murdoch2385ea32013-08-06 11:01:04 +010088 DCHECK(!local_file_watcher_);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010089
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010090 BrowserThread::PostTaskAndReplyWithResult(
91 BrowserThread::FILE,
92 FROM_HERE,
93 base::Bind(&CreateAndStartFilePathWatcher,
94 local_path,
95 google_apis::CreateRelayCallback(file_watcher_callback)),
Ben Murdoch2385ea32013-08-06 11:01:04 +010096 base::Bind(&FileWatcher::OnWatcherStarted,
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010097 weak_ptr_factory_.GetWeakPtr(),
98 callback));
99}
100
Ben Murdoch2385ea32013-08-06 11:01:04 +0100101void FileWatcher::OnWatcherStarted(
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100102 const BoolCallback& callback,
103 base::FilePathWatcher* file_watcher) {
104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
105 DCHECK(!callback.is_null());
Ben Murdoch2385ea32013-08-06 11:01:04 +0100106 DCHECK(!local_file_watcher_);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100107
108 if (file_watcher) {
Ben Murdoch2385ea32013-08-06 11:01:04 +0100109 local_file_watcher_ = file_watcher;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100110 callback.Run(true);
111 } else {
112 callback.Run(false);
113 }
114}
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100115
116} // namespace file_manager