| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "dbus/test_service.h" | 5 #include "dbus/test_service.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/test/test_timeouts.h" | 8 #include "base/test/test_timeouts.h" |
| 9 #include "base/threading/platform_thread.h" | 9 #include "base/threading/platform_thread.h" |
| 10 #include "dbus/bus.h" | 10 #include "dbus/bus.h" |
| 11 #include "dbus/exported_object.h" | 11 #include "dbus/exported_object.h" |
| 12 #include "dbus/message.h" | 12 #include "dbus/message.h" |
| 13 #include "dbus/object_manager.h" |
| 13 #include "dbus/object_path.h" | 14 #include "dbus/object_path.h" |
| 14 #include "dbus/property.h" | 15 #include "dbus/property.h" |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 void EmptyCallback(bool /* success */) { | 19 void EmptyCallback(bool /* success */) { |
| 19 } | 20 } |
| 20 | 21 |
| 21 } // namespace | 22 } // namespace |
| 22 | 23 |
| 23 namespace dbus { | 24 namespace dbus { |
| 24 | 25 |
| 25 // Echo, SlowEcho, AsyncEcho, BrokenMethod, GetAll, Get, Set. | 26 // Echo, SlowEcho, AsyncEcho, BrokenMethod, GetAll, Get, Set, PerformAction, |
| 26 const int TestService::kNumMethodsToExport = 7; | 27 // GetManagedObjects. |
| 28 const int TestService::kNumMethodsToExport = 9; |
| 27 | 29 |
| 28 TestService::Options::Options() { | 30 TestService::Options::Options() { |
| 29 } | 31 } |
| 30 | 32 |
| 31 TestService::Options::~Options() { | 33 TestService::Options::~Options() { |
| 32 } | 34 } |
| 33 | 35 |
| 34 TestService::TestService(const Options& options) | 36 TestService::TestService(const Options& options) |
| 35 : base::Thread("TestService"), | 37 : base::Thread("TestService"), |
| 36 dbus_task_runner_(options.dbus_task_runner), | 38 dbus_task_runner_(options.dbus_task_runner), |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 exported_object_->ExportMethod( | 199 exported_object_->ExportMethod( |
| 198 "org.chromium.TestInterface", | 200 "org.chromium.TestInterface", |
| 199 "BrokenMethod", | 201 "BrokenMethod", |
| 200 base::Bind(&TestService::BrokenMethod, | 202 base::Bind(&TestService::BrokenMethod, |
| 201 base::Unretained(this)), | 203 base::Unretained(this)), |
| 202 base::Bind(&TestService::OnExported, | 204 base::Bind(&TestService::OnExported, |
| 203 base::Unretained(this))); | 205 base::Unretained(this))); |
| 204 ++num_methods; | 206 ++num_methods; |
| 205 | 207 |
| 206 exported_object_->ExportMethod( | 208 exported_object_->ExportMethod( |
| 209 "org.chromium.TestInterface", |
| 210 "PerformAction", |
| 211 base::Bind(&TestService::PerformAction, |
| 212 base::Unretained(this)), |
| 213 base::Bind(&TestService::OnExported, |
| 214 base::Unretained(this))); |
| 215 ++num_methods; |
| 216 |
| 217 exported_object_->ExportMethod( |
| 207 kPropertiesInterface, | 218 kPropertiesInterface, |
| 208 kPropertiesGetAll, | 219 kPropertiesGetAll, |
| 209 base::Bind(&TestService::GetAllProperties, | 220 base::Bind(&TestService::GetAllProperties, |
| 210 base::Unretained(this)), | 221 base::Unretained(this)), |
| 211 base::Bind(&TestService::OnExported, | 222 base::Bind(&TestService::OnExported, |
| 212 base::Unretained(this))); | 223 base::Unretained(this))); |
| 213 ++num_methods; | 224 ++num_methods; |
| 214 | 225 |
| 215 exported_object_->ExportMethod( | 226 exported_object_->ExportMethod( |
| 216 kPropertiesInterface, | 227 kPropertiesInterface, |
| 217 kPropertiesGet, | 228 kPropertiesGet, |
| 218 base::Bind(&TestService::GetProperty, | 229 base::Bind(&TestService::GetProperty, |
| 219 base::Unretained(this)), | 230 base::Unretained(this)), |
| 220 base::Bind(&TestService::OnExported, | 231 base::Bind(&TestService::OnExported, |
| 221 base::Unretained(this))); | 232 base::Unretained(this))); |
| 222 ++num_methods; | 233 ++num_methods; |
| 223 | 234 |
| 224 exported_object_->ExportMethod( | 235 exported_object_->ExportMethod( |
| 225 kPropertiesInterface, | 236 kPropertiesInterface, |
| 226 kPropertiesSet, | 237 kPropertiesSet, |
| 227 base::Bind(&TestService::SetProperty, | 238 base::Bind(&TestService::SetProperty, |
| 228 base::Unretained(this)), | 239 base::Unretained(this)), |
| 229 base::Bind(&TestService::OnExported, | 240 base::Bind(&TestService::OnExported, |
| 230 base::Unretained(this))); | 241 base::Unretained(this))); |
| 231 ++num_methods; | 242 ++num_methods; |
| 232 | 243 |
| 244 exported_object_manager_ = bus_->GetExportedObject( |
| 245 dbus::ObjectPath("/org/chromium/TestService")); |
| 246 |
| 247 exported_object_manager_->ExportMethod( |
| 248 kObjectManagerInterface, |
| 249 kObjectManagerGetManagedObjects, |
| 250 base::Bind(&TestService::GetManagedObjects, |
| 251 base::Unretained(this)), |
| 252 base::Bind(&TestService::OnExported, |
| 253 base::Unretained(this))); |
| 254 ++num_methods; |
| 255 |
| 233 // Just print an error message as we don't want to crash tests. | 256 // Just print an error message as we don't want to crash tests. |
| 234 // Tests will fail at a call to WaitUntilServiceIsStarted(). | 257 // Tests will fail at a call to WaitUntilServiceIsStarted(). |
| 235 if (num_methods != kNumMethodsToExport) { | 258 if (num_methods != kNumMethodsToExport) { |
| 236 LOG(ERROR) << "The number of methods does not match"; | 259 LOG(ERROR) << "The number of methods does not match"; |
| 237 } | 260 } |
| 238 message_loop->Run(); | 261 message_loop->Run(); |
| 239 } | 262 } |
| 240 | 263 |
| 241 void TestService::Echo(MethodCall* method_call, | 264 void TestService::Echo(MethodCall* method_call, |
| 242 dbus::ExportedObject::ResponseSender response_sender) { | 265 dbus::ExportedObject::ResponseSender response_sender) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 void TestService::GetAllProperties( | 305 void TestService::GetAllProperties( |
| 283 MethodCall* method_call, | 306 MethodCall* method_call, |
| 284 dbus::ExportedObject::ResponseSender response_sender) { | 307 dbus::ExportedObject::ResponseSender response_sender) { |
| 285 MessageReader reader(method_call); | 308 MessageReader reader(method_call); |
| 286 std::string interface; | 309 std::string interface; |
| 287 if (!reader.PopString(&interface)) { | 310 if (!reader.PopString(&interface)) { |
| 288 response_sender.Run(scoped_ptr<dbus::Response>()); | 311 response_sender.Run(scoped_ptr<dbus::Response>()); |
| 289 return; | 312 return; |
| 290 } | 313 } |
| 291 | 314 |
| 292 // The properties response is a dictionary of strings identifying the | |
| 293 // property and a variant containing the property value. We return all | |
| 294 // of the properties, thus the response is: | |
| 295 // | |
| 296 // { | |
| 297 // "Name": Variant<"TestService">, | |
| 298 // "Version": Variant<10>, | |
| 299 // "Methods": Variant<["Echo", "SlowEcho", "AsyncEcho", "BrokenMethod"]>, | |
| 300 // "Objects": Variant<[objectpath:"/TestObjectPath"]> | |
| 301 // ] | |
| 302 | |
| 303 scoped_ptr<Response> response = Response::FromMethodCall(method_call); | 315 scoped_ptr<Response> response = Response::FromMethodCall(method_call); |
| 304 MessageWriter writer(response.get()); | 316 MessageWriter writer(response.get()); |
| 305 | 317 |
| 306 MessageWriter array_writer(NULL); | 318 AddPropertiesToWriter(&writer); |
| 307 MessageWriter dict_entry_writer(NULL); | |
| 308 MessageWriter variant_writer(NULL); | |
| 309 MessageWriter variant_array_writer(NULL); | |
| 310 | |
| 311 writer.OpenArray("{sv}", &array_writer); | |
| 312 | |
| 313 array_writer.OpenDictEntry(&dict_entry_writer); | |
| 314 dict_entry_writer.AppendString("Name"); | |
| 315 dict_entry_writer.AppendVariantOfString("TestService"); | |
| 316 array_writer.CloseContainer(&dict_entry_writer); | |
| 317 | |
| 318 array_writer.OpenDictEntry(&dict_entry_writer); | |
| 319 dict_entry_writer.AppendString("Version"); | |
| 320 dict_entry_writer.AppendVariantOfInt16(10); | |
| 321 array_writer.CloseContainer(&dict_entry_writer); | |
| 322 | |
| 323 array_writer.OpenDictEntry(&dict_entry_writer); | |
| 324 dict_entry_writer.AppendString("Methods"); | |
| 325 dict_entry_writer.OpenVariant("as", &variant_writer); | |
| 326 variant_writer.OpenArray("s", &variant_array_writer); | |
| 327 variant_array_writer.AppendString("Echo"); | |
| 328 variant_array_writer.AppendString("SlowEcho"); | |
| 329 variant_array_writer.AppendString("AsyncEcho"); | |
| 330 variant_array_writer.AppendString("BrokenMethod"); | |
| 331 variant_writer.CloseContainer(&variant_array_writer); | |
| 332 dict_entry_writer.CloseContainer(&variant_writer); | |
| 333 array_writer.CloseContainer(&dict_entry_writer); | |
| 334 | |
| 335 array_writer.OpenDictEntry(&dict_entry_writer); | |
| 336 dict_entry_writer.AppendString("Objects"); | |
| 337 dict_entry_writer.OpenVariant("ao", &variant_writer); | |
| 338 variant_writer.OpenArray("o", &variant_array_writer); | |
| 339 variant_array_writer.AppendObjectPath(dbus::ObjectPath("/TestObjectPath")); | |
| 340 variant_writer.CloseContainer(&variant_array_writer); | |
| 341 dict_entry_writer.CloseContainer(&variant_writer); | |
| 342 array_writer.CloseContainer(&dict_entry_writer); | |
| 343 | |
| 344 writer.CloseContainer(&array_writer); | |
| 345 | 319 |
| 346 response_sender.Run(response.Pass()); | 320 response_sender.Run(response.Pass()); |
| 347 } | 321 } |
| 348 | 322 |
| 349 void TestService::GetProperty( | 323 void TestService::GetProperty( |
| 350 MethodCall* method_call, | 324 MethodCall* method_call, |
| 351 dbus::ExportedObject::ResponseSender response_sender) { | 325 dbus::ExportedObject::ResponseSender response_sender) { |
| 352 MessageReader reader(method_call); | 326 MessageReader reader(method_call); |
| 353 std::string interface; | 327 std::string interface; |
| 354 if (!reader.PopString(&interface)) { | 328 if (!reader.PopString(&interface)) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 if (!reader.PopVariantOfString(&value)) { | 419 if (!reader.PopVariantOfString(&value)) { |
| 446 response_sender.Run(scoped_ptr<dbus::Response>()); | 420 response_sender.Run(scoped_ptr<dbus::Response>()); |
| 447 return; | 421 return; |
| 448 } | 422 } |
| 449 | 423 |
| 450 SendPropertyChangedSignal(value); | 424 SendPropertyChangedSignal(value); |
| 451 | 425 |
| 452 response_sender.Run(Response::FromMethodCall(method_call)); | 426 response_sender.Run(Response::FromMethodCall(method_call)); |
| 453 } | 427 } |
| 454 | 428 |
| 429 void TestService::PerformAction( |
| 430 MethodCall* method_call, |
| 431 dbus::ExportedObject::ResponseSender response_sender) { |
| 432 MessageReader reader(method_call); |
| 433 std::string action; |
| 434 dbus::ObjectPath object_path; |
| 435 if (!reader.PopString(&action) || !reader.PopObjectPath(&object_path)) { |
| 436 response_sender.Run(scoped_ptr<dbus::Response>()); |
| 437 return; |
| 438 } |
| 439 |
| 440 if (action == "AddObject") |
| 441 AddObject(object_path); |
| 442 else if (action == "RemoveObject") |
| 443 RemoveObject(object_path); |
| 444 |
| 445 scoped_ptr<Response> response = Response::FromMethodCall(method_call); |
| 446 response_sender.Run(response.Pass()); |
| 447 } |
| 448 |
| 449 void TestService::GetManagedObjects( |
| 450 MethodCall* method_call, |
| 451 dbus::ExportedObject::ResponseSender response_sender) { |
| 452 scoped_ptr<Response> response = Response::FromMethodCall(method_call); |
| 453 MessageWriter writer(response.get()); |
| 454 |
| 455 // The managed objects response is a dictionary of object paths identifying |
| 456 // the object(s) with a dictionary of strings identifying the interface(s) |
| 457 // they implement and then a dictionary of property values. |
| 458 // |
| 459 // Thus this looks something like: |
| 460 // |
| 461 // { |
| 462 // "/org/chromium/TestObject": { |
| 463 // "org.chromium.TestInterface": { /* Properties */ } |
| 464 // } |
| 465 // } |
| 466 |
| 467 |
| 468 MessageWriter array_writer(NULL); |
| 469 MessageWriter dict_entry_writer(NULL); |
| 470 MessageWriter object_array_writer(NULL); |
| 471 MessageWriter object_dict_entry_writer(NULL); |
| 472 |
| 473 writer.OpenArray("{oa{sa{sv}}}", &array_writer); |
| 474 |
| 475 array_writer.OpenDictEntry(&dict_entry_writer); |
| 476 dict_entry_writer.AppendObjectPath( |
| 477 dbus::ObjectPath("/org/chromium/TestObject")); |
| 478 dict_entry_writer.OpenArray("{sa{sv}}", &object_array_writer); |
| 479 |
| 480 object_array_writer.OpenDictEntry(&object_dict_entry_writer); |
| 481 object_dict_entry_writer.AppendString("org.chromium.TestInterface"); |
| 482 AddPropertiesToWriter(&object_dict_entry_writer); |
| 483 object_array_writer.CloseContainer(&object_dict_entry_writer); |
| 484 |
| 485 dict_entry_writer.CloseContainer(&object_array_writer); |
| 486 |
| 487 array_writer.CloseContainer(&dict_entry_writer); |
| 488 writer.CloseContainer(&array_writer); |
| 489 |
| 490 response_sender.Run(response.Pass()); |
| 491 } |
| 492 |
| 493 void TestService::AddPropertiesToWriter(MessageWriter* writer) |
| 494 { |
| 495 // The properties response is a dictionary of strings identifying the |
| 496 // property and a variant containing the property value. We return all |
| 497 // of the properties, thus the response is: |
| 498 // |
| 499 // { |
| 500 // "Name": Variant<"TestService">, |
| 501 // "Version": Variant<10>, |
| 502 // "Methods": Variant<["Echo", "SlowEcho", "AsyncEcho", "BrokenMethod"]>, |
| 503 // "Objects": Variant<[objectpath:"/TestObjectPath"]> |
| 504 // ] |
| 505 |
| 506 MessageWriter array_writer(NULL); |
| 507 MessageWriter dict_entry_writer(NULL); |
| 508 MessageWriter variant_writer(NULL); |
| 509 MessageWriter variant_array_writer(NULL); |
| 510 |
| 511 writer->OpenArray("{sv}", &array_writer); |
| 512 |
| 513 array_writer.OpenDictEntry(&dict_entry_writer); |
| 514 dict_entry_writer.AppendString("Name"); |
| 515 dict_entry_writer.AppendVariantOfString("TestService"); |
| 516 array_writer.CloseContainer(&dict_entry_writer); |
| 517 |
| 518 array_writer.OpenDictEntry(&dict_entry_writer); |
| 519 dict_entry_writer.AppendString("Version"); |
| 520 dict_entry_writer.AppendVariantOfInt16(10); |
| 521 array_writer.CloseContainer(&dict_entry_writer); |
| 522 |
| 523 array_writer.OpenDictEntry(&dict_entry_writer); |
| 524 dict_entry_writer.AppendString("Methods"); |
| 525 dict_entry_writer.OpenVariant("as", &variant_writer); |
| 526 variant_writer.OpenArray("s", &variant_array_writer); |
| 527 variant_array_writer.AppendString("Echo"); |
| 528 variant_array_writer.AppendString("SlowEcho"); |
| 529 variant_array_writer.AppendString("AsyncEcho"); |
| 530 variant_array_writer.AppendString("BrokenMethod"); |
| 531 variant_writer.CloseContainer(&variant_array_writer); |
| 532 dict_entry_writer.CloseContainer(&variant_writer); |
| 533 array_writer.CloseContainer(&dict_entry_writer); |
| 534 |
| 535 array_writer.OpenDictEntry(&dict_entry_writer); |
| 536 dict_entry_writer.AppendString("Objects"); |
| 537 dict_entry_writer.OpenVariant("ao", &variant_writer); |
| 538 variant_writer.OpenArray("o", &variant_array_writer); |
| 539 variant_array_writer.AppendObjectPath(dbus::ObjectPath("/TestObjectPath")); |
| 540 variant_writer.CloseContainer(&variant_array_writer); |
| 541 dict_entry_writer.CloseContainer(&variant_writer); |
| 542 array_writer.CloseContainer(&dict_entry_writer); |
| 543 |
| 544 writer->CloseContainer(&array_writer); |
| 545 } |
| 546 |
| 547 void TestService::AddObject(const dbus::ObjectPath& object_path) { |
| 548 message_loop()->PostTask( |
| 549 FROM_HERE, |
| 550 base::Bind(&TestService::AddObjectInternal, |
| 551 base::Unretained(this), |
| 552 object_path)); |
| 553 } |
| 554 |
| 555 void TestService::AddObjectInternal(const dbus::ObjectPath& object_path) { |
| 556 dbus::Signal signal(kObjectManagerInterface, kObjectManagerInterfacesAdded); |
| 557 dbus::MessageWriter writer(&signal); |
| 558 writer.AppendObjectPath(object_path); |
| 559 |
| 560 MessageWriter array_writer(NULL); |
| 561 MessageWriter dict_entry_writer(NULL); |
| 562 |
| 563 writer.OpenArray("{sa{sv}}", &array_writer); |
| 564 array_writer.OpenDictEntry(&dict_entry_writer); |
| 565 dict_entry_writer.AppendString("org.chromium.TestInterface"); |
| 566 AddPropertiesToWriter(&dict_entry_writer); |
| 567 array_writer.CloseContainer(&dict_entry_writer); |
| 568 writer.CloseContainer(&array_writer); |
| 569 |
| 570 exported_object_manager_->SendSignal(&signal); |
| 571 } |
| 572 |
| 573 void TestService::RemoveObject(const dbus::ObjectPath& object_path) { |
| 574 message_loop()->PostTask( |
| 575 FROM_HERE, |
| 576 base::Bind(&TestService::RemoveObjectInternal, |
| 577 base::Unretained(this), |
| 578 object_path)); |
| 579 } |
| 580 |
| 581 void TestService::RemoveObjectInternal(const dbus::ObjectPath& object_path) { |
| 582 dbus::Signal signal(kObjectManagerInterface, kObjectManagerInterfacesRemoved); |
| 583 dbus::MessageWriter writer(&signal); |
| 584 |
| 585 writer.AppendObjectPath(object_path); |
| 586 |
| 587 std::vector<std::string> interfaces; |
| 588 interfaces.push_back("org.chromium.TestInterface"); |
| 589 writer.AppendArrayOfStrings(interfaces); |
| 590 |
| 591 exported_object_manager_->SendSignal(&signal); |
| 592 } |
| 593 |
| 455 void TestService::SendPropertyChangedSignal(const std::string& name) { | 594 void TestService::SendPropertyChangedSignal(const std::string& name) { |
| 456 message_loop()->PostTask( | 595 message_loop()->PostTask( |
| 457 FROM_HERE, | 596 FROM_HERE, |
| 458 base::Bind(&TestService::SendPropertyChangedSignalInternal, | 597 base::Bind(&TestService::SendPropertyChangedSignalInternal, |
| 459 base::Unretained(this), | 598 base::Unretained(this), |
| 460 name)); | 599 name)); |
| 461 } | 600 } |
| 462 | 601 |
| 463 void TestService::SendPropertyChangedSignalInternal(const std::string& name) { | 602 void TestService::SendPropertyChangedSignalInternal(const std::string& name) { |
| 464 dbus::Signal signal(kPropertiesInterface, kPropertiesChanged); | 603 dbus::Signal signal(kPropertiesInterface, kPropertiesChanged); |
| 465 dbus::MessageWriter writer(&signal); | 604 dbus::MessageWriter writer(&signal); |
| 466 writer.AppendString("org.chromium.TestService"); | 605 writer.AppendString("org.chromium.TestInterface"); |
| 467 | 606 |
| 468 MessageWriter array_writer(NULL); | 607 MessageWriter array_writer(NULL); |
| 469 MessageWriter dict_entry_writer(NULL); | 608 MessageWriter dict_entry_writer(NULL); |
| 470 | 609 |
| 471 writer.OpenArray("{sv}", &array_writer); | 610 writer.OpenArray("{sv}", &array_writer); |
| 472 array_writer.OpenDictEntry(&dict_entry_writer); | 611 array_writer.OpenDictEntry(&dict_entry_writer); |
| 473 dict_entry_writer.AppendString("Name"); | 612 dict_entry_writer.AppendString("Name"); |
| 474 dict_entry_writer.AppendVariantOfString(name); | 613 dict_entry_writer.AppendVariantOfString(name); |
| 475 array_writer.CloseContainer(&dict_entry_writer); | 614 array_writer.CloseContainer(&dict_entry_writer); |
| 476 writer.CloseContainer(&array_writer); | 615 writer.CloseContainer(&array_writer); |
| 477 | 616 |
| 478 exported_object_->SendSignal(&signal); | 617 exported_object_->SendSignal(&signal); |
| 479 } | 618 } |
| 480 | 619 |
| 481 } // namespace dbus | 620 } // namespace dbus |
| OLD | NEW |