Success page added
[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 "accountsettingspage.h"
26 #include "generic-account-setup-context.h"
27 #include "provider-plugin-process-priv.h"
28
29 #include <Accounts/Account>
30 #include <Accounts/Manager>
31 #include <MComponentCache>
32 #include <MApplication>
33 #include <MApplicationIfProxy>
34 #include <MApplicationWindow>
35
36 #include <QDebug>
37
38 namespace AccountsUI {
39
40 static ProviderPluginProcess *plugin_instance = 0;
41
42 void ProviderPluginProcessPrivate::printAccountId()
43 {
44     Accounts::Account *account = context()->account();
45
46     QFile output;
47     output.open(STDOUT_FILENO, QIODevice::WriteOnly);
48     QByteArray ba = QString("%1 %2").arg(account->id()).arg(QString::number(returnToApp)).toAscii();
49     output.write(ba.constData());
50     output.close();
51 }
52
53 AbstractAccountSetupContext *ProviderPluginProcessPrivate::context() const
54 {
55     if (!m_context) {
56         m_context = q_ptr->accountSetupContext(account, setupType, q_ptr);
57         m_context->setServiceType(serviceType);
58     }
59     return m_context;
60 }
61
62 void ProviderPluginProcessPrivate::serviceEnabled(Accounts::Service *service)
63 {
64     qDebug() << Q_FUNC_INFO << service->name();
65
66     QDomElement root = service->domDocument().documentElement();
67     QDomElement handler = root.firstChildElement("handler");
68     if (!handler.isNull()) {
69         QString type = handler.attribute("type");
70         if (type == "command") {
71             /* Syntax for the service file:
72              *
73              *   <handler type="command">/usr/bin/appname [args]...</handler>
74              */
75             QString command = handler.text();
76             qDebug() << "Executing" << command;
77
78             /* The account plugin process is going to die very soon; the
79              * handler must be started as a detached process, for it to
80              * continue to live. */
81             bool ok = QProcess::startDetached(command);
82             if (!ok)
83                 qWarning() << "Could not execute:" << command;
84         }
85         /* support more types (e.g., D-Bus services) here */
86     }
87 }
88
89 void ProviderPluginProcessPrivate::accountSaved()
90 {
91     qDebug() << Q_FUNC_INFO;
92
93     account->selectService();
94     if (account->enabled()) {
95         /* Go through the enabled services and run the activation command, if
96          * present */
97         foreach (Accounts::Service *service, account->services()) {
98             account->selectService(service);
99             if (account->enabled() && !enabledServices.contains(service))
100                 serviceEnabled(service);
101         }
102     }
103 }
104
105 void ProviderPluginProcessPrivate::monitorServices()
106 {
107     connect(account, SIGNAL(synced()), this, SLOT(accountSaved()));
108
109     /* If we are editing an account, get the list of services initially
110      * enabled, to avoid starting up their handlers for no reason */
111     account->selectService();
112     if (setupType == EditExisting && account->enabled()) {
113         foreach (Accounts::Service *service, account->services()) {
114             account->selectService(service);
115             if (account->enabled())
116                 enabledServices.append(service);
117         }
118     }
119 }
120
121 ProviderPluginProcess::ProviderPluginProcess(AccountPluginInterface *plugin,
122                                              int &argc, char **argv)
123     : d_ptr(new ProviderPluginProcessPrivate(plugin, argc, argv))
124 {
125     Q_D(ProviderPluginProcess);
126     init(argc, argv);
127     d->m_context = plugin->accountSetupContext(d->account, d->setupType, this);
128     d->m_context->setServiceType(d->serviceType);
129 }
130
131 ProviderPluginProcess::ProviderPluginProcess(int &argc, char **argv)
132     : d_ptr(new ProviderPluginProcessPrivate(argc, argv))
133 {
134     init(argc, argv);
135 }
136
137 void ProviderPluginProcess::init(int &argc, char **argv)
138 {
139     Q_UNUSED(argc);
140     Q_UNUSED(argv);
141     Q_D(ProviderPluginProcess);
142     d->q_ptr = this;
143     if (plugin_instance != 0)
144         qWarning() << "ProviderPluginProcess already instantiated";
145     plugin_instance = this;
146 }
147
148 ProviderPluginProcess::~ProviderPluginProcess()
149 {
150     Q_D(ProviderPluginProcess);
151
152     delete d;
153 }
154
155 ProviderPluginProcess *ProviderPluginProcess::instance()
156 {
157     return plugin_instance;
158 }
159
160 MApplicationPage * ProviderPluginProcess::mainPage()
161 {
162     Q_D(ProviderPluginProcess);
163     AbstractAccountSetupContext *context = d->context();
164
165     if (context->setupType() == CreateNew)
166         return new AddAccountPage(context, d->serviceType);
167
168     if (context->setupType() == EditExisting)
169         return new AccountSettingsPage(context);
170
171     /* we should never come to this point */
172     Q_ASSERT(false);
173     return 0;
174 }
175
176 int ProviderPluginProcess::exec()
177 {
178     Q_D(ProviderPluginProcess);
179
180     /* if we the account is invalid (either because it does not exists or
181      * couldn't be loaded because of some DB error), return immediately */
182     if (d->account == 0) {
183         qWarning() << Q_FUNC_INFO << "account() is NULL";
184         return 1;
185     }
186
187     d->window->show();
188     MApplicationPage *page = mainPage();
189
190     if (page == 0) {
191         qWarning() << Q_FUNC_INFO << "The mainPage() returned 0";
192         return 1;
193     }
194
195     page->appear(d->window);
196
197     return d->application->exec();
198 }
199
200 void ProviderPluginProcess::quit()
201 {
202     Q_D(ProviderPluginProcess);
203
204     if (d->windowId != 0)
205     {
206         MApplicationIfProxy mApplicationIfProxy("com.nokia.accounts-ui",
207                 this);
208
209         if (mApplicationIfProxy.connection().isConnected()) {
210             mApplicationIfProxy.launch();
211         }
212     }
213
214     d->printAccountId();
215
216     QCoreApplication::exit(0);
217 }
218
219 AbstractAccountSetupContext *ProviderPluginProcess::setupContext() const
220 {
221     Q_D(const ProviderPluginProcess);
222     return d->context();
223 }
224
225 AbstractAccountSetupContext *ProviderPluginProcess::accountSetupContext(
226             Accounts::Account *account,
227             SetupType type,
228             QObject *parent)
229 {
230     return new GenericAccountSetupContext(account, type, parent);
231 }
232
233 void ProviderPluginProcess::setReturnToApp(bool returnToApp)
234 {
235     Q_D(ProviderPluginProcess);
236     d->returnToApp = returnToApp;
237 }
238 } // namespace