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