Index: chrome/browser/local_discovery/storage/privet_filesystem_operations.cc |
diff --git a/chrome/browser/local_discovery/storage/privet_filesystem_operations.cc b/chrome/browser/local_discovery/storage/privet_filesystem_operations.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a151fbce647060c85883135a90fcbfa30b144702 |
--- /dev/null |
+++ b/chrome/browser/local_discovery/storage/privet_filesystem_operations.cc |
@@ -0,0 +1,184 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/local_discovery/storage/privet_filesystem_operations.h" |
+ |
+namespace local_discovery { |
+ |
+namespace { |
+const char kPrivetListEntries[] = "entries"; |
+const char kPrivetListKeyName[] = "name"; |
+const char kPrivetListKeySize[] = "size"; |
+const char kPrivetListKeyType[] = "type"; |
+const char kPrivetListTypeDir[] = "dir"; |
+} |
+ |
+PrivetFileSystemAsyncOperationUtil::PrivetFileSystemAsyncOperationUtil( |
+ const base::FilePath& full_path, |
+ net::URLRequestContextGetter* request_context, |
+ Delegate* delegate) |
+ : parsed_path_(full_path), request_context_(request_context), |
+ delegate_(delegate) { |
Vitaly Buka (NO REVIEWS)
2014/02/03 23:32:33
it would be nice to have DCHECK() for threads in b
Noam Samuel
2014/02/04 00:06:36
Done.
|
+} |
+ |
+PrivetFileSystemAsyncOperationUtil::~PrivetFileSystemAsyncOperationUtil() { |
+} |
+ |
+void PrivetFileSystemAsyncOperationUtil::Start() { |
+ service_discovery_client_ = ServiceDiscoverySharedClient::GetInstance(); |
+ privet_device_resolver_.reset(new PrivetDeviceResolver( |
+ service_discovery_client_.get(), |
+ parsed_path_.service_name, |
+ base::Bind( |
+ &PrivetFileSystemAsyncOperationUtil::OnGotDeviceDescription, |
+ base::Unretained(this)))); |
+ privet_device_resolver_->Start(); |
+} |
+ |
+void PrivetFileSystemAsyncOperationUtil::OnGotDeviceDescription( |
+ bool success, const DeviceDescription& device_description) { |
+ if (!success) { |
+ delegate_->PrivetFileSystemResolved(NULL, |
+ parsed_path_.path); |
+ return; |
+ } |
+ |
+ privet_async_factory_ = PrivetHTTPAsynchronousFactory::CreateInstance( |
+ service_discovery_client_.get(), |
+ request_context_.get()); |
+ privet_http_resolution_ = privet_async_factory_->CreatePrivetHTTP( |
+ parsed_path_.service_name, |
+ device_description.address, |
+ base::Bind(&PrivetFileSystemAsyncOperationUtil::OnGotPrivetHTTP, |
+ base::Unretained(this))); |
+ privet_http_resolution_->Start(); |
+} |
+ |
+void PrivetFileSystemAsyncOperationUtil::OnGotPrivetHTTP( |
+ scoped_ptr<PrivetHTTPClient> privet_http_client) { |
+ privet_client_ = privet_http_client.Pass(); |
+ delegate_->PrivetFileSystemResolved(privet_client_.get(), |
+ parsed_path_.path); |
+} |
+ |
+ |
+PrivetFileSystemListOperation::PrivetFileSystemListOperation( |
+ const base::FilePath& full_path, |
+ content::BrowserContext* browser_context, |
+ PrivetFileSystemAsyncOperationContainer* async_file_util, |
+ const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) |
+ : full_path_(full_path), browser_context_(browser_context), |
+ async_file_util_(async_file_util), |
+ callback_(callback), weak_factory_(this) { |
+} |
+ |
+PrivetFileSystemListOperation::~PrivetFileSystemListOperation() { |
+} |
+ |
+void PrivetFileSystemListOperation::Start() { |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind( |
+ &PrivetFileSystemListOperation::StartOnUIThread, |
+ weak_factory_.GetWeakPtr())); |
+} |
+ |
+void PrivetFileSystemListOperation::StartOnUIThread() { |
+ core_.reset(new PrivetFileSystemAsyncOperationUtil( |
+ full_path_, |
+ browser_context_->GetRequestContext(), |
+ this)); |
+ core_->Start(); |
+} |
+ |
+void PrivetFileSystemListOperation::PrivetFileSystemResolved( |
+ PrivetHTTPClient* http_client, |
+ const std::string& path) { |
+ if (!http_client) { |
+ TriggerCallback(base::File::FILE_ERROR_FAILED, |
+ fileapi::AsyncFileUtil::EntryList(), false); |
+ return; |
+ } |
+ |
+ list_operation_ = http_client->CreateStorageListOperation( |
+ path, |
+ base::Bind(&PrivetFileSystemListOperation::OnStorageListResult, |
+ base::Unretained(this))); |
+ list_operation_->Start(); |
+} |
+ |
+void PrivetFileSystemListOperation::TriggerCallback( |
+ base::File::Error result, |
+ const fileapi::AsyncFileUtil::EntryList& file_list, |
+ bool has_more) { |
+ list_operation_.reset(); |
+ core_.reset(); |
+ content::BrowserThread::PostTask( |
+ content::BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind( |
+ &PrivetFileSystemListOperation::TriggerCallbackOnIOThread, |
+ weak_factory_.GetWeakPtr(), |
Vitaly Buka (NO REVIEWS)
2014/02/03 23:32:33
race condition again
Noam Samuel
2014/02/04 00:06:36
OK for this one. Will fix on next one.
|
+ result, file_list, has_more)); |
+} |
+ |
+void PrivetFileSystemListOperation::TriggerCallbackOnIOThread( |
+ base::File::Error result, |
+ fileapi::AsyncFileUtil::EntryList file_list, |
+ bool has_more) { |
+ fileapi::AsyncFileUtil::ReadDirectoryCallback callback; |
+ callback = callback_; |
+ async_file_util_->RemoveOperation(this); |
+ callback.Run(result, file_list, has_more); |
+} |
+ |
+void PrivetFileSystemListOperation::OnStorageListResult( |
+ const base::DictionaryValue* value) { |
+ fileapi::AsyncFileUtil::EntryList entry_list; |
+ |
+ if (!value) { |
+ TriggerCallback(base::File::FILE_ERROR_FAILED, |
+ fileapi::AsyncFileUtil::EntryList(), false); |
+ return; |
+ } |
+ |
+ const base::ListValue* entries; |
+ if (!value->GetList(kPrivetListEntries, &entries)) { |
+ TriggerCallback(base::File::FILE_ERROR_FAILED, |
+ fileapi::AsyncFileUtil::EntryList(), false); |
+ return; |
+ } |
+ |
+ for (uint i = 0; i < entries->GetSize(); i++) { |
+ const base::DictionaryValue* entry_value; |
+ if (!entries->GetDictionary(i, &entry_value)) { |
+ TriggerCallback(base::File::FILE_ERROR_FAILED, |
+ fileapi::AsyncFileUtil::EntryList(), false); |
+ return; |
+ } |
+ |
+ std::string name; |
+ std::string type; |
+ int size = 0; |
+ |
+ entry_value->GetString(kPrivetListKeyName, &name); |
+ entry_value->GetString(kPrivetListKeyType, &type); |
+ entry_value->GetInteger(kPrivetListKeySize, &size); |
+ |
+ fileapi::DirectoryEntry entry( |
+ name, |
+ (type == kPrivetListTypeDir) ? |
+ fileapi::DirectoryEntry::DIRECTORY : fileapi::DirectoryEntry::FILE, |
+ size, |
+ base::Time() /* TODO(noamsml) */); |
+ |
+ entry_list.push_back(entry); |
+ } |
+ |
+ TriggerCallback(base::File::FILE_OK, entry_list, false); |
+} |
+ |
+ |
+} // namespace local_discovery |