blob: 2fb05c143be7c4b75aeafb580e8c01a94bee4b15 [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,
73 base::Bind(&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,
90 base::Bind(&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(
fdoray6ef45cf2016-08-25 15:36:3796 FROM_HERE, base::Bind(&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,
123 base::Bind(&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(
148 FROM_HERE,
149 base::Bind(&TestService::ReleaseOwnershipInternal,
150 base::Unretained(this),
151 callback));
152}
153
154void TestService::ReleaseOwnershipInternal(
155 base::Closure callback) {
hashimoto067d84f522016-01-05 08:48:03156 bus_->ReleaseOwnership(service_name_);
[email protected]043fb8c2014-03-07 02:24:33157 has_ownership_ = false;
158
159 bus_->GetOriginTaskRunner()->PostTask(
160 FROM_HERE,
161 callback);
162}
163
armansitoebff093d2014-09-05 17:49:34164void TestService::SetSendImmediatePropertiesChanged() {
165 send_immediate_properties_changed_ = true;
166}
167
[email protected]12f97662011-08-20 01:07:17168void TestService::OnExported(const std::string& interface_name,
169 const std::string& method_name,
170 bool success) {
171 if (!success) {
172 LOG(ERROR) << "Failed to export: " << interface_name << "."
173 << method_name;
174 // Returning here will make WaitUntilServiceIsStarted() to time out
175 // and return false.
176 return;
177 }
178
179 ++num_exported_methods_;
[email protected]332577d2014-01-09 04:39:17180 if (num_exported_methods_ == kNumMethodsToExport) {
181 // As documented in exported_object.h, the service name should be
182 // requested after all methods are exposed.
Peter Kasting341e1fb2018-02-24 00:03:01183 bus_->RequestOwnership(
184 service_name_, request_ownership_options_,
185 base::Bind(&TestService::OnOwnership, base::Unretained(this),
186 base::DoNothing()));
[email protected]332577d2014-01-09 04:39:17187 }
[email protected]12f97662011-08-20 01:07:17188}
189
fdoraye1e050c52016-07-19 21:05:54190void TestService::Run(base::RunLoop* run_loop) {
[email protected]a51076112011-08-17 20:58:12191 Bus::Options bus_options;
192 bus_options.bus_type = Bus::SESSION;
193 bus_options.connection_type = Bus::PRIVATE;
[email protected]200328a2013-02-20 01:36:53194 bus_options.dbus_task_runner = dbus_task_runner_;
[email protected]a51076112011-08-17 20:58:12195 bus_ = new Bus(bus_options);
196
197 exported_object_ = bus_->GetExportedObject(
[email protected]2a57ca642013-06-13 06:37:19198 ObjectPath("/org/chromium/TestObject"));
[email protected]12f97662011-08-20 01:07:17199
200 int num_methods = 0;
201 exported_object_->ExportMethod(
[email protected]a51076112011-08-17 20:58:12202 "org.chromium.TestInterface",
203 "Echo",
204 base::Bind(&TestService::Echo,
[email protected]12f97662011-08-20 01:07:17205 base::Unretained(this)),
206 base::Bind(&TestService::OnExported,
207 base::Unretained(this)));
208 ++num_methods;
209
210 exported_object_->ExportMethod(
[email protected]a51076112011-08-17 20:58:12211 "org.chromium.TestInterface",
212 "SlowEcho",
213 base::Bind(&TestService::SlowEcho,
[email protected]12f97662011-08-20 01:07:17214 base::Unretained(this)),
215 base::Bind(&TestService::OnExported,
216 base::Unretained(this)));
217 ++num_methods;
218
219 exported_object_->ExportMethod(
[email protected]a51076112011-08-17 20:58:12220 "org.chromium.TestInterface",
[email protected]9aa74cc2011-11-30 04:57:42221 "AsyncEcho",
222 base::Bind(&TestService::AsyncEcho,
223 base::Unretained(this)),
224 base::Bind(&TestService::OnExported,
225 base::Unretained(this)));
226 ++num_methods;
227
228 exported_object_->ExportMethod(
229 "org.chromium.TestInterface",
[email protected]a51076112011-08-17 20:58:12230 "BrokenMethod",
231 base::Bind(&TestService::BrokenMethod,
[email protected]12f97662011-08-20 01:07:17232 base::Unretained(this)),
233 base::Bind(&TestService::OnExported,
234 base::Unretained(this)));
235 ++num_methods;
[email protected]a51076112011-08-17 20:58:12236
[email protected]cf910da22012-02-15 04:21:08237 exported_object_->ExportMethod(
[email protected]9cc40cb2013-03-25 18:20:08238 "org.chromium.TestInterface",
239 "PerformAction",
240 base::Bind(&TestService::PerformAction,
241 base::Unretained(this)),
242 base::Bind(&TestService::OnExported,
243 base::Unretained(this)));
244 ++num_methods;
245
246 exported_object_->ExportMethod(
[email protected]cf910da22012-02-15 04:21:08247 kPropertiesInterface,
248 kPropertiesGetAll,
249 base::Bind(&TestService::GetAllProperties,
250 base::Unretained(this)),
251 base::Bind(&TestService::OnExported,
252 base::Unretained(this)));
253 ++num_methods;
254
255 exported_object_->ExportMethod(
256 kPropertiesInterface,
257 kPropertiesGet,
258 base::Bind(&TestService::GetProperty,
259 base::Unretained(this)),
260 base::Bind(&TestService::OnExported,
261 base::Unretained(this)));
262 ++num_methods;
263
264 exported_object_->ExportMethod(
265 kPropertiesInterface,
266 kPropertiesSet,
267 base::Bind(&TestService::SetProperty,
268 base::Unretained(this)),
269 base::Bind(&TestService::OnExported,
270 base::Unretained(this)));
271 ++num_methods;
272
[email protected]9cc40cb2013-03-25 18:20:08273 exported_object_manager_ = bus_->GetExportedObject(
[email protected]2a57ca642013-06-13 06:37:19274 ObjectPath("/org/chromium/TestService"));
[email protected]9cc40cb2013-03-25 18:20:08275
276 exported_object_manager_->ExportMethod(
277 kObjectManagerInterface,
278 kObjectManagerGetManagedObjects,
279 base::Bind(&TestService::GetManagedObjects,
280 base::Unretained(this)),
281 base::Bind(&TestService::OnExported,
282 base::Unretained(this)));
283 ++num_methods;
284
[email protected]12f97662011-08-20 01:07:17285 // Just print an error message as we don't want to crash tests.
286 // Tests will fail at a call to WaitUntilServiceIsStarted().
287 if (num_methods != kNumMethodsToExport) {
288 LOG(ERROR) << "The number of methods does not match";
289 }
fdoraye1e050c52016-07-19 21:05:54290 run_loop->Run();
[email protected]a51076112011-08-17 20:58:12291}
292
[email protected]9aa74cc2011-11-30 04:57:42293void TestService::Echo(MethodCall* method_call,
[email protected]2a57ca642013-06-13 06:37:19294 ExportedObject::ResponseSender response_sender) {
[email protected]a51076112011-08-17 20:58:12295 MessageReader reader(method_call);
296 std::string text_message;
[email protected]9aa74cc2011-11-30 04:57:42297 if (!reader.PopString(&text_message)) {
dcheng2a193282016-04-08 22:55:04298 response_sender.Run(std::unique_ptr<Response>());
[email protected]9aa74cc2011-11-30 04:57:42299 return;
300 }
[email protected]a51076112011-08-17 20:58:12301
dcheng2a193282016-04-08 22:55:04302 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9b25d452013-02-07 09:46:24303 MessageWriter writer(response.get());
[email protected]a51076112011-08-17 20:58:12304 writer.AppendString(text_message);
dchenge48600452015-12-28 02:24:50305 response_sender.Run(std::move(response));
[email protected]a51076112011-08-17 20:58:12306}
307
[email protected]2a57ca642013-06-13 06:37:19308void TestService::SlowEcho(MethodCall* method_call,
309 ExportedObject::ResponseSender response_sender) {
[email protected]02798a982012-01-27 00:45:33310 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
[email protected]9aa74cc2011-11-30 04:57:42311 Echo(method_call, response_sender);
[email protected]a51076112011-08-17 20:58:12312}
313
[email protected]2a57ca642013-06-13 06:37:19314void TestService::AsyncEcho(MethodCall* method_call,
315 ExportedObject::ResponseSender response_sender) {
[email protected]9aa74cc2011-11-30 04:57:42316 // Schedule a call to Echo() to send an asynchronous response after we return.
Alexander Timin0439ffe2018-10-30 18:10:00317 task_runner()->PostDelayedTask(
318 FROM_HERE,
319 base::Bind(&TestService::Echo, base::Unretained(this), method_call,
320 response_sender),
fdoray6ef45cf2016-08-25 15:36:37321 TestTimeouts::tiny_timeout());
[email protected]9aa74cc2011-11-30 04:57:42322}
323
[email protected]2a57ca642013-06-13 06:37:19324void TestService::BrokenMethod(MethodCall* method_call,
325 ExportedObject::ResponseSender response_sender) {
dcheng2a193282016-04-08 22:55:04326 response_sender.Run(std::unique_ptr<Response>());
[email protected]a51076112011-08-17 20:58:12327}
328
[email protected]cf910da22012-02-15 04:21:08329
330void TestService::GetAllProperties(
331 MethodCall* method_call,
[email protected]2a57ca642013-06-13 06:37:19332 ExportedObject::ResponseSender response_sender) {
[email protected]cf910da22012-02-15 04:21:08333 MessageReader reader(method_call);
334 std::string interface;
335 if (!reader.PopString(&interface)) {
dcheng2a193282016-04-08 22:55:04336 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08337 return;
338 }
339
dcheng2a193282016-04-08 22:55:04340 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9b25d452013-02-07 09:46:24341 MessageWriter writer(response.get());
[email protected]cf910da22012-02-15 04:21:08342
[email protected]9cc40cb2013-03-25 18:20:08343 AddPropertiesToWriter(&writer);
[email protected]cf910da22012-02-15 04:21:08344
dchenge48600452015-12-28 02:24:50345 response_sender.Run(std::move(response));
[email protected]cf910da22012-02-15 04:21:08346}
347
[email protected]2a57ca642013-06-13 06:37:19348void TestService::GetProperty(MethodCall* method_call,
349 ExportedObject::ResponseSender response_sender) {
[email protected]cf910da22012-02-15 04:21:08350 MessageReader reader(method_call);
351 std::string interface;
352 if (!reader.PopString(&interface)) {
dcheng2a193282016-04-08 22:55:04353 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08354 return;
355 }
356
357 std::string name;
358 if (!reader.PopString(&name)) {
dcheng2a193282016-04-08 22:55:04359 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08360 return;
361 }
362
[email protected]72bbacc2012-03-21 23:43:45363 if (name == "Name") {
364 // Return the previous value for the "Name" property:
365 // Variant<"TestService">
dcheng2a193282016-04-08 22:55:04366 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9b25d452013-02-07 09:46:24367 MessageWriter writer(response.get());
[email protected]72bbacc2012-03-21 23:43:45368
369 writer.AppendVariantOfString("TestService");
370
dchenge48600452015-12-28 02:24:50371 response_sender.Run(std::move(response));
[email protected]72bbacc2012-03-21 23:43:45372 } else if (name == "Version") {
373 // Return a new value for the "Version" property:
374 // Variant<20>
dcheng2a193282016-04-08 22:55:04375 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9b25d452013-02-07 09:46:24376 MessageWriter writer(response.get());
[email protected]72bbacc2012-03-21 23:43:45377
378 writer.AppendVariantOfInt16(20);
379
dchenge48600452015-12-28 02:24:50380 response_sender.Run(std::move(response));
[email protected]72bbacc2012-03-21 23:43:45381 } else if (name == "Methods") {
382 // Return the previous value for the "Methods" property:
383 // Variant<["Echo", "SlowEcho", "AsyncEcho", "BrokenMethod"]>
dcheng2a193282016-04-08 22:55:04384 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9b25d452013-02-07 09:46:24385 MessageWriter writer(response.get());
Ben Chan14d500372017-11-09 20:20:16386 MessageWriter variant_writer(nullptr);
387 MessageWriter variant_array_writer(nullptr);
[email protected]72bbacc2012-03-21 23:43:45388
389 writer.OpenVariant("as", &variant_writer);
390 variant_writer.OpenArray("s", &variant_array_writer);
391 variant_array_writer.AppendString("Echo");
392 variant_array_writer.AppendString("SlowEcho");
393 variant_array_writer.AppendString("AsyncEcho");
394 variant_array_writer.AppendString("BrokenMethod");
395 variant_writer.CloseContainer(&variant_array_writer);
396 writer.CloseContainer(&variant_writer);
397
dchenge48600452015-12-28 02:24:50398 response_sender.Run(std::move(response));
[email protected]72bbacc2012-03-21 23:43:45399 } else if (name == "Objects") {
400 // Return the previous value for the "Objects" property:
401 // Variant<[objectpath:"/TestObjectPath"]>
dcheng2a193282016-04-08 22:55:04402 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9b25d452013-02-07 09:46:24403 MessageWriter writer(response.get());
Ben Chan14d500372017-11-09 20:20:16404 MessageWriter variant_writer(nullptr);
405 MessageWriter variant_array_writer(nullptr);
[email protected]72bbacc2012-03-21 23:43:45406
407 writer.OpenVariant("ao", &variant_writer);
408 variant_writer.OpenArray("o", &variant_array_writer);
[email protected]2a57ca642013-06-13 06:37:19409 variant_array_writer.AppendObjectPath(ObjectPath("/TestObjectPath"));
[email protected]72bbacc2012-03-21 23:43:45410 variant_writer.CloseContainer(&variant_array_writer);
411 writer.CloseContainer(&variant_writer);
412
dchenge48600452015-12-28 02:24:50413 response_sender.Run(std::move(response));
[email protected]ebbfffa22014-03-15 07:40:49414 } else if (name == "Bytes") {
415 // Return the previous value for the "Bytes" property:
416 // Variant<[0x54, 0x65, 0x73, 0x74]>
dcheng2a193282016-04-08 22:55:04417 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]ebbfffa22014-03-15 07:40:49418 MessageWriter writer(response.get());
Ben Chan14d500372017-11-09 20:20:16419 MessageWriter variant_writer(nullptr);
420 MessageWriter variant_array_writer(nullptr);
[email protected]ebbfffa22014-03-15 07:40:49421
422 writer.OpenVariant("ay", &variant_writer);
avi22437c692015-12-22 18:12:45423 const uint8_t bytes[] = {0x54, 0x65, 0x73, 0x74};
[email protected]ebbfffa22014-03-15 07:40:49424 variant_writer.AppendArrayOfBytes(bytes, sizeof(bytes));
425 writer.CloseContainer(&variant_writer);
426
dchenge48600452015-12-28 02:24:50427 response_sender.Run(std::move(response));
[email protected]72bbacc2012-03-21 23:43:45428 } else {
429 // Return error.
dcheng2a193282016-04-08 22:55:04430 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08431 return;
432 }
[email protected]cf910da22012-02-15 04:21:08433}
434
[email protected]2a57ca642013-06-13 06:37:19435void TestService::SetProperty(MethodCall* method_call,
436 ExportedObject::ResponseSender response_sender) {
[email protected]cf910da22012-02-15 04:21:08437 MessageReader reader(method_call);
438 std::string interface;
439 if (!reader.PopString(&interface)) {
dcheng2a193282016-04-08 22:55:04440 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08441 return;
442 }
443
444 std::string name;
445 if (!reader.PopString(&name)) {
dcheng2a193282016-04-08 22:55:04446 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08447 return;
448 }
449
450 if (name != "Name") {
dcheng2a193282016-04-08 22:55:04451 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08452 return;
453 }
454
455 std::string value;
456 if (!reader.PopVariantOfString(&value)) {
dcheng2a193282016-04-08 22:55:04457 response_sender.Run(std::unique_ptr<Response>());
[email protected]cf910da22012-02-15 04:21:08458 return;
459 }
460
461 SendPropertyChangedSignal(value);
462
[email protected]9b25d452013-02-07 09:46:24463 response_sender.Run(Response::FromMethodCall(method_call));
[email protected]cf910da22012-02-15 04:21:08464}
465
[email protected]9cc40cb2013-03-25 18:20:08466void TestService::PerformAction(
467 MethodCall* method_call,
[email protected]2a57ca642013-06-13 06:37:19468 ExportedObject::ResponseSender response_sender) {
[email protected]9cc40cb2013-03-25 18:20:08469 MessageReader reader(method_call);
470 std::string action;
[email protected]2a57ca642013-06-13 06:37:19471 ObjectPath object_path;
[email protected]9cc40cb2013-03-25 18:20:08472 if (!reader.PopString(&action) || !reader.PopObjectPath(&object_path)) {
dcheng2a193282016-04-08 22:55:04473 response_sender.Run(std::unique_ptr<Response>());
[email protected]9cc40cb2013-03-25 18:20:08474 return;
475 }
476
armansitoebff093d2014-09-05 17:49:34477 if (action == "AddObject") {
[email protected]9cc40cb2013-03-25 18:20:08478 AddObject(object_path);
armansitoebff093d2014-09-05 17:49:34479 } else if (action == "RemoveObject") {
[email protected]9cc40cb2013-03-25 18:20:08480 RemoveObject(object_path);
armansitoebff093d2014-09-05 17:49:34481 } else if (action == "SetSendImmediatePropertiesChanged") {
482 SetSendImmediatePropertiesChanged();
dtapuska1d622f02015-02-09 22:51:40483 } else if (action == "ReleaseOwnership") {
[email protected]043fb8c2014-03-07 02:24:33484 ReleaseOwnership(base::Bind(&TestService::PerformActionResponse,
485 base::Unretained(this),
486 method_call, response_sender));
487 return;
488 } else if (action == "Ownership") {
489 ReleaseOwnership(base::Bind(&TestService::OwnershipReleased,
490 base::Unretained(this),
491 method_call, response_sender));
492 return;
jpawlowskied276542015-05-11 11:07:04493 } else if (action == "InvalidateProperty") {
494 SendPropertyInvalidatedSignal();
[email protected]043fb8c2014-03-07 02:24:33495 }
[email protected]9cc40cb2013-03-25 18:20:08496
dcheng2a193282016-04-08 22:55:04497 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
dchenge48600452015-12-28 02:24:50498 response_sender.Run(std::move(response));
[email protected]9cc40cb2013-03-25 18:20:08499}
500
[email protected]043fb8c2014-03-07 02:24:33501void TestService::PerformActionResponse(
502 MethodCall* method_call,
503 ExportedObject::ResponseSender response_sender) {
dcheng2a193282016-04-08 22:55:04504 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
dchenge48600452015-12-28 02:24:50505 response_sender.Run(std::move(response));
[email protected]043fb8c2014-03-07 02:24:33506}
507
508void TestService::OwnershipReleased(
509 MethodCall* method_call,
510 ExportedObject::ResponseSender response_sender) {
511 RequestOwnership(base::Bind(&TestService::OwnershipRegained,
512 base::Unretained(this),
513 method_call, response_sender));
514}
515
516
517void TestService::OwnershipRegained(
518 MethodCall* method_call,
519 ExportedObject::ResponseSender response_sender,
520 bool success) {
521 PerformActionResponse(method_call, response_sender);
522}
523
524
[email protected]9cc40cb2013-03-25 18:20:08525void TestService::GetManagedObjects(
526 MethodCall* method_call,
[email protected]2a57ca642013-06-13 06:37:19527 ExportedObject::ResponseSender response_sender) {
dcheng2a193282016-04-08 22:55:04528 std::unique_ptr<Response> response = Response::FromMethodCall(method_call);
[email protected]9cc40cb2013-03-25 18:20:08529 MessageWriter writer(response.get());
530
531 // The managed objects response is a dictionary of object paths identifying
532 // the object(s) with a dictionary of strings identifying the interface(s)
533 // they implement and then a dictionary of property values.
534 //
535 // Thus this looks something like:
536 //
537 // {
538 // "/org/chromium/TestObject": {
539 // "org.chromium.TestInterface": { /* Properties */ }
540 // }
541 // }
542
543
Ben Chan14d500372017-11-09 20:20:16544 MessageWriter array_writer(nullptr);
545 MessageWriter dict_entry_writer(nullptr);
546 MessageWriter object_array_writer(nullptr);
547 MessageWriter object_dict_entry_writer(nullptr);
[email protected]9cc40cb2013-03-25 18:20:08548
549 writer.OpenArray("{oa{sa{sv}}}", &array_writer);
550
551 array_writer.OpenDictEntry(&dict_entry_writer);
[email protected]2a57ca642013-06-13 06:37:19552 dict_entry_writer.AppendObjectPath(ObjectPath("/org/chromium/TestObject"));
[email protected]9cc40cb2013-03-25 18:20:08553 dict_entry_writer.OpenArray("{sa{sv}}", &object_array_writer);
554
555 object_array_writer.OpenDictEntry(&object_dict_entry_writer);
556 object_dict_entry_writer.AppendString("org.chromium.TestInterface");
557 AddPropertiesToWriter(&object_dict_entry_writer);
558 object_array_writer.CloseContainer(&object_dict_entry_writer);
559
560 dict_entry_writer.CloseContainer(&object_array_writer);
561
562 array_writer.CloseContainer(&dict_entry_writer);
563 writer.CloseContainer(&array_writer);
564
dchenge48600452015-12-28 02:24:50565 response_sender.Run(std::move(response));
armansitoebff093d2014-09-05 17:49:34566
567 if (send_immediate_properties_changed_)
568 SendPropertyChangedSignal("ChangedTestServiceName");
[email protected]9cc40cb2013-03-25 18:20:08569}
570
[email protected]2a57ca642013-06-13 06:37:19571void TestService::AddPropertiesToWriter(MessageWriter* writer) {
[email protected]9cc40cb2013-03-25 18:20:08572 // The properties response is a dictionary of strings identifying the
573 // property and a variant containing the property value. We return all
574 // of the properties, thus the response is:
575 //
576 // {
577 // "Name": Variant<"TestService">,
578 // "Version": Variant<10>,
579 // "Methods": Variant<["Echo", "SlowEcho", "AsyncEcho", "BrokenMethod"]>,
580 // "Objects": Variant<[objectpath:"/TestObjectPath"]>
[email protected]ebbfffa22014-03-15 07:40:49581 // "Bytes": Variant<[0x54, 0x65, 0x73, 0x74]>
[email protected]2a57ca642013-06-13 06:37:19582 // }
[email protected]9cc40cb2013-03-25 18:20:08583
Ben Chan14d500372017-11-09 20:20:16584 MessageWriter array_writer(nullptr);
585 MessageWriter dict_entry_writer(nullptr);
586 MessageWriter variant_writer(nullptr);
587 MessageWriter variant_array_writer(nullptr);
[email protected]9cc40cb2013-03-25 18:20:08588
589 writer->OpenArray("{sv}", &array_writer);
590
591 array_writer.OpenDictEntry(&dict_entry_writer);
592 dict_entry_writer.AppendString("Name");
593 dict_entry_writer.AppendVariantOfString("TestService");
594 array_writer.CloseContainer(&dict_entry_writer);
595
596 array_writer.OpenDictEntry(&dict_entry_writer);
597 dict_entry_writer.AppendString("Version");
598 dict_entry_writer.AppendVariantOfInt16(10);
599 array_writer.CloseContainer(&dict_entry_writer);
600
601 array_writer.OpenDictEntry(&dict_entry_writer);
602 dict_entry_writer.AppendString("Methods");
603 dict_entry_writer.OpenVariant("as", &variant_writer);
604 variant_writer.OpenArray("s", &variant_array_writer);
605 variant_array_writer.AppendString("Echo");
606 variant_array_writer.AppendString("SlowEcho");
607 variant_array_writer.AppendString("AsyncEcho");
608 variant_array_writer.AppendString("BrokenMethod");
609 variant_writer.CloseContainer(&variant_array_writer);
610 dict_entry_writer.CloseContainer(&variant_writer);
611 array_writer.CloseContainer(&dict_entry_writer);
612
613 array_writer.OpenDictEntry(&dict_entry_writer);
614 dict_entry_writer.AppendString("Objects");
615 dict_entry_writer.OpenVariant("ao", &variant_writer);
616 variant_writer.OpenArray("o", &variant_array_writer);
[email protected]2a57ca642013-06-13 06:37:19617 variant_array_writer.AppendObjectPath(ObjectPath("/TestObjectPath"));
[email protected]9cc40cb2013-03-25 18:20:08618 variant_writer.CloseContainer(&variant_array_writer);
619 dict_entry_writer.CloseContainer(&variant_writer);
620 array_writer.CloseContainer(&dict_entry_writer);
621
[email protected]ebbfffa22014-03-15 07:40:49622 array_writer.OpenDictEntry(&dict_entry_writer);
623 dict_entry_writer.AppendString("Bytes");
624 dict_entry_writer.OpenVariant("ay", &variant_writer);
avi22437c692015-12-22 18:12:45625 const uint8_t bytes[] = {0x54, 0x65, 0x73, 0x74};
[email protected]ebbfffa22014-03-15 07:40:49626 variant_writer.AppendArrayOfBytes(bytes, sizeof(bytes));
627 dict_entry_writer.CloseContainer(&variant_writer);
628 array_writer.CloseContainer(&dict_entry_writer);
629
[email protected]9cc40cb2013-03-25 18:20:08630 writer->CloseContainer(&array_writer);
631}
632
[email protected]2a57ca642013-06-13 06:37:19633void TestService::AddObject(const ObjectPath& object_path) {
Alexander Timin0439ffe2018-10-30 18:10:00634 task_runner()->PostTask(FROM_HERE,
635 base::Bind(&TestService::AddObjectInternal,
636 base::Unretained(this), object_path));
[email protected]9cc40cb2013-03-25 18:20:08637}
638
[email protected]2a57ca642013-06-13 06:37:19639void TestService::AddObjectInternal(const ObjectPath& object_path) {
640 Signal signal(kObjectManagerInterface, kObjectManagerInterfacesAdded);
641 MessageWriter writer(&signal);
[email protected]9cc40cb2013-03-25 18:20:08642 writer.AppendObjectPath(object_path);
643
Ben Chan14d500372017-11-09 20:20:16644 MessageWriter array_writer(nullptr);
645 MessageWriter dict_entry_writer(nullptr);
[email protected]9cc40cb2013-03-25 18:20:08646
647 writer.OpenArray("{sa{sv}}", &array_writer);
648 array_writer.OpenDictEntry(&dict_entry_writer);
649 dict_entry_writer.AppendString("org.chromium.TestInterface");
650 AddPropertiesToWriter(&dict_entry_writer);
651 array_writer.CloseContainer(&dict_entry_writer);
652 writer.CloseContainer(&array_writer);
653
654 exported_object_manager_->SendSignal(&signal);
655}
656
[email protected]2a57ca642013-06-13 06:37:19657void TestService::RemoveObject(const ObjectPath& object_path) {
Alexander Timin0439ffe2018-10-30 18:10:00658 task_runner()->PostTask(FROM_HERE,
659 base::Bind(&TestService::RemoveObjectInternal,
660 base::Unretained(this), object_path));
[email protected]9cc40cb2013-03-25 18:20:08661}
662
[email protected]2a57ca642013-06-13 06:37:19663void TestService::RemoveObjectInternal(const ObjectPath& object_path) {
664 Signal signal(kObjectManagerInterface, kObjectManagerInterfacesRemoved);
665 MessageWriter writer(&signal);
[email protected]9cc40cb2013-03-25 18:20:08666
667 writer.AppendObjectPath(object_path);
668
669 std::vector<std::string> interfaces;
670 interfaces.push_back("org.chromium.TestInterface");
671 writer.AppendArrayOfStrings(interfaces);
672
673 exported_object_manager_->SendSignal(&signal);
674}
675
[email protected]cf910da22012-02-15 04:21:08676void TestService::SendPropertyChangedSignal(const std::string& name) {
Alexander Timin0439ffe2018-10-30 18:10:00677 task_runner()->PostTask(
fdoray6ef45cf2016-08-25 15:36:37678 FROM_HERE, base::Bind(&TestService::SendPropertyChangedSignalInternal,
679 base::Unretained(this), name));
[email protected]cf910da22012-02-15 04:21:08680}
681
682void TestService::SendPropertyChangedSignalInternal(const std::string& name) {
[email protected]2a57ca642013-06-13 06:37:19683 Signal signal(kPropertiesInterface, kPropertiesChanged);
684 MessageWriter writer(&signal);
[email protected]9cc40cb2013-03-25 18:20:08685 writer.AppendString("org.chromium.TestInterface");
[email protected]cf910da22012-02-15 04:21:08686
Ben Chan14d500372017-11-09 20:20:16687 MessageWriter array_writer(nullptr);
688 MessageWriter dict_entry_writer(nullptr);
[email protected]cf910da22012-02-15 04:21:08689
690 writer.OpenArray("{sv}", &array_writer);
691 array_writer.OpenDictEntry(&dict_entry_writer);
692 dict_entry_writer.AppendString("Name");
693 dict_entry_writer.AppendVariantOfString(name);
694 array_writer.CloseContainer(&dict_entry_writer);
695 writer.CloseContainer(&array_writer);
696
Ben Chan14d500372017-11-09 20:20:16697 MessageWriter invalidated_array_writer(nullptr);
jpawlowskied276542015-05-11 11:07:04698
699 writer.OpenArray("s", &invalidated_array_writer);
700 writer.CloseContainer(&invalidated_array_writer);
701
702 exported_object_->SendSignal(&signal);
703}
704
705void TestService::SendPropertyInvalidatedSignal() {
Alexander Timin0439ffe2018-10-30 18:10:00706 task_runner()->PostTask(
jpawlowskied276542015-05-11 11:07:04707 FROM_HERE, base::Bind(&TestService::SendPropertyInvalidatedSignalInternal,
708 base::Unretained(this)));
709}
710
711void TestService::SendPropertyInvalidatedSignalInternal() {
712 Signal signal(kPropertiesInterface, kPropertiesChanged);
713 MessageWriter writer(&signal);
714 writer.AppendString("org.chromium.TestInterface");
715
Ben Chan14d500372017-11-09 20:20:16716 MessageWriter array_writer(nullptr);
717 MessageWriter dict_entry_writer(nullptr);
jpawlowskied276542015-05-11 11:07:04718
719 writer.OpenArray("{sv}", &array_writer);
720 writer.CloseContainer(&array_writer);
721
Ben Chan14d500372017-11-09 20:20:16722 MessageWriter invalidated_array_writer(nullptr);
jpawlowskied276542015-05-11 11:07:04723
724 writer.OpenArray("s", &invalidated_array_writer);
725 invalidated_array_writer.AppendString("Name");
726 writer.CloseContainer(&invalidated_array_writer);
727
[email protected]cf910da22012-02-15 04:21:08728 exported_object_->SendSignal(&signal);
729}
730
[email protected]a51076112011-08-17 20:58:12731} // namespace dbus