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

Side by Side Diff: remoting/host/pairing_registry_delegate_linux.cc

Issue 21128006: Refactored PairingRegistry::Delegate such that it can retrieve/modify for a single client. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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
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/host/pairing_registry_delegate_linux.h" 5 #include "remoting/host/pairing_registry_delegate_linux.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/files/file_enumerator.h"
9 #include "base/files/important_file_writer.h" 10 #include "base/files/important_file_writer.h"
11 #include "base/json/json_file_value_serializer.h"
12 #include "base/json/json_string_value_serializer.h"
10 #include "base/location.h" 13 #include "base/location.h"
11 #include "base/single_thread_task_runner.h" 14 #include "base/single_thread_task_runner.h"
15 #include "base/strings/stringprintf.h"
12 #include "base/thread_task_runner_handle.h" 16 #include "base/thread_task_runner_handle.h"
17 #include "base/values.h"
13 #include "remoting/host/branding.h" 18 #include "remoting/host/branding.h"
14 19
15 namespace { 20 namespace {
16 const char kRegistryFilename[] = "paired-clients.json"; 21
22 // The pairing registry path relative to the configuration directory.
23 const char kRegistryDirectory[] = "pairing-registry";
Jamie 2013/07/30 21:35:07 I think paired-clients is sufficient for the direc
alexeypa (please no reviews) 2013/07/31 21:31:24 Done.
24
25 const char kPairingFilenameFormat[] = "%s.json";
26 const char kPairingFilenamePattern[] = "*.json";
27
17 } // namespace 28 } // namespace
18 29
19 namespace remoting { 30 namespace remoting {
20 31
21 using protocol::PairingRegistry; 32 using protocol::PairingRegistry;
22 33
23 PairingRegistryDelegateLinux::PairingRegistryDelegateLinux( 34 PairingRegistryDelegateLinux::PairingRegistryDelegateLinux(
24 scoped_refptr<base::TaskRunner> task_runner) 35 scoped_refptr<base::TaskRunner> task_runner)
25 : task_runner_(task_runner), 36 : task_runner_(task_runner),
26 weak_factory_(this) { 37 weak_factory_(this) {
27 } 38 }
28 39
29 PairingRegistryDelegateLinux::~PairingRegistryDelegateLinux() { 40 PairingRegistryDelegateLinux::~PairingRegistryDelegateLinux() {
30 } 41 }
31 42
43 void PairingRegistryDelegateLinux::LoadAll(
44 const protocol::PairingRegistry::GetAllPairingsCallback& callback) {
45 // Wrap the callback in a helper function that will run it on this thread.
46 PairingRegistry::GetAllPairingsCallback run_callback_on_this_thread =
47 base::Bind(
48 &PairingRegistryDelegateLinux::RunGetAllPairingsCallbackOnThread,
49 base::ThreadTaskRunnerHandle::Get(),
50 callback);
51 task_runner_->PostTask(
52 FROM_HERE,
53 base::Bind(&PairingRegistryDelegateLinux::DoLoadAll,
54 weak_factory_.GetWeakPtr(),
55 run_callback_on_this_thread));
56 }
57
58 void PairingRegistryDelegateLinux::DeleteAll(
59 const protocol::PairingRegistry::DoneCallback& callback) {
60 // Wrap the callback in a helper function that will run it on this thread.
61 PairingRegistry::DoneCallback run_callback_on_this_thread =
62 base::Bind(&PairingRegistryDelegateLinux::RunDoneCallbackOnThread,
63 base::ThreadTaskRunnerHandle::Get(),
64 callback);
65 task_runner_->PostTask(
66 FROM_HERE,
67 base::Bind(&PairingRegistryDelegateLinux::DoDeleteAll,
68 weak_factory_.GetWeakPtr(),
69 run_callback_on_this_thread));
70 }
71
72 void PairingRegistryDelegateLinux::Load(
73 const std::string& client_id,
74 const protocol::PairingRegistry::GetPairingCallback& callback) {
75 // Wrap the callback in a helper function that will run it on this thread.
76 PairingRegistry::GetPairingCallback run_callback_on_this_thread =
77 base::Bind(&PairingRegistryDelegateLinux::RunGetPairingCallbackOnThread,
78 base::ThreadTaskRunnerHandle::Get(),
79 callback);
80 task_runner_->PostTask(
81 FROM_HERE,
82 base::Bind(&PairingRegistryDelegateLinux::DoLoad,
83 weak_factory_.GetWeakPtr(),
84 client_id,
85 run_callback_on_this_thread));
86 }
87
32 void PairingRegistryDelegateLinux::Save( 88 void PairingRegistryDelegateLinux::Save(
33 const std::string& pairings_json, 89 const protocol::PairingRegistry::Pairing& pairing,
34 const PairingRegistry::SaveCallback& callback) { 90 const protocol::PairingRegistry::DoneCallback& callback) {
35 // If a callback was supplied, wrap it in a helper function that will 91 // Wrap the callback in a helper function that will run it on this thread.
36 // run it on this thread. 92 PairingRegistry::DoneCallback run_callback_on_this_thread =
37 PairingRegistry::SaveCallback run_callback_on_this_thread; 93 base::Bind(&PairingRegistryDelegateLinux::RunDoneCallbackOnThread,
38 if (!callback.is_null()) { 94 base::ThreadTaskRunnerHandle::Get(),
39 run_callback_on_this_thread = 95 callback);
40 base::Bind(&PairingRegistryDelegateLinux::RunSaveCallbackOnThread,
41 base::ThreadTaskRunnerHandle::Get(),
42 callback);
43 }
44 task_runner_->PostTask( 96 task_runner_->PostTask(
45 FROM_HERE, 97 FROM_HERE,
46 base::Bind(&PairingRegistryDelegateLinux::DoSave, 98 base::Bind(&PairingRegistryDelegateLinux::DoSave,
47 weak_factory_.GetWeakPtr(), 99 weak_factory_.GetWeakPtr(),
48 pairings_json, 100 pairing,
49 run_callback_on_this_thread)); 101 run_callback_on_this_thread));
50 } 102 }
51 103
52 void PairingRegistryDelegateLinux::Load( 104 void PairingRegistryDelegateLinux::Delete(
53 const PairingRegistry::LoadCallback& callback) { 105 const std::string& client_id,
54 // Wrap the callback in a helper function that will run it on this thread. 106 const protocol::PairingRegistry::DoneCallback& callback) {
55 // Note that, unlike AddPairing, the GetPairing callback is mandatory. 107 // Wrap the callback in a helper function that will run it on this thread.
56 PairingRegistry::LoadCallback run_callback_on_this_thread = 108 PairingRegistry::DoneCallback run_callback_on_this_thread =
57 base::Bind(&PairingRegistryDelegateLinux::RunLoadCallbackOnThread, 109 base::Bind(&PairingRegistryDelegateLinux::RunDoneCallbackOnThread,
58 base::ThreadTaskRunnerHandle::Get(), 110 base::ThreadTaskRunnerHandle::Get(),
59 callback); 111 callback);
60 task_runner_->PostTask( 112 task_runner_->PostTask(
61 FROM_HERE, 113 FROM_HERE,
62 base::Bind(&PairingRegistryDelegateLinux::DoLoad, 114 base::Bind(&PairingRegistryDelegateLinux::DoDelete,
63 weak_factory_.GetWeakPtr(), 115 weak_factory_.GetWeakPtr(),
64 run_callback_on_this_thread)); 116 client_id,
65 } 117 run_callback_on_this_thread));
66 118 }
67 void PairingRegistryDelegateLinux::RunSaveCallbackOnThread( 119
120 void PairingRegistryDelegateLinux::DoLoadAll(
121 const protocol::PairingRegistry::GetAllPairingsCallback& callback) {
122 scoped_ptr<base::ListValue> pairings(new base::ListValue());
123
124 // Enumerate all pairing files in the pairing registry.
125 base::FilePath registry_path = GetRegistryPath();
126 base::FileEnumerator enumerator(registry_path, false,
127 base::FileEnumerator::FILES,
128 kPairingFilenamePattern);
129 for (base::FilePath pairing_file = enumerator.Next(); !pairing_file.empty();
130 pairing_file = enumerator.Next()) {
131 // Read the JSON containing pairing data.
132 JSONFileValueSerializer serializer(pairing_file);
133 int error_code;
134 std::string error_message;
135 scoped_ptr<base::Value> pairing_json(
136 serializer.Deserialize(&error_code, &error_message));
137 if (!pairing_json) {
138 LOG(WARNING) << "Failed to load '" << pairing_file.value() << "' ("
139 << error_code << ").";
140 continue;
141 }
142
143 // Parse the pairing data.
144 protocol::PairingRegistry::Pairing pairing =
145 protocol::PairingRegistry::Pairing::CreateFromJson(*pairing_json);
146 if (!pairing.is_valid()) {
147 LOG(WARNING) << "Could not parse '" << pairing_file.value() << "'";
148 continue;
149 }
150
151 // Clear the shared secrect and append the pairing data to the list.
152 protocol::PairingRegistry::Pairing sanitized_pairing(
153 pairing.created_time(),
154 pairing.client_name(),
155 pairing.client_id(),
156 "");
Jamie 2013/07/30 21:35:07 Would it make sense to make the extraction of the
alexeypa (please no reviews) 2013/07/31 21:31:24 Done.
157 pairings->Append(sanitized_pairing.EncodeJson().release());
158 }
159
160 callback.Run(pairings.Pass());
161 }
162
163 void PairingRegistryDelegateLinux::DoDeleteAll(
164 const protocol::PairingRegistry::DoneCallback& callback) {
165 // Delete all pairing files in the pairing registry.
166 base::FilePath registry_path = GetRegistryPath();
167 base::FileEnumerator enumerator(registry_path, false,
168 base::FileEnumerator::FILES,
169 kPairingFilenamePattern);
170
171 for (base::FilePath pairing_file = enumerator.Next(); !pairing_file.empty();
172 pairing_file = enumerator.Next()) {
173 base::DeleteFile(pairing_file, false);
Jamie 2013/07/30 21:35:07 DeleteFile can fail. I think we should try to cont
alexeypa (please no reviews) 2013/07/31 21:31:24 Done.
174 }
175
176 callback.Run(true);
177 }
178
179 void PairingRegistryDelegateLinux::DoLoad(
180 const std::string& client_id,
181 const protocol::PairingRegistry::GetPairingCallback& callback) {
182 base::FilePath registry_path = GetRegistryPath();
183 base::FilePath pairing_file = registry_path.Append(
184 base::StringPrintf(kPairingFilenameFormat, client_id.c_str()));
185
186 JSONFileValueSerializer serializer(pairing_file);
187 int error_code;
188 std::string error_message;
189 scoped_ptr<base::Value> pairing(
190 serializer.Deserialize(&error_code, &error_message));
191 if (!pairing) {
192 LOG(WARNING) << "Failed to load pairing information: " << error_message
193 << " (" << error_code << ").";
194 callback.Run(protocol::PairingRegistry::Pairing());
195 return;
196 }
197
198 callback.Run(protocol::PairingRegistry::Pairing::CreateFromJson(*pairing));
199 }
200
201 void PairingRegistryDelegateLinux::DoSave(
202 const protocol::PairingRegistry::Pairing& pairing,
203 const protocol::PairingRegistry::DoneCallback& callback) {
204 base::FilePath registry_path = GetRegistryPath();
205 base::PlatformFileError error;
206 if (!file_util::CreateDirectoryAndGetError(registry_path, &error)) {
207 LOG(ERROR) << "Could not create pairing registry directory: " << error;
208 callback.Run(false);
209 return;
210 }
211
212 std::string pairing_json;
213 JSONStringValueSerializer serializer(&pairing_json);
214 if (!serializer.Serialize(*pairing.EncodeJson())) {
215 LOG(ERROR) << "Failed to serialize pairing data for "
216 << pairing.client_id();
217 callback.Run(false);
218 return;
219 }
220
221 base::FilePath pairing_file = registry_path.Append(
222 base::StringPrintf(kPairingFilenameFormat, pairing.client_id().c_str()));
223 if (!base::ImportantFileWriter::WriteFileAtomically(pairing_file,
224 pairing_json)) {
225 LOG(ERROR) << "Could not save pairing data for " << pairing.client_id();
226 callback.Run(false);
227 return;
228 }
229
230 callback.Run(true);
231 }
232
233 void PairingRegistryDelegateLinux::DoDelete(
234 const std::string& client_id,
235 const protocol::PairingRegistry::DoneCallback& callback) {
236 base::FilePath registry_path = GetRegistryPath();
237 base::FilePath pairing_file = registry_path.Append(
238 base::StringPrintf(kPairingFilenameFormat, client_id.c_str()));
239
240 base::DeleteFile(pairing_file, false);
241 callback.Run(true);
242 }
243
244 void PairingRegistryDelegateLinux::RunDoneCallbackOnThread(
68 scoped_refptr<base::TaskRunner> task_runner, 245 scoped_refptr<base::TaskRunner> task_runner,
69 const PairingRegistry::SaveCallback& callback, 246 const protocol::PairingRegistry::DoneCallback& callback,
70 bool success) { 247 bool success) {
71 task_runner->PostTask(FROM_HERE, base::Bind(callback, success)); 248 // The callback is optional when a pairing is created.
72 } 249 if (!callback.is_null())
73 250 task_runner->PostTask(FROM_HERE, base::Bind(callback, success));
Jamie 2013/07/30 21:35:07 Would it be worth moving these Run*CallbackOnThrea
alexeypa (please no reviews) 2013/07/31 21:31:24 I made PairingRegistry::Delegate a synchronous cla
74 void PairingRegistryDelegateLinux::RunLoadCallbackOnThread( 251 }
75 scoped_refptr<base::TaskRunner> task_runner, 252
76 const PairingRegistry::LoadCallback& callback, 253 void PairingRegistryDelegateLinux::RunGetAllPairingsCallbackOnThread(
77 const std::string& pairings_json) { 254 scoped_refptr<base::TaskRunner> task_runner,
78 task_runner->PostTask(FROM_HERE, base::Bind(callback, pairings_json)); 255 const protocol::PairingRegistry::GetAllPairingsCallback& callback,
79 } 256 scoped_ptr<base::ListValue> pairings) {
80 257 task_runner->PostTask(FROM_HERE,
81 void PairingRegistryDelegateLinux::DoSave( 258 base::Bind(callback, base::Passed(&pairings)));
82 const std::string& pairings_json, 259 }
83 const PairingRegistry::SaveCallback& callback) { 260
84 base::FilePath registry_path = GetRegistryFilePath(); 261 void PairingRegistryDelegateLinux::RunGetPairingCallbackOnThread(
85 base::FilePath parent_directory = registry_path.DirName(); 262 scoped_refptr<base::TaskRunner> task_runner,
86 base::PlatformFileError error; 263 const protocol::PairingRegistry::GetPairingCallback& callback,
87 if (!file_util::CreateDirectoryAndGetError(parent_directory, &error)) { 264 protocol::PairingRegistry::Pairing pairing) {
88 LOG(ERROR) << "Could not create pairing registry directory: " << error; 265 task_runner->PostTask(FROM_HERE, base::Bind(callback, pairing));
89 return; 266 }
90 } 267
91 if (!base::ImportantFileWriter::WriteFileAtomically(registry_path, 268
92 pairings_json)) { 269 base::FilePath PairingRegistryDelegateLinux::GetRegistryPath() {
93 LOG(ERROR) << "Could not save pairing registry."; 270 if (!registry_path_for_testing_.empty()) {
94 } 271 return registry_path_for_testing_;
95
96 if (!callback.is_null()) {
97 callback.Run(true);
98 }
99 }
100
101 void PairingRegistryDelegateLinux::DoLoad(
102 const PairingRegistry::LoadCallback& callback) {
103 base::FilePath registry_path = GetRegistryFilePath();
104 std::string result;
105 if (!file_util::ReadFileToString(registry_path, &result)) {
106 LOG(ERROR) << "Load failed.";
107 }
108 callback.Run(result);
109 }
110
111 base::FilePath PairingRegistryDelegateLinux::GetRegistryFilePath() {
112 if (!filename_for_testing_.empty()) {
113 return filename_for_testing_;
114 } 272 }
115 273
116 base::FilePath config_dir = remoting::GetConfigDir(); 274 base::FilePath config_dir = remoting::GetConfigDir();
117 return config_dir.Append(kRegistryFilename); 275 return config_dir.Append(kRegistryDirectory);
118 } 276 }
119 277
120 void PairingRegistryDelegateLinux::SetFilenameForTesting( 278 void PairingRegistryDelegateLinux::SetRegistryPathForTesting(
121 const base::FilePath &filename) { 279 const base::FilePath& registry_path) {
122 filename_for_testing_ = filename; 280 registry_path_for_testing_ = registry_path;
123 } 281 }
124 282
125 283
126 scoped_ptr<PairingRegistry::Delegate> CreatePairingRegistryDelegate( 284 scoped_ptr<PairingRegistry::Delegate> CreatePairingRegistryDelegate(
127 scoped_refptr<base::TaskRunner> task_runner) { 285 scoped_refptr<base::TaskRunner> task_runner) {
128 return scoped_ptr<PairingRegistry::Delegate>( 286 return scoped_ptr<PairingRegistry::Delegate>(
129 new PairingRegistryDelegateLinux(task_runner)); 287 new PairingRegistryDelegateLinux(task_runner));
130 } 288 }
131 289
132 } // namespace remoting 290 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698