blob: 9afc9abdb8ef5d97a4204a77d48d0723944172ab [file] [log] [blame]
Paul Stewart1dce1ae2014-10-01 05:30:18 -07001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chromeos-dbus-bindings/proxy_generator.h"
6
7#include <string>
8#include <vector>
9
10#include <base/file_util.h>
11#include <base/files/file_path.h>
12#include <base/files/scoped_temp_dir.h>
13#include <gtest/gtest.h>
14
15#include "chromeos-dbus-bindings/interface.h"
16
17using std::string;
18using std::vector;
19using testing::Test;
20
21namespace chromeos_dbus_bindings {
22
23namespace {
24
25const char kInterfaceName[] = "org.chromium.TestInterface";
Alex Vakulenkofafef132014-11-03 14:52:09 -080026const char kInterfaceName2[] = "org.chromium.TestInterface2";
Paul Stewart1dce1ae2014-10-01 05:30:18 -070027const char kMethod1Name[] = "Elements";
28const char kMethod1Return[] = "s";
29const char kMethod1Argument1[] = "s";
30const char kMethod1ArgumentName1[] = "space_walk";
31const char kMethod1Argument2[] = "ao";
32const char kMethod1ArgumentName2[] = "ramblin_man";
33const char kMethod2Name[] = "ReturnToPatagonia";
34const char kMethod2Return[] = "x";
35const char kMethod3Name[] = "NiceWeatherForDucks";
36const char kMethod3Argument1[] = "b";
37const char kMethod4Name[] = "ExperimentNumberSix";
Alex Vakulenkofafef132014-11-03 14:52:09 -080038const char kMethod5Name[] = "GetPersonInfo";
39const char kMethod5Argument1[] = "s";
40const char kMethod5ArgumentName1[] = "name";
41const char kMethod5Argument2[] = "i";
42const char kMethod5ArgumentName2[] = "age";
Paul Stewart1dce1ae2014-10-01 05:30:18 -070043const char kSignal1Name[] = "Closer";
44const char kSignal2Name[] = "TheCurseOfKaZar";
45const char kSignal2Argument1[] = "as";
46const char kSignal2Argument2[] = "y";
47const char kExpectedContent[] = R"literal_string(
Alex Vakulenko99e8fb02014-12-01 17:22:03 -080048#include <memory>
Paul Stewart1dce1ae2014-10-01 05:30:18 -070049#include <string>
50#include <vector>
51
52#include <base/bind.h>
53#include <base/callback.h>
54#include <base/logging.h>
55#include <base/macros.h>
56#include <base/memory/ref_counted.h>
57#include <chromeos/any.h>
58#include <chromeos/dbus/dbus_method_invoker.h>
Alex Vakulenko99e8fb02014-12-01 17:22:03 -080059#include <chromeos/dbus/dbus_property.h>
Paul Stewart1dce1ae2014-10-01 05:30:18 -070060#include <chromeos/dbus/dbus_signal_handler.h>
61#include <chromeos/errors/error.h>
Alex Vakulenko4f3c05e2014-11-12 15:01:46 -080062#include <chromeos/variant_dictionary.h>
Paul Stewart1dce1ae2014-10-01 05:30:18 -070063#include <dbus/bus.h>
64#include <dbus/message.h>
Alex Vakulenko99e8fb02014-12-01 17:22:03 -080065#include <dbus/object_manager.h>
Paul Stewart1dce1ae2014-10-01 05:30:18 -070066#include <dbus/object_path.h>
67#include <dbus/object_proxy.h>
68
69namespace org {
70namespace chromium {
71
Alex Vakulenkoc95f06b2014-11-20 15:06:09 -080072// Interface proxy for org::chromium::TestInterface.
Alex Vakulenko4f3c05e2014-11-12 15:01:46 -080073class TestInterfaceProxy final {
Paul Stewart1dce1ae2014-10-01 05:30:18 -070074 public:
Paul Stewart1dce1ae2014-10-01 05:30:18 -070075 TestInterfaceProxy(
76 const scoped_refptr<dbus::Bus>& bus,
Alex Vakulenko6ef2d732014-11-25 14:04:27 -080077 const std::string& service_name) :
Alex Vakulenko99e8fb02014-12-01 17:22:03 -080078 bus_{bus},
79 service_name_{service_name},
80 dbus_object_proxy_{
81 bus_->GetObjectProxy(service_name_, object_path_)} {
Alex Vakulenkoc95f06b2014-11-20 15:06:09 -080082 }
83
Christopher Wiley824b5242014-12-03 11:58:01 -080084 ~TestInterfaceProxy() {
85 }
86
87 void RegisterCloserSignalHandler(
88 const base::Closure& signal_callback,
89 dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
Paul Stewart1dce1ae2014-10-01 05:30:18 -070090 chromeos::dbus_utils::ConnectToSignal(
91 dbus_object_proxy_,
92 "org.chromium.TestInterface",
93 "Closer",
Christopher Wiley824b5242014-12-03 11:58:01 -080094 signal_callback,
95 on_connected_callback);
96 }
97
98 void RegisterTheCurseOfKaZarSignalHandler(
99 const base::Callback<void(const std::vector<std::string>&,
100 uint8_t)>& signal_callback,
101 dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700102 chromeos::dbus_utils::ConnectToSignal(
103 dbus_object_proxy_,
104 "org.chromium.TestInterface",
105 "TheCurseOfKaZar",
Christopher Wiley824b5242014-12-03 11:58:01 -0800106 signal_callback,
107 on_connected_callback);
Alex Vakulenkoc95f06b2014-11-20 15:06:09 -0800108 }
109
110 void ReleaseObjectProxy(const base::Closure& callback) {
111 bus_->RemoveObjectProxy(service_name_, object_path_, callback);
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700112 }
Alex Vakulenko4f3c05e2014-11-12 15:01:46 -0800113
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800114 const dbus::ObjectPath& GetObjectPath() const {
115 return object_path_;
116 }
117
118 dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
119
Alex Vakulenko4f3c05e2014-11-12 15:01:46 -0800120 bool Elements(
Alex Vakulenkofafef132014-11-03 14:52:09 -0800121 const std::string& in_space_walk,
122 const std::vector<dbus::ObjectPath>& in_ramblin_man,
123 std::string* out_3,
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700124 chromeos::ErrorPtr* error) {
125 auto response = chromeos::dbus_utils::CallMethodAndBlock(
126 dbus_object_proxy_,
127 "org.chromium.TestInterface",
128 "Elements",
129 error,
Alex Vakulenkofafef132014-11-03 14:52:09 -0800130 in_space_walk,
131 in_ramblin_man);
132 return response && chromeos::dbus_utils::ExtractMethodCallResults(
133 response.get(), error, out_3);
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700134 }
Alex Vakulenko4f3c05e2014-11-12 15:01:46 -0800135
136 bool ReturnToPatagonia(
Alex Vakulenkofafef132014-11-03 14:52:09 -0800137 int64_t* out_1,
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700138 chromeos::ErrorPtr* error) {
139 auto response = chromeos::dbus_utils::CallMethodAndBlock(
140 dbus_object_proxy_,
141 "org.chromium.TestInterface",
142 "ReturnToPatagonia",
143 error);
Alex Vakulenkofafef132014-11-03 14:52:09 -0800144 return response && chromeos::dbus_utils::ExtractMethodCallResults(
145 response.get(), error, out_1);
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700146 }
Alex Vakulenko4f3c05e2014-11-12 15:01:46 -0800147
148 bool NiceWeatherForDucks(
Alex Vakulenkofafef132014-11-03 14:52:09 -0800149 bool in_1,
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700150 chromeos::ErrorPtr* error) {
151 auto response = chromeos::dbus_utils::CallMethodAndBlock(
152 dbus_object_proxy_,
153 "org.chromium.TestInterface",
154 "NiceWeatherForDucks",
155 error,
Alex Vakulenkofafef132014-11-03 14:52:09 -0800156 in_1);
157 return response && chromeos::dbus_utils::ExtractMethodCallResults(
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700158 response.get(), error);
159 }
Alex Vakulenko4f3c05e2014-11-12 15:01:46 -0800160
161 // Comment line1
162 // line2
163 bool ExperimentNumberSix(
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700164 chromeos::ErrorPtr* error) {
165 auto response = chromeos::dbus_utils::CallMethodAndBlock(
166 dbus_object_proxy_,
167 "org.chromium.TestInterface",
168 "ExperimentNumberSix",
169 error);
Alex Vakulenkofafef132014-11-03 14:52:09 -0800170 return response && chromeos::dbus_utils::ExtractMethodCallResults(
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700171 response.get(), error);
172 }
Alex Vakulenko4f3c05e2014-11-12 15:01:46 -0800173
Alex Vakulenkoc95f06b2014-11-20 15:06:09 -0800174 private:
175 scoped_refptr<dbus::Bus> bus_;
176 std::string service_name_;
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800177 const dbus::ObjectPath object_path_{"/org/chromium/Test"};
Alex Vakulenkoc95f06b2014-11-20 15:06:09 -0800178 dbus::ObjectProxy* dbus_object_proxy_;
179
180 DISALLOW_COPY_AND_ASSIGN(TestInterfaceProxy);
181};
182
183} // namespace chromium
184} // namespace org
185
186namespace org {
187namespace chromium {
188
189// Interface proxy for org::chromium::TestInterface2.
190class TestInterface2Proxy final {
191 public:
192 TestInterface2Proxy(
193 const scoped_refptr<dbus::Bus>& bus,
194 const std::string& service_name,
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800195 const dbus::ObjectPath& object_path) :
196 bus_{bus},
197 service_name_{service_name},
198 object_path_{object_path},
199 dbus_object_proxy_{
200 bus_->GetObjectProxy(service_name_, object_path_)} {
Alex Vakulenkoc95f06b2014-11-20 15:06:09 -0800201 }
202
203 ~TestInterface2Proxy() {
204 }
205
206 void ReleaseObjectProxy(const base::Closure& callback) {
207 bus_->RemoveObjectProxy(service_name_, object_path_, callback);
208 }
209
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800210 const dbus::ObjectPath& GetObjectPath() const {
211 return object_path_;
212 }
213
214 dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
215
Alex Vakulenko4f3c05e2014-11-12 15:01:46 -0800216 bool GetPersonInfo(
Alex Vakulenkofafef132014-11-03 14:52:09 -0800217 std::string* out_name,
218 int32_t* out_age,
219 chromeos::ErrorPtr* error) {
220 auto response = chromeos::dbus_utils::CallMethodAndBlock(
221 dbus_object_proxy_,
222 "org.chromium.TestInterface2",
223 "GetPersonInfo",
224 error);
225 return response && chromeos::dbus_utils::ExtractMethodCallResults(
226 response.get(), error, out_name, out_age);
227 }
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700228
229 private:
230 scoped_refptr<dbus::Bus> bus_;
231 std::string service_name_;
232 dbus::ObjectPath object_path_;
233 dbus::ObjectProxy* dbus_object_proxy_;
234
Alex Vakulenkoc95f06b2014-11-20 15:06:09 -0800235 DISALLOW_COPY_AND_ASSIGN(TestInterface2Proxy);
Paul Stewart1dce1ae2014-10-01 05:30:18 -0700236};
237
238} // namespace chromium
239} // namespace org
240)literal_string";
241
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800242const char kExpectedContentWithService[] = R"literal_string(
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800243#include <memory>
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800244#include <string>
245#include <vector>
246
247#include <base/bind.h>
248#include <base/callback.h>
249#include <base/logging.h>
250#include <base/macros.h>
251#include <base/memory/ref_counted.h>
252#include <chromeos/any.h>
253#include <chromeos/dbus/dbus_method_invoker.h>
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800254#include <chromeos/dbus/dbus_property.h>
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800255#include <chromeos/dbus/dbus_signal_handler.h>
256#include <chromeos/errors/error.h>
257#include <chromeos/variant_dictionary.h>
258#include <dbus/bus.h>
259#include <dbus/message.h>
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800260#include <dbus/object_manager.h>
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800261#include <dbus/object_path.h>
262#include <dbus/object_proxy.h>
263
264namespace org {
265namespace chromium {
266
267// Interface proxy for org::chromium::TestInterface.
268class TestInterfaceProxy final {
269 public:
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800270 TestInterfaceProxy(const scoped_refptr<dbus::Bus>& bus) :
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800271 bus_{bus},
272 dbus_object_proxy_{
273 bus_->GetObjectProxy(service_name_, object_path_)} {
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800274 }
275
Christopher Wiley824b5242014-12-03 11:58:01 -0800276 ~TestInterfaceProxy() {
277 }
278
279 void RegisterCloserSignalHandler(
280 const base::Closure& signal_callback,
281 dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800282 chromeos::dbus_utils::ConnectToSignal(
283 dbus_object_proxy_,
284 "org.chromium.TestInterface",
285 "Closer",
Christopher Wiley824b5242014-12-03 11:58:01 -0800286 signal_callback,
287 on_connected_callback);
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800288 }
289
290 void ReleaseObjectProxy(const base::Closure& callback) {
291 bus_->RemoveObjectProxy(service_name_, object_path_, callback);
292 }
293
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800294 const dbus::ObjectPath& GetObjectPath() const {
295 return object_path_;
296 }
297
298 dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
299
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800300 private:
301 scoped_refptr<dbus::Bus> bus_;
302 const std::string service_name_{"org.chromium.Test"};
303 const dbus::ObjectPath object_path_{"/org/chromium/Test"};
304 dbus::ObjectProxy* dbus_object_proxy_;
305
306 DISALLOW_COPY_AND_ASSIGN(TestInterfaceProxy);
307};
308
309} // namespace chromium
310} // namespace org
311
312namespace org {
313namespace chromium {
314
315// Interface proxy for org::chromium::TestInterface2.
316class TestInterface2Proxy final {
317 public:
318 TestInterface2Proxy(
319 const scoped_refptr<dbus::Bus>& bus,
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800320 const dbus::ObjectPath& object_path) :
321 bus_{bus},
322 object_path_{object_path},
323 dbus_object_proxy_{
324 bus_->GetObjectProxy(service_name_, object_path_)} {
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800325 }
326
327 ~TestInterface2Proxy() {
328 }
329
330 void ReleaseObjectProxy(const base::Closure& callback) {
331 bus_->RemoveObjectProxy(service_name_, object_path_, callback);
332 }
333
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800334 const dbus::ObjectPath& GetObjectPath() const {
335 return object_path_;
336 }
337
338 dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
339
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800340 private:
341 scoped_refptr<dbus::Bus> bus_;
342 const std::string service_name_{"org.chromium.Test"};
343 dbus::ObjectPath object_path_;
344 dbus::ObjectProxy* dbus_object_proxy_;
345
346 DISALLOW_COPY_AND_ASSIGN(TestInterface2Proxy);
347};
348
349} // namespace chromium
350} // namespace org
Alex Vakulenko6ef2d732014-11-25 14:04:27 -0800351)literal_string";
352
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800353const char kExpectedContentWithObjectManager[] = R"literal_string(
354#include <memory>
355#include <string>
356#include <vector>
357
358#include <base/bind.h>
359#include <base/callback.h>
360#include <base/logging.h>
361#include <base/macros.h>
362#include <base/memory/ref_counted.h>
363#include <chromeos/any.h>
364#include <chromeos/dbus/dbus_method_invoker.h>
365#include <chromeos/dbus/dbus_property.h>
366#include <chromeos/dbus/dbus_signal_handler.h>
367#include <chromeos/errors/error.h>
368#include <chromeos/variant_dictionary.h>
369#include <dbus/bus.h>
370#include <dbus/message.h>
371#include <dbus/object_manager.h>
372#include <dbus/object_path.h>
373#include <dbus/object_proxy.h>
374
375namespace org {
376namespace chromium {
377class ObjectManagerProxy;
378} // namespace chromium
379} // namespace org
380
381namespace org {
382namespace chromium {
383
384// Interface proxy for org::chromium::Itf1.
385class Itf1Proxy final {
386 public:
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800387 class PropertySet : public dbus::PropertySet {
388 public:
389 PropertySet(dbus::ObjectProxy* object_proxy,
390 const PropertyChangedCallback& callback)
391 : dbus::PropertySet{object_proxy,
392 "org.chromium.Itf1",
393 callback} {
394 RegisterProperty("data", &data);
395 }
396
397 chromeos::dbus_utils::Property<std::string> data;
398
399 private:
400 DISALLOW_COPY_AND_ASSIGN(PropertySet);
401 };
402
403 Itf1Proxy(
404 const scoped_refptr<dbus::Bus>& bus,
405 const std::string& service_name,
406 PropertySet* property_set) :
407 bus_{bus},
408 service_name_{service_name},
409 property_set_{property_set},
410 dbus_object_proxy_{
411 bus_->GetObjectProxy(service_name_, object_path_)} {
412 }
413
Christopher Wiley824b5242014-12-03 11:58:01 -0800414 ~Itf1Proxy() {
415 }
416
417 void RegisterCloserSignalHandler(
418 const base::Closure& signal_callback,
419 dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800420 chromeos::dbus_utils::ConnectToSignal(
421 dbus_object_proxy_,
422 "org.chromium.Itf1",
423 "Closer",
Christopher Wiley824b5242014-12-03 11:58:01 -0800424 signal_callback,
425 on_connected_callback);
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800426 }
427
428 void ReleaseObjectProxy(const base::Closure& callback) {
429 bus_->RemoveObjectProxy(service_name_, object_path_, callback);
430 }
431
432 const dbus::ObjectPath& GetObjectPath() const {
433 return object_path_;
434 }
435
436 dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
437
438 void SetPropertyChangedCallback(
439 const base::Callback<void(Itf1Proxy*, const std::string&)>& callback) {
440 on_property_changed_ = callback;
441 }
442
443 const PropertySet* GetProperties() const { return property_set_; }
444 PropertySet* GetProperties() { return property_set_; }
445
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800446 const std::string& data() const {
447 return property_set_->data.value();
448 }
449
450 private:
451 void OnPropertyChanged(const std::string& property_name) {
452 if (!on_property_changed_.is_null())
453 on_property_changed_.Run(this, property_name);
454 }
455
456 scoped_refptr<dbus::Bus> bus_;
457 std::string service_name_;
458 const dbus::ObjectPath object_path_{"/org/chromium/Test/Object"};
459 PropertySet* property_set_;
460 base::Callback<void(Itf1Proxy*, const std::string&)> on_property_changed_;
461 dbus::ObjectProxy* dbus_object_proxy_;
462
463 friend class org::chromium::ObjectManagerProxy;
464 DISALLOW_COPY_AND_ASSIGN(Itf1Proxy);
465};
466
467} // namespace chromium
468} // namespace org
469
470namespace org {
471namespace chromium {
472
473// Interface proxy for org::chromium::Itf2.
474class Itf2Proxy final {
475 public:
476 class PropertySet : public dbus::PropertySet {
477 public:
478 PropertySet(dbus::ObjectProxy* object_proxy,
479 const PropertyChangedCallback& callback)
480 : dbus::PropertySet{object_proxy,
481 "org.chromium.Itf2",
482 callback} {
483 }
484
485
486 private:
487 DISALLOW_COPY_AND_ASSIGN(PropertySet);
488 };
489
490 Itf2Proxy(
491 const scoped_refptr<dbus::Bus>& bus,
492 const std::string& service_name,
493 const dbus::ObjectPath& object_path) :
494 bus_{bus},
495 service_name_{service_name},
496 object_path_{object_path},
497 dbus_object_proxy_{
498 bus_->GetObjectProxy(service_name_, object_path_)} {
499 }
500
501 ~Itf2Proxy() {
502 }
503
504 void ReleaseObjectProxy(const base::Closure& callback) {
505 bus_->RemoveObjectProxy(service_name_, object_path_, callback);
506 }
507
508 const dbus::ObjectPath& GetObjectPath() const {
509 return object_path_;
510 }
511
512 dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
513
514 private:
515 scoped_refptr<dbus::Bus> bus_;
516 std::string service_name_;
517 dbus::ObjectPath object_path_;
518 dbus::ObjectProxy* dbus_object_proxy_;
519
520 DISALLOW_COPY_AND_ASSIGN(Itf2Proxy);
521};
522
523} // namespace chromium
524} // namespace org
525
526namespace org {
527namespace chromium {
528
529class ObjectManagerProxy : public dbus::ObjectManager::Interface {
530 public:
531 ObjectManagerProxy(const scoped_refptr<dbus::Bus>& bus,
532 const std::string& service_name)
533 : bus_{bus},
534 dbus_object_manager_{bus->GetObjectManager(
535 service_name,
536 dbus::ObjectPath{"/org/chromium/Test"})} {
537 dbus_object_manager_->RegisterInterface("org.chromium.Itf1", this);
538 dbus_object_manager_->RegisterInterface("org.chromium.Itf2", this);
539 }
540
541 dbus::ObjectManager* GetObjectManagerProxy() const {
542 return dbus_object_manager_;
543 }
544
545 org::chromium::Itf1Proxy* GetItf1Proxy(
546 const dbus::ObjectPath& object_path) {
547 auto p = itf1_instances_.find(object_path);
548 if (p != itf1_instances_.end())
549 return p->second.get();
550 return nullptr;
551 }
552 std::vector<org::chromium::Itf1Proxy*> GetItf1Instances() const {
553 std::vector<org::chromium::Itf1Proxy*> values;
554 values.reserve(itf1_instances_.size());
555 for (const auto& pair : itf1_instances_)
556 values.push_back(pair.second.get());
557 return values;
558 }
559 void SetItf1AddedCallback(
560 const base::Callback<void(org::chromium::Itf1Proxy*)>& callback) {
561 on_itf1_added_ = callback;
562 }
563 void SetItf1RemovedCallback(
564 const base::Callback<void(const dbus::ObjectPath&)>& callback) {
565 on_itf1_removed_ = callback;
566 }
567
568 org::chromium::Itf2Proxy* GetItf2Proxy(
569 const dbus::ObjectPath& object_path) {
570 auto p = itf2_instances_.find(object_path);
571 if (p != itf2_instances_.end())
572 return p->second.get();
573 return nullptr;
574 }
575 std::vector<org::chromium::Itf2Proxy*> GetItf2Instances() const {
576 std::vector<org::chromium::Itf2Proxy*> values;
577 values.reserve(itf2_instances_.size());
578 for (const auto& pair : itf2_instances_)
579 values.push_back(pair.second.get());
580 return values;
581 }
582 void SetItf2AddedCallback(
583 const base::Callback<void(org::chromium::Itf2Proxy*)>& callback) {
584 on_itf2_added_ = callback;
585 }
586 void SetItf2RemovedCallback(
587 const base::Callback<void(const dbus::ObjectPath&)>& callback) {
588 on_itf2_removed_ = callback;
589 }
590
591 private:
592 void OnPropertyChanged(const dbus::ObjectPath& object_path,
593 const std::string& interface_name,
594 const std::string& property_name) {
595 if (interface_name == "org.chromium.Itf1") {
596 auto p = itf1_instances_.find(object_path);
597 if (p == itf1_instances_.end())
598 return;
599 p->second->OnPropertyChanged(property_name);
600 return;
601 }
602 }
603
604 void ObjectAdded(
605 const dbus::ObjectPath& object_path,
606 const std::string& interface_name) override {
607 if (interface_name == "org.chromium.Itf1") {
608 auto property_set =
609 static_cast<org::chromium::Itf1Proxy::PropertySet*>(
610 dbus_object_manager_->GetProperties(object_path, interface_name));
611 std::unique_ptr<org::chromium::Itf1Proxy> itf1_proxy{
612 new org::chromium::Itf1Proxy{bus_, property_set}
613 };
614 auto p = itf1_instances_.emplace(object_path, std::move(itf1_proxy));
615 if (!on_itf1_added_.is_null())
616 on_itf1_added_.Run(p.first->second.get());
617 return;
618 }
619 if (interface_name == "org.chromium.Itf2") {
620 std::unique_ptr<org::chromium::Itf2Proxy> itf2_proxy{
621 new org::chromium::Itf2Proxy{bus_, object_path}
622 };
623 auto p = itf2_instances_.emplace(object_path, std::move(itf2_proxy));
624 if (!on_itf2_added_.is_null())
625 on_itf2_added_.Run(p.first->second.get());
626 return;
627 }
628 }
629
630 void ObjectRemoved(
631 const dbus::ObjectPath& object_path,
632 const std::string& interface_name) override {
633 if (interface_name == "org.chromium.Itf1") {
634 auto p = itf1_instances_.find(object_path);
635 if (p != itf1_instances_.end()) {
636 if (!on_itf1_removed_.is_null())
637 on_itf1_removed_.Run(object_path);
638 itf1_instances_.erase(p);
639 }
640 return;
641 }
642 if (interface_name == "org.chromium.Itf2") {
643 auto p = itf2_instances_.find(object_path);
644 if (p != itf2_instances_.end()) {
645 if (!on_itf2_removed_.is_null())
646 on_itf2_removed_.Run(object_path);
647 itf2_instances_.erase(p);
648 }
649 return;
650 }
651 }
652
653 dbus::PropertySet* CreateProperties(
654 dbus::ObjectProxy* object_proxy,
655 const dbus::ObjectPath& object_path,
656 const std::string& interface_name) override {
657 if (interface_name == "org.chromium.Itf1") {
658 return new org::chromium::Itf1Proxy::PropertySet{
659 object_proxy,
660 base::Bind(&ObjectManagerProxy::OnPropertyChanged,
661 weak_ptr_factory_.GetWeakPtr(),
662 object_path,
663 interface_name)
664 };
665 }
666 if (interface_name == "org.chromium.Itf2") {
667 return new org::chromium::Itf2Proxy::PropertySet{
668 object_proxy,
669 base::Bind(&ObjectManagerProxy::OnPropertyChanged,
670 weak_ptr_factory_.GetWeakPtr(),
671 object_path,
672 interface_name)
673 };
674 }
675 LOG(FATAL) << "Creating properties for unsupported interface "
676 << interface_name;
677 return nullptr;
678 }
679
680 scoped_refptr<dbus::Bus> bus_;
681 dbus::ObjectManager* dbus_object_manager_;
682 std::map<dbus::ObjectPath,
683 std::unique_ptr<org::chromium::Itf1Proxy>> itf1_instances_;
684 base::Callback<void(org::chromium::Itf1Proxy*)> on_itf1_added_;
685 base::Callback<void(const dbus::ObjectPath&)> on_itf1_removed_;
686 std::map<dbus::ObjectPath,
687 std::unique_ptr<org::chromium::Itf2Proxy>> itf2_instances_;
688 base::Callback<void(org::chromium::Itf2Proxy*)> on_itf2_added_;
689 base::Callback<void(const dbus::ObjectPath&)> on_itf2_removed_;
690 base::WeakPtrFactory<ObjectManagerProxy> weak_ptr_factory_{this};
691
692 DISALLOW_COPY_AND_ASSIGN(ObjectManagerProxy);
693};
694
695} // namespace chromium
696} // namespace org
697)literal_string";
698
699const char kExpectedContentWithObjectManagerAndServiceName[] = R"literal_string(
700#include <memory>
701#include <string>
702#include <vector>
703
704#include <base/bind.h>
705#include <base/callback.h>
706#include <base/logging.h>
707#include <base/macros.h>
708#include <base/memory/ref_counted.h>
709#include <chromeos/any.h>
710#include <chromeos/dbus/dbus_method_invoker.h>
711#include <chromeos/dbus/dbus_property.h>
712#include <chromeos/dbus/dbus_signal_handler.h>
713#include <chromeos/errors/error.h>
714#include <chromeos/variant_dictionary.h>
715#include <dbus/bus.h>
716#include <dbus/message.h>
717#include <dbus/object_manager.h>
718#include <dbus/object_path.h>
719#include <dbus/object_proxy.h>
720
721namespace org {
722namespace chromium {
723class ObjectManagerProxy;
724} // namespace chromium
725} // namespace org
726
727namespace org {
728namespace chromium {
729
730// Interface proxy for org::chromium::Itf1.
731class Itf1Proxy final {
732 public:
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800733 class PropertySet : public dbus::PropertySet {
734 public:
735 PropertySet(dbus::ObjectProxy* object_proxy,
736 const PropertyChangedCallback& callback)
737 : dbus::PropertySet{object_proxy,
738 "org.chromium.Itf1",
739 callback} {
740 }
741
742
743 private:
744 DISALLOW_COPY_AND_ASSIGN(PropertySet);
745 };
746
747 Itf1Proxy(const scoped_refptr<dbus::Bus>& bus) :
748 bus_{bus},
749 dbus_object_proxy_{
750 bus_->GetObjectProxy(service_name_, object_path_)} {
751 }
752
Christopher Wiley824b5242014-12-03 11:58:01 -0800753 ~Itf1Proxy() {
754 }
755
756 void RegisterCloserSignalHandler(
757 const base::Closure& signal_callback,
758 dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800759 chromeos::dbus_utils::ConnectToSignal(
760 dbus_object_proxy_,
761 "org.chromium.Itf1",
762 "Closer",
Christopher Wiley824b5242014-12-03 11:58:01 -0800763 signal_callback,
764 on_connected_callback);
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800765 }
766
767 void ReleaseObjectProxy(const base::Closure& callback) {
768 bus_->RemoveObjectProxy(service_name_, object_path_, callback);
769 }
770
771 const dbus::ObjectPath& GetObjectPath() const {
772 return object_path_;
773 }
774
775 dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
776
Alex Vakulenko99e8fb02014-12-01 17:22:03 -0800777 private:
778 scoped_refptr<dbus::Bus> bus_;
779 const std::string service_name_{"org.chromium.Test"};
780 const dbus::ObjectPath object_path_{"/org/chromium/Test/Object"};
781 dbus::ObjectProxy* dbus_object_proxy_;
782
783 DISALLOW_COPY_AND_ASSIGN(Itf1Proxy);
784};
785
786} // namespace chromium
787} // namespace org
788
789namespace org {
790namespace chromium {
791
792// Interface proxy for org::chromium::Itf2.
793class Itf2Proxy final {
794 public:
795 class PropertySet : public dbus::PropertySet {
796 public:
797 PropertySet(dbus::ObjectProxy* object_proxy,
798 const PropertyChangedCallback& callback)
799 : dbus::PropertySet{object_proxy,
800 "org.chromium.Itf2",
801 callback} {
802 }
803
804
805 private:
806 DISALLOW_COPY_AND_ASSIGN(PropertySet);
807 };
808
809 Itf2Proxy(
810 const scoped_refptr<dbus::Bus>& bus,
811 const dbus::ObjectPath& object_path) :
812 bus_{bus},
813 object_path_{object_path},
814 dbus_object_proxy_{
815 bus_->GetObjectProxy(service_name_, object_path_)} {
816 }
817
818 ~Itf2Proxy() {
819 }
820
821 void ReleaseObjectProxy(const base::Closure& callback) {
822 bus_->RemoveObjectProxy(service_name_, object_path_, callback);
823 }
824
825 const dbus::ObjectPath& GetObjectPath() const {
826 return object_path_;
827 }
828
829 dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
830
831 private:
832 scoped_refptr<dbus::Bus> bus_;
833 const std::string service_name_{"org.chromium.Test"};
834 dbus::ObjectPath object_path_;
835 dbus::ObjectProxy* dbus_object_proxy_;
836
837 DISALLOW_COPY_AND_ASSIGN(Itf2Proxy);
838};
839
840} // namespace chromium
841} // namespace org
842
843namespace org {
844namespace chromium {
845
846class ObjectManagerProxy : public dbus::ObjectManager::Interface {
847 public:
848 ObjectManagerProxy(const scoped_refptr<dbus::Bus>& bus)
849 : bus_{bus},
850 dbus_object_manager_{bus->GetObjectManager(
851 "org.chromium.Test",
852 dbus::ObjectPath{"/org/chromium/Test"})} {
853 dbus_object_manager_->RegisterInterface("org.chromium.Itf1", this);
854 dbus_object_manager_->RegisterInterface("org.chromium.Itf2", this);
855 }
856
857 dbus::ObjectManager* GetObjectManagerProxy() const {
858 return dbus_object_manager_;
859 }
860
861 org::chromium::Itf1Proxy* GetItf1Proxy(
862 const dbus::ObjectPath& object_path) {
863 auto p = itf1_instances_.find(object_path);
864 if (p != itf1_instances_.end())
865 return p->second.get();
866 return nullptr;
867 }
868 std::vector<org::chromium::Itf1Proxy*> GetItf1Instances() const {
869 std::vector<org::chromium::Itf1Proxy*> values;
870 values.reserve(itf1_instances_.size());
871 for (const auto& pair : itf1_instances_)
872 values.push_back(pair.second.get());
873 return values;
874 }
875 void SetItf1AddedCallback(
876 const base::Callback<void(org::chromium::Itf1Proxy*)>& callback) {
877 on_itf1_added_ = callback;
878 }
879 void SetItf1RemovedCallback(
880 const base::Callback<void(const dbus::ObjectPath&)>& callback) {
881 on_itf1_removed_ = callback;
882 }
883
884 org::chromium::Itf2Proxy* GetItf2Proxy(
885 const dbus::ObjectPath& object_path) {
886 auto p = itf2_instances_.find(object_path);
887 if (p != itf2_instances_.end())
888 return p->second.get();
889 return nullptr;
890 }
891 std::vector<org::chromium::Itf2Proxy*> GetItf2Instances() const {
892 std::vector<org::chromium::Itf2Proxy*> values;
893 values.reserve(itf2_instances_.size());
894 for (const auto& pair : itf2_instances_)
895 values.push_back(pair.second.get());
896 return values;
897 }
898 void SetItf2AddedCallback(
899 const base::Callback<void(org::chromium::Itf2Proxy*)>& callback) {
900 on_itf2_added_ = callback;
901 }
902 void SetItf2RemovedCallback(
903 const base::Callback<void(const dbus::ObjectPath&)>& callback) {
904 on_itf2_removed_ = callback;
905 }
906
907 private:
908 void OnPropertyChanged(const dbus::ObjectPath& object_path,
909 const std::string& interface_name,
910 const std::string& property_name) {
911 }
912
913 void ObjectAdded(
914 const dbus::ObjectPath& object_path,
915 const std::string& interface_name) override {
916 if (interface_name == "org.chromium.Itf1") {
917 std::unique_ptr<org::chromium::Itf1Proxy> itf1_proxy{
918 new org::chromium::Itf1Proxy{bus_}
919 };
920 auto p = itf1_instances_.emplace(object_path, std::move(itf1_proxy));
921 if (!on_itf1_added_.is_null())
922 on_itf1_added_.Run(p.first->second.get());
923 return;
924 }
925 if (interface_name == "org.chromium.Itf2") {
926 std::unique_ptr<org::chromium::Itf2Proxy> itf2_proxy{
927 new org::chromium::Itf2Proxy{bus_, object_path}
928 };
929 auto p = itf2_instances_.emplace(object_path, std::move(itf2_proxy));
930 if (!on_itf2_added_.is_null())
931 on_itf2_added_.Run(p.first->second.get());
932 return;
933 }
934 }
935
936 void ObjectRemoved(
937 const dbus::ObjectPath& object_path,
938 const std::string& interface_name) override {
939 if (interface_name == "org.chromium.Itf1") {
940 auto p = itf1_instances_.find(object_path);
941 if (p != itf1_instances_.end()) {
942 if (!on_itf1_removed_.is_null())
943 on_itf1_removed_.Run(object_path);
944 itf1_instances_.erase(p);
945 }
946 return;
947 }
948 if (interface_name == "org.chromium.Itf2") {
949 auto p = itf2_instances_.find(object_path);
950 if (p != itf2_instances_.end()) {
951 if (!on_itf2_removed_.is_null())
952 on_itf2_removed_.Run(object_path);
953 itf2_instances_.erase(p);
954 }
955 return;
956 }
957 }
958
959 dbus::PropertySet* CreateProperties(
960 dbus::ObjectProxy* object_proxy,
961 const dbus::ObjectPath& object_path,
962 const std::string& interface_name) override {
963 if (interface_name == "org.chromium.Itf1") {
964 return new org::chromium::Itf1Proxy::PropertySet{
965 object_proxy,
966 base::Bind(&ObjectManagerProxy::OnPropertyChanged,
967 weak_ptr_factory_.GetWeakPtr(),
968 object_path,
969 interface_name)
970 };
971 }
972 if (interface_name == "org.chromium.Itf2") {
973 return new org::chromium::Itf2Proxy::PropertySet{
974 object_proxy,
975 base::Bind(&ObjectManagerProxy::OnPropertyChanged,
976 weak_ptr_factory_.GetWeakPtr(),
977 object_path,
978 interface_name)
979 };
980 }
981 LOG(FATAL) << "Creating properties for unsupported interface "
982 << interface_name;
983 return nullptr;
984 }
985
986 scoped_refptr<dbus::Bus> bus_;
987 dbus::ObjectManager* dbus_object_manager_;
988 std::map<dbus::ObjectPath,
989 std::unique_ptr<org::chromium::Itf1Proxy>> itf1_instances_;
990 base::Callback<void(org::chromium::Itf1Proxy*)> on_itf1_added_;
991 base::Callback<void(const dbus::ObjectPath&)> on_itf1_removed_;
992 std::map<dbus::ObjectPath,
993 std::unique_ptr<org::chromium::Itf2Proxy>> itf2_instances_;
994 base::Callback<void(org::chromium::Itf2Proxy*)> on_itf2_added_;
995 base::Callback<void(const dbus::ObjectPath&)> on_itf2_removed_;
996 base::WeakPtrFactory<ObjectManagerProxy> weak_ptr_factory_{this};
997
998 DISALLOW_COPY_AND_ASSIGN(ObjectManagerProxy);
999};
1000
1001} // namespace chromium
1002} // namespace org
1003)literal_string";
Paul Stewart1dce1ae2014-10-01 05:30:18 -07001004} // namespace
1005
1006class ProxyGeneratorTest : public Test {
1007 public:
1008 void SetUp() override {
1009 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
1010 }
1011
1012 protected:
1013 base::FilePath CreateInputFile(const string& contents) {
1014 base::FilePath path;
1015 EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &path));
1016 EXPECT_EQ(contents.size(),
1017 base::WriteFile(path, contents.c_str(), contents.size()));
1018 return path;
1019 }
1020
1021 base::ScopedTempDir temp_dir_;
1022};
1023
1024TEST_F(ProxyGeneratorTest, GenerateAdaptors) {
1025 Interface interface;
1026 interface.name = kInterfaceName;
Alex Vakulenko6ef2d732014-11-25 14:04:27 -08001027 interface.path = "/org/chromium/Test";
Paul Stewart1dce1ae2014-10-01 05:30:18 -07001028 interface.methods.emplace_back(
1029 kMethod1Name,
1030 vector<Interface::Argument>{
1031 {kMethod1ArgumentName1, kMethod1Argument1},
1032 {kMethod1ArgumentName2, kMethod1Argument2}},
1033 vector<Interface::Argument>{{"", kMethod1Return}});
1034 interface.methods.emplace_back(
1035 kMethod2Name,
1036 vector<Interface::Argument>{},
1037 vector<Interface::Argument>{{"", kMethod2Return}});
1038 interface.methods.emplace_back(
1039 kMethod3Name,
1040 vector<Interface::Argument>{{"", kMethod3Argument1}},
1041 vector<Interface::Argument>{});
1042 interface.methods.emplace_back(kMethod4Name);
1043 interface.signals.emplace_back(kSignal1Name);
1044 interface.signals.emplace_back(
1045 kSignal2Name,
1046 vector<Interface::Argument>{
1047 {"", kSignal2Argument1},
1048 {"", kSignal2Argument2}});
Alex Vakulenko6ef2d732014-11-25 14:04:27 -08001049 interface.methods.back().doc_string = "Comment line1\nline2";
Alex Vakulenkofafef132014-11-03 14:52:09 -08001050 Interface interface2;
1051 interface2.name = kInterfaceName2;
1052 interface2.methods.emplace_back(
1053 kMethod5Name,
1054 vector<Interface::Argument>{},
1055 vector<Interface::Argument>{
1056 {kMethod5ArgumentName1, kMethod5Argument1},
1057 {kMethod5ArgumentName2, kMethod5Argument2}});
1058 vector<Interface> interfaces{interface, interface2};
Paul Stewart1dce1ae2014-10-01 05:30:18 -07001059 base::FilePath output_path = temp_dir_.path().Append("output.h");
Alex Vakulenko6ef2d732014-11-25 14:04:27 -08001060 ServiceConfig config;
1061 EXPECT_TRUE(ProxyGenerator::GenerateProxies(config, interfaces, output_path));
Paul Stewart1dce1ae2014-10-01 05:30:18 -07001062 string contents;
1063 EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
1064 // The header guards contain the (temporary) filename, so we search for
1065 // the content we need within the string.
1066 EXPECT_NE(string::npos, contents.find(kExpectedContent))
1067 << "Expected to find the following content...\n"
1068 << kExpectedContent << "...within content...\n" << contents;
1069}
1070
Alex Vakulenko6ef2d732014-11-25 14:04:27 -08001071TEST_F(ProxyGeneratorTest, GenerateAdaptorsWithServiceName) {
1072 Interface interface;
1073 interface.name = kInterfaceName;
1074 interface.path = "/org/chromium/Test";
1075 interface.signals.emplace_back(kSignal1Name);
1076 Interface interface2;
1077 interface2.name = kInterfaceName2;
1078 vector<Interface> interfaces{interface, interface2};
1079 base::FilePath output_path = temp_dir_.path().Append("output2.h");
1080 ServiceConfig config;
1081 config.service_name = "org.chromium.Test";
1082 EXPECT_TRUE(ProxyGenerator::GenerateProxies(config, interfaces, output_path));
1083 string contents;
1084 EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
1085 // The header guards contain the (temporary) filename, so we search for
1086 // the content we need within the string.
1087 EXPECT_NE(string::npos, contents.find(kExpectedContentWithService))
1088 << "Expected to find the following content...\n"
1089 << kExpectedContentWithService << "...within content...\n" << contents;
1090}
1091
Alex Vakulenko99e8fb02014-12-01 17:22:03 -08001092TEST_F(ProxyGeneratorTest, GenerateAdaptorsWithObjectManager) {
1093 Interface interface;
1094 interface.name = "org.chromium.Itf1";
1095 interface.path = "/org/chromium/Test/Object";
1096 interface.signals.emplace_back(kSignal1Name);
1097 interface.properties.emplace_back("data", "s", "read");
1098 Interface interface2;
1099 interface2.name = "org.chromium.Itf2";
1100 vector<Interface> interfaces{interface, interface2};
1101 base::FilePath output_path = temp_dir_.path().Append("output3.h");
1102 ServiceConfig config;
1103 config.object_manager.name = "org.chromium.ObjectManager";
1104 config.object_manager.object_path = "/org/chromium/Test";
1105 EXPECT_TRUE(ProxyGenerator::GenerateProxies(config, interfaces, output_path));
1106 string contents;
1107 EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
1108 // The header guards contain the (temporary) filename, so we search for
1109 // the content we need within the string.
1110 EXPECT_NE(string::npos, contents.find(kExpectedContentWithObjectManager))
1111 << "Expected to find the following content...\n"
1112 << kExpectedContentWithObjectManager << "...within content...\n"
1113 << contents;
1114}
1115
1116TEST_F(ProxyGeneratorTest, GenerateAdaptorsWithObjectManagerAndServiceName) {
1117 Interface interface;
1118 interface.name = "org.chromium.Itf1";
1119 interface.path = "/org/chromium/Test/Object";
1120 interface.signals.emplace_back(kSignal1Name);
1121 Interface interface2;
1122 interface2.name = "org.chromium.Itf2";
1123 vector<Interface> interfaces{interface, interface2};
1124 base::FilePath output_path = temp_dir_.path().Append("output4.h");
1125 ServiceConfig config;
1126 config.service_name = "org.chromium.Test";
1127 config.object_manager.name = "org.chromium.ObjectManager";
1128 config.object_manager.object_path = "/org/chromium/Test";
1129 EXPECT_TRUE(ProxyGenerator::GenerateProxies(config, interfaces, output_path));
1130 string contents;
1131 EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
1132 // The header guards contain the (temporary) filename, so we search for
1133 // the content we need within the string.
1134 EXPECT_NE(string::npos,
1135 contents.find(kExpectedContentWithObjectManagerAndServiceName))
1136 << "Expected to find the following content...\n"
1137 << kExpectedContentWithObjectManagerAndServiceName
1138 << "...within content...\n" << contents;
1139}
1140
Paul Stewart1dce1ae2014-10-01 05:30:18 -07001141} // namespace chromeos_dbus_bindings