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 namespace local_discovery { | |
8 | |
9 namespace { | |
10 const char kPrivetListEntries[] = "entries"; | |
11 const char kPrivetListKeyName[] = "name"; | |
12 const char kPrivetListKeySize[] = "size"; | |
13 const char kPrivetListKeyType[] = "type"; | |
14 const char kPrivetListTypeDir[] = "dir"; | |
15 } | |
16 | |
17 PrivetFileSystemAsyncOperationUtil::PrivetFileSystemAsyncOperationUtil( | |
18 const base::FilePath& full_path, | |
19 net::URLRequestContextGetter* request_context, | |
20 Delegate* delegate) | |
21 : parsed_path_(full_path), request_context_(request_context), | |
22 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.
| |
23 } | |
24 | |
25 PrivetFileSystemAsyncOperationUtil::~PrivetFileSystemAsyncOperationUtil() { | |
26 } | |
27 | |
28 void PrivetFileSystemAsyncOperationUtil::Start() { | |
29 service_discovery_client_ = ServiceDiscoverySharedClient::GetInstance(); | |
30 privet_device_resolver_.reset(new PrivetDeviceResolver( | |
31 service_discovery_client_.get(), | |
32 parsed_path_.service_name, | |
33 base::Bind( | |
34 &PrivetFileSystemAsyncOperationUtil::OnGotDeviceDescription, | |
35 base::Unretained(this)))); | |
36 privet_device_resolver_->Start(); | |
37 } | |
38 | |
39 void PrivetFileSystemAsyncOperationUtil::OnGotDeviceDescription( | |
40 bool success, const DeviceDescription& device_description) { | |
41 if (!success) { | |
42 delegate_->PrivetFileSystemResolved(NULL, | |
43 parsed_path_.path); | |
44 return; | |
45 } | |
46 | |
47 privet_async_factory_ = PrivetHTTPAsynchronousFactory::CreateInstance( | |
48 service_discovery_client_.get(), | |
49 request_context_.get()); | |
50 privet_http_resolution_ = privet_async_factory_->CreatePrivetHTTP( | |
51 parsed_path_.service_name, | |
52 device_description.address, | |
53 base::Bind(&PrivetFileSystemAsyncOperationUtil::OnGotPrivetHTTP, | |
54 base::Unretained(this))); | |
55 privet_http_resolution_->Start(); | |
56 } | |
57 | |
58 void PrivetFileSystemAsyncOperationUtil::OnGotPrivetHTTP( | |
59 scoped_ptr<PrivetHTTPClient> privet_http_client) { | |
60 privet_client_ = privet_http_client.Pass(); | |
61 delegate_->PrivetFileSystemResolved(privet_client_.get(), | |
62 parsed_path_.path); | |
63 } | |
64 | |
65 | |
66 PrivetFileSystemListOperation::PrivetFileSystemListOperation( | |
67 const base::FilePath& full_path, | |
68 content::BrowserContext* browser_context, | |
69 PrivetFileSystemAsyncOperationContainer* async_file_util, | |
70 const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) | |
71 : full_path_(full_path), browser_context_(browser_context), | |
72 async_file_util_(async_file_util), | |
73 callback_(callback), weak_factory_(this) { | |
74 } | |
75 | |
76 PrivetFileSystemListOperation::~PrivetFileSystemListOperation() { | |
77 } | |
78 | |
79 void PrivetFileSystemListOperation::Start() { | |
80 content::BrowserThread::PostTask( | |
81 content::BrowserThread::UI, | |
82 FROM_HERE, | |
83 base::Bind( | |
84 &PrivetFileSystemListOperation::StartOnUIThread, | |
85 weak_factory_.GetWeakPtr())); | |
86 } | |
87 | |
88 void PrivetFileSystemListOperation::StartOnUIThread() { | |
89 core_.reset(new PrivetFileSystemAsyncOperationUtil( | |
90 full_path_, | |
91 browser_context_->GetRequestContext(), | |
92 this)); | |
93 core_->Start(); | |
94 } | |
95 | |
96 void PrivetFileSystemListOperation::PrivetFileSystemResolved( | |
97 PrivetHTTPClient* http_client, | |
98 const std::string& path) { | |
99 if (!http_client) { | |
100 TriggerCallback(base::File::FILE_ERROR_FAILED, | |
101 fileapi::AsyncFileUtil::EntryList(), false); | |
102 return; | |
103 } | |
104 | |
105 list_operation_ = http_client->CreateStorageListOperation( | |
106 path, | |
107 base::Bind(&PrivetFileSystemListOperation::OnStorageListResult, | |
108 base::Unretained(this))); | |
109 list_operation_->Start(); | |
110 } | |
111 | |
112 void PrivetFileSystemListOperation::TriggerCallback( | |
113 base::File::Error result, | |
114 const fileapi::AsyncFileUtil::EntryList& file_list, | |
115 bool has_more) { | |
116 list_operation_.reset(); | |
117 core_.reset(); | |
118 content::BrowserThread::PostTask( | |
119 content::BrowserThread::IO, | |
120 FROM_HERE, | |
121 base::Bind( | |
122 &PrivetFileSystemListOperation::TriggerCallbackOnIOThread, | |
123 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.
| |
124 result, file_list, has_more)); | |
125 } | |
126 | |
127 void PrivetFileSystemListOperation::TriggerCallbackOnIOThread( | |
128 base::File::Error result, | |
129 fileapi::AsyncFileUtil::EntryList file_list, | |
130 bool has_more) { | |
131 fileapi::AsyncFileUtil::ReadDirectoryCallback callback; | |
132 callback = callback_; | |
133 async_file_util_->RemoveOperation(this); | |
134 callback.Run(result, file_list, has_more); | |
135 } | |
136 | |
137 void PrivetFileSystemListOperation::OnStorageListResult( | |
138 const base::DictionaryValue* value) { | |
139 fileapi::AsyncFileUtil::EntryList entry_list; | |
140 | |
141 if (!value) { | |
142 TriggerCallback(base::File::FILE_ERROR_FAILED, | |
143 fileapi::AsyncFileUtil::EntryList(), false); | |
144 return; | |
145 } | |
146 | |
147 const base::ListValue* entries; | |
148 if (!value->GetList(kPrivetListEntries, &entries)) { | |
149 TriggerCallback(base::File::FILE_ERROR_FAILED, | |
150 fileapi::AsyncFileUtil::EntryList(), false); | |
151 return; | |
152 } | |
153 | |
154 for (uint i = 0; i < entries->GetSize(); i++) { | |
155 const base::DictionaryValue* entry_value; | |
156 if (!entries->GetDictionary(i, &entry_value)) { | |
157 TriggerCallback(base::File::FILE_ERROR_FAILED, | |
158 fileapi::AsyncFileUtil::EntryList(), false); | |
159 return; | |
160 } | |
161 | |
162 std::string name; | |
163 std::string type; | |
164 int size = 0; | |
165 | |
166 entry_value->GetString(kPrivetListKeyName, &name); | |
167 entry_value->GetString(kPrivetListKeyType, &type); | |
168 entry_value->GetInteger(kPrivetListKeySize, &size); | |
169 | |
170 fileapi::DirectoryEntry entry( | |
171 name, | |
172 (type == kPrivetListTypeDir) ? | |
173 fileapi::DirectoryEntry::DIRECTORY : fileapi::DirectoryEntry::FILE, | |
174 size, | |
175 base::Time() /* TODO(noamsml) */); | |
176 | |
177 entry_list.push_back(entry); | |
178 } | |
179 | |
180 TriggerCallback(base::File::FILE_OK, entry_list, false); | |
181 } | |
182 | |
183 | |
184 } // namespace local_discovery | |
OLD | NEW |