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