• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

akonadi

servermanager.cpp

00001 /*
00002     Copyright (c) 2008 Volker Krause <vkrause@kde.org>
00003 
00004     This library is free software; you can redistribute it and/or modify it
00005     under the terms of the GNU Library General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or (at your
00007     option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful, but WITHOUT
00010     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00011     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00012     License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to the
00016     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017     02110-1301, USA.
00018 */
00019 
00020 #include "servermanager.h"
00021 #include "servermanager_p.h"
00022 
00023 #include "agenttype.h"
00024 #include "agentbase.h"
00025 #include "agentmanager.h"
00026 #include "selftestdialog_p.h"
00027 #include "session_p.h"
00028 
00029 #include <KDebug>
00030 #include <KGlobal>
00031 
00032 #include <QtDBus>
00033 
00034 #define AKONADI_CONTROL_SERVICE QLatin1String("org.freedesktop.Akonadi.Control")
00035 #define AKONADI_SERVER_SERVICE QLatin1String("org.freedesktop.Akonadi")
00036 
00037 using namespace Akonadi;
00038 
00039 class Akonadi::ServerManagerPrivate
00040 {
00041   public:
00042     ServerManagerPrivate() :
00043       instance( new ServerManager( this ) )
00044     {
00045       operational = instance->isRunning();
00046     }
00047 
00048     ~ServerManagerPrivate()
00049     {
00050       delete instance;
00051     }
00052 
00053     void serviceOwnerChanged( const QString &service, const QString &oldOwner, const QString &newOwner )
00054     {
00055       Q_UNUSED( oldOwner );
00056       Q_UNUSED( newOwner );
00057       if ( service != AKONADI_SERVER_SERVICE && service != AKONADI_CONTROL_SERVICE )
00058         return;
00059       serverProtocolVersion = -1,
00060       checkStatusChanged();
00061     }
00062 
00063     void checkStatusChanged()
00064     {
00065       const bool status = instance->isRunning();
00066       if ( status == operational )
00067         return;
00068       operational = status;
00069       if ( operational )
00070         emit instance->started();
00071       else
00072         emit instance->stopped();
00073     }
00074 
00075     ServerManager *instance;
00076     static int serverProtocolVersion;
00077     bool operational;
00078 };
00079 
00080 int ServerManagerPrivate::serverProtocolVersion = -1;
00081 
00082 K_GLOBAL_STATIC( ServerManagerPrivate, sInstance )
00083 
00084 ServerManager::ServerManager(ServerManagerPrivate * dd ) :
00085     d( dd )
00086 {
00087   connect( QDBusConnection::sessionBus().interface(),
00088            SIGNAL(serviceOwnerChanged(QString,QString,QString)),
00089            SLOT(serviceOwnerChanged(QString,QString,QString)) );
00090 
00091   // HACK see if we are a agent ourselves and skip AgentManager creation since that can cause deadlocks
00092   QObject *obj = QDBusConnection::sessionBus().objectRegisteredAt( QLatin1String("/") );
00093   if ( obj && dynamic_cast<AgentBase*>( obj ) )
00094     return;
00095   connect( AgentManager::self(), SIGNAL(typeAdded(Akonadi::AgentType)), SLOT(checkStatusChanged()) );
00096   connect( AgentManager::self(), SIGNAL(typeRemoved(Akonadi::AgentType)), SLOT(checkStatusChanged()) );
00097 }
00098 
00099 ServerManager * Akonadi::ServerManager::self()
00100 {
00101   return sInstance->instance;
00102 }
00103 
00104 bool ServerManager::start()
00105 {
00106   const bool ok = QProcess::startDetached( QLatin1String("akonadi_control") );
00107   if ( !ok ) {
00108     kWarning() << "Unable to execute akonadi_control, falling back to D-Bus auto-launch";
00109     QDBusReply<void> reply = QDBusConnection::sessionBus().interface()->startService( AKONADI_CONTROL_SERVICE );
00110     if ( !reply.isValid() ) {
00111       kDebug() << "Akonadi server could not be started via D-Bus either: "
00112                << reply.error().message();
00113       return false;
00114     }
00115   }
00116   return true;
00117 }
00118 
00119 bool ServerManager::stop()
00120 {
00121   QDBusInterface iface( AKONADI_CONTROL_SERVICE,
00122                         QString::fromLatin1("/ControlManager"),
00123                         QString::fromLatin1("org.freedesktop.Akonadi.ControlManager") );
00124   if ( !iface.isValid() )
00125     return false;
00126   iface.call( QDBus::NoBlock, QString::fromLatin1("shutdown") );
00127   return true;
00128 }
00129 
00130 void ServerManager::showSelfTestDialog( QWidget *parent )
00131 {
00132   Akonadi::SelfTestDialog dlg( parent );
00133   dlg.hideIntroduction();
00134   dlg.exec();
00135 }
00136 
00137 bool ServerManager::isRunning()
00138 {
00139   if ( !QDBusConnection::sessionBus().interface()->isServiceRegistered( AKONADI_CONTROL_SERVICE ) ||
00140        !QDBusConnection::sessionBus().interface()->isServiceRegistered( AKONADI_SERVER_SERVICE ) ) {
00141     return false;
00142   }
00143 
00144   // check if the server protocol is recent enough
00145   if ( sInstance.exists() ) {
00146     if ( Internal::serverProtocolVersion() >= 0 &&
00147          Internal::serverProtocolVersion() < SessionPrivate::minimumProtocolVersion() )
00148       return false;
00149   }
00150 
00151   // HACK see if we are a agent ourselves and skip the test below which can in some cases deadlock the server
00152   // and is not really needed in this case anyway since we happen to know at least one agent is available
00153   QObject *obj = QDBusConnection::sessionBus().objectRegisteredAt( QLatin1String("/") );
00154   if ( obj && dynamic_cast<AgentBase*>( obj ) )
00155     return true;
00156 
00157   // besides the running server processes we also need at least one resource to be operational
00158   AgentType::List agentTypes = AgentManager::self()->types();
00159   foreach ( const AgentType &type, agentTypes ) {
00160     if ( type.capabilities().contains( QLatin1String("Resource") ) )
00161       return true;
00162   }
00163   return false;
00164 }
00165 
00166 int Internal::serverProtocolVersion()
00167 {
00168   return ServerManagerPrivate::serverProtocolVersion;
00169 }
00170 
00171 void Internal::setServerProtocolVersion( int version )
00172 {
00173   ServerManagerPrivate::serverProtocolVersion = version;
00174   if ( sInstance.exists() )
00175     sInstance->checkStatusChanged();
00176 }
00177 
00178 #include "servermanager.moc"

akonadi

Skip menu "akonadi"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.6.2-20100208
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal