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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: remoting/host/pairing_registry_delegate_linux.cc
diff --git a/remoting/host/pairing_registry_delegate_linux.cc b/remoting/host/pairing_registry_delegate_linux.cc
new file mode 100644
index 0000000000000000000000000000000000000000..577bd5b138a777f43f718ea7c31272e33745de12
--- /dev/null
+++ b/remoting/host/pairing_registry_delegate_linux.cc
@@ -0,0 +1,214 @@
+// Copyright 2013 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 "remoting/host/pairing_registry_delegate_linux.h"
+
+#include "base/bind.h"
+#include "base/environment.h"
+#include "base/file_util.h"
+#include "base/files/important_file_writer.h"
+#include "base/json/json_file_value_serializer.h"
+#include "base/json/json_string_value_serializer.h"
+#include "base/location.h"
+#include "base/single_thread_task_runner.h"
+#include "base/string_number_conversions.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/values.h"
+#include "remoting/host/branding.h"
+
+namespace {
+const char kRegistryFilename[] = "paired-clients.json";
+const char kCreatedTimeKey[] = "created-time";
+const char kClientIdKey[] = "client-id";
+const char kClientNameKey[] = "client-name";
+const char kSharedSecretKey[] = "shared-secret";
+} // namespace
+
+namespace remoting {
+
+using protocol::PairingRegistry;
+
+PairingRegistryDelegateLinux::PairingRegistryDelegateLinux(
+ scoped_refptr<base::TaskRunner> task_runner)
+ : task_runner_(task_runner),
+ weak_factory_(this) {
+}
+
+PairingRegistryDelegateLinux::~PairingRegistryDelegateLinux() {
+}
+
+void PairingRegistryDelegateLinux::AddPairing(
+ const PairingRegistry::Pairing& new_paired_client,
+ const PairingRegistry::AddPairingCallback& callback) {
+ // If a callback was supplied, wrap it in a helper function that will
+ // run it on this thread.
+ PairingRegistry::AddPairingCallback run_callback_on_this_thread;
+ if (!callback.is_null()) {
+ run_callback_on_this_thread =
+ base::Bind(&PairingRegistryDelegateLinux::RunAddPairingCallbackOnThread,
+ base::ThreadTaskRunnerHandle::Get(),
+ callback);
+ }
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&PairingRegistryDelegateLinux::DoAddPairing,
+ weak_factory_.GetWeakPtr(),
+ new_paired_client,
+ run_callback_on_this_thread));
+}
+
+void PairingRegistryDelegateLinux::GetPairing(
+ const std::string& client_id,
+ const PairingRegistry::GetPairingCallback& callback) {
+ // Wrap the callback in a helper function that will run it on this thread.
+ // Note that, unlike AddPairing, the GetPairing callback is mandatory.
+ PairingRegistry::GetPairingCallback run_callback_on_this_thread =
+ base::Bind(&PairingRegistryDelegateLinux::RunGetPairingCallbackOnThread,
+ base::ThreadTaskRunnerHandle::Get(),
+ callback);
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&PairingRegistryDelegateLinux::DoGetPairing,
+ weak_factory_.GetWeakPtr(),
+ client_id,
+ run_callback_on_this_thread));
+}
+
+void PairingRegistryDelegateLinux::RunAddPairingCallbackOnThread(
+ scoped_refptr<base::TaskRunner> task_runner,
+ const PairingRegistry::AddPairingCallback& callback,
+ bool success) {
+ task_runner->PostTask(FROM_HERE, base::Bind(callback, success));
+}
+
+void PairingRegistryDelegateLinux::RunGetPairingCallbackOnThread(
+ scoped_refptr<base::TaskRunner> task_runner,
+ const PairingRegistry::GetPairingCallback& callback,
+ PairingRegistry::Pairing pairing) {
+ task_runner->PostTask(FROM_HERE, base::Bind(callback, pairing));
+}
+
+void PairingRegistryDelegateLinux::DoAddPairing(
+ const PairingRegistry::Pairing& new_paired_client,
+ const PairingRegistry::AddPairingCallback& callback) {
+ PairingRegistry::PairedClients paired_clients = LoadPairings();
+ paired_clients[new_paired_client.client_id()] = new_paired_client;
+ SavePairings(paired_clients);
+ if (!callback.is_null()) {
+ callback.Run(true);
+ }
+}
+
+void PairingRegistryDelegateLinux::DoGetPairing(
+ const std::string& client_id,
+ const PairingRegistry::GetPairingCallback& callback) {
+ PairingRegistry::PairedClients paired_clients = LoadPairings();
+ PairingRegistry::PairedClients::const_iterator i =
+ paired_clients.find(client_id);
+ PairingRegistry::Pairing result;
+ if (i != paired_clients.end()) {
+ result = i->second;
+ }
+ callback.Run(result);
+}
+
+PairingRegistry::PairedClients PairingRegistryDelegateLinux::LoadPairings() {
+ PairingRegistry::PairedClients result;
+
+ base::FilePath registry_path = GetRegistryFilePath();
+ JSONFileValueSerializer registry(registry_path);
+ int error_code;
+ std::string error_message;
+ scoped_ptr<base::Value> root(
+ registry.Deserialize(&error_code, &error_message));
+ if (!root) {
+ LOG(ERROR) << "Failed to load paired clients: " << error_message
+ << " (" << error_code << ").";
+ return result;
+ }
+
+ base::ListValue* root_list = NULL;
+ if (!root->GetAsList(&root_list)) {
+ LOG(ERROR) << "Failed to load paired clients: root node is not a list.";
+ return result;
+ }
+
+ for (size_t i = 0; i < root_list->GetSize(); ++i) {
+ base::DictionaryValue* pairing = NULL;
+ std::string created_time, client_name, client_id, shared_secret;
+ if (root_list->GetDictionary(i, &pairing) &&
+ pairing->GetString(kCreatedTimeKey, &created_time) &&
+ pairing->GetString(kClientNameKey, &client_name) &&
+ pairing->GetString(kClientIdKey, &client_id) &&
+ pairing->GetString(kSharedSecretKey, &shared_secret)) {
+ int64 created_time_value;
+ if (!base::StringToInt64(created_time, &created_time_value)) {
+ LOG(ERROR) << "Paired client " << i << " has invalid creation time.";
+ continue;
+ }
+ result[client_id] = PairingRegistry::Pairing(
+ base::Time::FromInternalValue(created_time_value),
+ client_name, client_id, shared_secret);
+ } else {
+ LOG(ERROR) << "Paired client " << i << " has unexpected format.";
+ }
+ }
+
+ return result;
+}
+
+void PairingRegistryDelegateLinux::SavePairings(
+ const PairingRegistry::PairedClients& paired_clients) {
+ base::ListValue root;
+ for (PairingRegistry::PairedClients::const_iterator i =
+ paired_clients.begin(); i != paired_clients.end(); ++i) {
+ base::DictionaryValue* pairing = new base::DictionaryValue();
+ std::string created_time =
+ base::Int64ToString(i->second.created_time().ToInternalValue());
+ pairing->SetString(kCreatedTimeKey, created_time);
+ pairing->SetString(kClientNameKey, i->second.client_name());
+ pairing->SetString(kClientIdKey, i->second.client_id());
+ pairing->SetString(kSharedSecretKey, i->second.shared_secret());
+ root.Append(pairing);
+ }
+
+ std::string pairings_json;
+ JSONStringValueSerializer serializer(&pairings_json);
+ serializer.Serialize(root);
+
+ base::FilePath registry_path = GetRegistryFilePath();
+ base::FilePath parent_directory = registry_path.DirName();
+ base::PlatformFileError error;
+ if (!file_util::CreateDirectoryAndGetError(parent_directory, &error)) {
+ LOG(ERROR) << "Could not create pairing registry directory: " << error;
+ return;
+ }
+ if (!base::ImportantFileWriter::WriteFileAtomically(registry_path,
+ pairings_json)) {
+ LOG(ERROR) << "Could not save pairing registry.";
+ }
+}
+
+base::FilePath PairingRegistryDelegateLinux::GetRegistryFilePath() {
+ if (!filename_for_testing_.empty()) {
+ return filename_for_testing_;
+ }
+
+ base::FilePath config_dir = remoting::GetConfigDir();
+ return config_dir.Append(kRegistryFilename);
+}
+
+void PairingRegistryDelegateLinux::SetFilenameForTesting(
+ const base::FilePath &filename) {
+ filename_for_testing_ = filename;
+}
+
+
+scoped_ptr<PairingRegistry::Delegate> CreatePairingRegistryDelegate(
+ scoped_refptr<base::TaskRunner> task_runner) {
+ return scoped_ptr<PairingRegistry::Delegate>(
+ new PairingRegistryDelegateLinux(task_runner));
+}
+
+} // namespace remoting

Powered by Google App Engine
This is Rietveld 408576698