blob: 4cfbcc94041ca1c80e579e8cc643a2ced10a650b [file] [log] [blame]
[email protected]02798a982012-01-27 00:45:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]a51076112011-08-17 20:58:122// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "dbus/test_service.h"
6
avi22437c692015-12-22 18:12:457#include <stdint.h>
dtapuska1d622f02015-02-09 22:51:408#include <string>
dchenge48600452015-12-28 02:24:509#include <utility>
dtapuska1d622f02015-02-09 22:51:4010#include <vector>
11
[email protected]a51076112011-08-17 20:58:1212#include "base/bind.h"
Peter Kasting341e1fb2018-02-24 00:03:0113#include "base/bind_helpers.h"
hashimoto067d84f522016-01-05 08:48:0314#include "base/guid.h"
Alexander Timin4f9c35c2018-11-01 20:15:2015#include "base/message_loop/message_loop.h"
fdoraye1e050c52016-07-19 21:05:5416#include "base/run_loop.h"
fdoray6ef45cf2016-08-25 15:36:3717#include "base/single_thread_task_runner.h"
[email protected]12f97662011-08-20 01:07:1718#include "base/test/test_timeouts.h"
[email protected]a51076112011-08-17 20:58:1219#include "base/threading/platform_thread.h"
20#include "dbus/bus.h"
21#include "dbus/exported_object.h"
22#include "dbus/message.h"
[email protected]9cc40cb2013-03-25 18:20:0823#include "dbus/object_manager.h"
[email protected]216ed0b2012-02-14 21:29:0624#include "dbus/object_path.h"
[email protected]cf910da22012-02-15 04:21:0825#include "dbus/property.h"
[email protected]a51076112011-08-17 20:58:1226
27namespace dbus {
28
[email protected]9cc40cb2013-03-25 18:20:0829// Echo, SlowEcho, AsyncEcho, BrokenMethod, GetAll, Get, Set, PerformAction,
armansitoebff093d2014-09-05 17:49:3430// GetManagedObjects
[email protected]9cc40cb2013-03-25 18:20:0831const int TestService::kNumMethodsToExport = 9;
[email protected]a51076112011-08-17 20:58:1232
[email protected]e2824902013-07-31 06:34:5933TestService::Options::Options()
34 : request_ownership_options(Bus::REQUIRE_PRIMARY) {
[email protected]12f97662011-08-20 01:07:1735}
36
Chris Watkins3740aae2017-11-29 07:44:1137TestService::Options::~Options() = default;
[email protected]12f97662011-08-20 01:07:1738
39TestService::TestService(const Options& options)
[email protected]a51076112011-08-17 20:58:1240 : base::Thread("TestService"),
hashimoto067d84f522016-01-05 08:48:0341 service_name_(options.service_name),
[email protected]e2824902013-07-31 06:34:5942 request_ownership_options_(options.request_ownership_options),
[email protected]200328a2013-02-20 01:36:5343 dbus_task_runner_(options.dbus_task_runner),
gab0faddf482016-06-02 12:26:5544 on_name_obtained_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
45 base::WaitableEvent::InitialState::NOT_SIGNALED),
earthdok340dde22014-10-08 13:00:2046 num_exported_methods_(0),
47 send_immediate_properties_changed_(false),
48 has_ownership_(false),
Ben Chan14d500372017-11-09 20:20:1649 exported_object_(nullptr),
50 exported_object_manager_(nullptr) {
hashimoto067d84f522016-01-05 08:48:0351 if (service_name_.empty()) {
52 service_name_ = "org.chromium.TestService-" + base::GenerateGUID();
53 }
[email protected]a51076112011-08-17 20:58:1254}
55
56TestService::~TestService() {
[email protected]d583c3a2011-11-02 15:31:5657 Stop();
[email protected]a51076112011-08-17 20:58:1258}
59
[email protected]12f97662011-08-20 01:07:1760bool TestService::StartService() {
[email protected]a51076112011-08-17 20:58:1261 base::Thread::Options thread_options;
[email protected]ff33b18e2013-05-01 16:10:3062 thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
[email protected]12f97662011-08-20 01:07:1763 return StartWithOptions(thread_options);
[email protected]a51076112011-08-17 20:58:1264}
65
Ryo Hashimoto3bbeb5c2018-08-13 04:58:3966void TestService::WaitUntilServiceIsStarted() {
[email protected]332577d2014-01-09 04:39:1767 // Wait until the ownership of the service name is obtained.
Ryo Hashimoto3bbeb5c2018-08-13 04:58:3968 on_name_obtained_.Wait();
[email protected]12f97662011-08-20 01:07:1769}
70
[email protected]e20d39fe2011-09-02 06:56:2371void TestService::ShutdownAndBlock() {
Alexander Timin0439ffe2018-10-30 18:10:0072 task_runner()->PostTask(FROM_HERE,
kylechar39c39282019-02-19 19:04:0473 base::BindOnce(&TestService::ShutdownAndBlockInternal,
74 base::Unretained(this)));
[email protected]a51076112011-08-17 20:58:1275}
76
[email protected]12f97662011-08-20 01:07:1777bool TestService::HasDBusThread() {
78 return bus_->HasDBusThread();
79}
80
[email protected]e20d39fe2011-09-02 06:56:2381void TestService::ShutdownAndBlockInternal() {
82 if (HasDBusThread())
83 bus_->ShutdownOnDBusThreadAndBlock();
84 else
85 bus_->ShutdownAndBlock();
86}
87
[email protected]3beaaa4e2011-08-23 07:29:2188void TestService::SendTestSignal(const std::string& message) {
Alexander Timin0439ffe2018-10-30 18:10:0089 task_runner()->PostTask(FROM_HERE,
kylechar39c39282019-02-19 19:04:0490 base::BindOnce(&TestService::SendTestSignalInternal,
91 base::Unretained(this), message));
[email protected]3beaaa4e2011-08-23 07:29:2192}
93
[email protected]df159b22011-09-14 22:10:2494void TestService::SendTestSignalFromRoot(const std::string& message) {
Alexander Timin0439ffe2018-10-30 18:10:0095 task_runner()->PostTask(
kylechar39c39282019-02-19 19:04:0496 FROM_HERE, base::BindOnce(&TestService::SendTestSignalFromRootInternal,
97 base::Unretained(this), message));
[email protected]df159b22011-09-14 22:10:2498}
99
[email protected]3beaaa4e2011-08-23 07:29:21100void TestService::SendTestSignalInternal(const std::string& message) {
[email protected]2a57ca642013-06-13 06:37:19101 Signal signal("org.chromium.TestInterface", "Test");
102 MessageWriter writer(&signal);
[email protected]3beaaa4e2011-08-23 07:29:21103 writer.AppendString(message);
104 exported_object_->SendSignal(&signal);
105}
106
[email protected]df159b22011-09-14 22:10:24107void TestService::SendTestSignalFromRootInternal(const std::string& message) {
[email protected]2a57ca642013-06-13 06:37:19108 Signal signal("org.chromium.TestInterface", "Test");
109 MessageWriter writer(&signal);
[email protected]df159b22011-09-14 22:10:24110 writer.AppendString(message);
111
Peter Kasting341e1fb2018-02-24 00:03:01112 bus_->RequestOwnership(service_name_, request_ownership_options_,
[email protected]15e7b162012-03-10 01:12:52113 base::Bind(&TestService::OnOwnership,
Peter Kasting341e1fb2018-02-24 00:03:01114 base::Unretained(this), base::DoNothing()));
[email protected]15e7b162012-03-10 01:12:52115
[email protected]df159b22011-09-14 22:10:24116 // Use "/" just like dbus-send does.
[email protected]2a57ca642013-06-13 06:37:19117 ExportedObject* root_object = bus_->GetExportedObject(ObjectPath("/"));
[email protected]df159b22011-09-14 22:10:24118 root_object->SendSignal(&signal);
119}
120
[email protected]6d36c0c2012-11-14 11:02:59121void TestService::RequestOwnership(base::Callback<void(bool)> callback) {
Alexander Timin0439ffe2018-10-30 18:10:00122 task_runner()->PostTask(FROM_HERE,
kylechar39c39282019-02-19 19:04:04123 base::BindOnce(&TestService::RequestOwnershipInternal,
124 base::Unretained(this), callback));
[email protected]8bbe31e2012-10-29 06:27:33125}
126
[email protected]6d36c0c2012-11-14 11:02:59127void TestService::RequestOwnershipInternal(
128 base::Callback<void(bool)> callback) {
hashimoto067d84f522016-01-05 08:48:03129 bus_->RequestOwnership(service_name_,
[email protected]e2824902013-07-31 06:34:59130 request_ownership_options_,
[email protected]8bbe31e2012-10-29 06:27:33131 base::Bind(&TestService::OnOwnership,
[email protected]6d36c0c2012-11-14 11:02:59132 base::Unretained(this),
133 callback));
[email protected]8bbe31e2012-10-29 06:27:33134}
135
[email protected]6d36c0c2012-11-14 11:02:59136void TestService::OnOwnership(base::Callback<void(bool)> callback,
137 const std::string& service_name,
[email protected]15e7b162012-03-10 01:12:52138 bool success) {
[email protected]6d36c0c2012-11-14 11:02:59139 has_ownership_ = success;
[email protected]15e7b162012-03-10 01:12:52140 LOG_IF(ERROR, !success) << "Failed to own: " << service_name;
[email protected]6d36c0c2012-11-14 11:02:59141 callback.Run(success);
[email protected]332577d2014-01-09 04:39:17142
143 on_name_obtained_.Signal();
[email protected]15e7b162012-03-10 01:12:52144}
145
[email protected]043fb8c2014-03-07 02:24:33146void TestService::ReleaseOwnership(base::Closure callback) {
147 bus_->GetDBusTaskRunner()->PostTask(
kylechar39c39282019-02-19 19:04:04148 FROM_HERE, base::BindOnce(&TestService::ReleaseOwnershipInternal,
149 base::Unretained(this), callback));
[email protected]043fb8c2014-03-07 02:24:33150}
151
152void TestService::ReleaseOwnershipInternal(
153 base::Closure callback) {
hashimoto067d84f522016-01-05 08:48:03154 bus_->ReleaseOwnership(service_name_);
[email protected]043fb8c2014-03-07 02:24:33155 has_ownership_ = false;
156
157 bus_->GetOriginTaskRunner()->PostTask(
158 FROM_HERE,
159 callback);
160}
161
armansitoebff093d2014-09-05 17:49:34162void TestService::SetSendImmediatePropertiesChanged() {
163 send_immediate_properties_changed_ = true;
164}
165
[email protected]12f97662011-08-20 01:07:17166void TestService::OnExported(const std::string& interface_name,
167 const std::string& method_name,
168 bool success) {
169 if (!success) {
170 LOG(ERROR) << "Failed to export: " << interface_name << "."
171 << method_name;
172 // Returning here will make WaitUntilServiceIsStarted() to time out
173 // and return false.
174 return;
175 }
176
177 ++num_exported_methods_;
[email protected]332577d2014-01-09 04:39:17178 if (num_exported_methods_ == kNumMethodsToExport) {
179 // As documented in exported_object.h, the service name should be
180 // requested after all methods are exposed.
Peter Kasting341e1fb2018-02-24 00:03:01181 bus_->RequestOwnership(
182 service_name_, request_ownership_options_,
183 base::Bind(&TestService::OnOwnership, base::Unretained(this),
184 base::DoNothing()));
[email protected]332577d2014-01-09 04:39:17185 }
[email protected]12f97662011-08-20 01:07:17186}
187
fdoraye1e050c52016-07-19 21:05:54188void TestService::Run(base::RunLoop* run_loop) {
[email protected]a51076112011-08-17 20:58:12189 Bus::Options bus_options;
190 bus_options.bus_type = Bus::SESSION;
191 bus_options.connection_type = Bus::PRIVATE;
[email protected]200328a2013-02-20 01:36:53192 bus_options.dbus_task_runner = dbus_task_runner_;
[email protected]a51076112011-08-17 20:58:12193 bus_ = new Bus(bus_options);
194
195 exported_object_ = bus_->GetExportedObject(
[email protected]2a57ca642013-06-13 06:37:19196 ObjectPath("/org/chromium/TestObject"));
[email protected]12f97662011-08-20 01:07:17197
198 int num_methods = 0;
199 exported_object_->ExportMethod(
[email protected]a51076112011-08-17 20:58:12200 "org.chromium.TestInterface",
201 "Echo",
202 base::Bind(&TestService::Echo,
[email protected]12f97662011-08-20 01:07:17203 base::Unretained(this)),
204 base::Bind(&TestService::OnExported,
205 base::Unretained(this)));
206 ++num_methods;
207
208 exported_object_->ExportMethod(
[email protected]a51076112011-08-17 20:58:12209 "org.chromium.TestInterface",
210 "SlowEcho",
211 base::Bind(&TestService::SlowEcho,
[email protected]12f97662011-08-20 01:07:17212 base::Unretained(this)),
213 base::Bind(&TestService::OnExported,
214 base::Unretained(this)));
215 ++num_methods;
216
217 exported_object_->ExportMethod(
[email protected]a51076112011-08-17 20:58:12218 "org.chromium.TestInterface",
[email protected]9aa74cc2011-11-30 04:57:42219 "AsyncEcho",
220 base::Bind(&TestService::AsyncEcho,
221 base::Unretained(this)),
222 base::Bind(&TestService::OnExported,
223 base::Unretained(this)));
224 ++num_methods;
225
226 exported_object_->ExportMethod(
227 "org.chromium.TestInterface",
[email protected]a51076112011-08-17 20:58:12228 "BrokenMethod",
229 base::Bind(&TestService::BrokenMethod,
[email protected]12f97662011-08-20 01:07:17230 base::Unretained(this)),
231 base::Bind(&TestService::OnExported,
232 base::Unretained(this)));
233 ++num_methods;
[email protected]a51076112011-08-17 20:58:12234
[email protected]cf910da22012-02-15 04:21:08235 exported_object_->ExportMethod(
[email protected]9cc40cb2013-03-25 18:20:08236 "org.chromium.TestInterface",
237 "PerformAction",
238 base::Bind(&TestService::PerformAction,
239 base::Unretained(this)),
240 base::Bind(&TestService::OnExported,
241 base::Unretained(this)));
242 ++num_methods;
243
244 exported_object_->ExportMethod(
[email protected]cf910da22012-02-15 04:21:08245 kPropertiesInterface,
246 kPropertiesGetAll,
247 base::Bind(&TestService::GetAllProperties,
248 base::Unretained(this)),
249 base::Bind(&TestService::OnExported,
250 base::Unretained(this)));
251 ++num_methods;
252
253 exported_object_->ExportMethod(
254 kPropertiesInterface,
255 kPropertiesGet,
256 base::Bind(&TestService::GetProperty,
257 base::Unretained(this)),
258 base::Bind(&TestService::OnExported,
259 base::Unretained(this)));
260 ++num_methods;
261
262 exported_object_->ExportMethod(
263 kPropertiesInterface,
264 kPropertiesSet,
265 base::Bind(&TestService::SetProperty,
266 base::Unretained(this)),
267 base::Bind(&TestService::OnExported,
268 base::Unretained(this)));
269 ++num_methods;
270
[email protected]9cc40cb2013-03-25 18:20:08271 exported_object_manager_ = bus_->GetExportedObject(
[email protected]2a57ca642013-06-13 06:37:19272 ObjectPath("/org/chromium/TestService"));
[email protected]9cc40cb2013-03-25 18:20:08273
274 exported_object_manager_->ExportMethod(
275 kObjectManagerInterface,
276 kObjectManagerGetManagedObjects,
277 base::Bind(&TestService::GetManagedObjects,
278 base::Unretained(this)),
279 base::Bind(&TestService::OnExported,
280 base::Unretained(this)));
281 ++num_methods;
282
[email protected]12f97662011-08-20 01:07:17283 // Just print an error message as we don't want to crash tests.
284 // Tests will fail at a call to WaitUntilServiceIsStarted().
285 if (num_methods != kNumMethodsToExport) {
286 LOG(ERROR) << "The number of methods does not match";
287 }
fdoraye1e050c52016-07-19 21:05:54288 run_loop->Run();
[email protected]a51076112011-08-17 20:58:12289}
290
[email protected]9aa74cc2011-11-30 04:57:42291void TestService::Echo(MethodCall* method_call,
[email protected]2a57ca642013-06-13 06:37:19292 ExportedObject::ResponseSender response_sender) {
[email protected]a51076112011-08-17 20:58:12293 MessageReader reader(method_call);
294 std::string text_message;
[email protected]9aa74cc2011-11-30 04:57:42295 if (!reader.PopString(&text_message)) {
dcheng2a193282016-04-08 22:55:04296 response_sender.Run(std::unique_ptr<Response>());
[email protected]9aa74cc2011-11-30 04:57:42297 return;
298 }
[email protected]a51076112011-08-17 20:58:12299
dcheng2a193282016-04-08 22:55:04300 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9b25d452013-02-07 09:46:24301 MessageWriter writer(response.get());
[email protected]a51076112011-08-17 20:58:12302 writer.AppendString(text_message);
dchenge48600452015-12-28 02:24:50303 response_sender.Run(std::move(response));
[email protected]a51076112011-08-17 20:58:12304}
305
[email protected]2a57ca642013-06-13 06:37:19306void TestService::SlowEcho(MethodCall* method_call,
307 ExportedObject::ResponseSender response_sender) {
[email protected]02798a982012-01-27 00:45:33308 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
[email protected]9aa74cc2011-11-30 04:57:42309 Echo(method_call, response_sender);
[email protected]a51076112011-08-17 20:58:12310}
311
[email protected]2a57ca642013-06-13 06:37:19312void TestService::AsyncEcho(MethodCall* method_call,
313 ExportedObject::ResponseSender response_sender) {
[email protected]9aa74cc2011-11-30 04:57:42314 // Schedule a call to Echo() to send an asynchronous response after we return.
Alexander Timin0439ffe2018-10-30 18:10:00315 task_runner()->PostDelayedTask(
316 FROM_HERE,
kylechar39c39282019-02-19 19:04:04317 base::BindOnce(&TestService::Echo, base::Unretained(this), method_call,
318 response_sender),
fdoray6ef45cf2016-08-25 15:36:37319 TestTimeouts::tiny_timeout());
[email protected]9aa74cc2011-11-30 04:57:42320}
321
[email protected]2a57ca642013-06-13 06:37:19322void TestService::BrokenMethod(MethodCall* method_call,
323 ExportedObject::ResponseSender response_sender) {
dcheng2a193282016-04-08 22:55:04324 response_sender.Run(std::unique_ptr<Response>());
[email protected]a51076112011-08-17 20:58:12325}
326
[email protected]cf910da22012-02-15 04:21:08327
328void TestService::GetAllProperties(
329 MethodCall* method_call,
[email protected]2a57ca642013-06-13 06:37:19330 ExportedObject::ResponseSender response_sender) {
[email protected]cf910da22012-02-15 04:21:08331 MessageReader reader(method_call);
332 std::string interface;
333 if (!reader.PopString(&interface)) {
dcheng2a193282016-04-08 22:55:04334 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08335 return;
336 }
337
dcheng2a193282016-04-08 22:55:04338 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9b25d452013-02-07 09:46:24339 MessageWriter writer(response.get());
[email protected]cf910da22012-02-15 04:21:08340
[email protected]9cc40cb2013-03-25 18:20:08341 AddPropertiesToWriter(&writer);
[email protected]cf910da22012-02-15 04:21:08342
dchenge48600452015-12-28 02:24:50343 response_sender.Run(std::move(response));
[email protected]cf910da22012-02-15 04:21:08344}
345
[email protected]2a57ca642013-06-13 06:37:19346void TestService::GetProperty(MethodCall* method_call,
347 ExportedObject::ResponseSender response_sender) {
[email protected]cf910da22012-02-15 04:21:08348 MessageReader reader(method_call);
349 std::string interface;
350 if (!reader.PopString(&interface)) {
dcheng2a193282016-04-08 22:55:04351 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08352 return;
353 }
354
355 std::string name;
356 if (!reader.PopString(&name)) {
dcheng2a193282016-04-08 22:55:04357 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08358 return;
359 }
360
[email protected]72bbacc2012-03-21 23:43:45361 if (name == "Name") {
362 // Return the previous value for the "Name" property:
363 // Variant<"TestService">
dcheng2a193282016-04-08 22:55:04364 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9b25d452013-02-07 09:46:24365 MessageWriter writer(response.get());
[email protected]72bbacc2012-03-21 23:43:45366
367 writer.AppendVariantOfString("TestService");
368
dchenge48600452015-12-28 02:24:50369 response_sender.Run(std::move(response));
[email protected]72bbacc2012-03-21 23:43:45370 } else if (name == "Version") {
371 // Return a new value for the "Version" property:
372 // Variant<20>
dcheng2a193282016-04-08 22:55:04373 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9b25d452013-02-07 09:46:24374 MessageWriter writer(response.get());
[email protected]72bbacc2012-03-21 23:43:45375
376 writer.AppendVariantOfInt16(20);
377
dchenge48600452015-12-28 02:24:50378 response_sender.Run(std::move(response));
[email protected]72bbacc2012-03-21 23:43:45379 } else if (name == "Methods") {
380 // Return the previous value for the "Methods" property:
381 // Variant<["Echo", "SlowEcho", "AsyncEcho", "BrokenMethod"]>
dcheng2a193282016-04-08 22:55:04382 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9b25d452013-02-07 09:46:24383 MessageWriter writer(response.get());
Ben Chan14d500372017-11-09 20:20:16384 MessageWriter variant_writer(nullptr);
385 MessageWriter variant_array_writer(nullptr);
[email protected]72bbacc2012-03-21 23:43:45386
387 writer.OpenVariant("as", &variant_writer);
388 variant_writer.OpenArray("s", &variant_array_writer);
389 variant_array_writer.AppendString("Echo");
390 variant_array_writer.AppendString("SlowEcho");
391 variant_array_writer.AppendString("AsyncEcho");
392 variant_array_writer.AppendString("BrokenMethod");
393 variant_writer.CloseContainer(&variant_array_writer);
394 writer.CloseContainer(&variant_writer);
395
dchenge48600452015-12-28 02:24:50396 response_sender.Run(std::move(response));
[email protected]72bbacc2012-03-21 23:43:45397 } else if (name == "Objects") {
398 // Return the previous value for the "Objects" property:
399 // Variant<[objectpath:"/TestObjectPath"]>
dcheng2a193282016-04-08 22:55:04400 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9b25d452013-02-07 09:46:24401 MessageWriter writer(response.get());
Ben Chan14d500372017-11-09 20:20:16402 MessageWriter variant_writer(nullptr);
403 MessageWriter variant_array_writer(nullptr);
[email protected]72bbacc2012-03-21 23:43:45404
405 writer.OpenVariant("ao", &variant_writer);
406 variant_writer.OpenArray("o", &variant_array_writer);
[email protected]2a57ca642013-06-13 06:37:19407 variant_array_writer.AppendObjectPath(ObjectPath("/TestObjectPath"));
[email protected]72bbacc2012-03-21 23:43:45408 variant_writer.CloseContainer(&variant_array_writer);
409 writer.CloseContainer(&variant_writer);
410
dchenge48600452015-12-28 02:24:50411 response_sender.Run(std::move(response));
[email protected]ebbfffa22014-03-15 07:40:49412 } else if (name == "Bytes") {
413 // Return the previous value for the "Bytes" property:
414 // Variant<[0x54, 0x65, 0x73, 0x74]>
dcheng2a193282016-04-08 22:55:04415 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]ebbfffa22014-03-15 07:40:49416 MessageWriter writer(response.get());
Ben Chan14d500372017-11-09 20:20:16417 MessageWriter variant_writer(nullptr);
418 MessageWriter variant_array_writer(nullptr);
[email protected]ebbfffa22014-03-15 07:40:49419
420 writer.OpenVariant("ay", &variant_writer);
avi22437c692015-12-22 18:12:45421 const uint8_t bytes[] = {0x54, 0x65, 0x73, 0x74};
[email protected]ebbfffa22014-03-15 07:40:49422 variant_writer.AppendArrayOfBytes(bytes, sizeof(bytes));
423 writer.CloseContainer(&variant_writer);
424
dchenge48600452015-12-28 02:24:50425 response_sender.Run(std::move(response));
[email protected]72bbacc2012-03-21 23:43:45426 } else {
427 // Return error.
dcheng2a193282016-04-08 22:55:04428 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08429 return;
430 }
[email protected]cf910da22012-02-15 04:21:08431}
432
[email protected]2a57ca642013-06-13 06:37:19433void TestService::SetProperty(MethodCall* method_call,
434 ExportedObject::ResponseSender response_sender) {
[email protected]cf910da22012-02-15 04:21:08435 MessageReader reader(method_call);
436 std::string interface;
437 if (!reader.PopString(&interface)) {
dcheng2a193282016-04-08 22:55:04438 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08439 return;
440 }
441
442 std::string name;
443 if (!reader.PopString(&name)) {
dcheng2a193282016-04-08 22:55:04444 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08445 return;
446 }
447
448 if (name != "Name") {
dcheng2a193282016-04-08 22:55:04449 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08450 return;
451 }
452
453 std::string value;
454 if (!reader.PopVariantOfString(&value)) {
dcheng2a193282016-04-08 22:55:04455 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08456 return;
457 }
458
459 SendPropertyChangedSignal(value);
460
[email protected]9b25d452013-02-07 09:46:24461 response_sender.Run(Response::FromMethodCall(method_call));
[email protected]cf910da22012-02-15 04:21:08462}
463
[email protected]9cc40cb2013-03-25 18:20:08464void TestService::PerformAction(
465 MethodCall* method_call,
[email protected]2a57ca642013-06-13 06:37:19466 ExportedObject::ResponseSender response_sender) {
[email protected]9cc40cb2013-03-25 18:20:08467 MessageReader reader(method_call);
468 std::string action;
[email protected]2a57ca642013-06-13 06:37:19469 ObjectPath object_path;
[email protected]9cc40cb2013-03-25 18:20:08470 if (!reader.PopString(&action) || !reader.PopObjectPath(&object_path)) {
dcheng2a193282016-04-08 22:55:04471 response_sender.Run(std::unique_ptr<Response>());
[email protected]9cc40cb2013-03-25 18:20:08472 return;
473 }
474
armansitoebff093d2014-09-05 17:49:34475 if (action == "AddObject") {
[email protected]9cc40cb2013-03-25 18:20:08476 AddObject(object_path);
armansitoebff093d2014-09-05 17:49:34477 } else if (action == "RemoveObject") {
[email protected]9cc40cb2013-03-25 18:20:08478 RemoveObject(object_path);
armansitoebff093d2014-09-05 17:49:34479 } else if (action == "SetSendImmediatePropertiesChanged") {
480 SetSendImmediatePropertiesChanged();
dtapuska1d622f02015-02-09 22:51:40481 } else if (action == "ReleaseOwnership") {
[email protected]043fb8c2014-03-07 02:24:33482 ReleaseOwnership(base::Bind(&TestService::PerformActionResponse,
483 base::Unretained(this),
484 method_call, response_sender));
485 return;
486 } else if (action == "Ownership") {
487 ReleaseOwnership(base::Bind(&TestService::OwnershipReleased,
488 base::Unretained(this),
489 method_call, response_sender));
490 return;
jpawlowskied276542015-05-11 11:07:04491 } else if (action == "InvalidateProperty") {
492 SendPropertyInvalidatedSignal();
[email protected]043fb8c2014-03-07 02:24:33493 }
[email protected]9cc40cb2013-03-25 18:20:08494
dcheng2a193282016-04-08 22:55:04495 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
dchenge48600452015-12-28 02:24:50496 response_sender.Run(std::move(response));
[email protected]9cc40cb2013-03-25 18:20:08497}
498
[email protected]043fb8c2014-03-07 02:24:33499void TestService::PerformActionResponse(
500 MethodCall* method_call,
501 ExportedObject::ResponseSender response_sender) {
dcheng2a193282016-04-08 22:55:04502 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
dchenge48600452015-12-28 02:24:50503 response_sender.Run(std::move(response));
[email protected]043fb8c2014-03-07 02:24:33504}
505
506void TestService::OwnershipReleased(
507 MethodCall* method_call,
508 ExportedObject::ResponseSender response_sender) {
509 RequestOwnership(base::Bind(&TestService::OwnershipRegained,
510 base::Unretained(this),
511 method_call, response_sender));
512}
513
514
515void TestService::OwnershipRegained(
516 MethodCall* method_call,
517 ExportedObject::ResponseSender response_sender,
518 bool success) {
519 PerformActionResponse(method_call, response_sender);
520}
521
522
[email protected]9cc40cb2013-03-25 18:20:08523void TestService::GetManagedObjects(
524 MethodCall* method_call,
[email protected]2a57ca642013-06-13 06:37:19525 ExportedObject::ResponseSender response_sender) {
dcheng2a193282016-04-08 22:55:04526 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9cc40cb2013-03-25 18:20:08527 MessageWriter writer(response.get());
528
529 // The managed objects response is a dictionary of object paths identifying
530 // the object(s) with a dictionary of strings identifying the interface(s)
531 // they implement and then a dictionary of property values.
532 //
533 // Thus this looks something like:
534 //
535 // {
536 // "/org/chromium/TestObject": {
537 // "org.chromium.TestInterface": { /* Properties */ }
538 // }
539 // }
540
541
Ben Chan14d500372017-11-09 20:20:16542 MessageWriter array_writer(nullptr);
543 MessageWriter dict_entry_writer(nullptr);
544 MessageWriter object_array_writer(nullptr);
545 MessageWriter object_dict_entry_writer(nullptr);
[email protected]9cc40cb2013-03-25 18:20:08546
547 writer.OpenArray("{oa{sa{sv}}}", &array_writer);
548
549 array_writer.OpenDictEntry(&dict_entry_writer);
[email protected]2a57ca642013-06-13 06:37:19550 dict_entry_writer.AppendObjectPath(ObjectPath("/org/chromium/TestObject"));
[email protected]9cc40cb2013-03-25 18:20:08551 dict_entry_writer.OpenArray("{sa{sv}}", &object_array_writer);
552
553 object_array_writer.OpenDictEntry(&object_dict_entry_writer);
554 object_dict_entry_writer.AppendString("org.chromium.TestInterface");
555 AddPropertiesToWriter(&object_dict_entry_writer);
556 object_array_writer.CloseContainer(&object_dict_entry_writer);
557
558 dict_entry_writer.CloseContainer(&object_array_writer);
559
560 array_writer.CloseContainer(&dict_entry_writer);
561 writer.CloseContainer(&array_writer);
562
dchenge48600452015-12-28 02:24:50563 response_sender.Run(std::move(response));
armansitoebff093d2014-09-05 17:49:34564
565 if (send_immediate_properties_changed_)
566 SendPropertyChangedSignal("ChangedTestServiceName");
[email protected]9cc40cb2013-03-25 18:20:08567}
568
[email protected]2a57ca642013-06-13 06:37:19569void TestService::AddPropertiesToWriter(MessageWriter* writer) {
[email protected]9cc40cb2013-03-25 18:20:08570 // The properties response is a dictionary of strings identifying the
571 // property and a variant containing the property value. We return all
572 // of the properties, thus the response is:
573 //
574 // {
575 // "Name": Variant<"TestService">,
576 // "Version": Variant<10>,
577 // "Methods": Variant<["Echo", "SlowEcho", "AsyncEcho", "BrokenMethod"]>,
578 // "Objects": Variant<[objectpath:"/TestObjectPath"]>
[email protected]ebbfffa22014-03-15 07:40:49579 // "Bytes": Variant<[0x54, 0x65, 0x73, 0x74]>
[email protected]2a57ca642013-06-13 06:37:19580 // }
[email protected]9cc40cb2013-03-25 18:20:08581
Ben Chan14d500372017-11-09 20:20:16582 MessageWriter array_writer(nullptr);
583 MessageWriter dict_entry_writer(nullptr);
584 MessageWriter variant_writer(nullptr);
585 MessageWriter variant_array_writer(nullptr);
[email protected]9cc40cb2013-03-25 18:20:08586
587 writer->OpenArray("{sv}", &array_writer);
588
589 array_writer.OpenDictEntry(&dict_entry_writer);
590 dict_entry_writer.AppendString("Name");
591 dict_entry_writer.AppendVariantOfString("TestService");
592 array_writer.CloseContainer(&dict_entry_writer);
593
594 array_writer.OpenDictEntry(&dict_entry_writer);
595 dict_entry_writer.AppendString("Version");
596 dict_entry_writer.AppendVariantOfInt16(10);
597 array_writer.CloseContainer(&dict_entry_writer);
598
599 array_writer.OpenDictEntry(&dict_entry_writer);
600 dict_entry_writer.AppendString("Methods");
601 dict_entry_writer.OpenVariant("as", &variant_writer);
602 variant_writer.OpenArray("s", &variant_array_writer);
603 variant_array_writer.AppendString("Echo");
604 variant_array_writer.AppendString("SlowEcho");
605 variant_array_writer.AppendString("AsyncEcho");
606 variant_array_writer.AppendString("BrokenMethod");
607 variant_writer.CloseContainer(&variant_array_writer);
608 dict_entry_writer.CloseContainer(&variant_writer);
609 array_writer.CloseContainer(&dict_entry_writer);
610
611 array_writer.OpenDictEntry(&dict_entry_writer);
612 dict_entry_writer.AppendString("Objects");
613 dict_entry_writer.OpenVariant("ao", &variant_writer);
614 variant_writer.OpenArray("o", &variant_array_writer);
[email protected]2a57ca642013-06-13 06:37:19615 variant_array_writer.AppendObjectPath(ObjectPath("/TestObjectPath"));
[email protected]9cc40cb2013-03-25 18:20:08616 variant_writer.CloseContainer(&variant_array_writer);
617 dict_entry_writer.CloseContainer(&variant_writer);
618 array_writer.CloseContainer(&dict_entry_writer);
619
[email protected]ebbfffa22014-03-15 07:40:49620 array_writer.OpenDictEntry(&dict_entry_writer);
621 dict_entry_writer.AppendString("Bytes");
622 dict_entry_writer.OpenVariant("ay", &variant_writer);
avi22437c692015-12-22 18:12:45623 const uint8_t bytes[] = {0x54, 0x65, 0x73, 0x74};
[email protected]ebbfffa22014-03-15 07:40:49624 variant_writer.AppendArrayOfBytes(bytes, sizeof(bytes));
625 dict_entry_writer.CloseContainer(&variant_writer);
626 array_writer.CloseContainer(&dict_entry_writer);
627
[email protected]9cc40cb2013-03-25 18:20:08628 writer->CloseContainer(&array_writer);
629}
630
[email protected]2a57ca642013-06-13 06:37:19631void TestService::AddObject(const ObjectPath& object_path) {
Alexander Timin0439ffe2018-10-30 18:10:00632 task_runner()->PostTask(FROM_HERE,
kylechar39c39282019-02-19 19:04:04633 base::BindOnce(&TestService::AddObjectInternal,
634 base::Unretained(this), object_path));
[email protected]9cc40cb2013-03-25 18:20:08635}
636
[email protected]2a57ca642013-06-13 06:37:19637void TestService::AddObjectInternal(const ObjectPath& object_path) {
638 Signal signal(kObjectManagerInterface, kObjectManagerInterfacesAdded);
639 MessageWriter writer(&signal);
[email protected]9cc40cb2013-03-25 18:20:08640 writer.AppendObjectPath(object_path);
641
Ben Chan14d500372017-11-09 20:20:16642 MessageWriter array_writer(nullptr);
643 MessageWriter dict_entry_writer(nullptr);
[email protected]9cc40cb2013-03-25 18:20:08644
645 writer.OpenArray("{sa{sv}}", &array_writer);
646 array_writer.OpenDictEntry(&dict_entry_writer);
647 dict_entry_writer.AppendString("org.chromium.TestInterface");
648 AddPropertiesToWriter(&dict_entry_writer);
649 array_writer.CloseContainer(&dict_entry_writer);
650 writer.CloseContainer(&array_writer);
651
652 exported_object_manager_->SendSignal(&signal);
653}
654
[email protected]2a57ca642013-06-13 06:37:19655void TestService::RemoveObject(const ObjectPath& object_path) {
Alexander Timin0439ffe2018-10-30 18:10:00656 task_runner()->PostTask(FROM_HERE,
kylechar39c39282019-02-19 19:04:04657 base::BindOnce(&TestService::RemoveObjectInternal,
658 base::Unretained(this), object_path));
[email protected]9cc40cb2013-03-25 18:20:08659}
660
[email protected]2a57ca642013-06-13 06:37:19661void TestService::RemoveObjectInternal(const ObjectPath& object_path) {
662 Signal signal(kObjectManagerInterface, kObjectManagerInterfacesRemoved);
663 MessageWriter writer(&signal);
[email protected]9cc40cb2013-03-25 18:20:08664
665 writer.AppendObjectPath(object_path);
666
667 std::vector<std::string> interfaces;
668 interfaces.push_back("org.chromium.TestInterface");
669 writer.AppendArrayOfStrings(interfaces);
670
671 exported_object_manager_->SendSignal(&signal);
672}
673
[email protected]cf910da22012-02-15 04:21:08674void TestService::SendPropertyChangedSignal(const std::string& name) {
Alexander Timin0439ffe2018-10-30 18:10:00675 task_runner()->PostTask(
kylechar39c39282019-02-19 19:04:04676 FROM_HERE, base::BindOnce(&TestService::SendPropertyChangedSignalInternal,
677 base::Unretained(this), name));
[email protected]cf910da22012-02-15 04:21:08678}
679
680void TestService::SendPropertyChangedSignalInternal(const std::string& name) {
[email protected]2a57ca642013-06-13 06:37:19681 Signal signal(kPropertiesInterface, kPropertiesChanged);
682 MessageWriter writer(&signal);
[email protected]9cc40cb2013-03-25 18:20:08683 writer.AppendString("org.chromium.TestInterface");
[email protected]cf910da22012-02-15 04:21:08684
Ben Chan14d500372017-11-09 20:20:16685 MessageWriter array_writer(nullptr);
686 MessageWriter dict_entry_writer(nullptr);
[email protected]cf910da22012-02-15 04:21:08687
688 writer.OpenArray("{sv}", &array_writer);
689 array_writer.OpenDictEntry(&dict_entry_writer);
690 dict_entry_writer.AppendString("Name");
691 dict_entry_writer.AppendVariantOfString(name);
692 array_writer.CloseContainer(&dict_entry_writer);
693 writer.CloseContainer(&array_writer);
694
Ben Chan14d500372017-11-09 20:20:16695 MessageWriter invalidated_array_writer(nullptr);
jpawlowskied276542015-05-11 11:07:04696
697 writer.OpenArray("s", &invalidated_array_writer);
698 writer.CloseContainer(&invalidated_array_writer);
699
700 exported_object_->SendSignal(&signal);
701}
702
703void TestService::SendPropertyInvalidatedSignal() {
Alexander Timin0439ffe2018-10-30 18:10:00704 task_runner()->PostTask(
kylechar39c39282019-02-19 19:04:04705 FROM_HERE,
706 base::BindOnce(&TestService::SendPropertyInvalidatedSignalInternal,
707 base::Unretained(this)));
jpawlowskied276542015-05-11 11:07:04708}
709
710void TestService::SendPropertyInvalidatedSignalInternal() {
711 Signal signal(kPropertiesInterface, kPropertiesChanged);
712 MessageWriter writer(&signal);
713 writer.AppendString("org.chromium.TestInterface");
714
Ben Chan14d500372017-11-09 20:20:16715 MessageWriter array_writer(nullptr);
716 MessageWriter dict_entry_writer(nullptr);
jpawlowskied276542015-05-11 11:07:04717
718 writer.OpenArray("{sv}", &array_writer);
719 writer.CloseContainer(&array_writer);
720
Ben Chan14d500372017-11-09 20:20:16721 MessageWriter invalidated_array_writer(nullptr);
jpawlowskied276542015-05-11 11:07:04722
723 writer.OpenArray("s", &invalidated_array_writer);
724 invalidated_array_writer.AppendString("Name");
725 writer.CloseContainer(&invalidated_array_writer);
726
[email protected]cf910da22012-02-15 04:21:08727 exported_object_->SendSignal(&signal);
728}
729
[email protected]a51076112011-08-17 20:58:12730} // namespace dbus