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.
5 #include "remoting/host/pairing_registry_delegate_linux.h"
8 #include "base/file_util.h"
9 #include "base/files/file_enumerator.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/strings/stringprintf.h"
15 #include "base/values.h"
16 #include "remoting/host/branding.h"
20 // The pairing registry path relative to the configuration directory.
21 const char kRegistryDirectory
[] = "paired-clients";
23 const char kPairingFilenameFormat
[] = "%s.json";
24 const char kPairingFilenamePattern
[] = "*.json";
30 using protocol::PairingRegistry
;
32 PairingRegistryDelegateLinux::PairingRegistryDelegateLinux() {
35 PairingRegistryDelegateLinux::~PairingRegistryDelegateLinux() {
38 scoped_ptr
<base::ListValue
> PairingRegistryDelegateLinux::LoadAll() {
39 scoped_ptr
<base::ListValue
> pairings(new base::ListValue());
41 // Enumerate all pairing files in the pairing registry.
42 base::FilePath registry_path
= GetRegistryPath();
43 base::FileEnumerator
enumerator(registry_path
, false,
44 base::FileEnumerator::FILES
,
45 kPairingFilenamePattern
);
46 for (base::FilePath pairing_file
= enumerator
.Next(); !pairing_file
.empty();
47 pairing_file
= enumerator
.Next()) {
48 // Read the JSON containing pairing data.
49 JSONFileValueSerializer
serializer(pairing_file
);
51 std::string error_message
;
52 scoped_ptr
<base::Value
> pairing_json(
53 serializer
.Deserialize(&error_code
, &error_message
));
55 LOG(WARNING
) << "Failed to load '" << pairing_file
.value() << "' ("
56 << error_code
<< ").";
60 pairings
->Append(pairing_json
.release());
63 return pairings
.Pass();
66 bool PairingRegistryDelegateLinux::DeleteAll() {
67 // Delete all pairing files in the pairing registry.
68 base::FilePath registry_path
= GetRegistryPath();
69 base::FileEnumerator
enumerator(registry_path
, false,
70 base::FileEnumerator::FILES
,
71 kPairingFilenamePattern
);
74 for (base::FilePath pairing_file
= enumerator
.Next(); !pairing_file
.empty();
75 pairing_file
= enumerator
.Next()) {
76 success
= success
&& base::DeleteFile(pairing_file
, false);
82 PairingRegistry::Pairing
PairingRegistryDelegateLinux::Load(
83 const std::string
& client_id
) {
84 base::FilePath registry_path
= GetRegistryPath();
85 base::FilePath pairing_file
= registry_path
.Append(
86 base::StringPrintf(kPairingFilenameFormat
, client_id
.c_str()));
88 JSONFileValueSerializer
serializer(pairing_file
);
90 std::string error_message
;
91 scoped_ptr
<base::Value
> pairing(
92 serializer
.Deserialize(&error_code
, &error_message
));
94 LOG(WARNING
) << "Failed to load pairing information: " << error_message
95 << " (" << error_code
<< ").";
96 return PairingRegistry::Pairing();
99 base::DictionaryValue
* pairing_dictionary
;
100 if (!pairing
->GetAsDictionary(&pairing_dictionary
)) {
101 LOG(WARNING
) << "Failed to parse pairing information: not a dictionary.";
102 return PairingRegistry::Pairing();
105 return PairingRegistry::Pairing::CreateFromValue(*pairing_dictionary
);
108 bool PairingRegistryDelegateLinux::Save(
109 const PairingRegistry::Pairing
& pairing
) {
110 base::FilePath registry_path
= GetRegistryPath();
111 base::File::Error error
;
112 if (!base::CreateDirectoryAndGetError(registry_path
, &error
)) {
113 LOG(ERROR
) << "Could not create pairing registry directory: " << error
;
117 std::string pairing_json
;
118 JSONStringValueSerializer
serializer(&pairing_json
);
119 if (!serializer
.Serialize(*pairing
.ToValue())) {
120 LOG(ERROR
) << "Failed to serialize pairing data for "
121 << pairing
.client_id();
125 base::FilePath pairing_file
= registry_path
.Append(
126 base::StringPrintf(kPairingFilenameFormat
, pairing
.client_id().c_str()));
127 if (!base::ImportantFileWriter::WriteFileAtomically(pairing_file
,
129 LOG(ERROR
) << "Could not save pairing data for " << pairing
.client_id();
136 bool PairingRegistryDelegateLinux::Delete(const std::string
& client_id
) {
137 base::FilePath registry_path
= GetRegistryPath();
138 base::FilePath pairing_file
= registry_path
.Append(
139 base::StringPrintf(kPairingFilenameFormat
, client_id
.c_str()));
141 return base::DeleteFile(pairing_file
, false);
144 base::FilePath
PairingRegistryDelegateLinux::GetRegistryPath() {
145 if (!registry_path_for_testing_
.empty()) {
146 return registry_path_for_testing_
;
149 base::FilePath config_dir
= remoting::GetConfigDir();
150 return config_dir
.Append(kRegistryDirectory
);
153 void PairingRegistryDelegateLinux::SetRegistryPathForTesting(
154 const base::FilePath
& registry_path
) {
155 registry_path_for_testing_
= registry_path
;
159 scoped_ptr
<PairingRegistry::Delegate
> CreatePairingRegistryDelegate() {
160 return scoped_ptr
<PairingRegistry::Delegate
>(
161 new PairingRegistryDelegateLinux());
164 } // namespace remoting