• Skip to content
  • Skip to link menu
KDE 4.2 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   QDBusReply<void> reply = QDBusConnection::sessionBus().interface()->startService( AKONADI_CONTROL_SERVICE );
00107   if ( !reply.isValid() ) {
00108     kDebug( 5250 ) << "Unable to start Akonadi control process: "
00109                      << reply.error().message();
00110 
00111     // start via D-Bus .service file didn't work, let's try starting the process manually
00112     if ( reply.error().type() == QDBusError::ServiceUnknown ) {
00113       const bool ok = QProcess::startDetached( QLatin1String("akonadi_control") );
00114       if ( !ok ) {
00115         kWarning( 5250 ) << "Error: unable to execute binary akonadi_control";
00116         return false;
00117       }
00118     } else {
00119       return false;
00120     }
00121   }
00122 
00123   return true;
00124 }
00125 
00126 bool ServerManager::stop()
00127 {
00128   QDBusInterface iface( AKONADI_CONTROL_SERVICE, "/ControlManager", "org.freedesktop.Akonadi.ControlManager" );
00129   if ( !iface.isValid() )
00130     return false;
00131   iface.call( QDBus::NoBlock, "shutdown" );
00132   return true;
00133 }
00134 
00135 void ServerManager::showSelfTestDialog( QWidget *parent )
00136 {
00137   Akonadi::SelfTestDialog dlg( parent );
00138   dlg.hideIntroduction();
00139   dlg.exec();
00140 }
00141 
00142 bool ServerManager::isRunning()
00143 {
00144   if ( !QDBusConnection::sessionBus().interface()->isServiceRegistered( AKONADI_CONTROL_SERVICE ) ||
00145        !QDBusConnection::sessionBus().interface()->isServiceRegistered( AKONADI_SERVER_SERVICE ) ) {
00146     return false;
00147   }
00148 
00149   // check if the server protocol is recent enough
00150   if ( sInstance.exists() ) {
00151     if ( Internal::serverProtocolVersion() >= 0 &&
00152          Internal::serverProtocolVersion() < SessionPrivate::minimumProtocolVersion() )
00153       return false;
00154   }
00155 
00156   // HACK see if we are a agent ourselves and skip the test below which can in some cases deadlock the server
00157   // and is not really needed in this case anyway since we happen to know at least one agent is available
00158   QObject *obj = QDBusConnection::sessionBus().objectRegisteredAt( QLatin1String("/") );
00159   if ( obj && dynamic_cast<AgentBase*>( obj ) )
00160     return true;
00161 
00162   // besides the running server processes we also need at least one resource to be operational
00163   AgentType::List agentTypes = AgentManager::self()->types();
00164   foreach ( const AgentType &type, agentTypes ) {
00165     if ( type.capabilities().contains( "Resource" ) )
00166       return true;
00167   }
00168   return false;
00169 }
00170 
00171 int Internal::serverProtocolVersion()
00172 {
00173   return ServerManagerPrivate::serverProtocolVersion;
00174 }
00175 
00176 void Internal::setServerProtocolVersion( int version )
00177 {
00178   ServerManagerPrivate::serverProtocolVersion = version;
00179   if ( sInstance.exists() )
00180     sInstance->checkStatusChanged();
00181 }
00182 
00183 #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
  • kabc
  • kblog
  • kcal
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.8
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