Fixing: 265994 - <coverity> defects from libaccounts-ui/0.141-1_0m6
[accounts-sso:libaccounts-ui.git] / lib / AccountsUI / provider-plugin-process.cpp
1 /*
2  * This file is part of accounts-ui
3  *
4  * Copyright (C) 2009-2010 Nokia Corporation.
5  *
6  * Contact: Alberto Mardegan <alberto.mardegan@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * version 2.1 as published by the Free Software Foundation.
11  *
12  * This library is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  */
22
23 #include "provider-plugin-process.h"
24 #include "add-account-page.h"
25 #include "account-settings-page.h"
26 #include "generic-account-setup-context.h"
27 #include "provider-plugin-process-priv.h"
28 #include "accountsmanagersingleton.h"
29
30 #include <Accounts/Account>
31 #include <Accounts/Manager>
32
33 #include <MComponentCache>
34 #include <MApplication>
35 #include <MApplicationWindow>
36
37 #include <QDebug>
38 #include <QFile>
39 #include <QLocalSocket>
40 #include <QProcess>
41 #include <QTimer>
42 namespace AccountsUI {
43
44 static ProviderPluginProcess *plugin_instance = 0;
45
46 AbstractAccountSetupContext *ProviderPluginProcessPrivate::context() const
47 {
48     if (!m_context) {
49         SetupType setupType;
50         switch (wrapped->setupType()) {
51         case AccountSetup::CreateNew:
52             setupType = CreateNew;
53             break;
54         case AccountSetup::EditExisting:
55             setupType = EditExisting;
56             break;
57         default:
58             qWarning() << "Setup type not recognized:" << wrapped->setupType();
59             return 0;
60         }
61
62         m_context = q_ptr->accountSetupContext(account, setupType, q_ptr);
63         m_context->setServiceType(wrapped->serviceType());
64     }
65     return m_context;
66 }
67
68 void ProviderPluginProcessPrivate::executeCommandFromXML(const QDomDocument
69                                                          &document)
70 {
71     QDomElement root = document.documentElement();
72     QDomElement handler = root.firstChildElement("handler");
73     if (!handler.isNull()) {
74         QString type = handler.attribute("type");
75         if (type == "command") {
76             /* Syntax for the service file:
77              *
78              *   <handler type="command">/usr/bin/appname [args]...</handler>
79              */
80             QString command = handler.text();
81             qDebug() << "Executing" << command;
82
83             /* The account plugin process is going to die very soon; the
84              * handler must be started as a detached process, for it to
85              * continue to live. */
86             bool ok = QProcess::startDetached(command);
87             if (!ok)
88                 qWarning() << "Could not execute:" << command;
89         }
90         /* support more types (e.g., D-Bus services) here */
91     }
92 }
93
94 void ProviderPluginProcessPrivate::serviceEnabled(Accounts::Service *service)
95 {
96     qDebug() << Q_FUNC_INFO << service->name();
97
98     executeCommandFromXML(service->domDocument());
99
100     // Commands might be specified in service-type files too
101     Accounts::Manager *manager = account->manager();
102     Accounts::ServiceType *serviceType =
103         manager->serviceType(service->serviceType());
104     if (serviceType != 0)
105         executeCommandFromXML(serviceType->domDocument());
106 }
107
108 void ProviderPluginProcessPrivate::accountSaved()
109 {
110     qDebug() << Q_FUNC_INFO;
111
112     account->selectService();
113     if (account->enabled()) {
114         /* Go through the enabled services and run the activation command, if
115          * present */
116         foreach (Accounts::Service *service, account->services()) {
117             account->selectService(service);
118             if (account->enabled() && !enabledServices.contains(service))
119                 serviceEnabled(service);
120         }
121     }
122 }
123
124 void ProviderPluginProcessPrivate::monitorServices()
125 {
126     connect(account, SIGNAL(synced()), this, SLOT(accountSaved()));
127
128     /* If we are editing an account, get the list of services initially
129      * enabled, to avoid starting up their handlers for no reason */
130     account->selectService();
131     if (wrapped->setupType() == AccountSetup::EditExisting &&
132         account->enabled()) {
133         foreach (Accounts::Service *service, account->services()) {
134             account->selectService(service);
135             if (account->enabled())
136                 enabledServices.append(service);
137         }
138     }
139 }
140
141 ProviderPluginProcess::ProviderPluginProcess(AccountPluginInterface *plugin,
142                                              int &argc, char **argv)
143     : d_ptr(new ProviderPluginProcessPrivate(plugin, argc, argv))
144 {
145     init(argc, argv);
146 }
147
148 ProviderPluginProcess::ProviderPluginProcess(int &argc, char **argv)
149     : d_ptr(new ProviderPluginProcessPrivate(argc, argv))
150 {
151     init(argc, argv);
152 }
153
154 void ProviderPluginProcess::init(int &argc, char **argv)
155 {
156     Q_UNUSED(argc);
157     Q_UNUSED(argv);
158     Q_D(ProviderPluginProcess);
159     d->q_ptr = this;
160     if (plugin_instance != 0)
161         qWarning() << "ProviderPluginProcess already instantiated";
162     plugin_instance = this;
163 }
164
165 ProviderPluginProcess::~ProviderPluginProcess()
166 {
167     Q_D(ProviderPluginProcess);
168     delete d;
169 }
170
171 ProviderPluginProcess *ProviderPluginProcess::instance()
172 {
173     return plugin_instance;
174 }
175
176 MApplicationPage * ProviderPluginProcess::mainPage()
177 {
178     Q_D(ProviderPluginProcess);
179     AbstractAccountSetupContext *context = d->context();
180
181     if (context->setupType() == CreateNew)
182         return new AddAccountPage(context);
183
184     if (context->setupType() == EditExisting)
185         return new AccountSettingsPage(context);
186
187     /* we should never come to this point */
188     Q_ASSERT(false);
189     return 0;
190 }
191
192 int ProviderPluginProcess::exec()
193 {
194     Q_D(ProviderPluginProcess);
195
196     if (!d->validProvider) {
197         qCritical()<< Q_FUNC_INFO << "Not a Valid Provider";
198         return 1;
199     }
200
201     /* if we the account is invalid (either because it does not exists or
202      * couldn't be loaded because of some DB error), return immediately */
203     if (d->account == 0) {
204         qWarning() << Q_FUNC_INFO << "account() is NULL";
205         return 1;
206     }
207
208     d->window->show();
209     MApplicationPage *page = mainPage();
210
211     if (page == 0) {
212         qWarning() << Q_FUNC_INFO << "The mainPage() returned 0";
213         return 1;
214     }
215
216     page->appear(d->window);
217
218     int result = d->application->exec();
219     return result;
220 }
221
222 void ProviderPluginProcess::quit()
223 {
224     Q_D(ProviderPluginProcess);
225     QTimer::singleShot(500, d->wrapped, SLOT(quit()));
226 }
227
228 AbstractAccountSetupContext *ProviderPluginProcess::setupContext() const
229 {
230     Q_D(const ProviderPluginProcess);
231     return d->context();
232 }
233
234 AbstractAccountSetupContext *ProviderPluginProcess::accountSetupContext(
235             Accounts::Account *account,
236             SetupType type,
237             QObject *parent)
238 {
239     return new GenericAccountSetupContext(account, type, parent);
240 }
241
242 void ProviderPluginProcess::setReturnToApp(bool returnToApp)
243 {
244     Q_D(ProviderPluginProcess);
245     d->returnToApp = returnToApp;
246 }
247
248 void ProviderPluginProcess::setReturnToAccountsList(bool value)
249 {
250     Q_D(ProviderPluginProcess);
251     d->wrapped->setReturnToAccountsList(value);
252 }
253
254 void ProviderPluginProcess::setExitData(const QVariant &data)
255 {
256     Q_D(ProviderPluginProcess);
257     d->wrapped->setExitData(data);
258 }
259
260 const LastPageActions &ProviderPluginProcess::lastPageActions() const
261 {
262     Q_D(const ProviderPluginProcess);
263     return d->lastPageActions;
264 }
265
266 bool ProviderPluginProcess::isSetupComplete()
267 {
268     Q_D(const ProviderPluginProcess);
269     return d->accountSetupCompleted;
270 }
271
272 void ProviderPluginProcess::setSetupComplete(bool value)
273 {
274     Q_D(ProviderPluginProcess);
275     d->accountSetupCompleted = value;
276 }
277
278 QString ProviderPluginProcess::translatedProviderName() const
279 {
280     Q_D(const ProviderPluginProcess);
281
282     if (!(d->translatedProviderName .isEmpty()))
283         return d->translatedProviderName;
284
285     QString providerName(d->account->providerName());
286     QString providerIconId;
287     Accounts::Provider *provider =
288             AccountsManager::instance()->provider(providerName);
289
290     if (provider) {
291         providerIconId = provider->iconName();
292         QString catalog = provider->trCatalog();
293         MLocale locale;
294         if (!catalog.isEmpty() && !locale.isInstalledTrCatalog(catalog)) {
295             locale.installTrCatalog(catalog);
296             MLocale::setDefault(locale);
297         }
298
299         d->translatedProviderName = qtTrId(provider->displayName().toLatin1());
300     }
301     if (!(d->translatedProviderName .isEmpty()))
302         return d->translatedProviderName;
303     else if (!providerName.isEmpty())
304         return providerName;
305     else
306         return QString();
307 }
308
309 void ProviderPluginProcess::setEditExistingAccount(Accounts::AccountId accountId)
310 {
311     Q_D(ProviderPluginProcess);
312     d->wrapped->setEditExistingAccount(accountId);
313 }
314
315 } // namespace