OLD | NEW |
| (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/local_discovery/storage/privet_filesystem_operations.h" | |
6 | |
7 #include "chrome/browser/local_discovery/storage/privet_filesystem_constants.h" | |
8 | |
9 namespace local_discovery { | |
10 | |
11 PrivetFileSystemOperationFactory::PrivetFileSystemOperationFactory( | |
12 content::BrowserContext* browser_context) | |
13 : browser_context_(browser_context), weak_factory_(this) {} | |
14 | |
15 PrivetFileSystemOperationFactory::~PrivetFileSystemOperationFactory() { | |
16 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
17 RemoveAllOperations(); | |
18 } | |
19 | |
20 void PrivetFileSystemOperationFactory::GetFileInfo( | |
21 const storage::FileSystemURL& url, | |
22 const storage::AsyncFileUtil::GetFileInfoCallback& callback) { | |
23 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
24 PrivetFileSystemAsyncOperation* operation = | |
25 new PrivetFileSystemDetailsOperation( | |
26 url.path(), browser_context_, this, &attribute_cache_, callback); | |
27 async_operations_.insert(operation); | |
28 operation->Start(); | |
29 } | |
30 | |
31 void PrivetFileSystemOperationFactory::ReadDirectory( | |
32 const storage::FileSystemURL& url, | |
33 const storage::AsyncFileUtil::ReadDirectoryCallback& callback) { | |
34 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
35 PrivetFileSystemAsyncOperation* operation = new PrivetFileSystemListOperation( | |
36 url.path(), browser_context_, this, &attribute_cache_, callback); | |
37 async_operations_.insert(operation); | |
38 operation->Start(); | |
39 } | |
40 | |
41 void PrivetFileSystemOperationFactory::RemoveOperation( | |
42 PrivetFileSystemAsyncOperation* operation) { | |
43 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
44 async_operations_.erase(operation); | |
45 delete operation; | |
46 } | |
47 | |
48 void PrivetFileSystemOperationFactory::RemoveAllOperations() { | |
49 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
50 STLDeleteElements(&async_operations_); | |
51 } | |
52 | |
53 PrivetFileSystemAsyncOperationUtil::PrivetFileSystemAsyncOperationUtil( | |
54 const base::FilePath& full_path, | |
55 content::BrowserContext* browser_context, | |
56 Delegate* delegate) | |
57 : parsed_path_(full_path), | |
58 browser_context_(browser_context), | |
59 delegate_(delegate), | |
60 weak_factory_(this) { | |
61 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
62 } | |
63 | |
64 PrivetFileSystemAsyncOperationUtil::~PrivetFileSystemAsyncOperationUtil() { | |
65 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
66 } | |
67 | |
68 void PrivetFileSystemAsyncOperationUtil::Start() { | |
69 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
70 request_context_ = browser_context_->GetRequestContext(); | |
71 service_discovery_client_ = ServiceDiscoverySharedClient::GetInstance(); | |
72 privet_device_resolver_.reset(new PrivetDeviceResolver( | |
73 service_discovery_client_.get(), | |
74 parsed_path_.service_name, | |
75 base::Bind( | |
76 &PrivetFileSystemAsyncOperationUtil::OnGotDeviceDescription, | |
77 base::Unretained(this)))); | |
78 privet_device_resolver_->Start(); | |
79 } | |
80 | |
81 void PrivetFileSystemAsyncOperationUtil::OnGotDeviceDescription( | |
82 bool success, const DeviceDescription& device_description) { | |
83 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
84 if (!success) { | |
85 delegate_->PrivetFileSystemResolved(NULL, parsed_path_.path); | |
86 return; | |
87 } | |
88 | |
89 privet_async_factory_ = PrivetHTTPAsynchronousFactory::CreateInstance( | |
90 service_discovery_client_.get(), request_context_.get()); | |
91 privet_http_resolution_ = privet_async_factory_->CreatePrivetHTTP( | |
92 parsed_path_.service_name, | |
93 device_description.address, | |
94 base::Bind(&PrivetFileSystemAsyncOperationUtil::OnGotPrivetHTTP, | |
95 base::Unretained(this))); | |
96 privet_http_resolution_->Start(); | |
97 } | |
98 | |
99 void PrivetFileSystemAsyncOperationUtil::OnGotPrivetHTTP( | |
100 scoped_ptr<PrivetHTTPClient> privet_http_client) { | |
101 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
102 privet_client_ = PrivetV1HTTPClient::CreateDefault(privet_http_client.Pass()); | |
103 delegate_->PrivetFileSystemResolved(privet_client_.get(), | |
104 parsed_path_.path); | |
105 } | |
106 | |
107 PrivetFileSystemListOperation::PrivetFileSystemListOperation( | |
108 const base::FilePath& full_path, | |
109 content::BrowserContext* browser_context, | |
110 PrivetFileSystemAsyncOperationContainer* container, | |
111 PrivetFileSystemAttributeCache* attribute_cache, | |
112 const storage::AsyncFileUtil::ReadDirectoryCallback& callback) | |
113 : core_(full_path, browser_context, this), | |
114 full_path_(full_path), | |
115 container_(container), | |
116 attribute_cache_(attribute_cache), | |
117 callback_(callback) { | |
118 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
119 } | |
120 | |
121 PrivetFileSystemListOperation::~PrivetFileSystemListOperation() { | |
122 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
123 } | |
124 | |
125 void PrivetFileSystemListOperation::Start() { | |
126 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
127 core_.Start(); | |
128 } | |
129 | |
130 void PrivetFileSystemListOperation::PrivetFileSystemResolved( | |
131 PrivetV1HTTPClient* http_client, | |
132 const std::string& path) { | |
133 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
134 if (!http_client) { | |
135 SignalError(); | |
136 return; | |
137 } | |
138 | |
139 list_operation_ = http_client->CreateStorageListOperation( | |
140 path, | |
141 base::Bind(&PrivetFileSystemListOperation::OnStorageListResult, | |
142 base::Unretained(this))); | |
143 list_operation_->Start(); | |
144 } | |
145 | |
146 void PrivetFileSystemListOperation::OnStorageListResult( | |
147 const base::DictionaryValue* value) { | |
148 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
149 list_operation_.reset(); | |
150 | |
151 if (!value) { | |
152 SignalError(); | |
153 return; | |
154 } | |
155 | |
156 attribute_cache_->AddFileInfoFromJSON(full_path_, value); | |
157 | |
158 storage::AsyncFileUtil::EntryList entry_list; | |
159 | |
160 const base::ListValue* entries; | |
161 if (!value->GetList(kPrivetListEntries, &entries)) { | |
162 SignalError(); | |
163 return; | |
164 } | |
165 | |
166 for (size_t i = 0; i < entries->GetSize(); i++) { | |
167 const base::DictionaryValue* entry_value; | |
168 if (!entries->GetDictionary(i, &entry_value)) { | |
169 SignalError(); | |
170 return; | |
171 } | |
172 | |
173 std::string name; | |
174 std::string type; | |
175 int size = 0; | |
176 | |
177 entry_value->GetString(kPrivetListKeyName, &name); | |
178 entry_value->GetString(kPrivetListKeyType, &type); | |
179 entry_value->GetInteger(kPrivetListKeySize, &size); | |
180 | |
181 storage::DirectoryEntry entry(name, | |
182 (type == kPrivetListTypeDir) | |
183 ? storage::DirectoryEntry::DIRECTORY | |
184 : storage::DirectoryEntry::FILE, | |
185 size, | |
186 base::Time() /* TODO(noamsml) */); | |
187 | |
188 entry_list.push_back(entry); | |
189 } | |
190 | |
191 TriggerCallbackAndDestroy(base::File::FILE_OK, entry_list, false); | |
192 } | |
193 | |
194 void PrivetFileSystemListOperation::SignalError() { | |
195 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
196 TriggerCallbackAndDestroy(base::File::FILE_ERROR_FAILED, | |
197 storage::AsyncFileUtil::EntryList(), | |
198 false); | |
199 } | |
200 | |
201 void PrivetFileSystemListOperation::TriggerCallbackAndDestroy( | |
202 base::File::Error result, | |
203 const storage::AsyncFileUtil::EntryList& file_list, | |
204 bool has_more) { | |
205 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
206 content::BrowserThread::PostTask( | |
207 content::BrowserThread::IO, | |
208 FROM_HERE, | |
209 base::Bind(callback_, result, file_list, has_more)); | |
210 container_->RemoveOperation(this); | |
211 } | |
212 | |
213 PrivetFileSystemDetailsOperation::PrivetFileSystemDetailsOperation( | |
214 const base::FilePath& full_path, | |
215 content::BrowserContext* browser_context, | |
216 PrivetFileSystemAsyncOperationContainer* container, | |
217 PrivetFileSystemAttributeCache* attribute_cache, | |
218 const storage::AsyncFileUtil::GetFileInfoCallback& callback) | |
219 : core_(full_path, browser_context, this), | |
220 full_path_(full_path), | |
221 container_(container), | |
222 attribute_cache_(attribute_cache), | |
223 callback_(callback) { | |
224 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
225 } | |
226 | |
227 PrivetFileSystemDetailsOperation::~PrivetFileSystemDetailsOperation() { | |
228 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
229 } | |
230 | |
231 void PrivetFileSystemDetailsOperation::Start() { | |
232 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
233 const base::File::Info* info = attribute_cache_->GetFileInfo(full_path_); | |
234 if (info) { | |
235 TriggerCallbackAndDestroy(base::File::FILE_OK, *info); | |
236 return; | |
237 } | |
238 | |
239 core_.Start(); | |
240 } | |
241 | |
242 void PrivetFileSystemDetailsOperation::PrivetFileSystemResolved( | |
243 PrivetV1HTTPClient* http_client, | |
244 const std::string& path) { | |
245 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
246 if (!http_client) { | |
247 SignalError(); | |
248 return; | |
249 } | |
250 | |
251 list_operation_ = http_client->CreateStorageListOperation( | |
252 path, | |
253 base::Bind(&PrivetFileSystemDetailsOperation::OnStorageListResult, | |
254 base::Unretained(this))); | |
255 list_operation_->Start(); | |
256 } | |
257 | |
258 void PrivetFileSystemDetailsOperation::OnStorageListResult( | |
259 const base::DictionaryValue* value) { | |
260 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
261 list_operation_.reset(); | |
262 | |
263 attribute_cache_->AddFileInfoFromJSON(full_path_, value); | |
264 const base::File::Info* info = attribute_cache_->GetFileInfo(full_path_); | |
265 | |
266 if (info) { | |
267 TriggerCallbackAndDestroy(base::File::FILE_OK, *info); | |
268 } else { | |
269 SignalError(); | |
270 } | |
271 } | |
272 | |
273 void PrivetFileSystemDetailsOperation::SignalError() { | |
274 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
275 TriggerCallbackAndDestroy(base::File::FILE_ERROR_FAILED, base::File::Info()); | |
276 } | |
277 | |
278 void PrivetFileSystemDetailsOperation::TriggerCallbackAndDestroy( | |
279 base::File::Error result, | |
280 const base::File::Info& info) { | |
281 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
282 content::BrowserThread::PostTask(content::BrowserThread::IO, | |
283 FROM_HERE, | |
284 base::Bind(callback_, result, info)); | |
285 container_->RemoveOperation(this); | |
286 } | |
287 | |
288 } // namespace local_discovery | |
OLD | NEW |