21 #include "servicecontrolinterface.h"
24 #include <QtCore/QTimer>
26 #include <QtDBus/QDBusServiceWatcher>
27 #include <QtDBus/QDBusPendingReply>
28 #include <QtDBus/QDBusPendingCallWatcher>
30 #include <KStandardDirs>
31 #include <KConfigGroup>
36 inline QString dbusServiceName(
const QString& serviceName ) {
37 return QString(
"org.kde.nepomuk.services.%1").arg(serviceName);
42 class Nepomuk2::ServiceController::Private
46 : processControl( 0 ),
47 serviceControlInterface( 0 ),
48 dbusServiceWatcher( 0 ),
52 failedToInitialize( false ),
62 OrgKdeNepomukServiceControlInterface* serviceControlInterface;
63 QDBusServiceWatcher* dbusServiceWatcher;
73 bool failedToInitialize;
76 void init( KService::Ptr
service );
81 void Nepomuk2::ServiceController::Private::init( KService::Ptr s )
84 autostart = service->property(
"X-KDE-Nepomuk-autostart", QVariant::Bool ).toBool();
85 KConfigGroup cg( Server::self()->config(), QString(
"Service-%1").arg(service->desktopEntryName()) );
86 autostart = cg.readEntry(
"autostart", autostart );
88 QVariant p = service->property(
"X-KDE-Nepomuk-start-on-demand", QVariant::Bool );
89 startOnDemand = ( p.isValid() ? p.toBool() : false );
91 p = service->property(
"X-KDE-Nepomuk-run-once", QVariant::Bool );
92 runOnce = ( p.isValid() ? p.toBool() : false );
98 void Nepomuk2::ServiceController::Private::reset()
103 currentState = ServiceController::StateStopped;
104 failedToInitialize =
false;
105 delete serviceControlInterface;
106 serviceControlInterface = 0;
116 d->dbusServiceWatcher =
new QDBusServiceWatcher( dbusServiceName(
name()),
117 QDBusConnection::sessionBus(),
118 QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration,
120 connect( d->dbusServiceWatcher, SIGNAL( serviceRegistered( QString ) ),
121 this, SLOT( slotServiceRegistered( QString ) ) );
122 connect( d->dbusServiceWatcher, SIGNAL( serviceUnregistered( QString ) ),
123 this, SLOT( slotServiceUnregistered( QString ) ) );
141 return d->service->desktopEntryName();
147 QStringList deps = d->service->property(
"X-KDE-Nepomuk-dependencies", QVariant::StringList ).toStringList();
148 if ( deps.isEmpty() ) {
149 deps.append(
"nepomukstorage" );
151 deps.removeAll( name() );
158 KConfigGroup cg(
Server::self()->config(), QString(
"Service-%1").arg(name()) );
159 cg.writeEntry(
"autostart", enable );
171 return d->startOnDemand;
183 if( d->currentState == StateStopped ) {
189 if( QDBusConnection::sessionBus().interface()->isServiceRegistered( dbusServiceName( name() ) ) ) {
190 kDebug() <<
"Attaching to already running service" << name();
192 d->currentState = StateRunning;
193 createServiceControlInterface();
196 kDebug() <<
"Starting" << name();
198 d->currentState = StateStarting;
200 if( !d->processControl ) {
202 connect( d->processControl, SIGNAL( finished(
bool ) ),
203 this, SLOT( slotProcessFinished(
bool ) ) );
207 QString exec = d->service->exec();
208 if( exec.isEmpty() ) {
209 d->processControl->start( KStandardDirs::findExe(
"nepomukservicestub" ),
210 QStringList() << name(),
214 d->processControl->start( KStandardDirs::findExe( exec ),
225 if( d->currentState == StateRunning ||
226 d->currentState == StateStarting ) {
227 kDebug() <<
"Stopping" << name();
231 d->currentState = StateStopping;
233 if ( d->serviceControlInterface ) {
234 d->serviceControlInterface->shutdown();
236 else if( d->processControl ) {
239 d->processControl->waitForStarted();
241 d->processControl->terminate();
244 kDebug() <<
"Cannot shut down service process.";
252 return( d->attached || ( d->processControl ? d->processControl->isRunning() : false ) );
258 return d->initialized;
262 void Nepomuk2::ServiceController::slotProcessFinished(
bool )
264 kDebug() <<
"Service" << name() <<
"went down";
266 emit serviceStopped(
this );
270 void Nepomuk2::ServiceController::slotServiceRegistered(
const QString& serviceName )
272 if( serviceName == dbusServiceName( name() ) ) {
273 d->currentState = StateRunning;
274 kDebug() << serviceName;
275 if( !d->processControl || !d->processControl->isRunning() ) {
278 createServiceControlInterface();
282 void Nepomuk2::ServiceController::slotServiceUnregistered(
const QString& serviceName )
287 if( serviceName == dbusServiceName( name() ) ) {
289 emit serviceStopped(
this );
291 kDebug() <<
"Attached service" << name() <<
"went down. Restarting ourselves.";
302 void Nepomuk2::ServiceController::createServiceControlInterface()
304 if(!d->attached && !d->started)
307 delete d->serviceControlInterface;
308 d->serviceControlInterface =
new OrgKdeNepomukServiceControlInterface( dbusServiceName( name() ),
309 QLatin1String(
"/servicecontrol"),
310 QDBusConnection::sessionBus(),
312 QDBusPendingCallWatcher* isInitializedWatcher =
new QDBusPendingCallWatcher(d->serviceControlInterface->isInitialized(),
314 connect(isInitializedWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
315 this, SLOT(slotIsInitializedDBusCallFinished(QDBusPendingCallWatcher*)));
319 void Nepomuk2::ServiceController::slotServiceInitialized(
bool success )
321 if ( !d->initialized ) {
323 kDebug() <<
"Service" << name() <<
"initialized";
324 d->initialized =
true;
325 emit serviceInitialized(
this );
329 KConfigGroup cg(
Server::self()->config(), QString(
"Service-%1").arg(name()) );
330 cg.writeEntry(
"autostart",
false );
334 d->failedToInitialize =
true;
335 kDebug() <<
"Failed to initialize service" << name();
345 return d->currentState;
348 void Nepomuk2::ServiceController::slotIsInitializedDBusCallFinished(QDBusPendingCallWatcher *watcher)
350 QDBusPendingReply<bool> isInitializedReply = *watcher;
351 if( isInitializedReply.isError() ) {
352 delete d->serviceControlInterface;
353 d->serviceControlInterface = 0;
354 kDebug() <<
"Failed to check service init state for" << name() <<
"Retrying.";
355 QMetaObject::invokeMethod(
this,
"createServiceControlInterface", Qt::QueuedConnection );
358 if( isInitializedReply.value() ) {
359 slotServiceInitialized(
true );
362 kDebug() <<
"Service" << name() <<
"not initialized yet. Listening for signal.";
363 connect( d->serviceControlInterface, SIGNAL( serviceInitialized(
bool ) ),
364 this, SLOT( slotServiceInitialized(
bool ) ),
365 Qt::QueuedConnection );
369 watcher->deleteLater();
372 #include "servicecontroller.moc"
QStringList dependencies() const
All the service's direct dependencies.
void setAutostart(bool enable)
KService::Ptr service() const
bool startOnDemand() const
bool isInitialized() const
QString name() const
The name of the service.
void start()
Make sure the service is running.
ServiceController(KService::Ptr service, QObject *parent)
This class starts and observes a process.