OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/drive/file_write_watcher.h" | 5 #include "chrome/browser/chromeos/drive/file_write_watcher.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 | 73 |
74 // Note: This should remain the last member so it'll be destroyed and | 74 // Note: This should remain the last member so it'll be destroyed and |
75 // invalidate its weak pointers before any other members are destroyed. | 75 // invalidate its weak pointers before any other members are destroyed. |
76 base::WeakPtrFactory<FileWriteWatcherImpl> weak_ptr_factory_; | 76 base::WeakPtrFactory<FileWriteWatcherImpl> weak_ptr_factory_; |
77 DISALLOW_COPY_AND_ASSIGN(FileWriteWatcherImpl); | 77 DISALLOW_COPY_AND_ASSIGN(FileWriteWatcherImpl); |
78 }; | 78 }; |
79 | 79 |
80 FileWriteWatcher::FileWriteWatcherImpl::FileWriteWatcherImpl() | 80 FileWriteWatcher::FileWriteWatcherImpl::FileWriteWatcherImpl() |
81 : delay_(base::TimeDelta::FromSeconds(kWriteEventDelayInSeconds)), | 81 : delay_(base::TimeDelta::FromSeconds(kWriteEventDelayInSeconds)), |
82 weak_ptr_factory_(this) { | 82 weak_ptr_factory_(this) { |
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 83 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
84 } | 84 } |
85 | 85 |
86 void FileWriteWatcher::FileWriteWatcherImpl::Destroy() { | 86 void FileWriteWatcher::FileWriteWatcherImpl::Destroy() { |
87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 87 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
88 | 88 |
89 // Just forwarding the call to FILE thread. | 89 // Just forwarding the call to FILE thread. |
90 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)->PostTask( | 90 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)->PostTask( |
91 FROM_HERE, | 91 FROM_HERE, |
92 base::Bind(&FileWriteWatcherImpl::DestroyOnFileThread, | 92 base::Bind(&FileWriteWatcherImpl::DestroyOnFileThread, |
93 base::Unretained(this))); | 93 base::Unretained(this))); |
94 } | 94 } |
95 | 95 |
96 void FileWriteWatcher::FileWriteWatcherImpl::StartWatch( | 96 void FileWriteWatcher::FileWriteWatcherImpl::StartWatch( |
97 const base::FilePath& path, | 97 const base::FilePath& path, |
98 const StartWatchCallback& on_start_callback, | 98 const StartWatchCallback& on_start_callback, |
99 const base::Closure& on_write_callback) { | 99 const base::Closure& on_write_callback) { |
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 100 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
101 | 101 |
102 // Forwarding the call to FILE thread and relaying the |callback|. | 102 // Forwarding the call to FILE thread and relaying the |callback|. |
103 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)->PostTask( | 103 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)->PostTask( |
104 FROM_HERE, | 104 FROM_HERE, |
105 base::Bind(&FileWriteWatcherImpl::StartWatchOnFileThread, | 105 base::Bind(&FileWriteWatcherImpl::StartWatchOnFileThread, |
106 base::Unretained(this), | 106 base::Unretained(this), |
107 path, | 107 path, |
108 google_apis::CreateRelayCallback(on_start_callback), | 108 google_apis::CreateRelayCallback(on_start_callback), |
109 google_apis::CreateRelayCallback(on_write_callback))); | 109 google_apis::CreateRelayCallback(on_write_callback))); |
110 } | 110 } |
111 | 111 |
112 FileWriteWatcher::FileWriteWatcherImpl::~FileWriteWatcherImpl() { | 112 FileWriteWatcher::FileWriteWatcherImpl::~FileWriteWatcherImpl() { |
113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 113 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
114 | 114 |
115 STLDeleteContainerPairSecondPointers(watchers_.begin(), watchers_.end()); | 115 STLDeleteContainerPairSecondPointers(watchers_.begin(), watchers_.end()); |
116 } | 116 } |
117 | 117 |
118 void FileWriteWatcher::FileWriteWatcherImpl::DestroyOnFileThread() { | 118 void FileWriteWatcher::FileWriteWatcherImpl::DestroyOnFileThread() { |
119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 119 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
120 | 120 |
121 delete this; | 121 delete this; |
122 } | 122 } |
123 | 123 |
124 void FileWriteWatcher::FileWriteWatcherImpl::StartWatchOnFileThread( | 124 void FileWriteWatcher::FileWriteWatcherImpl::StartWatchOnFileThread( |
125 const base::FilePath& path, | 125 const base::FilePath& path, |
126 const StartWatchCallback& on_start_callback, | 126 const StartWatchCallback& on_start_callback, |
127 const base::Closure& on_write_callback) { | 127 const base::Closure& on_write_callback) { |
128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 128 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
129 | 129 |
130 std::map<base::FilePath, PathWatchInfo*>::iterator it = watchers_.find(path); | 130 std::map<base::FilePath, PathWatchInfo*>::iterator it = watchers_.find(path); |
131 if (it != watchers_.end()) { | 131 if (it != watchers_.end()) { |
132 // We are already watching the path. | 132 // We are already watching the path. |
133 on_start_callback.Run(true); | 133 on_start_callback.Run(true); |
134 it->second->on_write_callbacks.push_back(on_write_callback); | 134 it->second->on_write_callbacks.push_back(on_write_callback); |
135 return; | 135 return; |
136 } | 136 } |
137 | 137 |
138 // Start watching |path|. | 138 // Start watching |path|. |
139 scoped_ptr<PathWatchInfo> info(new PathWatchInfo(on_write_callback)); | 139 scoped_ptr<PathWatchInfo> info(new PathWatchInfo(on_write_callback)); |
140 bool ok = info->watcher.Watch( | 140 bool ok = info->watcher.Watch( |
141 path, | 141 path, |
142 false, // recursive | 142 false, // recursive |
143 base::Bind(&FileWriteWatcherImpl::OnWriteEvent, | 143 base::Bind(&FileWriteWatcherImpl::OnWriteEvent, |
144 weak_ptr_factory_.GetWeakPtr())); | 144 weak_ptr_factory_.GetWeakPtr())); |
145 watchers_[path] = info.release(); | 145 watchers_[path] = info.release(); |
146 on_start_callback.Run(ok); | 146 on_start_callback.Run(ok); |
147 } | 147 } |
148 | 148 |
149 void FileWriteWatcher::FileWriteWatcherImpl::OnWriteEvent( | 149 void FileWriteWatcher::FileWriteWatcherImpl::OnWriteEvent( |
150 const base::FilePath& path, | 150 const base::FilePath& path, |
151 bool error) { | 151 bool error) { |
152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 152 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
153 | 153 |
154 if (error) | 154 if (error) |
155 return; | 155 return; |
156 | 156 |
157 std::map<base::FilePath, PathWatchInfo*>::iterator it = watchers_.find(path); | 157 std::map<base::FilePath, PathWatchInfo*>::iterator it = watchers_.find(path); |
158 DCHECK(it != watchers_.end()); | 158 DCHECK(it != watchers_.end()); |
159 | 159 |
160 // Heuristics for detecting the end of successive write operations. | 160 // Heuristics for detecting the end of successive write operations. |
161 // Delay running on_write_event_callback by |delay_| time, and if OnWriteEvent | 161 // Delay running on_write_event_callback by |delay_| time, and if OnWriteEvent |
162 // is called again in the period, the timer is reset. In other words, we | 162 // is called again in the period, the timer is reset. In other words, we |
163 // invoke callback when |delay_| has passed after the last OnWriteEvent(). | 163 // invoke callback when |delay_| has passed after the last OnWriteEvent(). |
164 it->second->timer.Start(FROM_HERE, | 164 it->second->timer.Start(FROM_HERE, |
165 delay_, | 165 delay_, |
166 base::Bind(&FileWriteWatcherImpl::InvokeCallback, | 166 base::Bind(&FileWriteWatcherImpl::InvokeCallback, |
167 weak_ptr_factory_.GetWeakPtr(), | 167 weak_ptr_factory_.GetWeakPtr(), |
168 path)); | 168 path)); |
169 } | 169 } |
170 | 170 |
171 void FileWriteWatcher::FileWriteWatcherImpl::InvokeCallback( | 171 void FileWriteWatcher::FileWriteWatcherImpl::InvokeCallback( |
172 const base::FilePath& path) { | 172 const base::FilePath& path) { |
173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 173 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
174 | 174 |
175 std::map<base::FilePath, PathWatchInfo*>::iterator it = watchers_.find(path); | 175 std::map<base::FilePath, PathWatchInfo*>::iterator it = watchers_.find(path); |
176 DCHECK(it != watchers_.end()); | 176 DCHECK(it != watchers_.end()); |
177 | 177 |
178 std::vector<base::Closure> callbacks; | 178 std::vector<base::Closure> callbacks; |
179 callbacks.swap(it->second->on_write_callbacks); | 179 callbacks.swap(it->second->on_write_callbacks); |
180 delete it->second; | 180 delete it->second; |
181 watchers_.erase(it); | 181 watchers_.erase(it); |
182 | 182 |
183 for (size_t i = 0; i < callbacks.size(); ++i) | 183 for (size_t i = 0; i < callbacks.size(); ++i) |
184 callbacks[i].Run(); | 184 callbacks[i].Run(); |
185 } | 185 } |
186 | 186 |
187 FileWriteWatcher::FileWriteWatcher() | 187 FileWriteWatcher::FileWriteWatcher() |
188 : watcher_impl_(new FileWriteWatcherImpl) { | 188 : watcher_impl_(new FileWriteWatcherImpl) { |
189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 189 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
190 } | 190 } |
191 | 191 |
192 FileWriteWatcher::~FileWriteWatcher() { | 192 FileWriteWatcher::~FileWriteWatcher() { |
193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 193 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
194 } | 194 } |
195 | 195 |
196 void FileWriteWatcher::StartWatch(const base::FilePath& file_path, | 196 void FileWriteWatcher::StartWatch(const base::FilePath& file_path, |
197 const StartWatchCallback& on_start_callback, | 197 const StartWatchCallback& on_start_callback, |
198 const base::Closure& on_write_callback) { | 198 const base::Closure& on_write_callback) { |
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 199 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
200 watcher_impl_->StartWatch(file_path, on_start_callback, on_write_callback); | 200 watcher_impl_->StartWatch(file_path, on_start_callback, on_write_callback); |
201 } | 201 } |
202 | 202 |
203 void FileWriteWatcher::DisableDelayForTesting() { | 203 void FileWriteWatcher::DisableDelayForTesting() { |
204 watcher_impl_->set_delay(base::TimeDelta()); | 204 watcher_impl_->set_delay(base::TimeDelta()); |
205 } | 205 } |
206 | 206 |
207 } // namespace internal | 207 } // namespace internal |
208 } // namespace drive | 208 } // namespace drive |
OLD | NEW |