Home | History | Annotate | Download | only in file_manager
      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.
     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 
     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 
     41 FileWatcher::~FileWatcher() {
     42   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     43 
     44   BrowserThread::DeleteSoon(BrowserThread::FILE,
     45                             FROM_HERE,
     46                             local_file_watcher_);
     47 }
     48 
     49 void FileWatcher::AddExtension(const std::string& extension_id) {
     50   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     51 
     52   extensions_[extension_id]++;
     53 }
     54 
     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 
     73 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 
     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 
    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