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 "remoting/protocol/pairing_registry.h" | 5 #include "remoting/protocol/pairing_registry.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/guid.h" | 9 #include "base/guid.h" |
10 #include "base/json/json_string_value_serializer.h" | 10 #include "base/json/json_string_value_serializer.h" |
11 #include "base/location.h" | |
12 #include "base/single_thread_task_runner.h" | |
11 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
14 #include "base/thread_task_runner_handle.h" | |
12 #include "base/values.h" | 15 #include "base/values.h" |
13 #include "crypto/random.h" | 16 #include "crypto/random.h" |
14 | 17 |
15 namespace remoting { | 18 namespace remoting { |
16 namespace protocol { | 19 namespace protocol { |
17 | 20 |
18 // How many bytes of random data to use for the shared secret. | 21 // How many bytes of random data to use for the shared secret. |
19 const int kKeySize = 16; | 22 const int kKeySize = 16; |
20 | 23 |
21 const char PairingRegistry::kCreatedTimeKey[] = "createdTime"; | 24 const char PairingRegistry::kCreatedTimeKey[] = "createdTime"; |
22 const char PairingRegistry::kClientIdKey[] = "clientId"; | 25 const char PairingRegistry::kClientIdKey[] = "clientId"; |
23 const char PairingRegistry::kClientNameKey[] = "clientName"; | 26 const char PairingRegistry::kClientNameKey[] = "clientName"; |
24 const char PairingRegistry::kSharedSecretKey[] = "sharedSecret"; | 27 const char PairingRegistry::kSharedSecretKey[] = "sharedSecret"; |
25 | 28 |
26 PairingRegistry::Pairing::Pairing() { | 29 PairingRegistry::Pairing::Pairing() { |
27 } | 30 } |
28 | 31 |
29 PairingRegistry::Pairing::Pairing(const base::Time& created_time, | 32 PairingRegistry::Pairing::Pairing(const base::Time& created_time, |
30 const std::string& client_name, | 33 const std::string& client_name, |
31 const std::string& client_id, | 34 const std::string& client_id, |
32 const std::string& shared_secret) | 35 const std::string& shared_secret) |
33 : created_time_(created_time), | 36 : created_time_(created_time), |
34 client_name_(client_name), | 37 client_name_(client_name), |
35 client_id_(client_id), | 38 client_id_(client_id), |
36 shared_secret_(shared_secret) { | 39 shared_secret_(shared_secret) { |
37 } | 40 } |
38 | 41 |
42 PairingRegistry::Pairing::~Pairing() { | |
43 } | |
44 | |
39 PairingRegistry::Pairing PairingRegistry::Pairing::Create( | 45 PairingRegistry::Pairing PairingRegistry::Pairing::Create( |
40 const std::string& client_name) { | 46 const std::string& client_name) { |
41 base::Time created_time = base::Time::Now(); | 47 base::Time created_time = base::Time::Now(); |
42 std::string client_id = base::GenerateGUID(); | 48 std::string client_id = base::GenerateGUID(); |
43 std::string shared_secret; | 49 std::string shared_secret; |
44 char buffer[kKeySize]; | 50 char buffer[kKeySize]; |
45 crypto::RandBytes(buffer, arraysize(buffer)); | 51 crypto::RandBytes(buffer, arraysize(buffer)); |
46 if (!base::Base64Encode(base::StringPiece(buffer, arraysize(buffer)), | 52 if (!base::Base64Encode(base::StringPiece(buffer, arraysize(buffer)), |
47 &shared_secret)) { | 53 &shared_secret)) { |
48 LOG(FATAL) << "Base64Encode failed."; | 54 LOG(FATAL) << "Base64Encode failed."; |
49 } | 55 } |
50 return Pairing(created_time, client_name, client_id, shared_secret); | 56 return Pairing(created_time, client_name, client_id, shared_secret); |
51 } | 57 } |
52 | 58 |
53 PairingRegistry::Pairing::~Pairing() { | 59 PairingRegistry::Pairing PairingRegistry::Pairing::CreateFromValue( |
60 const base::Value& pairing_json) { | |
61 const base::DictionaryValue* pairing = NULL; | |
62 if (!pairing_json.GetAsDictionary(&pairing)) { | |
63 LOG(ERROR) << "Failed to load pairing information: not a dictionary."; | |
64 return Pairing(); | |
65 } | |
66 | |
67 std::string client_name, client_id, shared_secret; | |
68 double created_time_value; | |
69 if (pairing->GetDouble(kCreatedTimeKey, &created_time_value) && | |
70 pairing->GetString(kClientNameKey, &client_name) && | |
71 pairing->GetString(kClientIdKey, &client_id) && | |
72 pairing->GetString(kSharedSecretKey, &shared_secret)) { | |
73 base::Time created_time = base::Time::FromJsTime(created_time_value); | |
74 return Pairing(created_time, client_name, client_id, shared_secret); | |
75 } | |
76 | |
77 LOG(ERROR) << "Failed to load pairing information: unexpected format."; | |
78 return Pairing(); | |
79 } | |
80 | |
81 scoped_ptr<base::Value> PairingRegistry::Pairing::ToValue() const { | |
82 scoped_ptr<base::DictionaryValue> pairing(new base::DictionaryValue()); | |
83 pairing->SetDouble(kCreatedTimeKey, created_time().ToJsTime()); | |
84 pairing->SetString(kClientNameKey, client_name()); | |
85 pairing->SetString(kClientIdKey, client_id()); | |
86 if (!shared_secret().empty()) | |
87 pairing->SetString(kSharedSecretKey, shared_secret()); | |
88 return pairing.PassAs<base::Value>(); | |
54 } | 89 } |
55 | 90 |
56 bool PairingRegistry::Pairing::operator==(const Pairing& other) const { | 91 bool PairingRegistry::Pairing::operator==(const Pairing& other) const { |
57 return created_time_ == other.created_time_ && | 92 return created_time_ == other.created_time_ && |
58 client_id_ == other.client_id_ && | 93 client_id_ == other.client_id_ && |
59 client_name_ == other.client_name_ && | 94 client_name_ == other.client_name_ && |
60 shared_secret_ == other.shared_secret_; | 95 shared_secret_ == other.shared_secret_; |
61 } | 96 } |
62 | 97 |
63 bool PairingRegistry::Pairing::is_valid() const { | 98 bool PairingRegistry::Pairing::is_valid() const { |
64 return !client_id_.empty() && !shared_secret_.empty(); | 99 return !client_id_.empty() && !shared_secret_.empty(); |
65 } | 100 } |
66 | 101 |
67 PairingRegistry::PairingRegistry(scoped_ptr<Delegate> delegate) | 102 PairingRegistry::PairingRegistry( |
68 : delegate_(delegate.Pass()) { | 103 scoped_refptr<base::SingleThreadTaskRunner> delegate_task_runner, |
104 scoped_ptr<Delegate> delegate) | |
105 : caller_task_runner_(base::ThreadTaskRunnerHandle::Get()), | |
106 delegate_task_runner_(delegate_task_runner), | |
107 delegate_(delegate.Pass()) { | |
69 DCHECK(delegate_); | 108 DCHECK(delegate_); |
70 } | 109 } |
71 | 110 |
72 PairingRegistry::~PairingRegistry() { | |
73 } | |
74 | |
75 PairingRegistry::Pairing PairingRegistry::CreatePairing( | 111 PairingRegistry::Pairing PairingRegistry::CreatePairing( |
76 const std::string& client_name) { | 112 const std::string& client_name) { |
77 DCHECK(CalledOnValidThread()); | 113 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
114 | |
78 Pairing result = Pairing::Create(client_name); | 115 Pairing result = Pairing::Create(client_name); |
79 AddPairing(result); | 116 AddPairing(result); |
80 return result; | 117 return result; |
81 } | 118 } |
82 | 119 |
83 void PairingRegistry::GetPairing(const std::string& client_id, | 120 void PairingRegistry::GetPairing(const std::string& client_id, |
84 const GetPairingCallback& callback) { | 121 const GetPairingCallback& callback) { |
85 DCHECK(CalledOnValidThread()); | 122 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
123 | |
86 GetPairingCallback wrapped_callback = base::Bind( | 124 GetPairingCallback wrapped_callback = base::Bind( |
87 &PairingRegistry::InvokeGetPairingCallbackAndScheduleNext, | 125 &PairingRegistry::InvokeGetPairingCallbackAndScheduleNext, |
88 this, callback); | 126 this, callback); |
89 LoadCallback load_callback = base::Bind( | |
90 &PairingRegistry::DoGetPairing, this, client_id, wrapped_callback); | |
91 // |Unretained| and |get| are both safe here because the delegate is owned | |
92 // by the pairing registry and so is guaranteed to exist when the request | |
93 // is serviced. | |
94 base::Closure request = base::Bind( | 127 base::Closure request = base::Bind( |
95 &PairingRegistry::Delegate::Load, | 128 &PairingRegistry::DoLoad, this, client_id, wrapped_callback); |
96 base::Unretained(delegate_.get()), load_callback); | |
97 ServiceOrQueueRequest(request); | 129 ServiceOrQueueRequest(request); |
98 } | 130 } |
99 | 131 |
100 void PairingRegistry::GetAllPairings( | 132 void PairingRegistry::GetAllPairings( |
101 const GetAllPairingsCallback& callback) { | 133 const GetAllPairingsCallback& callback) { |
102 DCHECK(CalledOnValidThread()); | 134 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
135 | |
103 GetAllPairingsCallback wrapped_callback = base::Bind( | 136 GetAllPairingsCallback wrapped_callback = base::Bind( |
104 &PairingRegistry::InvokeGetAllPairingsCallbackAndScheduleNext, | 137 &PairingRegistry::InvokeGetAllPairingsCallbackAndScheduleNext, |
105 this, callback); | 138 this, callback); |
106 LoadCallback load_callback = base::Bind( | 139 GetAllPairingsCallback sanitize_callback = base::Bind( |
107 &PairingRegistry::SanitizePairings, this, wrapped_callback); | 140 &PairingRegistry::SanitizePairings, |
141 this, wrapped_callback); | |
108 base::Closure request = base::Bind( | 142 base::Closure request = base::Bind( |
109 &PairingRegistry::Delegate::Load, | 143 &PairingRegistry::DoLoadAll, this, sanitize_callback); |
110 base::Unretained(delegate_.get()), load_callback); | |
111 ServiceOrQueueRequest(request); | 144 ServiceOrQueueRequest(request); |
112 } | 145 } |
113 | 146 |
114 void PairingRegistry::DeletePairing( | 147 void PairingRegistry::DeletePairing( |
115 const std::string& client_id, const SaveCallback& callback) { | 148 const std::string& client_id, const DoneCallback& callback) { |
116 DCHECK(CalledOnValidThread()); | 149 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
117 SaveCallback wrapped_callback = base::Bind( | 150 |
118 &PairingRegistry::InvokeSaveCallbackAndScheduleNext, | 151 DoneCallback wrapped_callback = base::Bind( |
152 &PairingRegistry::InvokeDoneCallbackAndScheduleNext, | |
119 this, callback); | 153 this, callback); |
120 LoadCallback load_callback = base::Bind( | |
121 &PairingRegistry::DoDeletePairing, this, client_id, wrapped_callback); | |
122 base::Closure request = base::Bind( | 154 base::Closure request = base::Bind( |
123 &PairingRegistry::Delegate::Load, | 155 &PairingRegistry::DoDelete, this, client_id, wrapped_callback); |
124 base::Unretained(delegate_.get()), load_callback); | |
125 ServiceOrQueueRequest(request); | 156 ServiceOrQueueRequest(request); |
126 } | 157 } |
127 | 158 |
128 void PairingRegistry::ClearAllPairings( | 159 void PairingRegistry::ClearAllPairings( |
129 const SaveCallback& callback) { | 160 const DoneCallback& callback) { |
130 DCHECK(CalledOnValidThread()); | 161 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
131 SaveCallback wrapped_callback = base::Bind( | 162 |
132 &PairingRegistry::InvokeSaveCallbackAndScheduleNext, | 163 DoneCallback wrapped_callback = base::Bind( |
164 &PairingRegistry::InvokeDoneCallbackAndScheduleNext, | |
133 this, callback); | 165 this, callback); |
134 base::Closure request = base::Bind( | 166 base::Closure request = base::Bind( |
135 &PairingRegistry::Delegate::Save, | 167 &PairingRegistry::DoDeleteAll, this, wrapped_callback); |
136 base::Unretained(delegate_.get()), | |
137 EncodeJson(PairedClients()), | |
138 wrapped_callback); | |
139 ServiceOrQueueRequest(request); | 168 ServiceOrQueueRequest(request); |
140 } | 169 } |
141 | 170 |
171 PairingRegistry::~PairingRegistry() { | |
172 } | |
173 | |
174 void PairingRegistry::PostTask( | |
175 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | |
176 const tracked_objects::Location& from_here, | |
177 const base::Closure& task) { | |
178 task_runner->PostTask(from_here, task); | |
179 } | |
180 | |
142 void PairingRegistry::AddPairing(const Pairing& pairing) { | 181 void PairingRegistry::AddPairing(const Pairing& pairing) { |
143 SaveCallback callback = base::Bind( | 182 DoneCallback wrapped_callback = base::Bind( |
144 &PairingRegistry::InvokeSaveCallbackAndScheduleNext, | 183 &PairingRegistry::InvokeDoneCallbackAndScheduleNext, |
145 this, SaveCallback()); | 184 this, DoneCallback()); |
146 LoadCallback load_callback = base::Bind( | |
147 &PairingRegistry::MergePairingAndSave, this, pairing, callback); | |
148 base::Closure request = base::Bind( | 185 base::Closure request = base::Bind( |
149 &PairingRegistry::Delegate::Load, | 186 &PairingRegistry::DoSave, this, pairing, wrapped_callback); |
150 base::Unretained(delegate_.get()), load_callback); | |
151 ServiceOrQueueRequest(request); | 187 ServiceOrQueueRequest(request); |
152 } | 188 } |
153 | 189 |
154 void PairingRegistry::MergePairingAndSave(const Pairing& pairing, | 190 void PairingRegistry::DoLoadAll( |
155 const SaveCallback& callback, | 191 const protocol::PairingRegistry::GetAllPairingsCallback& callback) { |
156 const std::string& pairings_json) { | 192 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
157 DCHECK(CalledOnValidThread()); | 193 |
158 PairedClients clients = DecodeJson(pairings_json); | 194 scoped_ptr<base::ListValue> pairings = delegate_->LoadAll(); |
159 clients[pairing.client_id()] = pairing; | 195 PostTask(caller_task_runner_, FROM_HERE, base::Bind(callback, |
160 std::string new_pairings_json = EncodeJson(clients); | 196 base::Passed(&pairings))); |
161 delegate_->Save(new_pairings_json, callback); | |
162 } | 197 } |
163 | 198 |
164 void PairingRegistry::DoGetPairing(const std::string& client_id, | 199 void PairingRegistry::DoDeleteAll( |
165 const GetPairingCallback& callback, | 200 const protocol::PairingRegistry::DoneCallback& callback) { |
166 const std::string& pairings_json) { | 201 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
167 PairedClients clients = DecodeJson(pairings_json); | 202 |
168 Pairing result = clients[client_id]; | 203 bool success = delegate_->DeleteAll(); |
169 callback.Run(result); | 204 PostTask(caller_task_runner_, FROM_HERE, base::Bind(callback, success)); |
170 } | 205 } |
171 | 206 |
172 void PairingRegistry::SanitizePairings(const GetAllPairingsCallback& callback, | 207 void PairingRegistry::DoLoad( |
173 const std::string& pairings_json) { | 208 const std::string& client_id, |
174 PairedClients clients = DecodeJson(pairings_json); | 209 const protocol::PairingRegistry::GetPairingCallback& callback) { |
175 callback.Run(ConvertToListValue(clients, false)); | 210 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
211 | |
212 Pairing pairing = delegate_->Load(client_id); | |
213 PostTask(caller_task_runner_, FROM_HERE, base::Bind(callback, pairing)); | |
176 } | 214 } |
177 | 215 |
178 void PairingRegistry::DoDeletePairing(const std::string& client_id, | 216 void PairingRegistry::DoSave( |
179 const SaveCallback& callback, | 217 const protocol::PairingRegistry::Pairing& pairing, |
180 const std::string& pairings_json) { | 218 const protocol::PairingRegistry::DoneCallback& callback) { |
181 PairedClients clients = DecodeJson(pairings_json); | 219 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
182 clients.erase(client_id); | 220 |
183 std::string new_pairings_json = EncodeJson(clients); | 221 bool success = delegate_->Save(pairing); |
184 delegate_->Save(new_pairings_json, callback); | 222 PostTask(caller_task_runner_, FROM_HERE, base::Bind(callback, success)); |
185 } | 223 } |
186 | 224 |
187 void PairingRegistry::InvokeLoadCallbackAndScheduleNext( | 225 void PairingRegistry::DoDelete( |
188 const LoadCallback& callback, const std::string& pairings_json) { | 226 const std::string& client_id, |
189 callback.Run(pairings_json); | 227 const protocol::PairingRegistry::DoneCallback& callback) { |
228 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); | |
229 | |
230 bool success = delegate_->Delete(client_id); | |
231 PostTask(caller_task_runner_, FROM_HERE, base::Bind(callback, success)); | |
232 } | |
233 | |
234 void PairingRegistry::InvokeDoneCallbackAndScheduleNext( | |
235 const DoneCallback& callback, bool success) { | |
236 // CreatePairing doesn't have a callback, so the callback can be null. | |
237 if (!callback.is_null()) | |
238 callback.Run(success); | |
239 | |
190 pending_requests_.pop(); | 240 pending_requests_.pop(); |
191 ServiceNextRequest(); | 241 ServiceNextRequest(); |
192 } | 242 } |
193 | |
194 void PairingRegistry::InvokeSaveCallbackAndScheduleNext( | |
195 const SaveCallback& callback, bool success) { | |
196 // CreatePairing doesn't have a callback, so the callback can be null. | |
197 if (!callback.is_null()) { | |
198 callback.Run(success); | |
199 } | |
200 pending_requests_.pop(); | |
201 ServiceNextRequest(); | |
202 } | |
203 | 243 |
204 void PairingRegistry::InvokeGetPairingCallbackAndScheduleNext( | 244 void PairingRegistry::InvokeGetPairingCallbackAndScheduleNext( |
205 const GetPairingCallback& callback, Pairing pairing) { | 245 const GetPairingCallback& callback, Pairing pairing) { |
206 callback.Run(pairing); | 246 callback.Run(pairing); |
207 pending_requests_.pop(); | 247 pending_requests_.pop(); |
208 ServiceNextRequest(); | 248 ServiceNextRequest(); |
209 } | 249 } |
210 | 250 |
211 void PairingRegistry::InvokeGetAllPairingsCallbackAndScheduleNext( | 251 void PairingRegistry::InvokeGetAllPairingsCallbackAndScheduleNext( |
212 const GetAllPairingsCallback& callback, | 252 const GetAllPairingsCallback& callback, |
213 scoped_ptr<base::ListValue> pairings) { | 253 scoped_ptr<base::ListValue> pairings) { |
214 callback.Run(pairings.Pass()); | 254 callback.Run(pairings.Pass()); |
215 pending_requests_.pop(); | 255 pending_requests_.pop(); |
216 ServiceNextRequest(); | 256 ServiceNextRequest(); |
217 } | 257 } |
218 | 258 |
219 // static | 259 void PairingRegistry::SanitizePairings(const GetAllPairingsCallback& callback, |
220 PairingRegistry::PairedClients PairingRegistry::DecodeJson( | 260 scoped_ptr<base::ListValue> pairings) { |
221 const std::string& pairings_json) { | 261 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
222 PairedClients result; | |
223 | 262 |
224 if (pairings_json.empty()) { | 263 scoped_ptr<base::ListValue> sanitized_pairings(new base::ListValue()); |
225 return result; | 264 for (size_t i = 0; i < pairings->GetSize(); ++i) { |
265 DictionaryValue* pairing_json; | |
266 if (!pairings->GetDictionary(i, &pairing_json)) { | |
267 LOG(WARNING) << "A pairing entry is not a disctionary."; | |
Jamie
2013/08/01 22:44:04
s/disctionary/dictionary/
alexeypa (please no reviews)
2013/08/01 23:07:42
Fixed by patch #4
| |
268 continue; | |
269 } | |
270 | |
271 // Parse the pairing data. | |
272 protocol::PairingRegistry::Pairing pairing = | |
273 protocol::PairingRegistry::Pairing::CreateFromValue(*pairing_json); | |
274 if (!pairing.is_valid()) { | |
275 LOG(WARNING) << "Could not parse a pairing entry."; | |
276 continue; | |
277 } | |
278 | |
279 // Clear the shared secrect and append the pairing data to the list. | |
280 protocol::PairingRegistry::Pairing sanitized_pairing( | |
281 pairing.created_time(), | |
282 pairing.client_name(), | |
283 pairing.client_id(), | |
284 ""); | |
285 sanitized_pairings->Append(sanitized_pairing.ToValue().release()); | |
226 } | 286 } |
227 | 287 |
228 JSONStringValueSerializer registry(pairings_json); | 288 callback.Run(sanitized_pairings.Pass()); |
229 int error_code; | |
230 std::string error_message; | |
231 scoped_ptr<base::Value> root( | |
232 registry.Deserialize(&error_code, &error_message)); | |
233 if (!root) { | |
234 LOG(ERROR) << "Failed to load paired clients: " << error_message | |
235 << " (" << error_code << ")."; | |
236 return result; | |
237 } | |
238 | |
239 base::ListValue* root_list = NULL; | |
240 if (!root->GetAsList(&root_list)) { | |
241 LOG(ERROR) << "Failed to load paired clients: root node is not a list."; | |
242 return result; | |
243 } | |
244 | |
245 for (size_t i = 0; i < root_list->GetSize(); ++i) { | |
246 base::DictionaryValue* pairing = NULL; | |
247 std::string client_name, client_id, shared_secret; | |
248 double created_time_value; | |
249 if (root_list->GetDictionary(i, &pairing) && | |
250 pairing->GetDouble(kCreatedTimeKey, &created_time_value) && | |
251 pairing->GetString(kClientNameKey, &client_name) && | |
252 pairing->GetString(kClientIdKey, &client_id) && | |
253 pairing->GetString(kSharedSecretKey, &shared_secret)) { | |
254 base::Time created_time = base::Time::FromJsTime(created_time_value); | |
255 result[client_id] = Pairing( | |
256 created_time, client_name, client_id, shared_secret); | |
257 } else { | |
258 LOG(ERROR) << "Paired client " << i << " has unexpected format."; | |
259 } | |
260 } | |
261 | |
262 return result; | |
263 } | 289 } |
264 | 290 |
265 void PairingRegistry::ServiceOrQueueRequest(const base::Closure& request) { | 291 void PairingRegistry::ServiceOrQueueRequest(const base::Closure& request) { |
266 bool servicing_request = !pending_requests_.empty(); | 292 bool servicing_request = !pending_requests_.empty(); |
267 pending_requests_.push(request); | 293 pending_requests_.push(request); |
268 if (!servicing_request) { | 294 if (!servicing_request) { |
269 ServiceNextRequest(); | 295 ServiceNextRequest(); |
270 } | 296 } |
271 } | 297 } |
272 | 298 |
273 void PairingRegistry::ServiceNextRequest() { | 299 void PairingRegistry::ServiceNextRequest() { |
274 if (pending_requests_.empty()) { | 300 if (pending_requests_.empty()) |
275 return; | 301 return; |
276 } | |
277 base::Closure request = pending_requests_.front(); | |
278 request.Run(); | |
279 } | |
280 | 302 |
281 // static | 303 PostTask(delegate_task_runner_, FROM_HERE, pending_requests_.front()); |
282 std::string PairingRegistry::EncodeJson(const PairedClients& clients) { | |
283 scoped_ptr<base::ListValue> root = ConvertToListValue(clients, true); | |
284 std::string result; | |
285 JSONStringValueSerializer serializer(&result); | |
286 serializer.Serialize(*root); | |
287 | |
288 return result; | |
289 } | |
290 | |
291 // static | |
292 scoped_ptr<base::ListValue> PairingRegistry::ConvertToListValue( | |
293 const PairedClients& clients, | |
294 bool include_shared_secrets) { | |
295 scoped_ptr<base::ListValue> root(new base::ListValue()); | |
296 for (PairedClients::const_iterator i = clients.begin(); | |
297 i != clients.end(); ++i) { | |
298 base::DictionaryValue* pairing = new base::DictionaryValue(); | |
299 pairing->SetDouble(kCreatedTimeKey, i->second.created_time().ToJsTime()); | |
300 pairing->SetString(kClientNameKey, i->second.client_name()); | |
301 pairing->SetString(kClientIdKey, i->second.client_id()); | |
302 if (include_shared_secrets) { | |
303 pairing->SetString(kSharedSecretKey, i->second.shared_secret()); | |
304 } | |
305 root->Append(pairing); | |
306 } | |
307 return root.Pass(); | |
308 } | 304 } |
309 | 305 |
310 } // namespace protocol | 306 } // namespace protocol |
311 } // namespace remoting | 307 } // namespace remoting |
OLD | NEW |