blob: 7e6422341fabee6bcf964ded6b3296cb6cfb38ec [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 Wiley2ffa0042014-05-05 16:09:16 -07009#include <base/json/json_writer.h>
10#include <dbus/bus.h>
Christopher Wiley54028f92014-04-01 17:33:29 -070011#include <dbus/object_path.h>
Alex Vakulenkof3d77e52014-04-15 11:36:32 -070012#include <dbus/values_util.h>
Christopher Wiley4b5f04c2014-03-27 14:45:37 -070013
Christopher Wiley54028f92014-04-01 17:33:29 -070014#include "buffet/async_event_sequencer.h"
Christopher Wiley4b5f04c2014-03-27 14:45:37 -070015#include "buffet/dbus_constants.h"
Christopher Wiley4b5f04c2014-03-27 14:45:37 -070016#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));
Christopher Wiley2ffa0042014-05-05 16:09:16 -070096 exported_object_->ExportMethod(
97 dbus_constants::kManagerInterface, dbus_constants::kManagerTestMethod,
98 dbus_utils::GetExportableDBusMethod(
99 base::Bind(&Manager::HandleTestMethod, base::Unretained(this))),
100 sequencer->GetExportHandler(
101 dbus_constants::kManagerInterface, dbus_constants::kManagerTestMethod,
102 "Failed exporting TestMethod method",
103 true));
Christopher Wiley54028f92014-04-01 17:33:29 -0700104 properties_.reset(new Properties(bus_));
105 // TODO(wiley): Initialize all properties appropriately before claiming
106 // the properties interface.
107 properties_->state_.SetValue("{}");
108 properties_->Init(
109 sequencer->GetHandler("Manager properties export failed.", true));
110 sequencer->OnAllTasksCompletedCall({cb});
Alex Vakulenkof3d77e52014-04-15 11:36:32 -0700111 device_info_.Load();
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700112}
113
Alex Vakulenkof3d77e52014-04-15 11:36:32 -0700114scoped_ptr<dbus::Response> Manager::HandleCheckDeviceRegistered(
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700115 dbus::MethodCall* method_call) {
116 // Read the parameters to the method.
117 dbus::MessageReader reader(method_call);
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700118 if (reader.HasMoreData()) {
Alex Vakulenkof3d77e52014-04-15 11:36:32 -0700119 return GetBadArgsError(method_call,
120 "Too many parameters to CheckDeviceRegistered");
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700121 }
122
Alex Vakulenkof3d77e52014-04-15 11:36:32 -0700123 LOG(INFO) << "Received call to Manager.CheckDeviceRegistered()";
124
125 bool registered = device_info_.CheckRegistration();
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700126
127 // Send back our response.
128 scoped_ptr<dbus::Response> response(
129 dbus::Response::FromMethodCall(method_call));
130 dbus::MessageWriter writer(response.get());
Alex Vakulenkof3d77e52014-04-15 11:36:32 -0700131 writer.AppendString(registered ? device_info_.GetDeviceId() : std::string());
132 return response.Pass();
133}
134
135scoped_ptr<dbus::Response> Manager::HandleGetDeviceInfo(
136 dbus::MethodCall* method_call) {
137 // Read the parameters to the method.
138 dbus::MessageReader reader(method_call);
139 if (reader.HasMoreData()) {
140 return GetBadArgsError(method_call,
141 "Too many parameters to GetDeviceInfo");
142 }
143
144 LOG(INFO) << "Received call to Manager.GetDeviceInfo()";
145
146 std::string device_info_str;
147 std::unique_ptr<base::Value> device_info = device_info_.GetDeviceInfo();
148 if (device_info)
149 base::JSONWriter::Write(device_info.get(), &device_info_str);
150
151 // Send back our response.
152 scoped_ptr<dbus::Response> response(
153 dbus::Response::FromMethodCall(method_call));
154 dbus::MessageWriter writer(response.get());
155 writer.AppendString(device_info_str);
156 return response.Pass();
157}
158
159scoped_ptr<dbus::Response> Manager::HandleStartRegisterDevice(
160 dbus::MethodCall* method_call) {
161 // Read the parameters to the method.
162 dbus::MessageReader reader(method_call);
163 if (!reader.HasMoreData()) {
164 return GetBadArgsError(method_call, "No parameters to StartRegisterDevice");
165 }
166
167 dbus::MessageReader array_reader(nullptr);
168 if (!reader.PopArray(&array_reader))
169 return GetBadArgsError(method_call, "Failed to read the parameter array");
170 std::map<std::string, std::shared_ptr<base::Value>> params;
171 while (array_reader.HasMoreData()) {
172 dbus::MessageReader dict_entry_reader(nullptr);
173 if (!array_reader.PopDictEntry(&dict_entry_reader))
174 return GetBadArgsError(method_call, "Failed to get a call parameter");
175 std::string key;
176 if (!dict_entry_reader.PopString(&key))
177 return GetBadArgsError(method_call, "Failed to read parameter key");
178 base::Value* value = dbus::PopDataAsValue(&dict_entry_reader);
179 if (!value)
180 return GetBadArgsError(method_call, "Failed to read parameter value");
181 params.insert(std::make_pair(key, std::shared_ptr<base::Value>(value)));
182 }
183 if (reader.HasMoreData())
184 return GetBadArgsError(method_call,
185 "Too many parameters to StartRegisterDevice");
186
187 LOG(INFO) << "Received call to Manager.StartRegisterDevice()";
188
189 std::string error_msg;
190 std::string id = device_info_.StartRegistration(params, &error_msg);
191 if(id.empty())
192 return GetBadArgsError(method_call, error_msg);
193
194 // Send back our response.
195 scoped_ptr<dbus::Response> response(
196 dbus::Response::FromMethodCall(method_call));
197 dbus::MessageWriter writer(response.get());
198 writer.AppendString(id);
199 return response.Pass();
200}
201
202scoped_ptr<dbus::Response> Manager::HandleFinishRegisterDevice(
203 dbus::MethodCall* method_call) {
204 // Read the parameters to the method.
205 dbus::MessageReader reader(method_call);
206 if (!reader.HasMoreData()) {
207 return GetBadArgsError(method_call,
208 "No parameters to FinishRegisterDevice");
209 }
210 std::string user_auth_code;
211 if (!reader.PopString(&user_auth_code)) {
212 return GetBadArgsError(method_call, "Failed to read UserAuthCode");
213 }
214 if (reader.HasMoreData()) {
215 return GetBadArgsError(method_call,
216 "Too many parameters to FinishRegisterDevice");
217 }
218
219 LOG(INFO) << "Received call to Manager.FinishRegisterDevice()";
220 bool success = device_info_.FinishRegistration(user_auth_code);
221
222 // Send back our response.
223 scoped_ptr<dbus::Response> response(
224 dbus::Response::FromMethodCall(method_call));
225 dbus::MessageWriter writer(response.get());
226 writer.AppendString(success ? device_info_.GetDeviceId() : std::string());
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700227 return response.Pass();
228}
229
230scoped_ptr<dbus::Response> Manager::HandleUpdateState(
231 dbus::MethodCall *method_call) {
232 // Read the parameters to the method.
233 dbus::MessageReader reader(method_call);
234 if (!reader.HasMoreData()) {
235 return GetBadArgsError(method_call, "No parameters to UpdateState");
236 }
237 std::string json_state_fragment;
238 if (!reader.PopString(&json_state_fragment)) {
239 return GetBadArgsError(method_call, "Failed to read json_state_fragment");
240 }
241 if (reader.HasMoreData()) {
242 return GetBadArgsError(method_call, "Too many parameters to UpdateState");
243 }
244
245 LOG(INFO) << "Received call to Manager.UpdateState()";
Christopher Wiley106686a2014-03-27 14:51:26 -0700246 // TODO(wiley): Merge json state blobs intelligently.
247 properties_->state_.SetValue(json_state_fragment);
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700248
249 // Send back our response.
250 return dbus::Response::FromMethodCall(method_call);
251}
252
Christopher Wiley2ffa0042014-05-05 16:09:16 -0700253scoped_ptr<dbus::Response> Manager::HandleTestMethod(
254 dbus::MethodCall* method_call) {
255 LOG(INFO) << "Received call to test method.";
256 return scoped_ptr<dbus::Response>();
257}
258
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700259} // namespace buffet