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

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

Issue 15709005: Linux pairing registry delegate implementation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reviewer feedback. Created 7 years, 6 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "remoting/host/pairing_registry_delegate_linux.h"
6
7 #include "base/bind.h"
8 #include "base/environment.h"
9 #include "base/file_util.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"
13 #include "base/location.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/string_number_conversions.h"
16 #include "base/thread_task_runner_handle.h"
17 #include "base/values.h"
18 #include "remoting/host/branding.h"
19
20 namespace {
21 const char kRegistryFilename[] = "paired-clients.json";
22 const char kCreatedTimeKey[] = "created-time";
23 const char kClientIdKey[] = "client-id";
24 const char kClientNameKey[] = "client-name";
25 const char kSharedSecretKey[] = "shared-secret";
26 } // namespace
27
28 namespace remoting {
29
30 using protocol::PairingRegistry;
31
32 PairingRegistryDelegateLinux::PairingRegistryDelegateLinux(
33 scoped_refptr<base::TaskRunner> task_runner)
34 : task_runner_(task_runner),
35 weak_factory_(this) {
36 }
37
38 PairingRegistryDelegateLinux::~PairingRegistryDelegateLinux() {
39 }
40
41 void PairingRegistryDelegateLinux::AddPairing(
42 const PairingRegistry::Pairing& new_paired_client,
43 const PairingRegistry::AddPairingCallback& callback) {
44 // If a callback was supplied, wrap it in a helper function that will
45 // run it on this thread.
46 PairingRegistry::AddPairingCallback run_callback_on_this_thread;
47 if (!callback.is_null()) {
48 run_callback_on_this_thread =
49 base::Bind(&PairingRegistryDelegateLinux::RunAddPairingCallbackOnThread,
50 base::ThreadTaskRunnerHandle::Get(),
51 callback);
52 }
53 task_runner_->PostTask(
54 FROM_HERE,
55 base::Bind(&PairingRegistryDelegateLinux::DoAddPairing,
56 weak_factory_.GetWeakPtr(),
57 new_paired_client,
58 run_callback_on_this_thread));
59 }
60
61 void PairingRegistryDelegateLinux::GetPairing(
62 const std::string& client_id,
63 const PairingRegistry::GetPairingCallback& callback) {
64 // Wrap the callback in a helper function that will run it on this thread.
65 // Note that, unlike AddPairing, the GetPairing callback is mandatory.
66 PairingRegistry::GetPairingCallback run_callback_on_this_thread =
67 base::Bind(&PairingRegistryDelegateLinux::RunGetPairingCallbackOnThread,
68 base::ThreadTaskRunnerHandle::Get(),
69 callback);
70 task_runner_->PostTask(
71 FROM_HERE,
72 base::Bind(&PairingRegistryDelegateLinux::DoGetPairing,
73 weak_factory_.GetWeakPtr(),
74 client_id,
75 run_callback_on_this_thread));
76 }
77
78 void PairingRegistryDelegateLinux::RunAddPairingCallbackOnThread(
79 scoped_refptr<base::TaskRunner> task_runner,
80 const PairingRegistry::AddPairingCallback& callback,
81 bool success) {
82 task_runner->PostTask(FROM_HERE, base::Bind(callback, success));
83 }
84
85 void PairingRegistryDelegateLinux::RunGetPairingCallbackOnThread(
86 scoped_refptr<base::TaskRunner> task_runner,
87 const PairingRegistry::GetPairingCallback& callback,
88 PairingRegistry::Pairing pairing) {
89 task_runner->PostTask(FROM_HERE, base::Bind(callback, pairing));
90 }
91
92 void PairingRegistryDelegateLinux::DoAddPairing(
93 const PairingRegistry::Pairing& new_paired_client,
94 const PairingRegistry::AddPairingCallback& callback) {
95 PairingRegistry::PairedClients paired_clients = LoadPairings();
96 paired_clients[new_paired_client.client_id()] = new_paired_client;
97 SavePairings(paired_clients);
98 if (!callback.is_null()) {
99 callback.Run(true);
100 }
101 }
102
103 void PairingRegistryDelegateLinux::DoGetPairing(
104 const std::string& client_id,
105 const PairingRegistry::GetPairingCallback& callback) {
106 PairingRegistry::PairedClients paired_clients = LoadPairings();
107 PairingRegistry::PairedClients::const_iterator i =
108 paired_clients.find(client_id);
109 PairingRegistry::Pairing result;
110 if (i != paired_clients.end()) {
111 result = i->second;
112 }
113 callback.Run(result);
114 }
115
116 PairingRegistry::PairedClients PairingRegistryDelegateLinux::LoadPairings() {
117 PairingRegistry::PairedClients result;
118
119 base::FilePath registry_path = GetRegistryFilePath();
120 JSONFileValueSerializer registry(registry_path);
121 int error_code;
122 std::string error_message;
123 scoped_ptr<base::Value> root(
124 registry.Deserialize(&error_code, &error_message));
125 if (!root) {
126 LOG(ERROR) << "Failed to load paired clients: " << error_message
127 << " (" << error_code << ").";
128 return result;
129 }
130
131 base::ListValue* root_list = NULL;
132 if (!root->GetAsList(&root_list)) {
133 LOG(ERROR) << "Failed to load paired clients: root node is not a list.";
134 return result;
135 }
136
137 for (size_t i = 0; i < root_list->GetSize(); ++i) {
138 base::DictionaryValue* pairing = NULL;
139 std::string created_time, client_name, client_id, shared_secret;
140 if (root_list->GetDictionary(i, &pairing) &&
141 pairing->GetString(kCreatedTimeKey, &created_time) &&
142 pairing->GetString(kClientNameKey, &client_name) &&
143 pairing->GetString(kClientIdKey, &client_id) &&
144 pairing->GetString(kSharedSecretKey, &shared_secret)) {
145 int64 created_time_value;
146 if (!base::StringToInt64(created_time, &created_time_value)) {
147 LOG(ERROR) << "Paired client " << i << " has invalid creation time.";
148 continue;
149 }
150 result[client_id] = PairingRegistry::Pairing(
151 base::Time::FromInternalValue(created_time_value),
152 client_name, client_id, shared_secret);
153 } else {
154 LOG(ERROR) << "Paired client " << i << " has unexpected format.";
155 }
156 }
157
158 return result;
159 }
160
161 void PairingRegistryDelegateLinux::SavePairings(
162 const PairingRegistry::PairedClients& paired_clients) {
163 base::ListValue root;
164 for (PairingRegistry::PairedClients::const_iterator i =
165 paired_clients.begin(); i != paired_clients.end(); ++i) {
166 base::DictionaryValue* pairing = new base::DictionaryValue();
167 std::string created_time =
168 base::Int64ToString(i->second.created_time().ToInternalValue());
169 pairing->SetString(kCreatedTimeKey, created_time);
170 pairing->SetString(kClientNameKey, i->second.client_name());
171 pairing->SetString(kClientIdKey, i->second.client_id());
172 pairing->SetString(kSharedSecretKey, i->second.shared_secret());
173 root.Append(pairing);
174 }
175
176 std::string pairings_json;
177 JSONStringValueSerializer serializer(&pairings_json);
178 serializer.Serialize(root);
179
180 base::FilePath registry_path = GetRegistryFilePath();
181 base::FilePath parent_directory = registry_path.DirName();
182 base::PlatformFileError error;
183 if (!file_util::CreateDirectoryAndGetError(parent_directory, &error)) {
184 LOG(ERROR) << "Could not create pairing registry directory: " << error;
185 return;
186 }
187 if (!base::ImportantFileWriter::WriteFileAtomically(registry_path,
188 pairings_json)) {
189 LOG(ERROR) << "Could not save pairing registry.";
190 }
191 }
192
193 base::FilePath PairingRegistryDelegateLinux::GetRegistryFilePath() {
194 if (!filename_for_testing_.empty()) {
195 return filename_for_testing_;
196 }
197
198 base::FilePath config_dir = remoting::GetConfigDir();
199 return config_dir.Append(kRegistryFilename);
200 }
201
202 void PairingRegistryDelegateLinux::SetFilenameForTesting(
203 const base::FilePath &filename) {
204 filename_for_testing_ = filename;
205 }
206
207
208 scoped_ptr<PairingRegistry::Delegate> CreatePairingRegistryDelegate(
209 scoped_refptr<base::TaskRunner> task_runner) {
210 return scoped_ptr<PairingRegistry::Delegate>(
211 new PairingRegistryDelegateLinux(task_runner));
212 }
213
214 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698