|
Lines 19-56
Link Here
|
| 19 |
|
19 |
|
| 20 |
/*! |
20 |
/*! |
| 21 |
* \file dbusInterface.cpp |
21 |
* \file dbusInterface.cpp |
| 22 |
* \brief In this file can be found the functionality to connect to |
22 |
* \brief In this file can be found the functionality to connect to |
| 23 |
* the HAL daemon via D-Bus, to handle D-Bus calls/events and to |
23 |
* the D-Bus, to handle D-Bus session management |
| 24 |
* provide wrapper to HAL lib and functions |
|
|
| 25 |
* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> |
24 |
* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> |
| 26 |
* \date 2006-2007 |
25 |
* \date 2006-2007 |
| 27 |
*/ |
26 |
*/ |
| 28 |
|
27 |
|
| 29 |
// KDE Header |
28 |
// QT - Header |
|
|
29 |
#include <tqtimer.h> |
| 30 |
|
| 31 |
// KDE Header |
| 30 |
#include <tdelocale.h> |
32 |
#include <tdelocale.h> |
| 31 |
|
33 |
|
| 32 |
// DBUS - Header |
34 |
// DBUS - Header |
|
|
35 |
#include "dbus/dbus-shared.h" |
| 33 |
#include "dbusInterface.h" |
36 |
#include "dbusInterface.h" |
|
|
37 |
#include <tqdbusdatalist.h> |
| 38 |
#include <tqdbusdatamap.h> |
| 39 |
#include <tqdbuserror.h> |
| 40 |
#include <tqdbusmessage.h> |
| 41 |
#include <tqdbusvariant.h> |
| 34 |
|
42 |
|
| 35 |
// system headers |
43 |
// system headers |
| 36 |
#include <iostream> |
44 |
#include <unistd.h> |
|
|
45 |
|
| 46 |
#define DBUS_CONN_NAME "TDEPowersave" |
| 37 |
|
47 |
|
| 38 |
static void* myInstance = 0; |
48 |
static void* myInstance = 0; |
| 39 |
|
49 |
|
| 40 |
/*! The default constructor of the class dbusInterface. */ |
50 |
/*! The default constructor of the class dbusInterface. */ |
| 41 |
dbusInterface::dbusInterface(){ |
51 |
dbusInterface::dbusInterface(): |
|
|
52 |
dBusConn(), |
| 53 |
dBusWatch(0), |
| 54 |
dBusLocal(0), |
| 55 |
systemdSession(), |
| 56 |
systemdSeat(0), |
| 57 |
systemdInhibit(-1), |
| 58 |
consolekitSession(), |
| 59 |
consolekitSeat(0) |
| 60 |
{ |
| 42 |
kdDebugFuncIn(trace); |
61 |
kdDebugFuncIn(trace); |
| 43 |
|
62 |
|
| 44 |
dbus_is_connected = false; |
|
|
| 45 |
acquiredPolicyPower = false; |
| 46 |
|
| 47 |
// add pointer to this for filter_function() |
63 |
// add pointer to this for filter_function() |
| 48 |
myInstance=this; |
64 |
myInstance=this; |
|
|
65 |
|
| 49 |
// init connection to dbus |
66 |
// init connection to dbus |
| 50 |
if(!initDBUS()) { |
67 |
initDBUS(); |
| 51 |
kdError() << "Can't connect to D-Bus" << endl; |
|
|
| 52 |
m_dBusQtConnection = NULL; |
| 53 |
} |
| 54 |
|
68 |
|
| 55 |
kdDebugFuncOut(trace); |
69 |
kdDebugFuncOut(trace); |
| 56 |
} |
70 |
} |
|
Lines 72-101
dbusInterface::~dbusInterface(){
Link Here
|
| 72 |
* \retval false if disconnected |
86 |
* \retval false if disconnected |
| 73 |
*/ |
87 |
*/ |
| 74 |
bool dbusInterface::isConnectedToDBUS() { |
88 |
bool dbusInterface::isConnectedToDBUS() { |
| 75 |
return dbus_is_connected; |
89 |
return dBusConn.isConnected(); |
| 76 |
} |
|
|
| 77 |
|
| 78 |
/*! |
| 79 |
* This function return information if the org.freedesktop.Policy.Power |
| 80 |
* interface was claimed. |
| 81 |
* \return boolean with the status of claim the interface |
| 82 |
* \retval true if acquired |
| 83 |
* \retval false if not |
| 84 |
*/ |
| 85 |
bool dbusInterface::acquiredPolicyPowerInterface() { |
| 86 |
return acquiredPolicyPower; |
| 87 |
} |
90 |
} |
| 88 |
|
91 |
|
| 89 |
/*! |
92 |
/*! |
| 90 |
* This function try a reconnect to D-Bus and HAL daemon. |
93 |
* This function try a reconnect to D-Bus. |
| 91 |
* \return boolean with the result of the operation |
94 |
* \return boolean with the result of the operation |
| 92 |
* \retval true if successful reconnected to D-Bus and HAL |
95 |
* \retval true if successful reconnected to D-Bus |
| 93 |
* \retval false if unsuccessful |
96 |
* \retval false if unsuccessful |
| 94 |
*/ |
97 |
*/ |
| 95 |
bool dbusInterface::reconnect() { |
98 |
bool dbusInterface::reconnect() { |
| 96 |
// close D-Bus connection |
99 |
// close D-Bus connection |
| 97 |
close(); |
100 |
close(); |
| 98 |
// init D-Bus conntection and HAL context |
101 |
// init D-Bus conntection |
| 99 |
return (initDBUS()); |
102 |
return (initDBUS()); |
| 100 |
} |
103 |
} |
| 101 |
|
104 |
|
|
Lines 106-123
bool dbusInterface::reconnect() {
Link Here
|
| 106 |
* \retval false if any problems |
109 |
* \retval false if any problems |
| 107 |
*/ |
110 |
*/ |
| 108 |
bool dbusInterface::close() { |
111 |
bool dbusInterface::close() { |
| 109 |
if ( m_dBusQtConnection != NULL ) { |
112 |
if( dBusConn.isConnected() ) { |
| 110 |
releasePolicyPowerIface(); |
113 |
if( dBusWatch ) { |
| 111 |
m_dBusQtConnection->close(); |
114 |
delete dBusWatch; |
| 112 |
m_dBusQtConnection = NULL; |
115 |
} |
|
|
116 |
if( dBusLocal ) { |
| 117 |
delete dBusLocal; |
| 118 |
} |
| 119 |
if( systemdSeat ) { |
| 120 |
delete systemdSeat; |
| 121 |
} |
| 122 |
if( consolekitSeat ) { |
| 123 |
delete consolekitSeat; |
| 124 |
} |
| 113 |
} |
125 |
} |
| 114 |
dbus_is_connected = false; |
126 |
dBusConn.closeConnection(DBUS_CONN_NAME); |
| 115 |
|
|
|
| 116 |
return true; |
127 |
return true; |
| 117 |
} |
128 |
} |
| 118 |
|
129 |
|
| 119 |
/* ----> D-Bus section :: START <---- */ |
|
|
| 120 |
|
| 121 |
/*! |
130 |
/*! |
| 122 |
* This function initialise the connection to the D-Bus daemon. |
131 |
* This function initialise the connection to the D-Bus daemon. |
| 123 |
* \return boolean with the result of the operation |
132 |
* \return boolean with the result of the operation |
|
Lines 127-654
bool dbusInterface::close() {
Link Here
|
| 127 |
bool dbusInterface::initDBUS(){ |
136 |
bool dbusInterface::initDBUS(){ |
| 128 |
kdDebugFuncIn(trace); |
137 |
kdDebugFuncIn(trace); |
| 129 |
|
138 |
|
| 130 |
dbus_is_connected = false; |
139 |
dBusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus, DBUS_CONN_NAME); |
| 131 |
|
|
|
| 132 |
DBusError error; |
| 133 |
dbus_error_init(&error); |
| 134 |
|
| 135 |
dbus_connection = dbus_bus_get( DBUS_BUS_SYSTEM, &error ); |
| 136 |
|
140 |
|
| 137 |
if (dbus_connection == NULL){ |
141 |
if( !dBusConn.isConnected() ) { |
| 138 |
kdError() << "Failed to open connection to system message bus: " << error.message << endl; |
142 |
kdError() << "Failed to open connection to system message bus: " << dBusConn.lastError().message() << endl; |
| 139 |
dbus_error_free (&error); |
143 |
TQTimer::singleShot(4000, this, TQT_SLOT(reconnect())); |
| 140 |
return false; |
144 |
return false; |
| 141 |
} |
145 |
} |
| 142 |
|
146 |
|
| 143 |
if ( dbus_error_is_set( &error ) ) { |
147 |
// watcher for NameOwnerChanged signals |
| 144 |
kdError() << "Failed to register connection with system message bus: " << error.message << endl; |
148 |
dBusWatch = new TQT_DBusProxy(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, dBusConn); |
| 145 |
return false; |
149 |
TQObject::connect(dBusWatch, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)), |
| 146 |
} |
150 |
this, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); |
| 147 |
|
151 |
|
| 148 |
acquirePolicyPowerIface(); |
152 |
// watcher for Disconnect signal |
| 149 |
|
153 |
dBusLocal = new TQT_DBusProxy(DBUS_SERVICE_DBUS, DBUS_PATH_LOCAL, DBUS_INTERFACE_LOCAL, dBusConn); |
| 150 |
dbus_connection_set_exit_on_disconnect( dbus_connection, false ); |
154 |
TQObject::connect(dBusLocal, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)), |
| 151 |
|
155 |
this, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); |
| 152 |
/* add the filter function which should be executed on events on the bus */ |
156 |
|
| 153 |
if ( ! dbus_connection_add_filter( dbus_connection, filterFunction, this, NULL) ) { |
157 |
// find already running SystemD |
| 154 |
kdFatal() << "Error: Not enough memory to add filter to dbus connection" << endl; |
158 |
TQT_DBusProxy checkSystemD(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, dBusConn); |
| 155 |
exit(EXIT_FAILURE); |
159 |
if( checkSystemD.canSend() ) { |
| 156 |
} |
160 |
TQValueList<TQT_DBusData> params; |
| 157 |
|
161 |
params << TQT_DBusData::fromString(SYSTEMD_LOGIN1_SERVICE); |
| 158 |
/* add a match rule to catch all signals going through the bus with D-Bus interface */ |
162 |
TQT_DBusMessage reply = checkSystemD.sendWithReply("NameHasOwner", params); |
| 159 |
dbus_bus_add_match( dbus_connection, "type='signal'," |
163 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 && reply[0].toBool() ) { |
| 160 |
"interface='org.freedesktop.DBus'," |
164 |
onServiceRegistered(SYSTEMD_LOGIN1_SERVICE); |
| 161 |
"member='NameOwnerChanged'", NULL); |
165 |
} |
| 162 |
|
|
|
| 163 |
/* add a match rule to catch all signals going through the bus with ConsoleKit Interface */ |
| 164 |
dbus_bus_add_match( dbus_connection, "type='signal'," |
| 165 |
"interface='org.freedesktop.ConsoleKit.Session'," |
| 166 |
"member='ActiveChanged'", NULL); |
| 167 |
|
| 168 |
m_dBusQtConnection = new DBusQt::Connection(this); |
| 169 |
m_dBusQtConnection->dbus_connection_setup_with_qt_main(dbus_connection); |
| 170 |
|
| 171 |
dbus_is_connected = true; |
| 172 |
|
| 173 |
kdDebugFuncOut(trace); |
| 174 |
return true; |
| 175 |
} |
| 176 |
|
| 177 |
/*! |
| 178 |
* This function acquire the org.freedesktop.Policy.Power interface |
| 179 |
* \return boolean with the result of the operation |
| 180 |
* \retval true if successful acquired the interface |
| 181 |
* \retval false if unsuccessful |
| 182 |
*/ |
| 183 |
bool dbusInterface::acquirePolicyPowerIface(){ |
| 184 |
kdDebugFuncIn(trace); |
| 185 |
|
| 186 |
if (dbus_connection == NULL) { |
| 187 |
kdDebugFuncOut(trace); |
| 188 |
return false; |
| 189 |
} |
166 |
} |
| 190 |
|
167 |
|
| 191 |
DBusError err; |
168 |
// find already running ConsoleKit |
| 192 |
dbus_error_init(&err); |
169 |
TQT_DBusProxy checkConsoleKit(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, dBusConn); |
| 193 |
int ret = dbus_bus_request_name(dbus_connection, "org.freedesktop.Policy.Power", |
170 |
if( checkConsoleKit.canSend() ) { |
| 194 |
DBUS_NAME_FLAG_REPLACE_EXISTING, &err); |
171 |
TQValueList<TQT_DBusData> params; |
| 195 |
if (dbus_error_is_set(&err)) { |
172 |
params << TQT_DBusData::fromString(CK_SERVICE); |
| 196 |
kdWarning() << "Acquire org.freedesktop.Policy.Power interface failed with error: " << err.message << endl; |
173 |
TQT_DBusMessage reply = checkConsoleKit.sendWithReply("NameHasOwner", params); |
| 197 |
dbus_error_free(&err); |
174 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 && reply[0].toBool() ) { |
| 198 |
} |
175 |
onServiceRegistered(CK_SERVICE); |
| 199 |
switch (ret) { |
176 |
} |
| 200 |
case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: |
|
|
| 201 |
kdDebug() << "Acquired org.freedesktop.Policy.Power interface" << endl; |
| 202 |
acquiredPolicyPower = true; |
| 203 |
break; |
| 204 |
case DBUS_REQUEST_NAME_REPLY_IN_QUEUE: |
| 205 |
kdWarning() << "Queued to acquire org.freedesktop.Policy.Power interface" << endl; |
| 206 |
acquiredPolicyPower = false; |
| 207 |
break; |
| 208 |
default: |
| 209 |
acquiredPolicyPower = false; |
| 210 |
break; |
| 211 |
} |
177 |
} |
| 212 |
|
178 |
|
| 213 |
kdDebugFuncOut(trace); |
179 |
kdDebugFuncOut(trace); |
| 214 |
return acquiredPolicyPower; |
180 |
return true; |
| 215 |
} |
181 |
} |
| 216 |
|
182 |
|
| 217 |
/*! |
183 |
/*! |
| 218 |
* This function release the org.freedesktop.Policy.Power interface |
184 |
* This function handles signals from the D-Bus daemon. |
| 219 |
* \return boolean with the result of the operation |
|
|
| 220 |
* \retval true if successful acquired the interface |
| 221 |
* \retval false if unsuccessful |
| 222 |
*/ |
185 |
*/ |
| 223 |
bool dbusInterface::releasePolicyPowerIface(){ |
186 |
void dbusInterface::handleDBusSignal(const TQT_DBusMessage& msg) { |
| 224 |
kdDebugFuncIn(trace); |
187 |
// dbus terminated |
| 225 |
|
188 |
if( msg.path() == DBUS_PATH_LOCAL |
| 226 |
int result; |
189 |
&& msg.interface() == DBUS_INTERFACE_LOCAL |
| 227 |
bool retval = false; |
190 |
&& msg.member() == "Disconnected" ) { |
| 228 |
DBusError error; |
191 |
close(); |
| 229 |
|
192 |
TQTimer::singleShot(1000, this, TQT_SLOT(reconnect())); |
| 230 |
if (dbus_connection == NULL) { |
193 |
return; |
| 231 |
kdDebugFuncOut(trace); |
|
|
| 232 |
return false; |
| 233 |
} |
194 |
} |
| 234 |
|
195 |
|
| 235 |
dbus_error_init(&error); |
196 |
// service registered / unregistered |
| 236 |
|
197 |
if( msg.path() == DBUS_PATH_DBUS |
| 237 |
result = dbus_bus_release_name(dbus_connection, "org.freedesktop.Policy.Power", &error); |
198 |
&& msg.interface() == DBUS_INTERFACE_DBUS |
| 238 |
|
199 |
&& msg.member() == "NameOwnerChanged" ) { |
| 239 |
if ( dbus_error_is_set( &error ) ) { |
200 |
if( msg[1].toString().isEmpty() ) { |
| 240 |
kdError() << "Failed to release org.freedesktop.Policy.Power: " << error.message << endl; |
201 |
// old-owner is empty |
| 241 |
dbus_error_free(&error); |
202 |
onServiceRegistered(msg[0].toString()); |
| 242 |
} else { |
|
|
| 243 |
switch (result) { |
| 244 |
case DBUS_RELEASE_NAME_REPLY_RELEASED: |
| 245 |
kdDebug() << "Released org.freedesktop.Policy.Power interface" << endl; |
| 246 |
retval = true; |
| 247 |
acquiredPolicyPower = false; |
| 248 |
break; |
| 249 |
case DBUS_RELEASE_NAME_REPLY_NOT_OWNER: |
| 250 |
kdWarning() << "Couldn't release org.freedesktop.Policy.Power, not the owner" << endl; |
| 251 |
break; |
| 252 |
case DBUS_RELEASE_NAME_REPLY_NON_EXISTENT: |
| 253 |
kdWarning() << "Couldn't release org.freedesktop.Policy.Power, Iface not existing" << endl; |
| 254 |
break; |
| 255 |
default: |
| 256 |
kdWarning() << "Couldn't release org.freedesktop.Policy.Power, unknown error" << endl; |
| 257 |
break; |
| 258 |
} |
203 |
} |
|
|
204 |
if( msg[2].toString().isEmpty() ) { |
| 205 |
// new-owner is empty |
| 206 |
onServiceUnregistered(msg[0].toString()); |
| 207 |
} |
| 208 |
return; |
| 259 |
} |
209 |
} |
| 260 |
|
|
|
| 261 |
return retval; |
| 262 |
kdDebugFuncOut(trace); |
| 263 |
} |
| 264 |
|
| 265 |
/*! |
| 266 |
* This function check if the org.freedesktop.Policy.Power |
| 267 |
* interface is owned by someone |
| 268 |
* \return boolean with the result of the operation |
| 269 |
* \retval true if the interface is owned by someone |
| 270 |
* \retval false if else |
| 271 |
*/ |
| 272 |
bool dbusInterface::isPolicyPowerIfaceOwned(){ |
| 273 |
kdDebugFuncIn(trace); |
| 274 |
|
210 |
|
| 275 |
bool retval = false; |
211 |
// systemd session changed |
| 276 |
DBusError error; |
212 |
if( systemdSeat && systemdSeat->canSend() |
| 277 |
|
213 |
&& msg.path() == systemdSeat->path() |
| 278 |
if (dbus_connection == NULL) { |
214 |
&& msg.interface() == DBUS_INTERFACE_PROPERTIES |
| 279 |
kdDebugFuncOut(trace); |
215 |
&& msg.member() == "PropertiesChanged" |
| 280 |
return false; |
216 |
&& msg[0].toString() == SYSTEMD_LOGIN1_SEAT_IFACE) { |
|
|
217 |
bool activeSessionProperty = false; |
| 218 |
TQT_DBusDataMap<TQString> map = msg[1].toStringKeyMap(); |
| 219 |
TQT_DBusDataMap<TQString>::const_iterator it = map.begin(); |
| 220 |
for (; !activeSessionProperty && it != map.end(); ++it) { |
| 221 |
if( it.key() != "ActiveSession" ) { |
| 222 |
activeSessionProperty = true; |
| 223 |
} |
| 224 |
} |
| 225 |
TQValueList<TQString> list = msg[2].toList().toStringList(); |
| 226 |
TQValueList<TQString>::const_iterator it1 = list.begin(); |
| 227 |
for (; !activeSessionProperty && it1 != list.end(); ++it1) { |
| 228 |
if( (*it1) == "ActiveSession" ) { |
| 229 |
activeSessionProperty = true; |
| 230 |
} |
| 231 |
} |
| 232 |
if( activeSessionProperty ) { |
| 233 |
emit activeSessionChanged(checkActiveSession()); |
| 234 |
} |
| 235 |
return; |
| 281 |
} |
236 |
} |
| 282 |
|
237 |
|
| 283 |
dbus_error_init(&error); |
238 |
// consolekit session changed |
| 284 |
|
239 |
if( consolekitSeat && consolekitSeat->canSend() |
| 285 |
retval = dbus_bus_name_has_owner(dbus_connection, "org.freedesktop.Policy.Power", &error); |
240 |
&& msg.path() == consolekitSeat->path() |
| 286 |
|
241 |
&& msg.interface() == CK_SEAT_IFACE |
| 287 |
if ( dbus_error_is_set( &error ) ) { |
242 |
&& msg.member() == "ActiveSessionChanged") { |
| 288 |
kdError() << "Failed to check if org.freedesktop.Policy.Power has an owner: " << error.message << endl; |
243 |
emit activeSessionChanged(msg[0].toString() == TQString(consolekitSession)); |
| 289 |
dbus_error_free(&error); |
244 |
return; |
| 290 |
} |
245 |
} |
| 291 |
|
|
|
| 292 |
kdDebugFuncOut(trace); |
| 293 |
return retval; |
| 294 |
} |
| 295 |
|
| 296 |
/* ----> DBUS section :: END <---- */ |
| 297 |
|
| 298 |
/* ----> D-Bus methode calls functions :: START <---- */ |
| 299 |
/*! |
| 300 |
* This function call a D-Bus method |
| 301 |
* \param interface TQString with te dbus interface |
| 302 |
* \param path TQString with the object path |
| 303 |
* \param object TQString with the object name |
| 304 |
* \param method TQString with the name of the methode |
| 305 |
* \param first_arg_type integer with the dbus type of the first argument |
| 306 |
* \param ... more arguments |
| 307 |
* \return If the query was successful or not |
| 308 |
*/ |
| 309 |
bool dbusInterface::dbusSystemMethodCall( TQString interface, TQString path, TQString object, TQString method, |
| 310 |
int first_arg_type, ... ) { |
| 311 |
kdDebugFuncIn(trace); |
| 312 |
|
| 313 |
bool _ret = false; |
| 314 |
va_list var_args; |
| 315 |
|
| 316 |
va_start(var_args, first_arg_type); |
| 317 |
_ret = dbusMethodCall( interface, path, object, method, DBUS_BUS_SYSTEM, |
| 318 |
NULL, -1, first_arg_type, var_args); |
| 319 |
va_end(var_args); |
| 320 |
|
| 321 |
kdDebugFuncOut(trace); |
| 322 |
return _ret; |
| 323 |
} |
| 324 |
|
| 325 |
|
| 326 |
/*! |
| 327 |
* This overloaded function call a D-Bus method on the D-Bus system bus with a return value |
| 328 |
* \param interface TQString with the dbus interface |
| 329 |
* \param path TQString with the object path |
| 330 |
* \param object TQString with the object name |
| 331 |
* \param method TQString with the name of the method |
| 332 |
* \param retvalue void pointer to arguments, if NULL we make a simple call |
| 333 |
* \param retval_type Integer with the dbus type of the return value, set to -1 if retvalue is NULL |
| 334 |
* \param first_arg_type Integer with the dbus type of the first argument followed by the value |
| 335 |
* \return If the query was successful or not |
| 336 |
*/ |
| 337 |
bool dbusInterface::dbusSystemMethodCall( TQString interface, TQString path, TQString object, TQString method, |
| 338 |
void *retvalue, int retval_type, int first_arg_type, ... ) { |
| 339 |
kdDebugFuncIn(trace); |
| 340 |
|
| 341 |
bool _ret = false; |
| 342 |
va_list var_args; |
| 343 |
|
| 344 |
va_start(var_args, first_arg_type); |
| 345 |
_ret = dbusMethodCall( interface, path, object, method, DBUS_BUS_SYSTEM, |
| 346 |
retvalue, retval_type, first_arg_type, var_args); |
| 347 |
va_end(var_args); |
| 348 |
|
| 349 |
kdDebugFuncOut(trace); |
| 350 |
return _ret; |
| 351 |
} |
246 |
} |
| 352 |
|
247 |
|
| 353 |
|
248 |
/*! |
| 354 |
/*! |
249 |
* This function handles dBus service registering |
| 355 |
* This function call a D-Bus method with a return value |
|
|
| 356 |
* \param interface TQString with the dbus interface |
| 357 |
* \param path TQString with the object path |
| 358 |
* \param object TQString with the object name |
| 359 |
* \param method TQString with the name of the method |
| 360 |
* \param dbus_type DBusBusType with the D-Bus BUS Type |
| 361 |
* \param retvalue void pointer to arguments, if NULL we make a simple call |
| 362 |
* \param retval_type Integer with the dbus type of the return value, set to -1 if retvalue is NULL |
| 363 |
* \param first_arg_type Integer with the dbus type of the first argument followed by the value |
| 364 |
* \param var_args va_list with more arguments |
| 365 |
* \return If the query was successful or not |
| 366 |
*/ |
250 |
*/ |
| 367 |
bool dbusInterface::dbusMethodCall( TQString interface, TQString path, TQString object, TQString method, |
251 |
void dbusInterface::onServiceRegistered(const TQString& service) { |
| 368 |
DBusBusType dbus_type, void *retvalue, int retval_type, int first_arg_type, |
252 |
if( service == SYSTEMD_LOGIN1_SERVICE ) { |
| 369 |
va_list var_args ) { |
253 |
// get current session |
| 370 |
kdDebugFuncIn(trace); |
254 |
TQT_DBusProxy managerIface(SYSTEMD_LOGIN1_SERVICE, SYSTEMD_LOGIN1_PATH, SYSTEMD_LOGIN1_MANAGER_IFACE, dBusConn); |
| 371 |
|
255 |
systemdSession = TQT_DBusObjectPath(); |
| 372 |
DBusMessage *message; |
256 |
if( managerIface.canSend() ) { |
| 373 |
DBusMessage *reply; |
257 |
TQValueList<TQT_DBusData> params; |
| 374 |
DBusError error; |
258 |
params << TQT_DBusData::fromUInt32( getpid() ); |
| 375 |
bool ret = false; |
259 |
TQT_DBusMessage reply = managerIface.sendWithReply("GetSessionByPID", params); |
| 376 |
|
260 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 377 |
dbus_error_init(&error); |
261 |
systemdSession = reply[0].toObjectPath(); |
| 378 |
|
262 |
} |
| 379 |
dbus_connection = dbus_bus_get(dbus_type, &error); |
263 |
} |
| 380 |
|
264 |
if( !systemdSession.isValid() ) { |
| 381 |
if (dbus_error_is_set(&error)) { |
265 |
kdWarning() << "The session is not registered with systemd" << endl; |
| 382 |
kdError() << "Could not get dbus connection: " << error.message << endl; |
266 |
return; |
| 383 |
dbus_error_free(&error); |
267 |
} |
| 384 |
goto out; |
|
|
| 385 |
} |
| 386 |
|
| 387 |
message = dbus_message_new_method_call( interface.ascii(), path.ascii(), object.ascii(), method.ascii() ); |
| 388 |
dbus_message_append_args_valist(message, first_arg_type, var_args); |
| 389 |
|
268 |
|
| 390 |
if (retvalue == NULL) { |
269 |
// get session seat |
| 391 |
if (!dbus_connection_send(dbus_connection, message, NULL)) { |
270 |
TQT_DBusProxy sessionProperties(SYSTEMD_LOGIN1_SERVICE, systemdSession, DBUS_INTERFACE_PROPERTIES, dBusConn); |
| 392 |
kdError() << "Could not send method call." << endl; |
271 |
TQT_DBusObjectPath seat; |
| 393 |
dbus_message_unref( message ); |
272 |
if( sessionProperties.canSend() ) { |
| 394 |
goto out; |
273 |
TQValueList<TQT_DBusData> params; |
|
|
274 |
params |
| 275 |
<< TQT_DBusData::fromString( SYSTEMD_LOGIN1_SESSION_IFACE ) |
| 276 |
<< TQT_DBusData::fromString( "Seat" ); |
| 277 |
TQT_DBusMessage reply = sessionProperties.sendWithReply("Get", params); |
| 278 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 279 |
seat = reply[0].toVariant().value.toStruct()[1].toObjectPath(); |
| 280 |
} |
| 395 |
} |
281 |
} |
| 396 |
} else { |
282 |
if( !seat.isValid() ) { |
| 397 |
reply = dbus_connection_send_with_reply_and_block(dbus_connection, message, -1, &error); |
283 |
kdWarning() << "Unable to associate systemd session with a seat" << endl; |
| 398 |
|
284 |
return; |
| 399 |
if (dbus_error_is_set(&error)) { |
|
|
| 400 |
kdError() << "Could not send dbus message: " << error.message << endl; |
| 401 |
dbus_message_unref(message); |
| 402 |
dbus_error_free(&error); |
| 403 |
goto out; |
| 404 |
} |
285 |
} |
| 405 |
|
286 |
|
| 406 |
int type = dbus_message_get_type(reply); |
287 |
// watch session changes |
| 407 |
if (type == DBUS_MESSAGE_TYPE_METHOD_RETURN) { |
288 |
systemdSeat = new TQT_DBusProxy(SYSTEMD_LOGIN1_SERVICE, seat, DBUS_INTERFACE_PROPERTIES, dBusConn); |
| 408 |
if (!dbus_message_get_args(reply, &error, retval_type, retvalue, DBUS_TYPE_INVALID)){ |
289 |
TQObject::connect(systemdSeat, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)), |
| 409 |
if (dbus_error_is_set(&error)) { |
290 |
this, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); |
| 410 |
kdError() << "Could not get argument from reply: " |
291 |
|
| 411 |
<< error.message << endl; |
292 |
// inhibit systemd handling of power/sleep/hibernate/lid buttons |
| 412 |
dbus_error_free(&error); |
293 |
// http://www.freedesktop.org/wiki/Software/systemd/inhibit |
| 413 |
} |
294 |
if( !systemdInhibit.isValid() && managerIface.canSend() ) { |
| 414 |
dbus_message_unref(reply); |
295 |
TQValueList<TQT_DBusData> params; |
| 415 |
dbus_message_unref(message); |
296 |
params |
| 416 |
goto out; |
297 |
<< TQT_DBusData::fromString("handle-power-key:handle-suspend-key:handle-hibernate-key:handle-lid-switch") // what |
|
|
298 |
<< TQT_DBusData::fromString("TDEPowersave") // who |
| 299 |
<< TQT_DBusData::fromString("TDE handles power events") // why |
| 300 |
<< TQT_DBusData::fromString("block"); // mode |
| 301 |
TQT_DBusMessage reply = managerIface.sendWithReply("Inhibit", params); |
| 302 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 303 |
systemdInhibit = reply[0].toUnixFd(); |
| 417 |
} |
304 |
} |
| 418 |
} else { |
|
|
| 419 |
kdError() << "Revieved invalid DBUS_MESSAGE_TYPE: " << type |
| 420 |
<< "expected: " << DBUS_MESSAGE_TYPE_METHOD_RETURN << endl; |
| 421 |
dbus_message_unref(reply); |
| 422 |
dbus_message_unref(message); |
| 423 |
goto out; |
| 424 |
} |
305 |
} |
|
|
306 |
return; |
| 425 |
} |
307 |
} |
|
|
308 |
if( service == CK_SERVICE ) { |
| 309 |
// get current session |
| 310 |
TQT_DBusProxy managerIface(CK_SERVICE, CK_MANAGER_OBJECT, CK_MANAGER_IFACE, dBusConn); |
| 311 |
consolekitSession = TQT_DBusObjectPath(); |
| 312 |
if( managerIface.canSend() ) { |
| 313 |
TQValueList<TQT_DBusData> params; |
| 314 |
params << TQT_DBusData::fromUInt32( getpid() ); |
| 315 |
TQT_DBusMessage reply = managerIface.sendWithReply("GetSessionForUnixProcess", params); |
| 316 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 317 |
consolekitSession = reply[0].toObjectPath(); |
| 318 |
} |
| 319 |
} |
| 320 |
if( !consolekitSession.isValid() ) { |
| 321 |
kdWarning() << "The session is not registered with consolekit" << endl; |
| 322 |
return; |
| 323 |
} |
| 426 |
|
324 |
|
| 427 |
ret = true; // if we are here, everything should be okay |
325 |
// get session seat |
| 428 |
dbus_message_unref(message); |
326 |
TQT_DBusObjectPath seat; |
| 429 |
dbus_connection_flush(dbus_connection); |
327 |
if( dBusConn.isConnected() ) { |
| 430 |
|
328 |
TQT_DBusMessage msg = TQT_DBusMessage::methodCall(CK_SERVICE, consolekitSession, CK_SESSION_IFACE, "GetSeatId"); |
| 431 |
out: |
329 |
TQT_DBusMessage reply = dBusConn.sendWithReply(msg); |
| 432 |
kdDebugFuncOut(trace); |
330 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 433 |
return ret; |
331 |
seat = reply[0].toObjectPath(); |
| 434 |
} |
332 |
} |
| 435 |
|
333 |
} |
| 436 |
/* ----> D-Bus methode calls functions :: END <---- */ |
334 |
if( !seat.isValid() ) { |
| 437 |
/* ---> PolicyKit method call section :: START <--- */ |
335 |
kdWarning() << "Unable to associate consolekit session with a seat" << endl; |
| 438 |
|
336 |
return; |
| 439 |
/*! |
337 |
} |
| 440 |
* Check if the user is privileged to a special privilege |
|
|
| 441 |
* \param privilege TQString with the name of the requested privilege |
| 442 |
* \param udi TQString with the UDI. |
| 443 |
* \param ressource TQString with the name of the ressource |
| 444 |
* \param user TQString with the name of the user. If empty the current user is used. |
| 445 |
* \return int with info if the user is allowed or not. |
| 446 |
* \retval 0 if not allowed |
| 447 |
* \retval 1 if allowed |
| 448 |
* \retval -1 if a error occurs or we could not query the interface |
| 449 |
*/ |
| 450 |
int dbusInterface::isUserPrivileged(TQString privilege, TQString udi, TQString ressource, TQString user) { |
| 451 |
kdDebugFuncIn(trace); |
| 452 |
|
338 |
|
| 453 |
const char *_unique_name; |
339 |
// watch session changes |
| 454 |
const char *_user; |
340 |
consolekitSeat = new TQT_DBusProxy(CK_SERVICE, seat, CK_SEAT_IFACE, dBusConn); |
| 455 |
const char *_privilege; |
341 |
TQObject::connect(consolekitSeat, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)), |
| 456 |
|
342 |
this, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); |
| 457 |
int retval = -1; |
343 |
return; |
| 458 |
|
|
|
| 459 |
if (user.isEmpty() || user.isNull()) |
| 460 |
_user = getenv("USER"); |
| 461 |
else |
| 462 |
_user = user.latin1(); |
| 463 |
|
| 464 |
if (_user == NULL || privilege.isEmpty()) |
| 465 |
goto out; |
| 466 |
|
| 467 |
_unique_name = dbus_bus_get_unique_name(dbus_connection); |
| 468 |
_privilege = privilege.latin1(); |
| 469 |
|
| 470 |
// not sure if we need this, but to avoid problems |
| 471 |
dbus_bool_t _retval; |
| 472 |
const char *_ressource; |
| 473 |
_ressource = ressource.latin1(); |
| 474 |
|
| 475 |
if (!dbusSystemMethodCall( "org.freedesktop.PolicyKit", |
| 476 |
"/org/freedesktop/PolicyKit/Manager", |
| 477 |
"org.freedesktop.PolicyKit.Manager", |
| 478 |
"IsUserPrivileged", |
| 479 |
&_retval, DBUS_TYPE_BOOLEAN, |
| 480 |
DBUS_TYPE_STRING, &_unique_name, |
| 481 |
DBUS_TYPE_STRING, &_user, |
| 482 |
DBUS_TYPE_STRING, &_privilege, |
| 483 |
DBUS_TYPE_STRING, &_ressource, |
| 484 |
DBUS_TYPE_INVALID)) { |
| 485 |
retval = -1; // only to be sure we have no changes trough the call |
| 486 |
} else { |
| 487 |
retval = (int) _retval; |
| 488 |
} |
344 |
} |
| 489 |
|
|
|
| 490 |
out: |
| 491 |
kdDebugFuncOut(trace); |
| 492 |
return retval; |
| 493 |
} |
345 |
} |
| 494 |
/* ---> PolicyKit method call section :: END <--- */ |
|
|
| 495 |
|
346 |
|
| 496 |
/*! |
347 |
/*! |
| 497 |
* Use this TQT_SLOT to emit a reviced messages to the tdepowersave. |
348 |
* This function handles dBus service unregistering |
| 498 |
* NOTE: Because of the filter function this need to be a public function. |
|
|
| 499 |
* Don't use this function in any other place than this class. |
| 500 |
* \param type enum with the type of the message |
| 501 |
* \param message String with the message |
| 502 |
* \param string String with additional info |
| 503 |
*/ |
349 |
*/ |
| 504 |
void dbusInterface::emitMsgReceived( msg_type type, TQString message, TQString string ) { |
350 |
void dbusInterface::onServiceUnregistered(const TQString& service) { |
| 505 |
|
351 |
if( service == SYSTEMD_LOGIN1_SERVICE ) { |
| 506 |
if (message.startsWith("dbus.terminate")) |
352 |
systemdSession = TQT_DBusObjectPath(); |
| 507 |
dbus_is_connected = false; |
353 |
if( systemdSeat ) { |
| 508 |
|
354 |
delete systemdSeat; |
| 509 |
if (type == POLICY_POWER_OWNER_CHANGED) { |
355 |
} |
| 510 |
if (message.startsWith("NOW_OWNER")) |
356 |
return; |
| 511 |
acquiredPolicyPower = true; |
357 |
} |
| 512 |
else |
358 |
if( service == CK_SERVICE ) { |
| 513 |
acquiredPolicyPower = false; |
359 |
consolekitSession = TQT_DBusObjectPath(); |
|
|
360 |
if( consolekitSeat ) { |
| 361 |
delete consolekitSeat; |
| 362 |
} |
| 363 |
return; |
| 514 |
} |
364 |
} |
| 515 |
|
|
|
| 516 |
emit msgReceived_withStringString( type, message, string ); |
| 517 |
} |
365 |
} |
| 518 |
|
366 |
|
| 519 |
#include "dbusInterface.moc" |
367 |
/*! |
| 520 |
// --> functions which are not member of the class ... |
368 |
* This functions is used to check if session is active |
| 521 |
|
|
|
| 522 |
/*! |
| 523 |
* This function is needed filter function for the D-Bus connection to filter |
| 524 |
* all needed messages from the bus which are needful for TDEPowersave. |
| 525 |
* \param connection existing connection to the D-Bus daemon |
| 526 |
* \param message the recieved message from the D-Bus daemon |
| 527 |
* \param data void pointer (see dbus bindings for more information) |
| 528 |
* \return DBusHandlerResult |
| 529 |
*/ |
369 |
*/ |
| 530 |
DBusHandlerResult |
370 |
bool dbusInterface::checkActiveSession() { |
| 531 |
filterFunction (DBusConnection *connection, DBusMessage *message, void */*data*/) { |
371 |
if( systemdSeat && systemdSeat->canSend() ) { |
| 532 |
kdDebugFuncIn(trace); |
372 |
TQT_DBusObjectPath activeSession; |
| 533 |
|
373 |
TQValueList<TQT_DBusData> params; |
| 534 |
bool reply_wanted; |
374 |
params |
| 535 |
char *value; |
375 |
<< TQT_DBusData::fromString( SYSTEMD_LOGIN1_SEAT_IFACE ) |
| 536 |
TQString ifaceType; |
376 |
<< TQT_DBusData::fromString( "ActiveSession" ); |
| 537 |
|
377 |
TQT_DBusMessage reply = systemdSeat->sendWithReply("Get", params); |
| 538 |
DBusError error; |
378 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 539 |
dbus_error_init( &error ); |
379 |
activeSession = reply[0].toVariant().value.toStruct()[1].toObjectPath(); |
| 540 |
|
380 |
return (activeSession == systemdSession); |
| 541 |
if (dbus_message_is_signal (message, |
|
|
| 542 |
DBUS_INTERFACE_LOCAL, |
| 543 |
"Disconnected")){ |
| 544 |
((dbusInterface*) myInstance)->emitMsgReceived( DBUS_EVENT, "dbus.terminate", 0 ); |
| 545 |
dbus_connection_unref(connection); |
| 546 |
kdDebugFuncOut(trace); |
| 547 |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 548 |
} |
| 549 |
|
| 550 |
if ( dbus_message_get_type( message ) != DBUS_MESSAGE_TYPE_SIGNAL ) { |
| 551 |
if (trace) kdDebug() << "recieved message, but wasn't from type DBUS_MESSAGE_TYPE_SIGNAL" << endl; |
| 552 |
kdDebugFuncOut(trace); |
| 553 |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 554 |
} |
| 555 |
|
| 556 |
ifaceType = dbus_message_get_interface( message ); |
| 557 |
if (ifaceType == NULL) { |
| 558 |
kdDebug() << "Received message from invalid interface" << endl; |
| 559 |
kdDebugFuncOut(trace); |
| 560 |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 561 |
} |
| 562 |
|
| 563 |
reply_wanted = !dbus_message_get_no_reply( message ); |
| 564 |
|
| 565 |
if (ifaceType.startsWith(DBUS_INTERFACE_DBUS)) { |
| 566 |
if(trace) kdDebug() << "Received from DBUS_INTERFACE_DBUS" << endl; |
| 567 |
/* get the name of the signal */ |
| 568 |
const char *signal = dbus_message_get_member( message ); |
| 569 |
|
| 570 |
/* get the first argument. This must be a string at the moment */ |
| 571 |
dbus_message_get_args( message, &error, DBUS_TYPE_STRING, &value, DBUS_TYPE_INVALID ); |
| 572 |
|
| 573 |
if ( dbus_error_is_set( &error ) ) { |
| 574 |
kdWarning() << "Received signal " << error.message << " but no string argument" << endl; |
| 575 |
dbus_error_free( &error ); |
| 576 |
kdDebugFuncOut(trace); |
| 577 |
return DBUS_HANDLER_RESULT_HANDLED; |
| 578 |
} |
381 |
} |
| 579 |
|
382 |
} |
| 580 |
if (trace) kdDebug() << "filter_function::SIGNAL=" << signal << " VALUE=" << value << endl; |
383 |
if( consolekitSeat && consolekitSeat->canSend() ) { |
| 581 |
|
384 |
TQT_DBusObjectPath activeSession; |
| 582 |
/* our name is... */ |
385 |
TQValueList<TQT_DBusData> params; |
| 583 |
if ( ! strcmp( signal, "NameAcquired" ) ) { |
386 |
TQT_DBusMessage reply = consolekitSeat->sendWithReply("GetActiveSession", params); |
| 584 |
kdDebugFuncOut(trace); |
387 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 585 |
return DBUS_HANDLER_RESULT_HANDLED; |
388 |
activeSession = reply[0].toObjectPath(); |
| 586 |
} |
389 |
return (activeSession == consolekitSession); |
| 587 |
|
|
|
| 588 |
else if ( ! strcmp( signal, "NameOwnerChanged" )) { |
| 589 |
char *service; |
| 590 |
char *old_owner; |
| 591 |
char *new_owner; |
| 592 |
|
| 593 |
if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &service, |
| 594 |
DBUS_TYPE_STRING, &old_owner, |
| 595 |
DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID)) { |
| 596 |
if (!strcmp(service, "org.freedesktop.Policy.Power")) { |
| 597 |
const char *own_name; |
| 598 |
|
| 599 |
own_name = dbus_bus_get_unique_name(((dbusInterface*) myInstance)->get_DBUS_connection()); |
| 600 |
|
| 601 |
if (!strcmp(new_owner, own_name)) { |
| 602 |
kdDebug() << "=== now owner of org.freedesktop.Policy.Power ===" << endl; |
| 603 |
// we have now again the ower of the name! |
| 604 |
((dbusInterface*) myInstance)->emitMsgReceived( POLICY_POWER_OWNER_CHANGED, |
| 605 |
"NOW_OWNER", |
| 606 |
NULL ); |
| 607 |
} else { |
| 608 |
// some other has now the interface |
| 609 |
kdDebug() << "=== someone owner of org.freedesktop.Policy.Power ===" << endl; |
| 610 |
((dbusInterface*) myInstance)->emitMsgReceived( POLICY_POWER_OWNER_CHANGED, |
| 611 |
"OTHER_OWNER", |
| 612 |
NULL ); |
| 613 |
} |
| 614 |
} |
| 615 |
} |
| 616 |
} |
| 617 |
kdDebugFuncOut(trace); |
| 618 |
return DBUS_HANDLER_RESULT_HANDLED; |
| 619 |
} else if (ifaceType.startsWith("org.freedesktop.ConsoleKit.Session")) { |
| 620 |
kdDebug() << "Received from org.freedesktop.ConsoleKit.Session" << endl; |
| 621 |
|
| 622 |
const char *session = dbus_message_get_path (message); |
| 623 |
const char *signal = dbus_message_get_member( message ); |
| 624 |
|
| 625 |
if (! strcmp(signal, "ActiveChanged")) { |
| 626 |
dbus_bool_t active; |
| 627 |
|
| 628 |
if (dbus_message_get_args( message, &error, DBUS_TYPE_BOOLEAN, &active, DBUS_TYPE_INVALID )) { |
| 629 |
((dbusInterface*) myInstance)->emitMsgReceived( CONSOLEKIT_SESSION_ACTIVE, |
| 630 |
session, TQString("%1").arg((int)active)); |
| 631 |
} else { |
| 632 |
if (dbus_error_is_set( &error )) dbus_error_free( &error ); |
| 633 |
} |
| 634 |
} else { |
| 635 |
kdDebug() << "Received unknown signal from org.freedesktop.ConsoleKit.Session: " |
| 636 |
<< signal << endl; |
| 637 |
kdDebugFuncOut(trace); |
| 638 |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 639 |
} |
390 |
} |
| 640 |
kdDebugFuncOut(trace); |
|
|
| 641 |
return DBUS_HANDLER_RESULT_HANDLED; |
| 642 |
} else { |
| 643 |
kdDebugFuncOut(trace); |
| 644 |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 645 |
} |
391 |
} |
|
|
392 |
return false; |
| 646 |
} |
393 |
} |
| 647 |
|
394 |
|
| 648 |
// --> some functions to get private members |
395 |
#include "dbusInterface.moc" |
| 649 |
|
|
|
| 650 |
//! to get the current connection to D-Bus |
| 651 |
DBusConnection * dbusInterface::get_DBUS_connection() { |
| 652 |
return dbus_connection; |
| 653 |
} |
| 654 |
|