24#include "provider-plugin-proxy.h"
25#include "provider-plugin-proxy-priv.h"
27#include <Accounts/Manager>
30#include <QLocalServer>
31#include <QLocalSocket>
33using namespace Accounts;
37ProviderPluginProxyPrivate::~ProviderPluginProxyPrivate()
39 qDebug() << Q_FUNC_INFO;
41 process->disconnect();
47void ProviderPluginProxyPrivate::startProcess(Provider provider,
49 const QString &serviceType)
53 error = ProviderPluginProxy::NoError;
58 QString pluginFileName;
60 if (!findPlugin(provider, processName, pluginFileName)) {
61 error = ProviderPluginProxy::PluginNotFound;
65 providerName = provider.name();
67 socketName = provider.name() + QString::number(pid);
69 QStringList arguments;
70 arguments << QLatin1String(
"--socketName") << socketName;
72 if (parentWidget != 0) {
73 WId windowId = parentWidget->effectiveWinId();
74 arguments << QLatin1String(
"--windowId") << QString::number(windowId);
78 arguments << QLatin1String(
"--edit") << QString::number(accountId);
79 setupType = EditExisting;
81 arguments << QLatin1String(
"--create") << provider.name();
82 setupType = CreateNew;
85 if (!serviceType.isEmpty())
86 arguments << QLatin1String(
"--serviceType") << serviceType;
88 arguments += additionalParameters;
90#ifndef QT_NO_DEBUG_OUTPUT
91 arguments << QLatin1String(
"-output-level") << QLatin1String(
"debug");
95 process =
new QProcess();
97 pluginName = pluginFileName;
99 qDebug() << Q_FUNC_INFO << processName << arguments;
101 connect(process, SIGNAL(readyReadStandardError()),
102 this, SLOT(onReadStandardError()));
103 connect(process, SIGNAL(error(QProcess::ProcessError)),
104 this, SLOT(onError(QProcess::ProcessError)));
105 connect(process, SIGNAL(finished(
int, QProcess::ExitStatus)),
106 this, SLOT(onFinished(
int, QProcess::ExitStatus)));
107 connect(process, SIGNAL(started()),
this, SLOT(setCommunicationChannel()));
109 process->start(processName, arguments);
112bool ProviderPluginProxyPrivate::findPlugin(Provider provider,
114 QString &pluginFileName)
116 static const char pluginNamePattern[] =
"%1plugin";
117 bool pluginTagExists =
true;
119 QDomElement root(provider.domDocument().documentElement());
120 QString pluginName(root.
121 firstChildElement(QString::fromLatin1(
"plugin")).
123 if (pluginName.isEmpty()) {
124 pluginName = provider.name();
125 pluginTagExists =
false;
128 QStringList pluginFileNames;
129 pluginFileNames << QString::fromLatin1(pluginNamePattern).arg(pluginName);
135 if (!pluginTagExists) {
136 pluginFileNames << QString::fromLatin1(pluginNamePattern).
137 arg(QLatin1String(
"generic"));
140 foreach (QString name, pluginFileNames) {
141 foreach (QString pluginDir, pluginDirs) {
142 QFileInfo pluginFileInfo(pluginDir, name);
144 if (pluginFileInfo.exists()) {
145 pluginPath = pluginFileInfo.canonicalFilePath();
146 pluginFileName = name;
155void ProviderPluginProxyPrivate::setCommunicationChannel()
157 QLocalServer *server =
new QLocalServer();
158 QLocalServer::removeServer(socketName);
159 if (!server->listen(socketName))
160 qWarning() <<
"Server not up";
162 connect(server, SIGNAL(newConnection()),
this, SLOT(onNewConnection()));
165void ProviderPluginProxyPrivate::onNewConnection()
167 QLocalServer *server = qobject_cast<QLocalServer*>(sender());
168 QLocalSocket *socket = server->nextPendingConnection();
169 if (!socket->waitForConnected()) {
170 qWarning() <<
"Server Connection not established";
173 if (!socket->waitForReadyRead()) {
174 qWarning() <<
"Server data not available for reading";
177 pluginOutput = socket->readAll();
182void ProviderPluginProxyPrivate::onReadStandardError()
184 qDebug() << QString::fromLatin1(process->readAllStandardError());
187void ProviderPluginProxyPrivate::onError(QProcess::ProcessError err)
191 if (err == QProcess::FailedToStart) {
193 error = ProviderPluginProxy::PluginCrashed;
197 process->deleteLater();
202 qDebug() <<
"Error: " << err;
205void ProviderPluginProxyPrivate::onFinished(
int exitCode,
206 QProcess::ExitStatus exitStatus)
213 if (exitStatus == QProcess::CrashExit) {
214 error = ProviderPluginProxy::PluginCrashed;
216 process->deleteLater();
222 if (!pluginOutput.isEmpty()) {
223 QDataStream stream(pluginOutput);
224 stream.device()->seek(0);
225 stream >> createdAccountId >> exitData;
229 process->deleteLater();
238 d_ptr(new ProviderPluginProxyPrivate(this))
242ProviderPluginProxy::~ProviderPluginProxy()
249 const QString &serviceType)
253 if (!provider.isValid()) {
254 qCritical() <<
" NULL pointer to provider";
255 d->error = ProviderPluginProxy::PluginNotFound;
260 d->startProcess(provider, 0, serviceType);
264 const QString &serviceType)
269 qCritical() <<
" NULL pointer to account";
270 d->error = ProviderPluginProxy::AccountNotFound;
275 Manager *manager = account->manager();
276 Provider provider = manager->provider(account->providerName());
277 d->startProcess(provider, account->id(), serviceType);
283 d->parentWidget = parent;
289 d->pluginDirs = pluginDirs;
295 return d->pluginDirs;
301 return d->createdAccountId != 0;
313 return d->createdAccountId;
319 return d->process != 0;
334 return d->pluginName;
342 return d->providerName;
348 d->additionalParameters = parameters;
354 return d->additionalParameters;
364 d->process->disconnect();
Client class for accounts UI plugins.
void setPluginDirectories(const QStringList &pluginDirs)
Set the list of directories which will be searched for provider plugins.
QStringList pluginDirectories() const
Get the list of directories which will be searched for provider plugins.
void createAccount(Accounts::Provider provider, const QString &serviceType)
Runs the account plugin to create an account.
void setParentWidget(QWidget *parent)
Attempt to set the next executed account plugin modal to a given widget.
Error
Error codes for plugin execution.
ProviderPluginProxy(QObject *parent=0)
Constructor.
void finished()
Emitted when the plugin execution has been completed.
void editAccount(Accounts::Account *account, const QString &serviceType)
Runs the account plugin to edit an account.
SetupType setupType() const
Returns the operation being performed by the plugin.
void setAdditionalParameters(const QStringList ¶meters)
Sets additional parameters to be passed to the plugin process on the next invocation of createAccount...
bool killRunningPlugin()
Kills the plugin being executed.
Error error() const
Gets the error code of the last plugin execution.
Accounts::AccountId createdAccountId() const
Gets the ID of the newly created account.
bool accountCreated() const
Checks whether an account was created by the plugin executed last.
bool isPluginRunning()
Checks whether a plugin is running.
QStringList additionalParameters() const
Gets the list of additional parameters passed to the plugin process.