Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: chrome/browser/file_system/entry_watcher_service.cc

Issue 452043003: [ew] Add basic classes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Uploaded. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 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/file_system/entry_watcher_service.h"
6
7 #include "base/thread_task_runner_handle.h"
8 #include "chrome/browser/extensions/extension_util.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/common/extensions/api/file_system.h"
11 #include "components/keyed_service/content/browser_context_dependency_manager.h"
12 #include "content/public/browser/browser_context.h"
13 #include "content/public/browser/storage_partition.h"
14 #include "extensions/browser/event_router.h"
15 #include "webkit/browser/fileapi/file_system_context.h"
16
17 namespace {
18
19 // Default implementation for dispatching an event. Can be replaced for unit
20 // tests by EntryWatcherService::SetDispatchEventImplForTesting().
21 void DispatchEventImpl(extensions::EventRouter* event_router,
22 const std::string& extension_id,
23 scoped_ptr<extensions::Event> event) {
24 event_router->DispatchEventToExtension(extension_id, event.Pass());
25 }
26
27 // Default implementation for acquiring a file system context for a specific
28 // |extension_id| and |context|.
29 fileapi::FileSystemContext* GetFileSystemContextImpl(
30 const std::string& extension_id,
31 content::BrowserContext* context) {
32 const GURL site =
33 extensions::util::GetSiteForExtensionId(extension_id, context);
34 return content::BrowserContext::GetStoragePartitionForSite(context, site)
35 ->GetFileSystemContext();
36 }
37
38 } // namespace
39
40 EntryWatcherService::EntryWatcherService(content::BrowserContext* context)
41 : context_(context),
42 dispatch_event_impl_(base::Bind(&DispatchEventImpl,
43 extensions::EventRouter::Get(context))),
44 get_file_system_context_impl_(base::Bind(&GetFileSystemContextImpl)),
45 observing_(this),
46 weak_ptr_factory_(this) {
47 // TODO(mtomasz): Restore persistent watchers.
48 }
49
50 EntryWatcherService::~EntryWatcherService() {
51 }
52
53 void EntryWatcherService::SetDispatchEventImplForTesting(
54 const DispatchEventImplCallback& callback) {
55 dispatch_event_impl_ = callback;
56 }
57
58 void EntryWatcherService::SetGetFileSystemContextImplForTesting(
59 const GetFileSystemContextImplCallback& callback) {
60 get_file_system_context_impl_ = callback;
61 }
62
63 void EntryWatcherService::WatchDirectory(
64 const std::string& extension_id,
65 const fileapi::FileSystemURL& url,
66 bool recursive,
67 const fileapi::WatcherManager::StatusCallback& callback) {
68 // TODO(mtomasz): Add support for recursive watchers.
69 if (recursive) {
70 base::ThreadTaskRunnerHandle::Get()->PostTask(
71 FROM_HERE,
72 base::Bind(callback, base::File::FILE_ERROR_INVALID_OPERATION));
73 return;
74 }
75
76 fileapi::FileSystemContext* const context =
77 get_file_system_context_impl_.Run(extension_id, context_);
78 DCHECK(context);
79
80 fileapi::WatcherManager* const watcher_manager =
81 context->GetWatcherManager(url.type());
82 if (!watcher_manager) {
83 base::ThreadTaskRunnerHandle::Get()->PostTask(
84 FROM_HERE,
85 base::Bind(callback, base::File::FILE_ERROR_INVALID_OPERATION));
86 return;
87 }
88
89 watcher_manager->WatchDirectory(
90 url,
91 recursive,
92 base::Bind(&EntryWatcherService::OnWatchDirectoryCompleted,
93 weak_ptr_factory_.GetWeakPtr(),
94 extension_id,
95 url,
96 recursive,
97 callback));
98 }
99
100 void EntryWatcherService::UnwatchEntry(
101 const std::string& extension_id,
102 const fileapi::FileSystemURL& url,
103 const fileapi::WatcherManager::StatusCallback& callback) {
104 fileapi::FileSystemContext* const context =
105 get_file_system_context_impl_.Run(extension_id, context_);
106 DCHECK(context);
107
108 fileapi::WatcherManager* const watcher_manager =
109 context->GetWatcherManager(url.type());
110 if (!watcher_manager) {
111 base::ThreadTaskRunnerHandle::Get()->PostTask(
112 FROM_HERE,
113 base::Bind(callback, base::File::FILE_ERROR_INVALID_OPERATION));
114 return;
115 }
116
117 watcher_manager->UnwatchEntry(
118 url,
119 base::Bind(&EntryWatcherService::OnUnwatchEntryCompleted,
120 weak_ptr_factory_.GetWeakPtr(),
121 extension_id,
122 url,
123 callback));
124 }
125
126 std::vector<fileapi::FileSystemURL> EntryWatcherService::GetWatchedEntries(
127 const std::string& extension_id) {
128 std::vector<fileapi::FileSystemURL> result;
129 for (WatcherMap::const_iterator it = watchers_.begin(); it != watchers_.end();
130 ++it) {
131 const std::map<std::string, EntryWatcher>::const_iterator watcher_it =
132 it->second.find(extension_id);
133 if (watcher_it != it->second.end())
134 result.push_back(watcher_it->second.url);
135 }
136
137 return result;
138 }
139
140 void EntryWatcherService::OnEntryChanged(const fileapi::FileSystemURL& url) {
141 const WatcherMap::const_iterator it = watchers_.find(url.ToGURL());
142 DCHECK(it != watchers_.end());
143 for (std::map<std::string, EntryWatcher>::const_iterator watcher_it =
144 it->second.begin();
145 watcher_it != it->second.end();
146 ++watcher_it) {
147 const std::string& extension_id = watcher_it->first;
148 extensions::api::file_system::EntryChangedEvent event;
149 dispatch_event_impl_.Run(
150 extension_id,
151 make_scoped_ptr(new extensions::Event(
152 extensions::api::file_system::OnEntryChanged::kEventName,
153 extensions::api::file_system::OnEntryChanged::Create(event))));
154 }
155 }
156
157 void EntryWatcherService::OnEntryRemoved(const fileapi::FileSystemURL& url) {
158 WatcherMap::const_iterator it = watchers_.find(url.ToGURL());
159 DCHECK(it != watchers_.end());
160 for (std::map<std::string, EntryWatcher>::const_iterator watcher_it =
161 it->second.begin();
162 watcher_it != it->second.end();
163 ++watcher_it) {
164 const std::string& extension_id = watcher_it->first;
165 extensions::api::file_system::EntryRemovedEvent event;
166 dispatch_event_impl_.Run(
167 extension_id,
168 make_scoped_ptr(new extensions::Event(
169 extensions::api::file_system::OnEntryRemoved::kEventName,
170 extensions::api::file_system::OnEntryRemoved::Create(event))));
171 }
172 }
173
174 void EntryWatcherService::OnWatchDirectoryCompleted(
175 const std::string& extension_id,
176 const fileapi::FileSystemURL& url,
177 bool recursive,
178 const fileapi::WatcherManager::StatusCallback& callback,
179 base::File::Error result) {
180 if (result != base::File::FILE_OK) {
181 callback.Run(result);
182 return;
183 }
184
185 fileapi::FileSystemContext* const context =
186 get_file_system_context_impl_.Run(extension_id, context_);
187 DCHECK(context);
188
189 fileapi::WatcherManager* const watcher_manager =
190 context->GetWatcherManager(url.type());
191 if (!watcher_manager) {
192 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
193 return;
194 }
195
196 // Observe the manager if not observed yet.
197 if (!observing_.IsObserving(watcher_manager))
198 observing_.Add(watcher_manager);
199
200 const GURL gurl = url.ToGURL();
201 watchers_[gurl][extension_id] =
202 EntryWatcher(url, true /* directory */, recursive);
203
204 // TODO(mtomasz): Save in preferences.
205
206 callback.Run(base::File::FILE_OK);
207 }
208
209 void EntryWatcherService::OnUnwatchEntryCompleted(
210 const std::string& extension_id,
211 const fileapi::FileSystemURL& url,
212 const fileapi::WatcherManager::StatusCallback& callback,
213 base::File::Error result) {
214 if (result != base::File::FILE_OK) {
215 callback.Run(result);
216 return;
217 }
218
219 DCHECK_EQ(base::File::FILE_OK, result);
benwells 2014/08/14 05:16:32 This DCHECK can be removed as well.
mtomasz 2014/08/15 05:35:57 Done.
220
221 const GURL gurl = url.ToGURL();
222 if (watchers_[gurl].erase(extension_id) == 0) {
223 callback.Run(base::File::FILE_ERROR_NOT_FOUND);
224 return;
225 }
226
227 if (watchers_[gurl].empty())
228 watchers_.erase(gurl);
229
230 // TODO(mtomasz): Save in preferences.
231
232 callback.Run(base::File::FILE_OK);
233 }
234
235 EntryWatcherService::EntryWatcher::EntryWatcher()
236 : directory(false), recursive(false) {
237 }
238
239 EntryWatcherService::EntryWatcher::EntryWatcher(
240 const fileapi::FileSystemURL& url,
241 bool directory,
242 bool recursive)
243 : url(url), directory(directory), recursive(recursive) {
244 }
245
246 EntryWatcherService::EntryWatcher::~EntryWatcher() {
247 }
OLDNEW
« no previous file with comments | « chrome/browser/file_system/entry_watcher_service.h ('k') | chrome/browser/file_system/entry_watcher_service_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698