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 "content/public/browser/browser_thread.h"
      9 #include "google_apis/drive/task_util.h"
     10 
     11 using content::BrowserThread;
     12 
     13 namespace file_manager {
     14 namespace {
     15 
     16 // Creates a base::FilePathWatcher and starts watching at |watch_path| with
     17 // |callback|. Returns NULL on failure.
     18 base::FilePathWatcher* CreateAndStartFilePathWatcher(
     19     const base::FilePath& watch_path,
     20     const base::FilePathWatcher::Callback& callback) {
     21   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
     22   DCHECK(!callback.is_null());
     23 
     24   scoped_ptr<base::FilePathWatcher> watcher(new base::FilePathWatcher);
     25   if (!watcher->Watch(watch_path, false /* recursive */, callback))
     26     return NULL;
     27 
     28   return watcher.release();
     29 }
     30 
     31 }  // namespace
     32 
     33 FileWatcher::FileWatcher(const base::FilePath& virtual_path)
     34     : local_file_watcher_(NULL),
     35       virtual_path_(virtual_path),
     36       weak_ptr_factory_(this) {
     37   DCHECK_CURRENTLY_ON(BrowserThread::UI);
     38 }
     39 
     40 FileWatcher::~FileWatcher() {
     41   DCHECK_CURRENTLY_ON(BrowserThread::UI);
     42 
     43   BrowserThread::DeleteSoon(BrowserThread::FILE,
     44                             FROM_HERE,
     45                             local_file_watcher_);
     46 }
     47 
     48 void FileWatcher::AddExtension(const std::string& extension_id) {
     49   DCHECK_CURRENTLY_ON(BrowserThread::UI);
     50 
     51   extensions_[extension_id]++;
     52 }
     53 
     54 void FileWatcher::RemoveExtension(const std::string& extension_id) {
     55   DCHECK_CURRENTLY_ON(BrowserThread::UI);
     56 
     57   ExtensionCountMap::iterator it = extensions_.find(extension_id);
     58   if (it == extensions_.end()) {
     59     LOG(ERROR) << " Extension [" << extension_id
     60                << "] tries to unsubscribe from folder ["
     61                << virtual_path_.value()
     62                << "] it isn't subscribed";
     63     return;
     64   }
     65 
     66   // If entry found - decrease it's count and remove if necessary
     67   --it->second;
     68   if (it->second == 0)
     69     extensions_.erase(it);
     70 }
     71 
     72 std::vector<std::string> FileWatcher::GetExtensionIds() const {
     73   std::vector<std::string> extension_ids;
     74   for (ExtensionCountMap::const_iterator iter = extensions_.begin();
     75        iter != extensions_.end(); ++iter) {
     76     extension_ids.push_back(iter->first);
     77   }
     78   return extension_ids;
     79 }
     80 
     81 void FileWatcher::WatchLocalFile(
     82     const base::FilePath& local_path,
     83     const base::FilePathWatcher::Callback& file_watcher_callback,
     84     const BoolCallback& callback) {
     85   DCHECK_CURRENTLY_ON(BrowserThread::UI);
     86   DCHECK(!callback.is_null());
     87   DCHECK(!local_file_watcher_);
     88 
     89   BrowserThread::PostTaskAndReplyWithResult(
     90       BrowserThread::FILE,
     91       FROM_HERE,
     92       base::Bind(&CreateAndStartFilePathWatcher,
     93                  local_path,
     94                  google_apis::CreateRelayCallback(file_watcher_callback)),
     95       base::Bind(&FileWatcher::OnWatcherStarted,
     96                  weak_ptr_factory_.GetWeakPtr(),
     97                  callback));
     98 }
     99 
    100 void FileWatcher::OnWatcherStarted(
    101     const BoolCallback& callback,
    102     base::FilePathWatcher* file_watcher) {
    103   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    104   DCHECK(!callback.is_null());
    105   DCHECK(!local_file_watcher_);
    106 
    107   if (file_watcher) {
    108     local_file_watcher_ = file_watcher;
    109     callback.Run(true);
    110   } else {
    111     callback.Run(false);
    112   }
    113 }
    114 
    115 }  // namespace file_manager
    116