blob: a6c8d9f45964b9db2e0302e434fa9b5b1d9406f4 [file] [log] [blame]
Christopher Wiley4b5f04c2014-03-27 14:45:37 -07001// Copyright 2014 The Chromium OS 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 "buffet/manager.h"
6
7#include <base/bind.h>
8#include <base/bind_helpers.h>
Christopher Wiley54028f92014-04-01 17:33:29 -07009#include <dbus/object_path.h>
Alex Vakulenkof3d77e52014-04-15 11:36:32 -070010#include <dbus/values_util.h>
11#include <base/json/json_writer.h>
Christopher Wiley4b5f04c2014-03-27 14:45:37 -070012
Christopher Wiley54028f92014-04-01 17:33:29 -070013#include "buffet/async_event_sequencer.h"
Christopher Wiley4b5f04c2014-03-27 14:45:37 -070014#include "buffet/dbus_constants.h"
15#include "buffet/dbus_manager.h"
16#include "buffet/dbus_utils.h"
17
18using buffet::dbus_utils::GetBadArgsError;
19
20namespace buffet {
21
Christopher Wiley54028f92014-04-01 17:33:29 -070022Manager::Manager(dbus::Bus* bus)
23 : bus_(bus),
24 exported_object_(bus->GetExportedObject(
25 dbus::ObjectPath(dbus_constants::kManagerServicePath))) { }
Christopher Wiley4b5f04c2014-03-27 14:45:37 -070026
27Manager::~Manager() {
Christopher Wiley106686a2014-03-27 14:51:26 -070028 // Prevent the properties object from making calls to the exported object.
29 properties_.reset(nullptr);
Christopher Wiley4b5f04c2014-03-27 14:45:37 -070030 // Unregister ourselves from the Bus. This prevents the bus from calling
31 // our callbacks in between the Manager's death and the bus unregistering
32 // our exported object on shutdown. Unretained makes no promises of memory
33 // management.
Christopher Wiley54028f92014-04-01 17:33:29 -070034 exported_object_->Unregister();
35 exported_object_ = nullptr;
36}
37
38void Manager::Init(const OnInitFinish& cb) {
39 scoped_refptr<dbus_utils::AsyncEventSequencer> sequencer(
40 new dbus_utils::AsyncEventSequencer());
41 exported_object_->ExportMethod(
42 dbus_constants::kManagerInterface,
Alex Vakulenkof3d77e52014-04-15 11:36:32 -070043 dbus_constants::kManagerCheckDeviceRegistered,
Christopher Wiley54028f92014-04-01 17:33:29 -070044 dbus_utils::GetExportableDBusMethod(
Alex Vakulenkof3d77e52014-04-15 11:36:32 -070045 base::Bind(&Manager::HandleCheckDeviceRegistered,
Christopher Wiley54028f92014-04-01 17:33:29 -070046 base::Unretained(this))),
47 sequencer->GetExportHandler(
48 dbus_constants::kManagerInterface,
Alex Vakulenkof3d77e52014-04-15 11:36:32 -070049 dbus_constants::kManagerCheckDeviceRegistered,
50 "Failed exporting CheckDeviceRegistered method",
51 true));
52 exported_object_->ExportMethod(
53 dbus_constants::kManagerInterface,
54 dbus_constants::kManagerGetDeviceInfo,
55 dbus_utils::GetExportableDBusMethod(
56 base::Bind(&Manager::HandleGetDeviceInfo,
57 base::Unretained(this))),
58 sequencer->GetExportHandler(
59 dbus_constants::kManagerInterface,
60 dbus_constants::kManagerGetDeviceInfo,
61 "Failed exporting GetDeviceInfo method",
62 true));
63 exported_object_->ExportMethod(
64 dbus_constants::kManagerInterface,
65 dbus_constants::kManagerStartRegisterDevice,
66 dbus_utils::GetExportableDBusMethod(
67 base::Bind(&Manager::HandleStartRegisterDevice,
68 base::Unretained(this))),
69 sequencer->GetExportHandler(
70 dbus_constants::kManagerInterface,
71 dbus_constants::kManagerStartRegisterDevice,
72 "Failed exporting StartRegisterDevice method",
73 true));
74 exported_object_->ExportMethod(
75 dbus_constants::kManagerInterface,
76 dbus_constants::kManagerFinishRegisterDevice,
77 dbus_utils::GetExportableDBusMethod(
78 base::Bind(&Manager::HandleFinishRegisterDevice,
79 base::Unretained(this))),
80 sequencer->GetExportHandler(
81 dbus_constants::kManagerInterface,
82 dbus_constants::kManagerFinishRegisterDevice,
83 "Failed exporting FinishRegisterDevice method",
Christopher Wiley54028f92014-04-01 17:33:29 -070084 true));
85 exported_object_->ExportMethod(
86 dbus_constants::kManagerInterface,
87 dbus_constants::kManagerUpdateStateMethod,
88 dbus_utils::GetExportableDBusMethod(
89 base::Bind(&Manager::HandleUpdateState,
90 base::Unretained(this))),
91 sequencer->GetExportHandler(
92 dbus_constants::kManagerInterface,
93 dbus_constants::kManagerUpdateStateMethod,
94 "Failed exporting UpdateState method",
95 true));
96 properties_.reset(new Properties(bus_));
97 // TODO(wiley): Initialize all properties appropriately before claiming
98 // the properties interface.
99 properties_->state_.SetValue("{}");
100 properties_->Init(
101 sequencer->GetHandler("Manager properties export failed.", true));
102 sequencer->OnAllTasksCompletedCall({cb});
Alex Vakulenkof3d77e52014-04-15 11:36:32 -0700103 device_info_.Load();
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700104}
105
Alex Vakulenkof3d77e52014-04-15 11:36:32 -0700106scoped_ptr<dbus::Response> Manager::HandleCheckDeviceRegistered(
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700107 dbus::MethodCall* method_call) {
108 // Read the parameters to the method.
109 dbus::MessageReader reader(method_call);
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700110 if (reader.HasMoreData()) {
Alex Vakulenkof3d77e52014-04-15 11:36:32 -0700111 return GetBadArgsError(method_call,
112 "Too many parameters to CheckDeviceRegistered");
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700113 }
114
Alex Vakulenkof3d77e52014-04-15 11:36:32 -0700115 LOG(INFO) << "Received call to Manager.CheckDeviceRegistered()";
116
117 bool registered = device_info_.CheckRegistration();
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700118
119 // Send back our response.
120 scoped_ptr<dbus::Response> response(
121 dbus::Response::FromMethodCall(method_call));
122 dbus::MessageWriter writer(response.get());
Alex Vakulenkof3d77e52014-04-15 11:36:32 -0700123 writer.AppendString(registered ? device_info_.GetDeviceId() : std::string());
124 return response.Pass();
125}
126
127scoped_ptr<dbus::Response> Manager::HandleGetDeviceInfo(
128 dbus::MethodCall* method_call) {
129 // Read the parameters to the method.
130 dbus::MessageReader reader(method_call);
131 if (reader.HasMoreData()) {
132 return GetBadArgsError(method_call,
133 "Too many parameters to GetDeviceInfo");
134 }
135
136 LOG(INFO) << "Received call to Manager.GetDeviceInfo()";
137
138 std::string device_info_str;
139 std::unique_ptr<base::Value> device_info = device_info_.GetDeviceInfo();
140 if (device_info)
141 base::JSONWriter::Write(device_info.get(), &device_info_str);
142
143 // Send back our response.
144 scoped_ptr<dbus::Response> response(
145 dbus::Response::FromMethodCall(method_call));
146 dbus::MessageWriter writer(response.get());
147 writer.AppendString(device_info_str);
148 return response.Pass();
149}
150
151scoped_ptr<dbus::Response> Manager::HandleStartRegisterDevice(
152 dbus::MethodCall* method_call) {
153 // Read the parameters to the method.
154 dbus::MessageReader reader(method_call);
155 if (!reader.HasMoreData()) {
156 return GetBadArgsError(method_call, "No parameters to StartRegisterDevice");
157 }
158
159 dbus::MessageReader array_reader(nullptr);
160 if (!reader.PopArray(&array_reader))
161 return GetBadArgsError(method_call, "Failed to read the parameter array");
162 std::map<std::string, std::shared_ptr<base::Value>> params;
163 while (array_reader.HasMoreData()) {
164 dbus::MessageReader dict_entry_reader(nullptr);
165 if (!array_reader.PopDictEntry(&dict_entry_reader))
166 return GetBadArgsError(method_call, "Failed to get a call parameter");
167 std::string key;
168 if (!dict_entry_reader.PopString(&key))
169 return GetBadArgsError(method_call, "Failed to read parameter key");
170 base::Value* value = dbus::PopDataAsValue(&dict_entry_reader);
171 if (!value)
172 return GetBadArgsError(method_call, "Failed to read parameter value");
173 params.insert(std::make_pair(key, std::shared_ptr<base::Value>(value)));
174 }
175 if (reader.HasMoreData())
176 return GetBadArgsError(method_call,
177 "Too many parameters to StartRegisterDevice");
178
179 LOG(INFO) << "Received call to Manager.StartRegisterDevice()";
180
181 std::string error_msg;
182 std::string id = device_info_.StartRegistration(params, &error_msg);
183 if(id.empty())
184 return GetBadArgsError(method_call, error_msg);
185
186 // Send back our response.
187 scoped_ptr<dbus::Response> response(
188 dbus::Response::FromMethodCall(method_call));
189 dbus::MessageWriter writer(response.get());
190 writer.AppendString(id);
191 return response.Pass();
192}
193
194scoped_ptr<dbus::Response> Manager::HandleFinishRegisterDevice(
195 dbus::MethodCall* method_call) {
196 // Read the parameters to the method.
197 dbus::MessageReader reader(method_call);
198 if (!reader.HasMoreData()) {
199 return GetBadArgsError(method_call,
200 "No parameters to FinishRegisterDevice");
201 }
202 std::string user_auth_code;
203 if (!reader.PopString(&user_auth_code)) {
204 return GetBadArgsError(method_call, "Failed to read UserAuthCode");
205 }
206 if (reader.HasMoreData()) {
207 return GetBadArgsError(method_call,
208 "Too many parameters to FinishRegisterDevice");
209 }
210
211 LOG(INFO) << "Received call to Manager.FinishRegisterDevice()";
212 bool success = device_info_.FinishRegistration(user_auth_code);
213
214 // Send back our response.
215 scoped_ptr<dbus::Response> response(
216 dbus::Response::FromMethodCall(method_call));
217 dbus::MessageWriter writer(response.get());
218 writer.AppendString(success ? device_info_.GetDeviceId() : std::string());
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700219 return response.Pass();
220}
221
222scoped_ptr<dbus::Response> Manager::HandleUpdateState(
223 dbus::MethodCall *method_call) {
224 // Read the parameters to the method.
225 dbus::MessageReader reader(method_call);
226 if (!reader.HasMoreData()) {
227 return GetBadArgsError(method_call, "No parameters to UpdateState");
228 }
229 std::string json_state_fragment;
230 if (!reader.PopString(&json_state_fragment)) {
231 return GetBadArgsError(method_call, "Failed to read json_state_fragment");
232 }
233 if (reader.HasMoreData()) {
234 return GetBadArgsError(method_call, "Too many parameters to UpdateState");
235 }
236
237 LOG(INFO) << "Received call to Manager.UpdateState()";
Christopher Wiley106686a2014-03-27 14:51:26 -0700238 // TODO(wiley): Merge json state blobs intelligently.
239 properties_->state_.SetValue(json_state_fragment);
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700240
241 // Send back our response.
242 return dbus::Response::FromMethodCall(method_call);
243}
244
245} // namespace buffet