Fixed bug that allowed the destructor of a proxy to access invalid
[profile/ivi/common-api-dbus-runtime.git] / src / CommonAPI / DBus / DBusDaemonProxy.cpp
1 /* Copyright (C) 2013 BMW Group
2  * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
3  * Author: Juergen Gehring (juergen.gehring@bmw.de)
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "DBusDaemonProxy.h"
8 #include "DBusProxyHelper.h"
9
10
11 namespace CommonAPI {
12 namespace DBus {
13
14 StaticInterfaceVersionAttribute::StaticInterfaceVersionAttribute(const uint32_t& majorValue, const uint32_t& minorValue):
15                 version_(majorValue, minorValue) {
16 }
17
18 CallStatus StaticInterfaceVersionAttribute::getValue(Version& version) const {
19     version = version_;
20
21     return CallStatus::SUCCESS;
22 }
23
24 std::future<CallStatus> StaticInterfaceVersionAttribute::getValueAsync(AttributeAsyncCallback attributeAsyncCallback) {
25     attributeAsyncCallback(CallStatus::SUCCESS, version_);
26
27     std::promise<CallStatus> versionPromise;
28     versionPromise.set_value(CallStatus::SUCCESS);
29
30     return versionPromise.get_future();
31 }
32
33
34 StaticInterfaceVersionAttribute DBusDaemonProxy::interfaceVersionAttribute_(1, 0);
35 const std::string DBusDaemonProxy::dbusBusName_ = "org.freedesktop.DBus";
36 const std::string DBusDaemonProxy::dbusObjectPath_ = "/org/freedesktop/DBus";
37 const std::string DBusDaemonProxy::dbusInterfaceName_ = getInterfaceId();
38 const std::string DBusDaemonProxy::commonApiParticipantId_ = "org.freedesktop.DBus-/org/freedesktop/DBus";
39
40
41 DBusDaemonProxy::DBusDaemonProxy(const std::shared_ptr<DBusProxyConnection>& dbusConnection):
42                 DBusProxyBase(dbusConnection),
43                 nameOwnerChangedEvent_(*this, "NameOwnerChanged", "sss") {
44 }
45
46 std::string DBusDaemonProxy::getAddress() const {
47     return getDomain() + ":" + getServiceId() + ":" + getInstanceId();
48 }
49 const std::string& DBusDaemonProxy::getDomain() const {
50     return commonApiDomain_;
51 }
52 const std::string& DBusDaemonProxy::getServiceId() const {
53     return dbusInterfaceName_;
54 }
55 const std::string& DBusDaemonProxy::getInstanceId() const {
56     return commonApiParticipantId_;
57 }
58
59 const std::string& DBusDaemonProxy::getDBusBusName() const {
60     return dbusBusName_;
61 }
62 const std::string& DBusDaemonProxy::getDBusObjectPath() const {
63     return dbusObjectPath_;
64 }
65 const std::string& DBusDaemonProxy::getInterfaceName() const {
66     return dbusInterfaceName_;
67 }
68
69 bool DBusDaemonProxy::isAvailable() const {
70     return getDBusConnection()->isConnected();
71 }
72
73 ProxyStatusEvent& DBusDaemonProxy::getProxyStatusEvent() {
74     return getDBusConnection()->getConnectionStatusEvent();
75 }
76
77 InterfaceVersionAttribute& DBusDaemonProxy::getInterfaceVersionAttribute() {
78     return interfaceVersionAttribute_;
79 }
80
81 DBusDaemonProxy::NameOwnerChangedEvent& DBusDaemonProxy::getNameOwnerChangedEvent() {
82     return nameOwnerChangedEvent_;
83 }
84
85 void DBusDaemonProxy::listNames(CommonAPI::CallStatus& callStatus, std::vector<std::string>& busNames) const {
86     DBusMessage dbusMethodCall = createMethodCall("ListNames", "");
87
88     DBusError dbusError;
89     DBusMessage dbusMessageReply = getDBusConnection()->sendDBusMessageWithReplyAndBlock(dbusMethodCall, dbusError);
90
91     if (dbusError || !dbusMessageReply.isMethodReturnType()) {
92         callStatus = CallStatus::REMOTE_ERROR;
93         return;
94     }
95
96     DBusInputStream inputStream(dbusMessageReply);
97     const bool success = DBusSerializableArguments<std::vector<std::string>>::deserialize(inputStream, busNames);
98     if (!success) {
99         callStatus = CallStatus::REMOTE_ERROR;
100         return;
101     }
102
103     callStatus = CallStatus::SUCCESS;
104 }
105
106 std::future<CallStatus> DBusDaemonProxy::listNamesAsync(ListNamesAsyncCallback listNamesAsyncCallback) const {
107     DBusMessage dbusMessage = createMethodCall("ListNames", "");
108
109     return getDBusConnection()->sendDBusMessageWithReplyAsync(
110                     dbusMessage,
111                     DBusProxyAsyncCallbackHandler<std::vector<std::string>>::create(listNamesAsyncCallback));
112 }
113
114 void DBusDaemonProxy::nameHasOwner(const std::string& busName, CommonAPI::CallStatus& callStatus, bool& hasOwner) const {
115     DBusMessage dbusMethodCall = createMethodCall("NameHasOwner", "s");
116
117     DBusOutputStream outputStream(dbusMethodCall);
118     bool success = DBusSerializableArguments<std::string>::serialize(outputStream, busName);
119     if (!success) {
120         callStatus = CallStatus::OUT_OF_MEMORY;
121         return;
122     }
123     outputStream.flush();
124
125     DBusError dbusError;
126     DBusMessage dbusMessageReply = getDBusConnection()->sendDBusMessageWithReplyAndBlock(
127                     dbusMethodCall,
128                     dbusError);
129     if (dbusError || !dbusMessageReply.isMethodReturnType()) {
130         callStatus = CallStatus::REMOTE_ERROR;
131         return;
132     }
133
134     DBusInputStream inputStream(dbusMessageReply);
135     success = DBusSerializableArguments<bool>::deserialize(inputStream, hasOwner);
136     if (!success) {
137         callStatus = CallStatus::REMOTE_ERROR;
138         return;
139     }
140     callStatus = CallStatus::SUCCESS;
141 }
142
143 std::future<CallStatus> DBusDaemonProxy::nameHasOwnerAsync(const std::string& busName, NameHasOwnerAsyncCallback nameHasOwnerAsyncCallback) const {
144     DBusMessage dbusMessage = createMethodCall("NameHasOwner", "s");
145
146     DBusOutputStream outputStream(dbusMessage);
147     const bool success = DBusSerializableArguments<std::string>::serialize(outputStream, busName);
148     if (!success) {
149         std::promise<CallStatus> promise;
150         promise.set_value(CallStatus::OUT_OF_MEMORY);
151         return promise.get_future();
152     }
153     outputStream.flush();
154
155     return getDBusConnection()->sendDBusMessageWithReplyAsync(
156                     dbusMessage,
157                     DBusProxyAsyncCallbackHandler<bool>::create(nameHasOwnerAsyncCallback));
158 }
159
160 std::future<CallStatus> DBusDaemonProxy::getManagedObjectsAsync(const std::string& forDBusServiceName, GetManagedObjectsAsyncCallback callback) const {
161     // resolve remote objects
162     auto dbusMethodCallMessage = DBusMessage::createMethodCall(
163                     forDBusServiceName,
164                     "/",
165                     "org.freedesktop.DBus.ObjectManager",
166                     "GetManagedObjects",
167                     "");
168
169     const int timeoutMilliseconds = 100;
170
171     return getDBusConnection()->sendDBusMessageWithReplyAsync(
172                     dbusMethodCallMessage,
173                     DBusProxyAsyncCallbackHandler<DBusObjectToInterfaceDict>::create(callback),
174                     timeoutMilliseconds);
175 }
176
177
178 } // namespace DBus
179 } // namespace CommonAPI