• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
5 #include "chrome/browser/chromeos/file_manager/file_watcher.h"
6 
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "google_apis/drive/task_util.h"
11 
12 using content::BrowserThread;
13 
14 namespace file_manager {
15 namespace {
16 
17 // Creates a base::FilePathWatcher and starts watching at |watch_path| with
18 // |callback|. Returns NULL on failure.
CreateAndStartFilePathWatcher(const base::FilePath & watch_path,const base::FilePathWatcher::Callback & callback)19 base::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 
FileWatcher(const base::FilePath & virtual_path)34 FileWatcher::FileWatcher(const base::FilePath& virtual_path)
35     : local_file_watcher_(NULL),
36       virtual_path_(virtual_path),
37       weak_ptr_factory_(this) {
38   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
39 }
40 
~FileWatcher()41 FileWatcher::~FileWatcher() {
42   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
43 
44   BrowserThread::DeleteSoon(BrowserThread::FILE,
45                             FROM_HERE,
46                             local_file_watcher_);
47 }
48 
AddExtension(const std::string & extension_id)49 void FileWatcher::AddExtension(const std::string& extension_id) {
50   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
51 
52   extensions_[extension_id]++;
53 }
54 
RemoveExtension(const std::string & extension_id)55 void FileWatcher::RemoveExtension(const std::string& extension_id) {
56   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
57 
58   ExtensionCountMap::iterator it = extensions_.find(extension_id);
59   if (it == extensions_.end()) {
60     LOG(ERROR) << " Extension [" << extension_id
61                << "] tries to unsubscribe from folder ["
62                << virtual_path_.value()
63                << "] it isn't subscribed";
64     return;
65   }
66 
67   // If entry found - decrease it's count and remove if necessary
68   --it->second;
69   if (it->second == 0)
70     extensions_.erase(it);
71 }
72 
GetExtensionIds() const73 std::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 
WatchLocalFile(const base::FilePath & local_path,const base::FilePathWatcher::Callback & file_watcher_callback,const BoolCallback & callback)82 void FileWatcher::WatchLocalFile(
83     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());
88   DCHECK(!local_file_watcher_);
89 
90   BrowserThread::PostTaskAndReplyWithResult(
91       BrowserThread::FILE,
92       FROM_HERE,
93       base::Bind(&CreateAndStartFilePathWatcher,
94                  local_path,
95                  google_apis::CreateRelayCallback(file_watcher_callback)),
96       base::Bind(&FileWatcher::OnWatcherStarted,
97                  weak_ptr_factory_.GetWeakPtr(),
98                  callback));
99 }
100 
OnWatcherStarted(const BoolCallback & callback,base::FilePathWatcher * file_watcher)101 void FileWatcher::OnWatcherStarted(
102     const BoolCallback& callback,
103     base::FilePathWatcher* file_watcher) {
104   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
105   DCHECK(!callback.is_null());
106   DCHECK(!local_file_watcher_);
107 
108   if (file_watcher) {
109     local_file_watcher_ = file_watcher;
110     callback.Run(true);
111   } else {
112     callback.Run(false);
113   }
114 }
115 
116 }  // namespace file_manager
117