20 #include "servermanager.h"
21 #include "servermanager_p.h"
23 #include "agenttype.h"
24 #include "agentbase.h"
25 #include "agentmanager.h"
26 #include "dbusconnectionpool.h"
28 #include "selftestdialog_p.h"
30 #include "session_p.h"
31 #include "firstrun_p.h"
40 #include <boost/scoped_ptr.hpp>
42 #define AKONADI_CONTROL_SERVICE QLatin1String( "org.freedesktop.Akonadi.Control" )
43 #define AKONADI_SERVER_SERVICE QLatin1String( "org.freedesktop.Akonadi" )
45 using namespace Akonadi;
47 class Akonadi::ServerManagerPrivate
50 ServerManagerPrivate() :
51 instance( new ServerManager( this ) ),
52 mState( ServerManager::NotRunning ),
53 mSafetyTimer( new QTimer ),
56 mState = instance->state();
57 mSafetyTimer->setSingleShot(
true );
58 mSafetyTimer->setInterval( 30000 );
59 QObject::connect( mSafetyTimer.get(), SIGNAL(timeout()), instance, SLOT(timeout()) );
60 KGlobal::locale()->insertCatalog( QString::fromLatin1(
"libakonadi" ) );
61 if ( mState == ServerManager::Running && Internal::clientType() == Internal::User )
62 mFirstRunner =
new Firstrun( instance );
65 ~ServerManagerPrivate()
70 void serviceOwnerChanged(
const QString&,
const QString&,
const QString& )
72 serverProtocolVersion = -1,
76 void checkStatusChanged()
78 setState( instance->state() );
81 void setState( ServerManager::State state )
84 if ( mState != state ) {
86 emit instance->stateChanged( state );
87 if ( state == ServerManager::Running ) {
88 emit instance->started();
89 if ( !mFirstRunner && Internal::clientType() == Internal::User )
90 mFirstRunner =
new Firstrun( instance );
91 }
else if ( state == ServerManager::NotRunning || state == ServerManager::Broken ) {
92 emit instance->stopped();
95 if ( state == ServerManager::Starting || state == ServerManager::Stopping )
96 QMetaObject::invokeMethod( mSafetyTimer.get(),
"start", Qt::QueuedConnection );
98 QMetaObject::invokeMethod( mSafetyTimer.get(),
"stop", Qt::QueuedConnection );
104 if ( mState == ServerManager::Starting || mState == ServerManager::Stopping )
105 setState( ServerManager::Broken );
108 ServerManager *instance;
109 static int serverProtocolVersion;
110 ServerManager::State mState;
111 boost::scoped_ptr<QTimer> mSafetyTimer;
112 Firstrun *mFirstRunner;
113 static Internal::ClientType clientType;
116 int ServerManagerPrivate::serverProtocolVersion = -1;
117 Internal::ClientType ServerManagerPrivate::clientType = Internal::User;
119 K_GLOBAL_STATIC( ServerManagerPrivate, sInstance )
121 ServerManager::ServerManager(ServerManagerPrivate * dd ) :
124 qRegisterMetaType<Akonadi::ServerManager::State>();
126 QDBusServiceWatcher *watcher =
new QDBusServiceWatcher( AKONADI_SERVER_SERVICE,
127 DBusConnectionPool::threadConnection(),
128 QDBusServiceWatcher::WatchForOwnerChange,
this );
129 watcher->addWatchedService( AKONADI_CONTROL_SERVICE );
135 connect( watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
136 this, SLOT(serviceOwnerChanged(QString,QString,QString)), Qt::QueuedConnection );
139 if ( Internal::clientType() != Internal::User )
147 return sInstance->instance;
150 bool ServerManager::start()
152 const bool controlRegistered = DBusConnectionPool::threadConnection().interface()->isServiceRegistered( AKONADI_CONTROL_SERVICE );
153 const bool serverRegistered = DBusConnectionPool::threadConnection().interface()->isServiceRegistered( AKONADI_SERVER_SERVICE );
154 if ( controlRegistered && serverRegistered )
158 const bool controlLockRegistered = DBusConnectionPool::threadConnection().interface()->isServiceRegistered( AKONADI_CONTROL_SERVICE + QLatin1String(
".lock" ) );
159 if ( controlLockRegistered || controlRegistered ) {
160 kDebug() <<
"Akonadi server is already starting up";
161 sInstance->setState( Starting );
165 kDebug() <<
"executing akonadi_control";
166 const bool ok = QProcess::startDetached( QLatin1String(
"akonadi_control" ) );
168 kWarning() <<
"Unable to execute akonadi_control, falling back to D-Bus auto-launch";
169 QDBusReply<void> reply = DBusConnectionPool::threadConnection().interface()->startService( AKONADI_CONTROL_SERVICE );
170 if ( !reply.isValid() ) {
171 kDebug() <<
"Akonadi server could not be started via D-Bus either: "
172 << reply.error().message();
176 sInstance->setState( Starting );
180 bool ServerManager::stop()
182 QDBusInterface iface( AKONADI_CONTROL_SERVICE,
183 QString::fromLatin1(
"/ControlManager" ),
184 QString::fromLatin1(
"org.freedesktop.Akonadi.ControlManager" ) );
185 if ( !iface.isValid() )
187 iface.call( QDBus::NoBlock, QString::fromLatin1(
"shutdown" ) );
188 sInstance->setState( Stopping );
192 void ServerManager::showSelfTestDialog( QWidget *parent )
195 Akonadi::SelfTestDialog dlg( parent );
196 dlg.hideIntroduction();
201 bool ServerManager::isRunning()
203 return state() == Running;
209 if ( sInstance.exists() )
210 previousState = sInstance->mState;
212 const bool controlRegistered = DBusConnectionPool::threadConnection().interface()->isServiceRegistered( AKONADI_CONTROL_SERVICE );
213 const bool serverRegistered = DBusConnectionPool::threadConnection().interface()->isServiceRegistered( AKONADI_SERVER_SERVICE );
214 if ( controlRegistered && serverRegistered ) {
216 if ( sInstance.exists() ) {
217 if ( Internal::serverProtocolVersion() >= 0 &&
218 Internal::serverProtocolVersion() < SessionPrivate::minimumProtocolVersion() )
223 if ( Internal::clientType() == Internal::User ) {
226 foreach (
const AgentType &type, agentTypes ) {
227 if ( type.
capabilities().contains( QLatin1String(
"Resource" ) ) )
237 const bool controlLockRegistered = DBusConnectionPool::threadConnection().interface()->isServiceRegistered( AKONADI_CONTROL_SERVICE + QLatin1String(
".lock" ) );
238 if ( controlLockRegistered || controlRegistered ) {
239 kDebug() <<
"Akonadi server is already starting up";
240 if ( previousState == Running )
242 return previousState;
245 if ( serverRegistered ) {
246 kWarning() <<
"Akonadi server running without control process!";
250 if ( previousState == Starting || previousState == Broken )
251 return previousState;
255 int Internal::serverProtocolVersion()
257 return ServerManagerPrivate::serverProtocolVersion;
260 void Internal::setServerProtocolVersion(
int version )
262 ServerManagerPrivate::serverProtocolVersion = version;
263 if ( sInstance.exists() )
264 sInstance->checkStatusChanged();
267 Internal::ClientType Internal::clientType()
269 return ServerManagerPrivate::clientType;
272 void Internal::setClientType( ClientType type )
274 ServerManagerPrivate::clientType = type;
277 #include "servermanager.moc"