1//
2// Copyright (C) 2015 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include "shill/dbus/chromeos_dbus_adaptor.h"
18
19#include <string>
20
21#include <base/bind.h>
22#include <base/callback.h>
23
24#include "shill/error.h"
25#include "shill/logging.h"
26
27using base::Bind;
28using base::Passed;
29using brillo::dbus_utils::DBusObject;
30using brillo::dbus_utils::ExportedObjectManager;
31using std::string;
32
33namespace shill {
34
35namespace Logging {
36static auto kModuleLogScope = ScopeLogger::kDBus;
37static string ObjectID(ChromeosDBusAdaptor* d) {
38  if (d == nullptr)
39    return "(dbus_adaptor)";
40  return d->dbus_path().value();
41}
42}
43
44// public static
45const char ChromeosDBusAdaptor::kNullPath[] = "/";
46
47ChromeosDBusAdaptor::ChromeosDBusAdaptor(const scoped_refptr<dbus::Bus>& bus,
48                                         const std::string& object_path)
49    : dbus_path_(object_path),
50      dbus_object_(new DBusObject(nullptr, bus, dbus_path_)) {
51  SLOG(this, 2) << "DBusAdaptor: " << object_path;
52}
53
54ChromeosDBusAdaptor::~ChromeosDBusAdaptor() {}
55
56// static
57bool ChromeosDBusAdaptor::SetProperty(PropertyStore* store,
58                                      const std::string& name,
59                                      const brillo::Any& value,
60                                      brillo::ErrorPtr* error) {
61  Error e;
62  store->SetAnyProperty(name, value, &e);
63  return !e.ToChromeosError(error);
64}
65
66// static
67bool ChromeosDBusAdaptor::GetProperties(
68    const PropertyStore& store,
69    brillo::VariantDictionary* out_properties,
70    brillo::ErrorPtr* error) {
71  Error e;
72  store.GetProperties(out_properties, &e);
73  return !e.ToChromeosError(error);
74}
75
76// static
77bool ChromeosDBusAdaptor::ClearProperty(PropertyStore* store,
78                                        const std::string& name,
79                                        brillo::ErrorPtr* error) {
80  Error e;
81  store->ClearProperty(name, &e);
82  return !e.ToChromeosError(error);
83}
84
85// static
86string ChromeosDBusAdaptor::SanitizePathElement(const string& object_path) {
87  string sanitized_path(object_path);
88  size_t length = sanitized_path.length();
89
90  for (size_t i = 0; i < length; ++i) {
91    char c = sanitized_path[i];
92    // The D-Bus specification
93    // (http://dbus.freedesktop.org/doc/dbus-specification.html) states:
94    // Each element must only contain the ASCII characters "[A-Z][a-z][0-9]_"
95    if (!(c >= 'A' && c <= 'Z') &&
96        !(c >= 'a' && c <= 'z') &&
97        !(c >= '0' && c <= '9') &&
98        c != '_') {
99      sanitized_path[i] = '_';
100    }
101  }
102
103  return sanitized_path;
104}
105
106ResultCallback ChromeosDBusAdaptor::GetMethodReplyCallback(
107    DBusMethodResponsePtr<> response) {
108  return Bind(&ChromeosDBusAdaptor::MethodReplyCallback,
109              AsWeakPtr(),
110              Passed(&response));
111}
112
113ResultStringCallback ChromeosDBusAdaptor::GetStringMethodReplyCallback(
114    DBusMethodResponsePtr<string> response) {
115  return Bind(&ChromeosDBusAdaptor::StringMethodReplyCallback,
116              AsWeakPtr(),
117              Passed(&response));
118}
119
120ResultBoolCallback ChromeosDBusAdaptor::GetBoolMethodReplyCallback(
121    DBusMethodResponsePtr<bool> response) {
122  return Bind(&ChromeosDBusAdaptor::BoolMethodReplyCallback,
123              AsWeakPtr(),
124              Passed(&response));
125}
126
127void ChromeosDBusAdaptor::ReturnResultOrDefer(
128    const ResultCallback& callback, const Error& error) {
129  // Invoke response if command is completed synchronously (either
130  // success or failure).
131  if (!error.IsOngoing()) {
132    callback.Run(error);
133  }
134}
135
136void ChromeosDBusAdaptor::MethodReplyCallback(DBusMethodResponsePtr<> response,
137                                              const Error& error) {
138  brillo::ErrorPtr chromeos_error;
139  if (error.ToChromeosError(&chromeos_error)) {
140    response->ReplyWithError(chromeos_error.get());
141  } else {
142    response->Return();
143  }
144}
145
146template<typename T>
147void ChromeosDBusAdaptor::TypedMethodReplyCallback(
148    DBusMethodResponsePtr<T> response, const Error& error, const T& returned) {
149  brillo::ErrorPtr chromeos_error;
150  if (error.ToChromeosError(&chromeos_error)) {
151    response->ReplyWithError(chromeos_error.get());
152  } else {
153    response->Return(returned);
154  }
155}
156
157void ChromeosDBusAdaptor::StringMethodReplyCallback(
158    DBusMethodResponsePtr<string> response,
159    const Error& error,
160    const string& returned) {
161  TypedMethodReplyCallback(std::move(response), error, returned);
162}
163
164void ChromeosDBusAdaptor::BoolMethodReplyCallback(
165    DBusMethodResponsePtr<bool> response,
166    const Error& error,
167    bool returned) {
168  TypedMethodReplyCallback(std::move(response), error, returned);
169}
170
171}  // namespace shill
172