Merge lp:~mardy/ubuntu-system-settings-online-accounts/master into lp:ubuntu-system-settings-online-accounts

Proposed by Alberto Mardegan
Status: Merged
Approved by: David Barth
Approved revision: 129
Merged at revision: 154
Proposed branch: lp:~mardy/ubuntu-system-settings-online-accounts/master
Merge into: lp:ubuntu-system-settings-online-accounts
Diff against target: 5466 lines (+3258/-754)
81 files modified
.bzrignore (+10/-8)
client/OnlineAccountsClient/OnlineAccountsClient.pro (+2/-2)
client/OnlineAccountsClient/setup.cpp (+3/-1)
common-project-config.pri (+3/-0)
debian/control (+1/-1)
debian/rules (+1/-0)
debian/ubuntu-system-settings-online-accounts.install (+1/-0)
online-accounts-service/com.ubuntu.OnlineAccountsUi.service.in (+1/-1)
online-accounts-service/main.cpp (+109/-0)
online-accounts-service/mir-helper-stub.cpp (+69/-0)
online-accounts-service/mir-helper.cpp (+192/-0)
online-accounts-service/mir-helper.h (+68/-0)
online-accounts-service/online-accounts-service.pro (+82/-0)
online-accounts-service/request-manager.cpp (+42/-6)
online-accounts-service/request-manager.h (+3/-1)
online-accounts-service/request.cpp (+214/-0)
online-accounts-service/request.h (+70/-0)
online-accounts-service/service.cpp (+3/-11)
online-accounts-service/signonui-service.cpp (+19/-33)
online-accounts-service/ui-proxy.cpp (+301/-0)
online-accounts-service/ui-proxy.h (+54/-0)
online-accounts-ui/application-manager.cpp (+10/-0)
online-accounts-ui/browser-request.cpp (+12/-24)
online-accounts-ui/browser-request.h (+2/-4)
online-accounts-ui/globals.h (+1/-0)
online-accounts-ui/ipc.cpp (+184/-0)
online-accounts-ui/ipc.h (+67/-0)
online-accounts-ui/main.cpp (+18/-68)
online-accounts-ui/module/OAuth.qml (+0/-1)
online-accounts-ui/module/WebView.qml (+1/-2)
online-accounts-ui/module/qmldir.in (+2/-0)
online-accounts-ui/notification.cpp (+8/-0)
online-accounts-ui/notification.h (+1/-0)
online-accounts-ui/online-accounts-ui-helper.pro (+5/-37)
online-accounts-ui/online-accounts-ui.pro (+1/-1)
online-accounts-ui/panel-request.cpp (+6/-7)
online-accounts-ui/panel-request.h (+4/-3)
online-accounts-ui/provider-request.cpp (+4/-3)
online-accounts-ui/provider-request.h (+3/-2)
online-accounts-ui/qml/ProviderRequest.qml (+12/-5)
online-accounts-ui/qml/SignOnUiPage.qml (+40/-0)
online-accounts-ui/request-handler.cpp (+6/-0)
online-accounts-ui/request.cpp (+65/-52)
online-accounts-ui/request.h (+12/-6)
online-accounts-ui/signonui-request.cpp (+114/-56)
online-accounts-ui/signonui-request.h (+6/-6)
online-accounts-ui/ui-server.cpp (+199/-0)
online-accounts-ui/ui-server.h (+57/-0)
online-accounts-ui/ui.qrc (+1/-10)
system-settings-plugin/AccountEditPage.qml (+4/-20)
system-settings-plugin/MainPage.qml (+29/-45)
system-settings-plugin/NewAccountPage.qml (+0/-2)
system-settings-plugin/ProviderPluginList.qml (+16/-12)
system-settings-plugin/online-accounts.settings (+1/-1)
system-settings-plugin/plugin.cpp (+0/-89)
system-settings-plugin/plugin.h (+0/-38)
system-settings-plugin/system-settings-plugin.pro (+16/-29)
tests/client/tst_client.cpp (+1/-1)
tests/client/tst_qml_client.cpp (+1/-1)
tests/online-accounts-service/online-accounts-service.pro (+4/-0)
tests/online-accounts-service/tst_inactivity_timer.pro (+7/-3)
tests/online-accounts-service/tst_service.cpp (+128/-104)
tests/online-accounts-service/tst_service.pro (+14/-11)
tests/online-accounts-ui/data/com.ubuntu.tests_application.application (+19/-0)
tests/online-accounts-ui/mock/notification-mock.cpp (+81/-0)
tests/online-accounts-ui/mock/notification-mock.h (+66/-0)
tests/online-accounts-ui/mock/request-mock.cpp (+139/-0)
tests/online-accounts-ui/mock/request-mock.h (+61/-0)
tests/online-accounts-ui/mock/ui-server-mock.cpp (+68/-0)
tests/online-accounts-ui/mock/ui-server-mock.h (+53/-0)
tests/online-accounts-ui/online-accounts-ui.pri (+18/-0)
tests/online-accounts-ui/online-accounts-ui.pro (+1/-2)
tests/online-accounts-ui/qml/Source/qmldir (+1/-1)
tests/online-accounts-ui/tst_access_model.pro (+8/-15)
tests/online-accounts-ui/tst_application_manager.pro (+8/-15)
tests/online-accounts-ui/tst_notification.cpp (+33/-0)
tests/online-accounts-ui/tst_notification.pro (+3/-11)
tests/online-accounts-ui/tst_signonui_request.cpp (+336/-0)
tests/online-accounts-ui/tst_signonui_request.pro (+48/-0)
tests/tests.pro (+1/-0)
ubuntu-system-settings-online-accounts.pro (+4/-3)
To merge this branch: bzr merge lp:~mardy/ubuntu-system-settings-online-accounts/master
Reviewer Review Type Date Requested Status
David Barth (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Alexandre Abreu (community) Needs Information
Review via email: mp+222028@code.launchpad.net

Commit message

New version

- Use signon-ui-service, to fix co-installation with of signon-ui.
- Implement reauthentication (via snap-decisions)

Description of the change

New version

- Use signon-ui-service, to fix co-installation with of signon-ui.
- Implement reauthentication (via snap-decisions)

To post a comment you must log in.
Revision history for this message
Alexandre Abreu (abreu-alexandre) wrote :

So the signon-ui-service package provides the removed bits I guess ?

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alberto Mardegan (mardy) wrote :

> So the signon-ui-service package provides the removed bits I guess ?

Yes, the .service files are being moved there.

123. By Alberto Mardegan

Click hooks: remove stale file, handle updates

Remove the installed files when the click hook files get removed (meaning that an application has been unregistered).
Update the installed files when the date of the click hook file is newer.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
124. By Alberto Mardegan

Add a Notification class to wrap libnotify

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
125. By Alberto Mardegan

Minor reformatting of debian rules

This allows Jenkins hooks to enable coverage.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
126. By Alberto Mardegan

Add ApplicationManager::applicationFromProfile()

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
127. By Alberto Mardegan

Remove signon-ui provides

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
128. By Alberto Mardegan

Merge from trunk

129. By Alberto Mardegan

Implement account reauthentication and reauthorization

The need for a user interaction might arise at any time, depending on the remote service's policy. It will typically happen when an access token expires, or when an application requests new permissions or changes its key.
In order not to disrupt the user's activity, we preliminary implement this as a snap decision (as was suggested in https://docs.google.com/a/canonical.com/document/d/1puQ9Z0yKqzsQ1VQ1OOBkxgp78iWGnAhAkFXWJFTWIrE/edit#heading=h.topn0ejru38u). However, since design has not yet come up with a definitive approach, we keep the UI strings untranslated since they are not final.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
David Barth (dbarth) :
review: Approve
130. By Alberto Mardegan

From trunk

* Add forgotten test-dep on ubuntu-ui-toolkit-autopilot.
[ Leo Arias ]
* Refactored the autopilot tests to use the page object pattern. Added
  the method go to add account to be used in UX tests.
[ Michał Sawicz ]
* New icon from suru theme.

131. By Alberto Mardegan

Move the UI into a separate process

Introduce online-accounts-service as a UI-less DBus service which acts as a
dispatcher for authentication and authorization requests; the requests
themselves are processed by a subprocess, online-accounts-ui, of which multiple
instances can exists (each instance having single window).

This is the first step towards implementing trust session support.

132. By Alberto Mardegan

This branch moves the OA settings back into the main settings application, as an inline plugin. This should help with the overall UX, and in particular some annoying bugs ("black window", etc.)

The functional scope covers:
- listing online accounts
- changing apps permissions for an account
- adding a new online account
- removing an online account

The branch has currently some limitations:
- only support OAuth providers
- the system-widw OAuth provider path is hardcoded
- doesn't support providers installed in the home directory

The limitations should be easy to lift once the general logic is reviewed.

133. By Alberto Mardegan

Support Mir prompt sessions

134. By Alberto Mardegan

Avoid clicking multiple times

135. By Alberto Mardegan

Make the Mir dependency optional

Mir is not yet available for all architectures.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2014-06-05 13:28:30 +0000
+++ .bzrignore 2014-08-18 13:33:35 +0000
@@ -31,18 +31,20 @@
31/debian/*.substvars31/debian/*.substvars
32/plugins/example/libexample.so*32/plugins/example/libexample.so*
33/po/*.mo33/po/*.mo
34/src/com.ubuntu.OnlineAccountsUi.service34/online-accounts-service/com.ubuntu.OnlineAccountsUi.service
35/src/module/OnlineAccountsPlugin.pc35/online-accounts-service/online-accounts-service
36/src/module/libOnlineAccountsPlugin.so*36/online-accounts-ui/module/OnlineAccountsPlugin.pc
37/src/module/qmldir37/online-accounts-ui/module/libOnlineAccountsPlugin.so*
38/src/online-accounts-ui.desktop38/online-accounts-ui/module/qmldir
39/src/online-accounts-ui39/online-accounts-ui/online-accounts-ui.desktop
40/online-accounts-ui/online-accounts-ui
40/tests/click-hooks/tst_online_accounts_hooks41/tests/click-hooks/tst_online_accounts_hooks
41/tests/client/tst_client42/tests/client/tst_client
42/tests/client/tst_qml_client43/tests/client/tst_qml_client
44/tests/online-accounts-service/tst_inactivity_timer
45/tests/online-accounts-service/tst_service
43/tests/online-accounts-ui/qml/tst_online_accounts_qml46/tests/online-accounts-ui/qml/tst_online_accounts_qml
44/tests/online-accounts-ui/tst_access_model47/tests/online-accounts-ui/tst_access_model
45/tests/online-accounts-ui/tst_application_manager48/tests/online-accounts-ui/tst_application_manager
46/tests/online-accounts-ui/tst_inactivity_timer
47/tests/online-accounts-ui/tst_notification49/tests/online-accounts-ui/tst_notification
48/tests/online-accounts-ui/tst_service50/tests/online-accounts-ui/tst_signonui_request
4951
=== modified file 'client/OnlineAccountsClient/OnlineAccountsClient.pro'
--- client/OnlineAccountsClient/OnlineAccountsClient.pro 2014-03-19 12:14:14 +0000
+++ client/OnlineAccountsClient/OnlineAccountsClient.pro 2014-08-18 13:33:35 +0000
@@ -25,10 +25,10 @@
25INCLUDEPATH += \25INCLUDEPATH += \
26 $${TOP_SRC_DIR}26 $${TOP_SRC_DIR}
2727
28ONLINE_ACCOUNTS_UI_SRC = $${TOP_SRC_DIR}/src28ONLINE_ACCOUNTS_SERVICE_SRC = $${TOP_SRC_DIR}/online-accounts-service
2929
30DBUS_INTERFACES += \30DBUS_INTERFACES += \
31 $${ONLINE_ACCOUNTS_UI_SRC}/com.ubuntu.OnlineAccountsUi.xml31 $${ONLINE_ACCOUNTS_SERVICE_SRC}/com.ubuntu.OnlineAccountsUi.xml
3232
33SOURCES += \33SOURCES += \
34 setup.cpp34 setup.cpp
3535
=== modified file 'client/OnlineAccountsClient/setup.cpp'
--- client/OnlineAccountsClient/setup.cpp 2014-05-30 08:09:02 +0000
+++ client/OnlineAccountsClient/setup.cpp 2014-08-18 13:33:35 +0000
@@ -20,9 +20,9 @@
20 * <http://www.gnu.org/licenses/>.20 * <http://www.gnu.org/licenses/>.
21 */21 */
2222
23#include "online-accounts-ui/globals.h"
23#include "onlineaccountsui_interface.h"24#include "onlineaccountsui_interface.h"
24#include "setup.h"25#include "setup.h"
25#include "src/globals.h"
2626
27#include <QDBusConnection>27#include <QDBusConnection>
28#include <QDBusPendingCallWatcher>28#include <QDBusPendingCallWatcher>
@@ -76,6 +76,8 @@
76{76{
77 QVariantMap options;77 QVariantMap options;
7878
79 options.insert(OAU_KEY_PID, uint(getpid()));
80
79 QWindow *window = clientWindow();81 QWindow *window = clientWindow();
80 if (window) {82 if (window) {
81 options.insert(OAU_KEY_WINDOW_ID, window->winId());83 options.insert(OAU_KEY_WINDOW_ID, window->winId());
8284
=== modified file 'common-project-config.pri'
--- common-project-config.pri 2013-08-06 15:06:54 +0000
+++ common-project-config.pri 2014-08-18 13:33:35 +0000
@@ -47,3 +47,6 @@
47PLUGIN_MODULE_DIR = $$system("pkg-config --define-variable=prefix=$${INSTALL_PREFIX} --variable plugin_module_dir SystemSettings")47PLUGIN_MODULE_DIR = $$system("pkg-config --define-variable=prefix=$${INSTALL_PREFIX} --variable plugin_module_dir SystemSettings")
48PLUGIN_QML_DIR = $$system("pkg-config --define-variable=prefix=$${INSTALL_PREFIX} --variable plugin_qml_dir SystemSettings")48PLUGIN_QML_DIR = $$system("pkg-config --define-variable=prefix=$${INSTALL_PREFIX} --variable plugin_qml_dir SystemSettings")
49PLUGIN_PRIVATE_MODULE_DIR = $$system("pkg-config --define-variable=prefix=$${INSTALL_PREFIX} --variable plugin_private_module_dir SystemSettings")49PLUGIN_PRIVATE_MODULE_DIR = $$system("pkg-config --define-variable=prefix=$${INSTALL_PREFIX} --variable plugin_private_module_dir SystemSettings")
50
51I18N_DOMAIN="ubuntu-system-settings-online-accounts"
52SIGNONUI_I18N_DOMAIN="signon-ui"
5053
=== modified file 'debian/control'
--- debian/control 2014-06-04 12:00:43 +0000
+++ debian/control 2014-08-18 13:33:35 +0000
@@ -6,6 +6,7 @@
6 pkg-config,6 pkg-config,
7 python3:any,7 python3:any,
8 libaccounts-qt5-dev,8 libaccounts-qt5-dev,
9 libmirclient-dev [!powerpc !ppc64 !ppc64el],
9 libnotify-dev,10 libnotify-dev,
10 libsignon-qt5-dev,11 libsignon-qt5-dev,
11 libsystemsettings-dev (>= 0.1+13.10.20130806),12 libsystemsettings-dev (>= 0.1+13.10.20130806),
@@ -36,7 +37,6 @@
36 qtdeclarative5-ubuntu-ui-toolkit-plugin | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles,37 qtdeclarative5-ubuntu-ui-toolkit-plugin | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles,
37 signon-ui-service,38 signon-ui-service,
38 ubuntu-system-settings39 ubuntu-system-settings
39Provides: signon-ui
40Description: Online Accounts setup for Ubuntu Touch40Description: Online Accounts setup for Ubuntu Touch
41 Online Accounts setup utility for the Ubuntu Touch System Settings.41 Online Accounts setup utility for the Ubuntu Touch System Settings.
4242
4343
=== modified file 'debian/rules'
--- debian/rules 2014-06-06 08:10:04 +0000
+++ debian/rules 2014-08-18 13:33:35 +0000
@@ -8,6 +8,7 @@
8 dh_auto_configure -- \8 dh_auto_configure -- \
9 LIBDIR=/usr/lib/$(DEB_HOST_MULTIARCH) \9 LIBDIR=/usr/lib/$(DEB_HOST_MULTIARCH) \
10 "QMAKE_CXXFLAGS=$(CFLAGS)" \10 "QMAKE_CXXFLAGS=$(CFLAGS)" \
11 CONFIG+=enable-mir \
11 CONFIG+=ubuntu-docs \12 CONFIG+=ubuntu-docs \
12 ubuntu-system-settings-online-accounts.pro13 ubuntu-system-settings-online-accounts.pro
1314
1415
=== modified file 'debian/ubuntu-system-settings-online-accounts.install'
--- debian/ubuntu-system-settings-online-accounts.install 2014-06-04 09:59:37 +0000
+++ debian/ubuntu-system-settings-online-accounts.install 2014-08-18 13:33:35 +0000
@@ -1,4 +1,5 @@
1usr/bin/online-accounts-hooks1usr/bin/online-accounts-hooks
2usr/bin/online-accounts-service
2usr/bin/online-accounts-ui3usr/bin/online-accounts-ui
3usr/lib/*/pkgconfig/OnlineAccountsPlugin.pc4usr/lib/*/pkgconfig/OnlineAccountsPlugin.pc
4usr/lib/*/ubuntu-system-settings5usr/lib/*/ubuntu-system-settings
56
=== added directory 'online-accounts-service'
=== renamed file 'src/com.canonical.indicators.webcredentials.xml' => 'online-accounts-service/com.canonical.indicators.webcredentials.xml'
=== renamed file 'src/com.ubuntu.OnlineAccountsUi.service.in' => 'online-accounts-service/com.ubuntu.OnlineAccountsUi.service.in'
--- src/com.ubuntu.OnlineAccountsUi.service.in 2013-11-21 12:26:22 +0000
+++ online-accounts-service/com.ubuntu.OnlineAccountsUi.service.in 2014-08-18 13:33:35 +0000
@@ -1,3 +1,3 @@
1[D-BUS Service]1[D-BUS Service]
2Name=com.ubuntu.OnlineAccountsUi2Name=com.ubuntu.OnlineAccountsUi
3Exec=$${INSTALL_PREFIX}/bin/$${TARGET} --desktop_file_hint=$${desktop.path}/$${TARGET}.desktop3Exec=$${INSTALL_PREFIX}/bin/$${TARGET}
44
=== renamed file 'src/com.ubuntu.OnlineAccountsUi.xml' => 'online-accounts-service/com.ubuntu.OnlineAccountsUi.xml'
=== renamed file 'src/inactivity-timer.cpp' => 'online-accounts-service/inactivity-timer.cpp'
=== renamed file 'src/inactivity-timer.h' => 'online-accounts-service/inactivity-timer.h'
=== renamed file 'src/indicator-service.cpp' => 'online-accounts-service/indicator-service.cpp'
=== renamed file 'src/indicator-service.h' => 'online-accounts-service/indicator-service.h'
=== added file 'online-accounts-service/main.cpp'
--- online-accounts-service/main.cpp 1970-01-01 00:00:00 +0000
+++ online-accounts-service/main.cpp 2014-08-18 13:33:35 +0000
@@ -0,0 +1,109 @@
1/*
2 * Copyright (C) 2013 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "debug.h"
22#include "globals.h"
23#include "inactivity-timer.h"
24#include "indicator-service.h"
25#include "request-manager.h"
26#include "service.h"
27#include "signonui-service.h"
28
29#include <QCoreApplication>
30#include <QDBusConnection>
31#include <QProcessEnvironment>
32
33using namespace OnlineAccountsUi;
34
35int main(int argc, char **argv)
36{
37 QCoreApplication app(argc, argv);
38
39 /* read environment variables */
40 QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
41 if (environment.contains(QLatin1String("OAU_LOGGING_LEVEL"))) {
42 bool isOk;
43 int value = environment.value(
44 QLatin1String("OAU_LOGGING_LEVEL")).toInt(&isOk);
45 if (isOk)
46 setLoggingLevel(value);
47 }
48
49 /* default daemonTimeout to 5 seconds */
50 int daemonTimeout = 5;
51
52 /* override daemonTimeout if OAU_DAEMON_TIMEOUT is set */
53 if (environment.contains(QLatin1String("OAU_DAEMON_TIMEOUT"))) {
54 bool isOk;
55 int value = environment.value(
56 QLatin1String("OAU_DAEMON_TIMEOUT")).toInt(&isOk);
57 if (isOk)
58 daemonTimeout = value;
59 }
60
61 RequestManager *requestManager = new RequestManager();
62
63 Service *service = new Service();
64 QDBusConnection connection = QDBusConnection::sessionBus();
65 connection.registerService(OAU_SERVICE_NAME);
66 connection.registerObject(OAU_OBJECT_PATH, service);
67
68 SignOnUi::Service *signonuiService = new SignOnUi::Service();
69 connection.registerService(SIGNONUI_SERVICE_NAME);
70 connection.registerObject(SIGNONUI_OBJECT_PATH, signonuiService,
71 QDBusConnection::ExportAllContents);
72
73 SignOnUi::IndicatorService *indicatorService =
74 new SignOnUi::IndicatorService();
75 connection.registerService(WEBCREDENTIALS_BUS_NAME);
76 connection.registerObject(WEBCREDENTIALS_OBJECT_PATH,
77 indicatorService->serviceObject());
78
79
80 InactivityTimer *inactivityTimer = 0;
81 if (daemonTimeout > 0) {
82 inactivityTimer = new InactivityTimer(daemonTimeout * 1000);
83 inactivityTimer->watchObject(requestManager);
84 inactivityTimer->watchObject(indicatorService);
85 QObject::connect(inactivityTimer, SIGNAL(timeout()),
86 &app, SLOT(quit()));
87 }
88
89 int ret = app.exec();
90
91 connection.unregisterService(WEBCREDENTIALS_BUS_NAME);
92 connection.unregisterObject(WEBCREDENTIALS_OBJECT_PATH);
93 delete indicatorService;
94
95 connection.unregisterService(SIGNONUI_SERVICE_NAME);
96 connection.unregisterObject(SIGNONUI_OBJECT_PATH);
97 delete signonuiService;
98
99 connection.unregisterService(OAU_SERVICE_NAME);
100 connection.unregisterObject(OAU_OBJECT_PATH);
101 delete service;
102
103 delete requestManager;
104
105 delete inactivityTimer;
106
107 return ret;
108}
109
0110
=== added file 'online-accounts-service/mir-helper-stub.cpp'
--- online-accounts-service/mir-helper-stub.cpp 1970-01-01 00:00:00 +0000
+++ online-accounts-service/mir-helper-stub.cpp 2014-08-18 13:33:35 +0000
@@ -0,0 +1,69 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "debug.h"
22#include "mir-helper.h"
23
24using namespace OnlineAccountsUi;
25
26namespace OnlineAccountsUi {
27
28static MirHelper *m_instance = 0;
29
30} // namespace
31
32PromptSession::PromptSession(PromptSessionPrivate *priv):
33 d_ptr(priv)
34{
35}
36
37PromptSession::~PromptSession()
38{
39}
40
41QString PromptSession::requestSocket()
42{
43 return QString();
44}
45
46MirHelper::MirHelper(QObject *parent):
47 QObject(parent),
48 d_ptr(0)
49{
50}
51
52MirHelper::~MirHelper()
53{
54 m_instance = 0;
55}
56
57MirHelper *MirHelper::instance()
58{
59 if (!m_instance) {
60 m_instance = new MirHelper;
61 }
62 return m_instance;
63}
64
65PromptSession *MirHelper::createPromptSession(pid_t initiatorPid)
66{
67 Q_UNUSED(initiatorPid);
68 return 0;
69}
070
=== added file 'online-accounts-service/mir-helper.cpp'
--- online-accounts-service/mir-helper.cpp 1970-01-01 00:00:00 +0000
+++ online-accounts-service/mir-helper.cpp 2014-08-18 13:33:35 +0000
@@ -0,0 +1,192 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "debug.h"
22#include "mir-helper.h"
23
24#include <mir_toolkit/mir_client_library.h>
25#include <mir_toolkit/mir_prompt_session.h>
26
27#include <QList>
28#include <QStandardPaths>
29
30using namespace OnlineAccountsUi;
31
32namespace OnlineAccountsUi {
33
34static MirHelper *m_instance = 0;
35
36class PromptSessionPrivate
37{
38public:
39 inline PromptSessionPrivate(MirPromptSession *session);
40 inline ~PromptSessionPrivate();
41
42 MirPromptSession *m_mirSession;
43 QList<int> m_fds;
44 mutable PromptSession *q_ptr;
45};
46
47class MirHelperPrivate: public QObject
48{
49 Q_OBJECT
50 Q_DECLARE_PUBLIC(MirHelper)
51
52public:
53 inline MirHelperPrivate(MirHelper *helper);
54 inline ~MirHelperPrivate();
55
56 PromptSession *createPromptSession(pid_t initiatorPid);
57
58private:
59 friend class PromptSession;
60 MirConnection *m_connection;
61 QList<PromptSession*> m_sessions;
62 mutable MirHelper *q_ptr;
63};
64
65} // namespace
66
67PromptSessionPrivate::PromptSessionPrivate(MirPromptSession *session):
68 m_mirSession(session)
69{
70}
71
72PromptSessionPrivate::~PromptSessionPrivate()
73{
74 mir_prompt_session_release_sync(m_mirSession);
75 m_mirSession = 0;
76}
77
78PromptSession::PromptSession(PromptSessionPrivate *priv):
79 d_ptr(priv)
80{
81 MirHelperPrivate *helperPrivate = MirHelper::instance()->d_ptr;
82 helperPrivate->m_sessions.append(this);
83}
84
85PromptSession::~PromptSession()
86{
87 MirHelperPrivate *helperPrivate = MirHelper::instance()->d_ptr;
88 helperPrivate->m_sessions.removeOne(this);
89 delete d_ptr;
90}
91
92static void client_fd_callback(MirPromptSession *, size_t count,
93 int const *fds, void *context)
94{
95 PromptSessionPrivate *priv = (PromptSessionPrivate *)context;
96 for (size_t i = 0; i < count; i++) {
97 priv->m_fds.append(fds[i]);
98 }
99}
100
101QString PromptSession::requestSocket()
102{
103 Q_D(PromptSession);
104
105 d->m_fds.clear();
106 mir_wait_for(mir_prompt_session_new_fds_for_prompt_providers(
107 d->m_mirSession, 1, client_fd_callback, d));
108 if (!d->m_fds.isEmpty()) {
109 return QString("fd://%1").arg(d->m_fds[0]);
110 } else {
111 return QString();
112 }
113}
114
115MirHelperPrivate::MirHelperPrivate(MirHelper *helper):
116 QObject(helper),
117 q_ptr(helper)
118{
119 QString mirSocket =
120 QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) +
121 "/mir_socket_trusted";
122 m_connection = mir_connect_sync(mirSocket.toUtf8().constData(),
123 "online-accounts-service");
124 if (Q_UNLIKELY(!mir_connection_is_valid(m_connection))) {
125 qWarning() << "Invalid Mir connection:" <<
126 mir_connection_get_error_message(m_connection);
127 return;
128 }
129}
130
131MirHelperPrivate::~MirHelperPrivate()
132{
133 if (m_connection) {
134 mir_connection_release(m_connection);
135 m_connection = 0;
136 }
137}
138
139static void session_event_callback(MirPromptSession *,
140 MirPromptSessionState state,
141 void *)
142{
143 DEBUG() << "Prompt Session state updated to" << state;
144}
145
146
147PromptSession *MirHelperPrivate::createPromptSession(pid_t initiatorPid)
148{
149 if (Q_UNLIKELY(!m_connection)) return 0;
150
151 MirPromptSession *mirSession =
152 mir_connection_create_prompt_session_sync(m_connection,
153 initiatorPid,
154 session_event_callback,
155 this);
156 if (!mirSession) return 0;
157
158 if (Q_UNLIKELY(!mir_prompt_session_is_valid(mirSession))) {
159 qWarning() << "Invalid prompt session:" <<
160 mir_prompt_session_error_message(mirSession);
161 return 0;
162 }
163
164 return new PromptSession(new PromptSessionPrivate(mirSession));
165}
166
167MirHelper::MirHelper(QObject *parent):
168 QObject(parent),
169 d_ptr(new MirHelperPrivate(this))
170{
171}
172
173MirHelper::~MirHelper()
174{
175 m_instance = 0;
176}
177
178MirHelper *MirHelper::instance()
179{
180 if (!m_instance) {
181 m_instance = new MirHelper;
182 }
183 return m_instance;
184}
185
186PromptSession *MirHelper::createPromptSession(pid_t initiatorPid)
187{
188 Q_D(MirHelper);
189 return d->createPromptSession(initiatorPid);
190}
191
192#include "mir-helper.moc"
0193
=== added file 'online-accounts-service/mir-helper.h'
--- online-accounts-service/mir-helper.h 1970-01-01 00:00:00 +0000
+++ online-accounts-service/mir-helper.h 2014-08-18 13:33:35 +0000
@@ -0,0 +1,68 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef OAU_MIR_HELPER_H
22#define OAU_MIR_HELPER_H
23
24#include <QObject>
25
26namespace OnlineAccountsUi {
27
28class PromptSessionPrivate;
29class MirHelperPrivate;
30
31class PromptSession
32{
33public:
34 ~PromptSession();
35
36 QString requestSocket();
37
38private:
39 explicit PromptSession(PromptSessionPrivate *priv);
40
41private:
42 friend class MirHelperPrivate;
43 PromptSessionPrivate *d_ptr;
44 Q_DECLARE_PRIVATE(PromptSession)
45};
46
47class MirHelper: public QObject
48{
49 Q_OBJECT
50
51public:
52 static MirHelper *instance();
53
54 PromptSession *createPromptSession(pid_t initiatorPid);
55
56private:
57 explicit MirHelper(QObject *parent = 0);
58 ~MirHelper();
59
60private:
61 friend class PromptSession;
62 MirHelperPrivate *d_ptr;
63 Q_DECLARE_PRIVATE(MirHelper)
64};
65
66} // namespace
67
68#endif // OAU_MIR_HELPER_H
069
=== added file 'online-accounts-service/online-accounts-service.pro'
--- online-accounts-service/online-accounts-service.pro 1970-01-01 00:00:00 +0000
+++ online-accounts-service/online-accounts-service.pro 2014-08-18 13:33:35 +0000
@@ -0,0 +1,82 @@
1include(../common-project-config.pri)
2include($${TOP_SRC_DIR}/common-vars.pri)
3
4TEMPLATE = app
5TARGET = online-accounts-service
6
7CONFIG += \
8 link_pkgconfig \
9 no_keywords \
10 qt
11
12QT += \
13 dbus \
14 network
15
16PKGCONFIG += \
17 libnotify \
18 libsignon-qt5 \
19 signon-plugins-common
20
21
22CONFIG(enable-mir) : system(pkg-config --exists mirclient) {
23 PKGCONFIG += mirclient
24 SOURCES += mir-helper.cpp
25} else {
26 SOURCES += mir-helper-stub.cpp
27}
28
29DBUS_ADAPTORS += \
30 com.ubuntu.OnlineAccountsUi.xml
31
32DEFINES += \
33 DEBUG_ENABLED \
34 SIGNONUI_I18N_DOMAIN=\\\"$${SIGNONUI_I18N_DOMAIN}\\\"
35
36COMMON_SRC = ../online-accounts-ui
37
38INCLUDEPATH += \
39 $${COMMON_SRC}
40
41SOURCES += \
42 $${COMMON_SRC}/debug.cpp \
43 $${COMMON_SRC}/i18n.cpp \
44 $${COMMON_SRC}/ipc.cpp \
45 $${COMMON_SRC}/notification.cpp \
46 inactivity-timer.cpp \
47 indicator-service.cpp \
48 main.cpp \
49 reauthenticator.cpp \
50 request.cpp \
51 request-manager.cpp \
52 service.cpp \
53 signonui-service.cpp \
54 ui-proxy.cpp
55
56HEADERS += \
57 $${COMMON_SRC}/debug.h \
58 $${COMMON_SRC}/i18n.h \
59 $${COMMON_SRC}/ipc.h \
60 $${COMMON_SRC}/notification.h \
61 inactivity-timer.h \
62 indicator-service.h \
63 mir-helper.h \
64 reauthenticator.h \
65 request.h \
66 request-manager.h \
67 service.h \
68 signonui-service.h \
69 ui-proxy.h
70
71QMAKE_SUBSTITUTES += \
72 com.ubuntu.OnlineAccountsUi.service.in
73
74DBUS_ADAPTORS += \
75 com.canonical.indicators.webcredentials.xml
76
77service.path = $${INSTALL_PREFIX}/share/dbus-1/services
78service.files = \
79 com.ubuntu.OnlineAccountsUi.service
80INSTALLS += service
81
82include($${TOP_SRC_DIR}/common-installs-config.pri)
083
=== renamed file 'src/reauthenticator.cpp' => 'online-accounts-service/reauthenticator.cpp'
=== renamed file 'src/reauthenticator.h' => 'online-accounts-service/reauthenticator.h'
=== renamed file 'src/request-manager.cpp' => 'online-accounts-service/request-manager.cpp'
--- src/request-manager.cpp 2014-04-29 12:11:55 +0000
+++ online-accounts-service/request-manager.cpp 2014-08-18 13:33:35 +0000
@@ -19,8 +19,10 @@
19 */19 */
2020
21#include "debug.h"21#include "debug.h"
22#include "globals.h"
22#include "request.h"23#include "request.h"
23#include "request-manager.h"24#include "request-manager.h"
25#include "ui-proxy.h"
2426
25#include <QQueue>27#include <QQueue>
2628
@@ -41,17 +43,19 @@
41 RequestManagerPrivate(RequestManager *service);43 RequestManagerPrivate(RequestManager *service);
42 ~RequestManagerPrivate();44 ~RequestManagerPrivate();
4345
44 RequestQueue &queueForWindowId(WId windowId);46 RequestQueue &queueForWindowId(quint64 windowId);
45 void enqueue(Request *request);47 void enqueue(Request *request);
46 void runQueue(RequestQueue &queue);48 void runQueue(RequestQueue &queue);
4749
48private Q_SLOTS:50private Q_SLOTS:
49 void onRequestCompleted();51 void onRequestCompleted();
52 void onProxyFinished();
5053
51private:54private:
52 mutable RequestManager *q_ptr;55 mutable RequestManager *q_ptr;
53 /* each window Id has a different queue */56 /* each window Id has a different queue */
54 QMap<WId,RequestQueue> m_requests;57 QMap<quint64,RequestQueue> m_requests;
58 QList<UiProxy*> m_proxies;
55};59};
5660
57} // namespace61} // namespace
@@ -66,7 +70,7 @@
66{70{
67}71}
6872
69RequestQueue &RequestManagerPrivate::queueForWindowId(WId windowId)73RequestQueue &RequestManagerPrivate::queueForWindowId(quint64 windowId)
70{74{
71 if (!m_requests.contains(windowId)) {75 if (!m_requests.contains(windowId)) {
72 RequestQueue queue;76 RequestQueue queue;
@@ -78,9 +82,20 @@
78void RequestManagerPrivate::enqueue(Request *request)82void RequestManagerPrivate::enqueue(Request *request)
79{83{
80 Q_Q(RequestManager);84 Q_Q(RequestManager);
85
86 /* First, see if any of the existing proxies can handle this request */
87 Q_FOREACH(UiProxy *proxy, m_proxies) {
88 if (proxy->hasHandlerFor(request->parameters())) {
89 QObject::connect(request, SIGNAL(completed()),
90 request, SLOT(deleteLater()));
91 proxy->handleRequest(request);
92 return;
93 }
94 }
95
81 bool wasIdle = q->isIdle();96 bool wasIdle = q->isIdle();
8297
83 WId windowId = request->windowId();98 quint64 windowId = request->windowId();
8499
85 RequestQueue &queue = queueForWindowId(windowId);100 RequestQueue &queue = queueForWindowId(windowId);
86 queue.enqueue(request);101 queue.enqueue(request);
@@ -102,9 +117,20 @@
102 return; // Nothing to do117 return; // Nothing to do
103 }118 }
104119
120 pid_t clientPid = (request->interface() == OAU_INTERFACE) ?
121 request->parameters().value(OAU_KEY_PID, 0).toUInt() : 0;
122 UiProxy *proxy = new UiProxy(clientPid, this);
123 if (Q_UNLIKELY(!proxy->init())) {
124 qWarning() << "UiProxy initialization failed!";
125 runQueue(queue);
126 return;
127 }
105 QObject::connect(request, SIGNAL(completed()),128 QObject::connect(request, SIGNAL(completed()),
106 this, SLOT(onRequestCompleted()));129 this, SLOT(onRequestCompleted()));
107 request->start();130 QObject::connect(proxy, SIGNAL(finished()),
131 this, SLOT(onProxyFinished()));
132 m_proxies.append(proxy);
133 proxy->handleRequest(request);
108}134}
109135
110void RequestManagerPrivate::onRequestCompleted()136void RequestManagerPrivate::onRequestCompleted()
@@ -112,7 +138,7 @@
112 Q_Q(RequestManager);138 Q_Q(RequestManager);
113139
114 Request *request = qobject_cast<Request*>(sender());140 Request *request = qobject_cast<Request*>(sender());
115 WId windowId = request->windowId();141 quint64 windowId = request->windowId();
116142
117 RequestQueue &queue = queueForWindowId(windowId);143 RequestQueue &queue = queueForWindowId(windowId);
118 if (request != queue.head()) {144 if (request != queue.head()) {
@@ -135,6 +161,16 @@
135 }161 }
136}162}
137163
164void RequestManagerPrivate::onProxyFinished()
165{
166 Q_Q(RequestManager);
167
168 UiProxy *proxy = qobject_cast<UiProxy*>(sender());
169 m_proxies.removeOne(proxy);
170
171 proxy->deleteLater();
172}
173
138RequestManager::RequestManager(QObject *parent):174RequestManager::RequestManager(QObject *parent):
139 QObject(parent),175 QObject(parent),
140 d_ptr(new RequestManagerPrivate(this))176 d_ptr(new RequestManagerPrivate(this))
141177
=== renamed file 'src/request-manager.h' => 'online-accounts-service/request-manager.h'
--- src/request-manager.h 2014-04-29 12:11:55 +0000
+++ online-accounts-service/request-manager.h 2014-08-18 13:33:35 +0000
@@ -27,8 +27,9 @@
27namespace OnlineAccountsUi {27namespace OnlineAccountsUi {
2828
29class Request;29class Request;
30class UiProxy;
31
30class RequestManagerPrivate;32class RequestManagerPrivate;
31
32class RequestManager: public QObject33class RequestManager: public QObject
33{34{
34 Q_OBJECT35 Q_OBJECT
@@ -41,6 +42,7 @@
41 static RequestManager *instance();42 static RequestManager *instance();
4243
43 void enqueue(Request *request);44 void enqueue(Request *request);
45 UiProxy *findMatching(const QVariantMap &parameters);
4446
45 bool isIdle() const;47 bool isIdle() const;
4648
4749
=== added file 'online-accounts-service/request.cpp'
--- online-accounts-service/request.cpp 1970-01-01 00:00:00 +0000
+++ online-accounts-service/request.cpp 2014-08-18 13:33:35 +0000
@@ -0,0 +1,214 @@
1/*
2 * Copyright (C) 2013 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "debug.h"
22#include "globals.h"
23#include "request.h"
24
25using namespace OnlineAccountsUi;
26
27static bool mapIsSuperset(const QVariantMap &test, const QVariantMap &set)
28{
29 QMapIterator<QString, QVariant> it(set);
30 while (it.hasNext()) {
31 it.next();
32 if (test.value(it.key()) != it.value()) return false;
33 }
34
35 return true;
36}
37
38namespace OnlineAccountsUi {
39
40static QList<Request *> allRequests;
41
42class RequestPrivate: public QObject
43{
44 Q_OBJECT
45 Q_DECLARE_PUBLIC(Request)
46
47public:
48 RequestPrivate(const QDBusConnection &connection,
49 const QDBusMessage &message,
50 const QVariantMap &parameters,
51 Request *request);
52 ~RequestPrivate();
53
54 quint64 windowId() const {
55 return m_parameters[OAU_KEY_WINDOW_ID].toUInt();
56 }
57
58private:
59 QString findClientApparmorProfile();
60
61private:
62 mutable Request *q_ptr;
63 QDBusConnection m_connection;
64 QDBusMessage m_message;
65 QVariantMap m_parameters;
66 QString m_clientApparmorProfile;
67 bool m_inProgress;
68};
69
70} // namespace
71
72RequestPrivate::RequestPrivate(const QDBusConnection &connection,
73 const QDBusMessage &message,
74 const QVariantMap &parameters,
75 Request *request):
76 QObject(request),
77 q_ptr(request),
78 m_connection(connection),
79 m_message(message),
80 m_parameters(parameters),
81 m_inProgress(false)
82{
83 m_clientApparmorProfile = findClientApparmorProfile();
84}
85
86RequestPrivate::~RequestPrivate()
87{
88}
89
90QString RequestPrivate::findClientApparmorProfile()
91{
92 QString uniqueConnectionId = m_message.service();
93 /* This is mainly for unit tests: real messages on the session bus always
94 * have a service name. */
95 if (uniqueConnectionId.isEmpty()) return QString();
96
97 QString appId;
98
99 QDBusMessage msg =
100 QDBusMessage::createMethodCall("org.freedesktop.DBus",
101 "/org/freedesktop/DBus",
102 "org.freedesktop.DBus",
103 "GetConnectionAppArmorSecurityContext");
104 QVariantList args;
105 args << uniqueConnectionId;
106 msg.setArguments(args);
107 QDBusMessage reply = QDBusConnection::sessionBus().call(msg, QDBus::Block);
108 if (reply.type() == QDBusMessage::ReplyMessage) {
109 appId = reply.arguments().value(0, QString()).toString();
110 DEBUG() << "App ID:" << appId;
111 } else {
112 qWarning() << "Error getting app ID:" << reply.errorName() <<
113 reply.errorMessage();
114 }
115 return appId;
116}
117
118Request::Request(const QDBusConnection &connection,
119 const QDBusMessage &message,
120 const QVariantMap &parameters,
121 QObject *parent):
122 QObject(parent),
123 d_ptr(new RequestPrivate(connection, message, parameters, this))
124{
125 allRequests.append(this);
126}
127
128Request::~Request()
129{
130 allRequests.removeOne(this);
131}
132
133Request *Request::find(const QVariantMap &match)
134{
135 Q_FOREACH(Request *r, allRequests) {
136 if (mapIsSuperset(r->parameters(), match)) {
137 return r;
138 }
139 }
140
141 return 0;
142}
143
144quint64 Request::windowId() const
145{
146 Q_D(const Request);
147 return d->windowId();
148}
149
150void Request::setInProgress(bool inProgress)
151{
152 Q_D(Request);
153 d->m_inProgress = inProgress;
154}
155
156bool Request::isInProgress() const
157{
158 Q_D(const Request);
159 return d->m_inProgress;
160}
161
162const QVariantMap &Request::parameters() const
163{
164 Q_D(const Request);
165 return d->m_parameters;
166}
167
168QString Request::clientApparmorProfile() const
169{
170 Q_D(const Request);
171 return d->m_clientApparmorProfile;
172}
173
174QString Request::interface() const {
175 Q_D(const Request);
176 return d->m_message.interface();
177}
178
179void Request::cancel()
180{
181 setCanceled();
182}
183
184void Request::fail(const QString &name, const QString &message)
185{
186 Q_D(Request);
187 QDBusMessage reply = d->m_message.createErrorReply(name, message);
188 d->m_connection.send(reply);
189
190 Q_EMIT completed();
191}
192
193void Request::setCanceled()
194{
195 Q_D(Request);
196 if (d->m_inProgress) {
197 fail(OAU_ERROR_USER_CANCELED, QStringLiteral("Canceled"));
198 d->m_inProgress = false;
199 }
200}
201
202void Request::setResult(const QVariantMap &result)
203{
204 Q_D(Request);
205 if (d->m_inProgress) {
206 QDBusMessage reply = d->m_message.createReply(result);
207 d->m_connection.send(reply);
208
209 Q_EMIT completed();
210 d->m_inProgress = false;
211 }
212}
213
214#include "request.moc"
0215
=== added file 'online-accounts-service/request.h'
--- online-accounts-service/request.h 1970-01-01 00:00:00 +0000
+++ online-accounts-service/request.h 2014-08-18 13:33:35 +0000
@@ -0,0 +1,70 @@
1/*
2 * Copyright (C) 2013 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef OAU_REQUEST_H
22#define OAU_REQUEST_H
23
24#include <QDBusConnection>
25#include <QDBusMessage>
26#include <QObject>
27#include <QVariantMap>
28
29namespace OnlineAccountsUi {
30
31class RequestPrivate;
32class Request: public QObject
33{
34 Q_OBJECT
35
36public:
37 explicit Request(const QDBusConnection &connection,
38 const QDBusMessage &message,
39 const QVariantMap &parameters,
40 QObject *parent = 0);
41 ~Request();
42
43 static Request *find(const QVariantMap &match);
44
45 quint64 windowId() const;
46 void setInProgress(bool inProgress);
47 bool isInProgress() const;
48 const QVariantMap &parameters() const;
49 QString clientApparmorProfile() const;
50 QString interface() const;
51
52public Q_SLOTS:
53 void cancel();
54
55Q_SIGNALS:
56 void completed();
57
58public Q_SLOTS:
59 void fail(const QString &name, const QString &message);
60 void setCanceled();
61 void setResult(const QVariantMap &result);
62
63private:
64 RequestPrivate *d_ptr;
65 Q_DECLARE_PRIVATE(Request)
66};
67
68} // namespace
69
70#endif // OAU_REQUEST_H
071
=== renamed file 'src/service.cpp' => 'online-accounts-service/service.cpp'
--- src/service.cpp 2014-05-30 08:09:02 +0000
+++ online-accounts-service/service.cpp 2014-08-18 13:33:35 +0000
@@ -44,17 +44,9 @@
44 /* The following line tells QtDBus not to generate a reply now */44 /* The following line tells QtDBus not to generate a reply now */
45 setDelayedReply(true);45 setDelayedReply(true);
4646
47 Request *request = Request::newRequest(connection(),47 Request *request = new Request(connection(), message(), options, this);
48 message(),48 RequestManager *manager = RequestManager::instance();
49 options,49 manager->enqueue(request);
50 this);
51 if (request) {
52 RequestManager *manager = RequestManager::instance();
53 manager->enqueue(request);
54 } else {
55 sendErrorReply(OAU_ERROR_INVALID_PARAMETERS,
56 QStringLiteral("Invalid request"));
57 }
5850
59 return QVariantMap();51 return QVariantMap();
60}52}
6153
=== renamed file 'src/service.h' => 'online-accounts-service/service.h'
=== renamed file 'src/signonui-service.cpp' => 'online-accounts-service/signonui-service.cpp'
--- src/signonui-service.cpp 2014-04-29 14:34:44 +0000
+++ online-accounts-service/signonui-service.cpp 2014-08-18 13:33:35 +0000
@@ -20,14 +20,12 @@
2020
21#include "debug.h"21#include "debug.h"
22#include "request.h"22#include "request.h"
23#include "request-handler.h"
24#include "request-manager.h"23#include "request-manager.h"
25#include "signonui-request.h"
26#include "signonui-service.h"24#include "signonui-service.h"
27#include "browser-request.h"
2825
29#include <QDBusArgument>26#include <QDBusArgument>
30#include <QtQml>27#include <QDir>
28#include <QStandardPaths>
31#include <SignOn/uisessiondata_priv.h>29#include <SignOn/uisessiondata_priv.h>
3230
33using namespace SignOnUi;31using namespace SignOnUi;
@@ -77,6 +75,8 @@
77 void cancelUiRequest(const QString &requestId);75 void cancelUiRequest(const QString &requestId);
78 void removeIdentityData(quint32 id);76 void removeIdentityData(quint32 id);
7977
78 static QString rootDirForIdentity(quint32 id);
79
80private:80private:
81 mutable Service *q_ptr;81 mutable Service *q_ptr;
82};82};
@@ -106,20 +106,24 @@
106 }106 }
107}107}
108108
109QString ServicePrivate::rootDirForIdentity(quint32 id)
110{
111 QString cachePath =
112 QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
113 return cachePath + QString("/id-%1").arg(id);
114}
115
109void ServicePrivate::removeIdentityData(quint32 id)116void ServicePrivate::removeIdentityData(quint32 id)
110{117{
111 /* Remove any data associated with the given identity. */118 /* Remove any data associated with the given identity. */
112119 QDir rootDir(ServicePrivate::rootDirForIdentity(id));
113 /* The BrowserRequest class creates a directory to store the cookies */120 rootDir.removeRecursively();
114 BrowserRequest::removeIdentityData(id);
115}121}
116122
117Service::Service(QObject *parent):123Service::Service(QObject *parent):
118 QObject(parent),124 QObject(parent),
119 d_ptr(new ServicePrivate(this))125 d_ptr(new ServicePrivate(this))
120{126{
121 qmlRegisterType<SignOnUi::RequestHandler>("Ubuntu.OnlineAccounts.Plugin",
122 1, 0, "RequestHandler");
123}127}
124128
125Service::~Service()129Service::~Service()
@@ -135,29 +139,12 @@
135 setDelayedReply(true);139 setDelayedReply(true);
136140
137 OnlineAccountsUi::Request *request =141 OnlineAccountsUi::Request *request =
138 OnlineAccountsUi::Request::newRequest(connection(),142 new OnlineAccountsUi::Request(connection(),
139 message(),143 message(),
140 cleanParameters,144 cleanParameters,
141 this);145 this);
142146
143 /* Check if a RequestHandler has been setup to handle this request. If147 OnlineAccountsUi::RequestManager::instance()->enqueue(request);
144 * so, bing the request object to the handler and start the request
145 * immediately. */
146 SignOnUi::Request *signonRequest =
147 qobject_cast<SignOnUi::Request*>(request);
148 Q_ASSERT(signonRequest != 0);
149
150 RequestHandler *handler = RequestHandler::findMatching(cleanParameters);
151 if (handler != 0) {
152 DEBUG() << "Found RequestHandler!";
153 signonRequest->setHandler(handler);
154 QObject::connect(signonRequest, SIGNAL(completed()),
155 signonRequest, SLOT(deleteLater()));
156 signonRequest->start();
157 } else {
158 // proceed normally
159 OnlineAccountsUi::RequestManager::instance()->enqueue(request);
160 }
161148
162 return QVariantMap();149 return QVariantMap();
163}150}
@@ -165,7 +152,6 @@
165QVariantMap Service::refreshDialog(const QVariantMap &newParameters)152QVariantMap Service::refreshDialog(const QVariantMap &newParameters)
166{153{
167 QVariantMap cleanParameters = expandDBusArguments(newParameters);154 QVariantMap cleanParameters = expandDBusArguments(newParameters);
168 QString requestId = Request::id(cleanParameters);
169 // TODO find the request and update it155 // TODO find the request and update it
170156
171 /* The following line tells QtDBus not to generate a reply now */157 /* The following line tells QtDBus not to generate a reply now */
172158
=== renamed file 'src/signonui-service.h' => 'online-accounts-service/signonui-service.h'
=== added file 'online-accounts-service/ui-proxy.cpp'
--- online-accounts-service/ui-proxy.cpp 1970-01-01 00:00:00 +0000
+++ online-accounts-service/ui-proxy.cpp 2014-08-18 13:33:35 +0000
@@ -0,0 +1,301 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "debug.h"
22#include "ipc.h"
23#include "mir-helper.h"
24#include "request.h"
25#include "ui-proxy.h"
26
27#include <QDir>
28#include <QFileInfo>
29#include <QLocalServer>
30#include <QLocalSocket>
31#include <QProcess>
32#include <QProcessEnvironment>
33#include <QStandardPaths>
34#include <SignOn/uisessiondata_priv.h>
35
36using namespace OnlineAccountsUi;
37
38static int socketCounter = 1;
39
40namespace OnlineAccountsUi {
41
42class UiProxyPrivate: public QObject
43{
44 Q_OBJECT
45 Q_DECLARE_PUBLIC(UiProxy)
46
47public:
48 inline UiProxyPrivate(pid_t clientPid, UiProxy *pluginProxy);
49 inline ~UiProxyPrivate();
50
51 bool setupSocket();
52 bool init();
53 void sendOperation(const QVariantMap &data);
54 void sendRequest(int requestId, Request *request);
55 void setupPromptSession();
56
57private Q_SLOTS:
58 void onNewConnection();
59 void onDataReady(QByteArray &data);
60 void onRequestCompleted();
61
62private:
63 QProcess m_process;
64 QLocalServer m_server;
65 QLocalSocket *m_socket;
66 OnlineAccountsUi::Ipc m_ipc;
67 int m_nextRequestId;
68 QMap<int,Request*> m_requests;
69 QStringList m_handlers;
70 pid_t m_clientPid;
71 PromptSession *m_promptSession;
72 mutable UiProxy *q_ptr;
73};
74
75} // namespace
76
77UiProxyPrivate::UiProxyPrivate(pid_t clientPid, UiProxy *uiProxy):
78 QObject(uiProxy),
79 m_socket(0),
80 m_nextRequestId(0),
81 m_clientPid(clientPid),
82 m_promptSession(0),
83 q_ptr(uiProxy)
84{
85 QObject::connect(&m_server, SIGNAL(newConnection()),
86 this, SLOT(onNewConnection()));
87 QObject::connect(&m_ipc, SIGNAL(dataReady(QByteArray &)),
88 this, SLOT(onDataReady(QByteArray &)));
89 m_process.setProcessChannelMode(QProcess::ForwardedChannels);
90}
91
92UiProxyPrivate::~UiProxyPrivate()
93{
94 /* Cancel all requests */
95 Q_FOREACH(Request *request, m_requests) {
96 request->cancel();
97 }
98
99 delete m_promptSession;
100
101 if (m_socket) {
102 m_socket->abort();
103 delete m_socket;
104 }
105 m_server.close();
106}
107
108void UiProxyPrivate::sendOperation(const QVariantMap &data)
109{
110 QByteArray ba;
111 QDataStream stream(&ba, QIODevice::WriteOnly);
112 stream << data;
113 m_ipc.write(ba);
114}
115
116void UiProxyPrivate::onNewConnection()
117{
118 Q_Q(UiProxy);
119
120 QLocalSocket *socket = m_server.nextPendingConnection();
121 if (Q_UNLIKELY(socket == 0)) return;
122
123 if (Q_UNLIKELY(m_socket != 0)) {
124 qWarning() << "A socket is already active!";
125 socket->deleteLater();
126 return;
127 }
128
129 m_socket = socket;
130 QObject::connect(socket, SIGNAL(disconnected()),
131 q, SIGNAL(finished()));
132 m_ipc.setChannels(socket, socket);
133 m_server.close(); // stop listening
134
135 /* Execute any pending requests */
136 QMapIterator<int, Request*> it(m_requests);
137 while (it.hasNext()) {
138 it.next();
139 sendRequest(it.key(), it.value());
140 }
141}
142
143void UiProxyPrivate::onDataReady(QByteArray &data)
144{
145 Q_Q(UiProxy);
146
147 QVariantMap map;
148 QDataStream stream(&data, QIODevice::ReadOnly);
149 stream >> map;
150
151 DEBUG() << map;
152
153 int requestId = map.value(OAU_OPERATION_ID, -1).toInt();
154 Request *request = m_requests.value(requestId, 0);
155
156 QString code = map.value(OAU_OPERATION_CODE).toString();
157 if (code == OAU_OPERATION_CODE_REQUEST_FINISHED) {
158 Q_ASSERT(request);
159 request->setResult(map.value(OAU_OPERATION_DATA).toMap());
160 } else if (code == OAU_OPERATION_CODE_REQUEST_FAILED) {
161 Q_ASSERT(request);
162 request->fail(map.value(OAU_OPERATION_ERROR_NAME).toString(),
163 map.value(OAU_OPERATION_ERROR_MESSAGE).toString());
164 } else if (code == OAU_OPERATION_CODE_REGISTER_HANDLER) {
165 m_handlers.append(map.value(OAU_OPERATION_HANDLER_ID).toString());
166 } else {
167 qWarning() << "Invalid operation code: " << code;
168 }
169}
170
171bool UiProxyPrivate::setupSocket()
172{
173 QString runtimeDir =
174 QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
175 QDir socketDir(runtimeDir + "/online-accounts-ui");
176 if (!socketDir.exists()) socketDir.mkpath(".");
177
178 QString uniqueName = QString("ui-%1").arg(socketCounter++);
179
180 /* If the file exists, it's a stale file: online-accounts-ui is a single
181 * instance process, and the only one creating files in this directory. */
182 if (Q_UNLIKELY(socketDir.exists(uniqueName))) {
183 socketDir.remove(uniqueName);
184 }
185
186 /* Create the socket and set it into listen mode */
187 return m_server.listen(socketDir.filePath(uniqueName));
188}
189
190void UiProxyPrivate::setupPromptSession()
191{
192 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
193 if (!env.value("QT_QPA_PLATFORM").startsWith("ubuntu")) return;
194
195 PromptSession *session =
196 MirHelper::instance()->createPromptSession(m_clientPid);
197 if (!session) return;
198
199 QString mirSocket = session->requestSocket();
200 if (mirSocket.isEmpty()) {
201 delete session;
202 return;
203 }
204
205 m_promptSession = session;
206
207 env.insert("MIR_SOCKET", mirSocket);
208 m_process.setProcessEnvironment(env);
209}
210
211bool UiProxyPrivate::init()
212{
213 if (Q_UNLIKELY(!setupSocket())) return false;
214
215 QStringList arguments;
216 /* the first argument is required to be the desktop file */
217 arguments.append("--desktop_file_hint=/usr/share/applications/online-accounts-ui.desktop");
218 arguments.append("--socket");
219 arguments.append(m_server.fullServerName());
220
221 if (m_clientPid) {
222 setupPromptSession();
223 }
224
225 m_process.start("/usr/bin/online-accounts-ui", arguments);
226 return m_process.waitForStarted();
227}
228
229void UiProxyPrivate::sendRequest(int requestId, Request *request)
230{
231 QVariantMap operation;
232 operation.insert(OAU_OPERATION_CODE, OAU_OPERATION_CODE_PROCESS);
233 operation.insert(OAU_OPERATION_ID, requestId);
234 operation.insert(OAU_OPERATION_DATA, request->parameters());
235 operation.insert(OAU_OPERATION_INTERFACE, request->interface());
236 operation.insert(OAU_OPERATION_CLIENT_PROFILE,
237 request->clientApparmorProfile());
238 sendOperation(operation);
239}
240
241void UiProxyPrivate::onRequestCompleted()
242{
243 Request *request = qobject_cast<Request*>(sender());
244 int id = m_requests.key(request, -1);
245 if (id != -1) {
246 m_requests.remove(id);
247 }
248}
249
250UiProxy::UiProxy(pid_t clientPid, QObject *parent):
251 QObject(parent),
252 d_ptr(new UiProxyPrivate(clientPid, this))
253{
254}
255
256UiProxy::~UiProxy()
257{
258}
259
260bool UiProxy::init()
261{
262 Q_D(UiProxy);
263 return d->init();
264}
265
266void UiProxy::handleRequest(Request *request)
267{
268 Q_D(UiProxy);
269
270 int requestId = d->m_nextRequestId++;
271 d->m_requests.insert(requestId, request);
272 QObject::connect(request, SIGNAL(completed()),
273 d, SLOT(onRequestCompleted()));
274 request->setInProgress(true);
275
276 if (d->m_socket && d->m_socket->isValid()) {
277 d->sendRequest(requestId, request);
278 }
279}
280
281bool UiProxy::hasHandlerFor(const QVariantMap &parameters)
282{
283 Q_D(UiProxy);
284
285 /* Find if there's any handlers expecting to handle the SignOnUi
286 * request having "parameters" as parameters.
287 * This is simply done by matching on the X-RequestHandler key (aka
288 * matchKey()), if present. We expect that account plugins add that field
289 * to their AuthSession requests which they want to handle themselves.
290 */
291 DEBUG() << parameters;
292 if (!parameters.contains(SSOUI_KEY_CLIENT_DATA)) return false;
293 QVariant variant = parameters[SSOUI_KEY_CLIENT_DATA];
294 QVariantMap clientData = variant.toMap();
295 QString matchId = clientData.value(OAU_REQUEST_MATCH_KEY).toString();
296 if (matchId.isEmpty()) return false;
297
298 return d->m_handlers.contains(matchId);
299}
300
301#include "ui-proxy.moc"
0302
=== added file 'online-accounts-service/ui-proxy.h'
--- online-accounts-service/ui-proxy.h 1970-01-01 00:00:00 +0000
+++ online-accounts-service/ui-proxy.h 2014-08-18 13:33:35 +0000
@@ -0,0 +1,54 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef OAU_UI_PROXY_H
22#define OAU_UI_PROXY_H
23
24#include <QObject>
25#include <QVariantMap>
26
27namespace OnlineAccountsUi {
28
29class Request;
30
31class UiProxyPrivate;
32class UiProxy: public QObject
33{
34 Q_OBJECT
35
36public:
37 explicit UiProxy(pid_t clientPid, QObject *parent = 0);
38 ~UiProxy();
39
40 bool init();
41 void handleRequest(Request *request);
42 bool hasHandlerFor(const QVariantMap &parameters);
43
44Q_SIGNALS:
45 void finished();
46
47private:
48 UiProxyPrivate *d_ptr;
49 Q_DECLARE_PRIVATE(UiProxy)
50};
51
52} // namespace
53
54#endif // OAU_UI_PROXY_H
055
=== renamed directory 'src' => 'online-accounts-ui'
=== modified file 'online-accounts-ui/application-manager.cpp'
--- src/application-manager.cpp 2014-06-06 07:19:34 +0000
+++ online-accounts-ui/application-manager.cpp 2014-08-18 13:33:35 +0000
@@ -130,6 +130,16 @@
130130
131 if (Q_UNLIKELY(profile.isEmpty())) return QVariantMap();131 if (Q_UNLIKELY(profile.isEmpty())) return QVariantMap();
132132
133 /* Special case: when the applicationId is "system-settings", we don't
134 * require the existance of the .application file, because this request
135 * will always be about creating a new account. */
136 if (claimedAppId == "system-settings") {
137 QVariantMap app;
138 app.insert(QStringLiteral("id"), claimedAppId);
139 app.insert(QStringLiteral("profile"), profile);
140 return app;
141 }
142
133 QString applicationId = claimedAppId;143 QString applicationId = claimedAppId;
134 Accounts::Application application =144 Accounts::Application application =
135 AccountManager::instance()->application(applicationId);145 AccountManager::instance()->application(applicationId);
136146
=== modified file 'online-accounts-ui/browser-request.cpp'
--- src/browser-request.cpp 2014-04-29 14:34:44 +0000
+++ online-accounts-ui/browser-request.cpp 2014-08-18 13:33:35 +0000
@@ -28,6 +28,7 @@
2828
29#include <QDir>29#include <QDir>
30#include <QQmlContext>30#include <QQmlContext>
31#include <QQmlEngine>
31#include <QStandardPaths>32#include <QStandardPaths>
32#include <QTimer>33#include <QTimer>
33#include <SignOn/uisessiondata_priv.h>34#include <SignOn/uisessiondata_priv.h>
@@ -101,6 +102,7 @@
101102
102BrowserRequestPrivate::~BrowserRequestPrivate()103BrowserRequestPrivate::~BrowserRequestPrivate()
103{104{
105 DEBUG();
104 closeView();106 closeView();
105 delete m_dialog;107 delete m_dialog;
106}108}
@@ -133,18 +135,9 @@
133 QObject::connect(m_dialog, SIGNAL(finished(int)),135 QObject::connect(m_dialog, SIGNAL(finished(int)),
134 this, SLOT(onFinished()));136 this, SLOT(onFinished()));
135137
136 QUrl webview("qrc:/MainWindow.qml");138 m_dialog->engine()->addImportPath(PLUGIN_PRIVATE_MODULE_DIR);
137 QDir qmlDir("/usr/share/signon-ui/qml");
138 if (qmlDir.exists())
139 {
140 QFileInfo qmlFile(qmlDir.absolutePath() + "/MainWindow.qml");
141 if (qmlFile.exists())
142 webview.setUrl(qmlFile.absoluteFilePath());
143 }
144
145 m_dialog->rootContext()->setContextProperty("request", this);139 m_dialog->rootContext()->setContextProperty("request", this);
146 m_dialog->rootContext()->setContextProperty("rootDir", m_rootDir);140 m_dialog->setSource(QUrl("qrc:/qml/SignOnUiPage.qml"));
147 m_dialog->setSource(webview);
148 } else {141 } else {
149 DEBUG() << "Setting request on handler";142 DEBUG() << "Setting request on handler";
150 q->handler()->setRequest(this);143 q->handler()->setRequest(this);
@@ -187,6 +180,7 @@
187 m_dialog->accept();180 m_dialog->accept();
188 }181 }
189 } else {182 } else {
183 DEBUG();
190 onFinished();184 onFinished();
191 }185 }
192 }186 }
@@ -208,7 +202,7 @@
208202
209void BrowserRequestPrivate::onLoadFinished(bool ok)203void BrowserRequestPrivate::onLoadFinished(bool ok)
210{204{
211 Q_Q(const BrowserRequest);205 Q_Q(BrowserRequest);
212206
213 DEBUG() << "Load finished" << ok;207 DEBUG() << "Load finished" << ok;
214208
@@ -219,9 +213,7 @@
219213
220 if (m_dialog && !m_dialog->isVisible()) {214 if (m_dialog && !m_dialog->isVisible()) {
221 if (m_responseUrl.isEmpty()) {215 if (m_responseUrl.isEmpty()) {
222 Dialog::ShowMode mode =216 q->setWindow(m_dialog);
223 (q->windowId() == 0) ? Dialog::TopLevel : Dialog::Transient;
224 m_dialog->show(q->windowId(), mode);
225 } else {217 } else {
226 onFinished();218 onFinished();
227 }219 }
@@ -277,6 +269,7 @@
277{269{
278 Q_Q(BrowserRequest);270 Q_Q(BrowserRequest);
279271
272 DEBUG();
280 if (q->hasHandler()) {273 if (q->hasHandler()) {
281 q->handler()->setRequest(0);274 q->handler()->setRequest(0);
282 } else if (m_dialog) {275 } else if (m_dialog) {
@@ -284,23 +277,18 @@
284 }277 }
285}278}
286279
287BrowserRequest::BrowserRequest(const QDBusConnection &connection,280BrowserRequest::BrowserRequest(int id,
288 const QDBusMessage &message,281 const QString &clientProfile,
289 const QVariantMap &parameters,282 const QVariantMap &parameters,
290 QObject *parent):283 QObject *parent):
291 Request(connection, message, parameters, parent),284 Request(id, clientProfile, parameters, parent),
292 d_ptr(new BrowserRequestPrivate(this))285 d_ptr(new BrowserRequestPrivate(this))
293{286{
294}287}
295288
296BrowserRequest::~BrowserRequest()289BrowserRequest::~BrowserRequest()
297{290{
298}291 delete d_ptr;
299
300void BrowserRequest::removeIdentityData(quint32 id)
301{
302 QDir rootDir(BrowserRequestPrivate::rootDirForIdentity(id));
303 rootDir.removeRecursively();
304}292}
305293
306void BrowserRequest::start()294void BrowserRequest::start()
307295
=== modified file 'online-accounts-ui/browser-request.h'
--- src/browser-request.h 2014-04-29 14:34:44 +0000
+++ online-accounts-ui/browser-request.h 2014-08-18 13:33:35 +0000
@@ -34,14 +34,12 @@
34 Q_OBJECT34 Q_OBJECT
3535
36public:36public:
37 explicit BrowserRequest(const QDBusConnection &connection,37 explicit BrowserRequest(int id,
38 const QDBusMessage &message,38 const QString &clientProfile,
39 const QVariantMap &parameters,39 const QVariantMap &parameters,
40 QObject *parent = 0);40 QObject *parent = 0);
41 ~BrowserRequest();41 ~BrowserRequest();
4242
43 static void removeIdentityData(quint32 id);
44
45 // reimplemented virtual methods43 // reimplemented virtual methods
46 void start();44 void start();
4745
4846
=== modified file 'online-accounts-ui/globals.h'
--- src/globals.h 2014-04-29 12:11:55 +0000
+++ online-accounts-ui/globals.h 2014-08-18 13:33:35 +0000
@@ -29,6 +29,7 @@
29#define OAU_KEY_PROVIDER QStringLiteral("provider")29#define OAU_KEY_PROVIDER QStringLiteral("provider")
30#define OAU_KEY_SERVICE_TYPE QStringLiteral("serviceType")30#define OAU_KEY_SERVICE_TYPE QStringLiteral("serviceType")
31#define OAU_KEY_WINDOW_ID QStringLiteral("windowId")31#define OAU_KEY_WINDOW_ID QStringLiteral("windowId")
32#define OAU_KEY_PID QStringLiteral("pid")
3233
33// D-Bus error names34// D-Bus error names
34#define OAU_ERROR_PREFIX "com.ubuntu.OnlineAccountsUi."35#define OAU_ERROR_PREFIX "com.ubuntu.OnlineAccountsUi."
3536
=== added file 'online-accounts-ui/ipc.cpp'
--- online-accounts-ui/ipc.cpp 1970-01-01 00:00:00 +0000
+++ online-accounts-ui/ipc.cpp 2014-08-18 13:33:35 +0000
@@ -0,0 +1,184 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "ipc.h"
22
23#include <QByteArray>
24#include <QFile>
25#include <QIODevice>
26#include <QSocketNotifier>
27
28using namespace OnlineAccountsUi;
29
30static const QByteArray welcomeMessage = "OAUinitIPC";
31
32namespace OnlineAccountsUi {
33
34class IpcPrivate: public QObject
35{
36 Q_OBJECT
37 Q_DECLARE_PUBLIC(Ipc)
38
39public:
40 inline IpcPrivate(Ipc *ipc);
41 ~IpcPrivate() {};
42
43 void setChannels(QIODevice *readChannel, QIODevice *writeChannel);
44
45private Q_SLOTS:
46 void onReadyRead();
47
48private:
49 bool waitWelcomeMessage();
50
51private:
52 QIODevice *m_readChannel;
53 QIODevice *m_writeChannel;
54 int m_expectedLength;
55 bool m_gotWelcomeMessage;
56 QByteArray m_readBuffer;
57 mutable Ipc *q_ptr;
58};
59
60}; // namespace
61
62IpcPrivate::IpcPrivate(Ipc *ipc):
63 QObject(ipc),
64 m_readChannel(0),
65 m_writeChannel(0),
66 m_expectedLength(0),
67 m_gotWelcomeMessage(false),
68 q_ptr(ipc)
69{
70}
71
72void IpcPrivate::setChannels(QIODevice *readChannel, QIODevice *writeChannel)
73{
74 m_readChannel = readChannel;
75 m_writeChannel = writeChannel;
76 QObject::connect(m_readChannel, SIGNAL(readyRead()),
77 this, SLOT(onReadyRead()));
78 /* QFile need special handling */
79 QFile *file = qobject_cast<QFile*>(m_readChannel);
80 if (file != 0) {
81 QSocketNotifier *notifier = new QSocketNotifier(file->handle(),
82 QSocketNotifier::Read,
83 this);
84 QObject::connect(notifier, SIGNAL(activated(int)),
85 this, SLOT(onReadyRead()));
86 } else {
87 /* If the read channel is not a QFile, it means it's not the standard
88 * input, therefore we won't have the need to wait for the welcome
89 * message. */
90 m_gotWelcomeMessage = true;
91 }
92 onReadyRead();
93
94 file = qobject_cast<QFile*>(m_writeChannel);
95 if (file != 0) {
96 m_writeChannel->write(welcomeMessage);
97 }
98}
99
100void IpcPrivate::onReadyRead()
101{
102 Q_Q(Ipc);
103
104 while (true) {
105 if (m_expectedLength == 0) {
106 /* We are beginning a new read */
107
108 /* skip all noise */
109 if (!waitWelcomeMessage()) break;
110
111 int length;
112 int bytesRead = m_readChannel->read((char *)&length,
113 sizeof(length));
114 if (bytesRead < int(sizeof(length))) break;
115 m_expectedLength = length;
116 m_readBuffer.clear();
117 }
118
119 int neededBytes = m_expectedLength - m_readBuffer.length();
120 QByteArray buffer = m_readChannel->read(neededBytes);
121 m_readBuffer += buffer;
122 if (buffer.length() < neededBytes) break;
123 if (m_readBuffer.length() == m_expectedLength) {
124 Q_EMIT q->dataReady(m_readBuffer);
125 m_expectedLength = 0;
126 }
127 }
128}
129
130bool IpcPrivate::waitWelcomeMessage()
131{
132 if (m_gotWelcomeMessage) return true;
133
134 /* All Qt applications on the Nexus 4 write some dust to stdout when
135 * starting. So, skip all input until a well-defined welcome message is
136 * found */
137
138 QByteArray buffer;
139 int startCheckIndex = 0;
140 do {
141 buffer = m_readChannel->peek(40);
142 int found = buffer.indexOf(welcomeMessage, startCheckIndex);
143 int skip = (found >= 0) ? found : buffer.length() - welcomeMessage.length();
144 if (found >= 0) {
145 buffer = m_readChannel->read(skip + welcomeMessage.length());
146 m_gotWelcomeMessage = true;
147 return true;
148 }
149 if (skip > 0) {
150 buffer = m_readChannel->read(skip);
151 } else {
152 buffer.clear();
153 }
154 } while (!buffer.isEmpty());
155
156 return false;
157}
158
159Ipc::Ipc(QObject *parent):
160 QObject(parent),
161 d_ptr(new IpcPrivate(this))
162{
163}
164
165Ipc::~Ipc()
166{
167}
168
169void Ipc::setChannels(QIODevice *readChannel, QIODevice *writeChannel)
170{
171 Q_D(Ipc);
172 d->setChannels(readChannel, writeChannel);
173}
174
175void Ipc::write(const QByteArray &data)
176{
177 Q_D(Ipc);
178 int length = data.count();
179 d->m_writeChannel->write((char *)&length, sizeof(length));
180 d->m_writeChannel->write(data);
181 d->m_writeChannel->waitForBytesWritten(-1);
182}
183
184#include "ipc.moc"
0185
=== added file 'online-accounts-ui/ipc.h'
--- online-accounts-ui/ipc.h 1970-01-01 00:00:00 +0000
+++ online-accounts-ui/ipc.h 2014-08-18 13:33:35 +0000
@@ -0,0 +1,67 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef OAU_IPC_H
22#define OAU_IPC_H
23
24#include <QObject>
25
26class QByteArray;
27class QIODevice;
28
29#define OAU_OPERATION_CODE "code"
30#define OAU_OPERATION_CODE_PROCESS "process"
31#define OAU_OPERATION_CODE_REGISTER_HANDLER "newHandler"
32#define OAU_OPERATION_CODE_REQUEST_FINISHED "finished"
33#define OAU_OPERATION_CODE_REQUEST_FAILED "failed"
34#define OAU_OPERATION_ID "id"
35#define OAU_OPERATION_DATA "data"
36#define OAU_OPERATION_INTERFACE "interface"
37#define OAU_OPERATION_CLIENT_PROFILE "profile"
38#define OAU_OPERATION_ERROR_NAME "errname"
39#define OAU_OPERATION_ERROR_MESSAGE "errmsg"
40#define OAU_OPERATION_HANDLER_ID "handlerId"
41#define OAU_REQUEST_MATCH_KEY "X-RequestHandler"
42
43namespace OnlineAccountsUi {
44
45class IpcPrivate;
46class Ipc: public QObject
47{
48 Q_OBJECT
49
50public:
51 Ipc(QObject *parent = 0);
52 ~Ipc();
53
54 void setChannels(QIODevice *readChannel, QIODevice *writeChannel);
55 void write(const QByteArray &data);
56
57Q_SIGNALS:
58 void dataReady(QByteArray &data);
59
60private:
61 IpcPrivate *d_ptr;
62 Q_DECLARE_PRIVATE(Ipc)
63};
64
65}; // namespace
66
67#endif // OAU_IPC_H
068
=== modified file 'online-accounts-ui/main.cpp'
--- src/main.cpp 2014-04-29 12:11:55 +0000
+++ online-accounts-ui/main.cpp 2014-08-18 13:33:35 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2013 Canonical Ltd.2 * Copyright (C) 2013-2014 Canonical Ltd.
3 *3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *5 *
@@ -21,14 +21,9 @@
21#include "debug.h"21#include "debug.h"
22#include "globals.h"22#include "globals.h"
23#include "i18n.h"23#include "i18n.h"
24#include "inactivity-timer.h"24#include "ui-server.h"
25#include "indicator-service.h"
26#include "request-manager.h"
27#include "service.h"
28#include "signonui-service.h"
2925
30#include <QGuiApplication>26#include <QGuiApplication>
31#include <QDBusConnection>
32#include <QLibrary>27#include <QLibrary>
33#include <QProcessEnvironment>28#include <QProcessEnvironment>
3429
@@ -37,7 +32,6 @@
37int main(int argc, char **argv)32int main(int argc, char **argv)
38{33{
39 QGuiApplication app(argc, argv);34 QGuiApplication app(argc, argv);
40 app.setQuitOnLastWindowClosed(false);
4135
42 /* The testability driver is only loaded by QApplication but not by36 /* The testability driver is only loaded by QApplication but not by
43 * QGuiApplication. However, QApplication depends on QWidget which would37 * QGuiApplication. However, QApplication depends on QWidget which would
@@ -70,66 +64,22 @@
70 setLoggingLevel(value);64 setLoggingLevel(value);
71 }65 }
7266
73 /* default daemonTimeout to 5 seconds */
74 int daemonTimeout = 5;
75
76 /* override daemonTimeout if OAU_DAEMON_TIMEOUT is set */
77 if (environment.contains(QLatin1String("OAU_DAEMON_TIMEOUT"))) {
78 bool isOk;
79 int value = environment.value(
80 QLatin1String("OAU_DAEMON_TIMEOUT")).toInt(&isOk);
81 if (isOk)
82 daemonTimeout = value;
83 }
84
85 initTr(I18N_DOMAIN, NULL);67 initTr(I18N_DOMAIN, NULL);
8668
87 RequestManager *requestManager = new RequestManager();69 QStringList arguments = app.arguments();
8870 int i = arguments.indexOf("--socket");
89 Service *service = new Service();71 if (i < 0 || i + 1 >= arguments.count()) {
90 QDBusConnection connection = QDBusConnection::sessionBus();72 qWarning() << "Missing --socket argument";
91 connection.registerService(OAU_SERVICE_NAME);73 return EXIT_FAILURE;
92 connection.registerObject(OAU_OBJECT_PATH, service);74 }
9375
94 SignOnUi::Service *signonuiService = new SignOnUi::Service();76 UiServer server(arguments[i + 1]);
95 connection.registerService(SIGNONUI_SERVICE_NAME);77 QObject::connect(&server, SIGNAL(finished()),
96 connection.registerObject(SIGNONUI_OBJECT_PATH, signonuiService,78 &app, SLOT(quit()));
97 QDBusConnection::ExportAllContents);79 if (Q_UNLIKELY(!server.init())) {
9880 qWarning() << "Could not connect to socket";
99 SignOnUi::IndicatorService *indicatorService =81 return EXIT_FAILURE;
100 new SignOnUi::IndicatorService();82 }
101 connection.registerService(WEBCREDENTIALS_BUS_NAME);83
102 connection.registerObject(WEBCREDENTIALS_OBJECT_PATH,84 return app.exec();
103 indicatorService->serviceObject());
104
105
106 InactivityTimer *inactivityTimer = 0;
107 if (daemonTimeout > 0) {
108 inactivityTimer = new InactivityTimer(daemonTimeout * 1000);
109 inactivityTimer->watchObject(requestManager);
110 inactivityTimer->watchObject(indicatorService);
111 QObject::connect(inactivityTimer, SIGNAL(timeout()),
112 &app, SLOT(quit()));
113 }
114
115 int ret = app.exec();
116
117 connection.unregisterService(WEBCREDENTIALS_BUS_NAME);
118 connection.unregisterObject(WEBCREDENTIALS_OBJECT_PATH);
119 delete indicatorService;
120
121 connection.unregisterService(SIGNONUI_SERVICE_NAME);
122 connection.unregisterObject(SIGNONUI_OBJECT_PATH);
123 delete signonuiService;
124
125 connection.unregisterService(OAU_SERVICE_NAME);
126 connection.unregisterObject(OAU_OBJECT_PATH);
127 delete service;
128
129 delete requestManager;
130
131 delete inactivityTimer;
132
133 return ret;
134}85}
135
13686
=== modified file 'online-accounts-ui/module/OAuth.qml'
--- src/module/OAuth.qml 2014-04-29 12:11:55 +0000
+++ online-accounts-ui/module/OAuth.qml 2014-08-18 13:33:35 +0000
@@ -55,7 +55,6 @@
55 if (request) {55 if (request) {
56 console.log("RequestHandler captured request!")56 console.log("RequestHandler captured request!")
57 loader.setSource("WebView.qml", {57 loader.setSource("WebView.qml", {
58 "rootDir": request.rootDir,
59 "signonRequest": request58 "signonRequest": request
60 })59 })
61 } else {60 } else {
6261
=== modified file 'online-accounts-ui/module/WebView.qml'
--- src/module/WebView.qml 2014-04-29 12:11:55 +0000
+++ online-accounts-ui/module/WebView.qml 2014-08-18 13:33:35 +0000
@@ -5,7 +5,6 @@
55
6UbuntuWebView {6UbuntuWebView {
7 property QtObject signonRequest7 property QtObject signonRequest
8 property url rootDir
98
10 Component.onCompleted: url = signonRequest.startUrl9 Component.onCompleted: url = signonRequest.startUrl
1110
@@ -22,6 +21,6 @@
22 onUrlChanged: signonRequest.currentUrl = url21 onUrlChanged: signonRequest.currentUrl = url
2322
24 context: UbuntuWebContext {23 context: UbuntuWebContext {
25 dataPath: rootDir24 dataPath: signonRequest.rootDir
26 }25 }
27}26}
2827
=== modified file 'online-accounts-ui/module/qmldir.in'
--- src/module/qmldir.in 2013-06-05 11:33:39 +0000
+++ online-accounts-ui/module/qmldir.in 2014-08-18 13:33:35 +0000
@@ -1,7 +1,9 @@
1module $${API_URI}1module $${API_URI}
2KeyboardRectangle 1.0 KeyboardRectangle.qml
2OAuthMain 1.0 OAuthMain.qml3OAuthMain 1.0 OAuthMain.qml
3OAuth 1.0 OAuth.qml4OAuth 1.0 OAuth.qml
4Options 1.0 Options.qml5Options 1.0 Options.qml
5RemovalConfirmation 1.0 RemovalConfirmation.qml6RemovalConfirmation 1.0 RemovalConfirmation.qml
6ServiceItem 1.0 ServiceItem.qml7ServiceItem 1.0 ServiceItem.qml
7ServiceSwitches 1.0 ServiceSwitches.qml8ServiceSwitches 1.0 ServiceSwitches.qml
9WebView 1.0 WebView.qml
810
=== modified file 'online-accounts-ui/notification.cpp'
--- src/notification.cpp 2014-06-05 13:28:30 +0000
+++ online-accounts-ui/notification.cpp 2014-08-18 13:33:35 +0000
@@ -108,6 +108,14 @@
108 this, NULL);108 this, NULL);
109}109}
110110
111void Notification::setSnapDecision(bool snapDecision)
112{
113 Q_D(Notification);
114 notify_notification_set_hint(d->m_notification,
115 "x-canonical-snap-decisions",
116 g_variant_new_boolean(snapDecision));
117}
118
111void Notification::show()119void Notification::show()
112{120{
113 Q_D(Notification);121 Q_D(Notification);
114122
=== modified file 'online-accounts-ui/notification.h'
--- src/notification.h 2014-06-05 13:28:30 +0000
+++ online-accounts-ui/notification.h 2014-08-18 13:33:35 +0000
@@ -37,6 +37,7 @@
37 ~Notification();37 ~Notification();
3838
39 void addAction(const QString &action, const QString &label);39 void addAction(const QString &action, const QString &label);
40 void setSnapDecision(bool snapDecision);
4041
41public Q_SLOTS:42public Q_SLOTS:
42 void show();43 void show();
4344
=== renamed file 'src/online-accounts-ui.pro' => 'online-accounts-ui/online-accounts-ui-helper.pro'
--- src/online-accounts-ui.pro 2014-06-05 13:28:30 +0000
+++ online-accounts-ui/online-accounts-ui-helper.pro 2014-08-18 13:33:35 +0000
@@ -21,16 +21,10 @@
21 libsignon-qt5 \21 libsignon-qt5 \
22 signon-plugins-common22 signon-plugins-common
2323
24I18N_DOMAIN="ubuntu-system-settings-online-accounts"
25SIGNONUI_I18N_DOMAIN="signon-ui"
26
27DEFINES += \24DEFINES += \
28 I18N_DOMAIN=\\\"$${I18N_DOMAIN}\\\" \25 I18N_DOMAIN=\\\"$${I18N_DOMAIN}\\\" \
29 SIGNONUI_I18N_DOMAIN=\\\"$${SIGNONUI_I18N_DOMAIN}\\\"26 SIGNONUI_I18N_DOMAIN=\\\"$${SIGNONUI_I18N_DOMAIN}\\\"
3027
31DBUS_ADAPTORS += \
32 com.ubuntu.OnlineAccountsUi.xml
33
34DEFINES += \28DEFINES += \
35 DEBUG_ENABLED \29 DEBUG_ENABLED \
36 OAU_PLUGIN_DIR=\\\"$${ONLINE_ACCOUNTS_PLUGIN_DIR}/\\\" \30 OAU_PLUGIN_DIR=\\\"$${ONLINE_ACCOUNTS_PLUGIN_DIR}/\\\" \
@@ -44,19 +38,15 @@
44 debug.cpp \38 debug.cpp \
45 dialog.cpp \39 dialog.cpp \
46 i18n.cpp \40 i18n.cpp \
47 inactivity-timer.cpp \41 ipc.cpp \
48 indicator-service.cpp \
49 main.cpp \42 main.cpp \
50 notification.cpp \43 notification.cpp \
51 panel-request.cpp \44 panel-request.cpp \
52 provider-request.cpp \45 provider-request.cpp \
53 reauthenticator.cpp \
54 request.cpp \46 request.cpp \
55 request-handler.cpp \47 request-handler.cpp \
56 request-manager.cpp \
57 service.cpp \
58 signonui-request.cpp \48 signonui-request.cpp \
59 signonui-service.cpp49 ui-server.cpp
6050
61HEADERS += \51HEADERS += \
62 access-model.h \52 access-model.h \
@@ -66,33 +56,20 @@
66 debug.h \56 debug.h \
67 dialog.h \57 dialog.h \
68 i18n.h \58 i18n.h \
69 inactivity-timer.h \59 ipc.h \
70 indicator-service.h \
71 notification.h \60 notification.h \
72 panel-request.h \61 panel-request.h \
73 provider-request.h \62 provider-request.h \
74 reauthenticator.h \
75 request.h \63 request.h \
76 request-handler.h \64 request-handler.h \
77 request-manager.h \
78 service.h \
79 signonui-request.h \65 signonui-request.h \
80 signonui-service.h66 ui-server.h
8167
82QML_SOURCES = \68QML_SOURCES = \
83 qml/AccountCreationPage.qml \69 qml/AccountCreationPage.qml \
84 qml/AccountEditPage.qml \
85 qml/AccountItem.qml \
86 qml/AccountsPage.qml \
87 qml/AddAccountLabel.qml \
88 qml/AuthorizationPage.qml \70 qml/AuthorizationPage.qml \
89 qml/MainPage.qml \
90 qml/NewAccountPage.qml \
91 qml/NoAccountsPage.qml \
92 qml/NormalStartupPage.qml \
93 qml/ProviderPluginList.qml \
94 qml/ProviderRequest.qml \71 qml/ProviderRequest.qml \
95 qml/ProvidersList.qml72 qml/SignOnUiPage.qml
9673
97RESOURCES += \74RESOURCES += \
98 ui.qrc75 ui.qrc
@@ -102,17 +79,8 @@
102 $${RESOURCES}79 $${RESOURCES}
10380
104QMAKE_SUBSTITUTES += \81QMAKE_SUBSTITUTES += \
105 com.ubuntu.OnlineAccountsUi.service.in \
106 online-accounts-ui.desktop.in82 online-accounts-ui.desktop.in
10783
108DBUS_ADAPTORS += \
109 com.canonical.indicators.webcredentials.xml
110
111service.path = $${INSTALL_PREFIX}/share/dbus-1/services
112service.files = \
113 com.ubuntu.OnlineAccountsUi.service
114INSTALLS += service
115
116desktop.path = $${INSTALL_PREFIX}/share/applications84desktop.path = $${INSTALL_PREFIX}/share/applications
117desktop.files += online-accounts-ui.desktop85desktop.files += online-accounts-ui.desktop
118INSTALLS += desktop86INSTALLS += desktop
11987
=== renamed file 'src/src.pro' => 'online-accounts-ui/online-accounts-ui.pro'
--- src/src.pro 2014-04-29 12:11:55 +0000
+++ online-accounts-ui/online-accounts-ui.pro 2014-08-18 13:33:35 +0000
@@ -1,4 +1,4 @@
1TEMPLATE = subdirs1TEMPLATE = subdirs
2SUBDIRS = \2SUBDIRS = \
3 module \3 module \
4 online-accounts-ui.pro4 online-accounts-ui-helper.pro
55
=== modified file 'online-accounts-ui/panel-request.cpp'
--- src/panel-request.cpp 2014-05-30 08:09:02 +0000
+++ online-accounts-ui/panel-request.cpp 2014-08-18 13:33:35 +0000
@@ -65,7 +65,9 @@
65PanelRequestPrivate::~PanelRequestPrivate()65PanelRequestPrivate::~PanelRequestPrivate()
66{66{
67 DEBUG() << "view:" << m_view;67 DEBUG() << "view:" << m_view;
68 /* TODO Uncomment this once QTBUG-40766 is resolved:
68 delete m_view;69 delete m_view;
70 */
69}71}
7072
71void PanelRequestPrivate::start()73void PanelRequestPrivate::start()
@@ -103,18 +105,15 @@
103105
104 if (!visible) {106 if (!visible) {
105 q->setResult(QVariantMap());107 q->setResult(QVariantMap());
106 /* FIXME HACK: remove when window reparenting is implemented */
107 if (QGuiApplication::platformName().startsWith("ubuntu")) {
108 QDesktopServices::openUrl(QUrl("application:///ubuntu-system-settings.desktop"));
109 }
110 }108 }
111}109}
112110
113PanelRequest::PanelRequest(const QDBusConnection &connection,111PanelRequest::PanelRequest(const QString &interface,
114 const QDBusMessage &message,112 int id,
113 const QString &clientProfile,
115 const QVariantMap &parameters,114 const QVariantMap &parameters,
116 QObject *parent):115 QObject *parent):
117 Request(connection, message, parameters, parent),116 Request(interface, id, clientProfile, parameters, parent),
118 d_ptr(new PanelRequestPrivate(this))117 d_ptr(new PanelRequestPrivate(this))
119{118{
120}119}
121120
=== modified file 'online-accounts-ui/panel-request.h'
--- src/panel-request.h 2014-05-30 08:09:02 +0000
+++ online-accounts-ui/panel-request.h 2014-08-18 13:33:35 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2013 Canonical Ltd.2 * Copyright (C) 2013-2014 Canonical Ltd.
3 *3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *5 *
@@ -31,8 +31,9 @@
31 Q_OBJECT31 Q_OBJECT
3232
33public:33public:
34 explicit PanelRequest(const QDBusConnection &connection,34 explicit PanelRequest(const QString &interface,
35 const QDBusMessage &message,35 int id,
36 const QString &clientProfile,
36 const QVariantMap &parameters,37 const QVariantMap &parameters,
37 QObject *parent = 0);38 QObject *parent = 0);
38 ~PanelRequest();39 ~PanelRequest();
3940
=== modified file 'online-accounts-ui/provider-request.cpp'
--- src/provider-request.cpp 2014-05-30 09:28:43 +0000
+++ online-accounts-ui/provider-request.cpp 2014-08-18 13:33:35 +0000
@@ -164,11 +164,12 @@
164 m_view->close();164 m_view->close();
165}165}
166166
167ProviderRequest::ProviderRequest(const QDBusConnection &connection,167ProviderRequest::ProviderRequest(const QString &interface,
168 const QDBusMessage &message,168 int id,
169 const QString &clientProfile,
169 const QVariantMap &parameters,170 const QVariantMap &parameters,
170 QObject *parent):171 QObject *parent):
171 Request(connection, message, parameters, parent),172 Request(interface, id, clientProfile, parameters, parent),
172 d_ptr(new ProviderRequestPrivate(this))173 d_ptr(new ProviderRequestPrivate(this))
173{174{
174}175}
175176
=== modified file 'online-accounts-ui/provider-request.h'
--- src/provider-request.h 2014-02-03 10:27:39 +0000
+++ online-accounts-ui/provider-request.h 2014-08-18 13:33:35 +0000
@@ -31,8 +31,9 @@
31 Q_OBJECT31 Q_OBJECT
3232
33public:33public:
34 explicit ProviderRequest(const QDBusConnection &connection,34 explicit ProviderRequest(const QString &interface,
35 const QDBusMessage &message,35 int id,
36 const QString &clientProfile,
36 const QVariantMap &parameters,37 const QVariantMap &parameters,
37 QObject *parent = 0);38 QObject *parent = 0);
38 ~ProviderRequest();39 ~ProviderRequest();
3940
=== modified file 'online-accounts-ui/qml/ProviderRequest.qml'
--- src/qml/ProviderRequest.qml 2014-05-29 21:14:11 +0000
+++ online-accounts-ui/qml/ProviderRequest.qml 2014-08-18 13:33:35 +0000
@@ -54,7 +54,7 @@
54 id: loader54 id: loader
55 anchors.fill: parent55 anchors.fill: parent
56 active: false56 active: false
57 sourceComponent: accessModel.count <= 1 ? accountCreationPage : authorizationPage57 sourceComponent: (accessModel.count <= 1 || applicationInfo.id === "system-settings") ? accountCreationPage : authorizationPage
58 onLoaded: {58 onLoaded: {
59 // use this trick to break the sourceComponent binding59 // use this trick to break the sourceComponent binding
60 var tmp = sourceComponent60 var tmp = sourceComponent
@@ -165,10 +165,17 @@
165 }165 }
166166
167 function grantAccessIfReady() {167 function grantAccessIfReady() {
168 if (root.__createdAccountId != 0 &&168 if (root.__createdAccountId != 0) {
169 accountsModel.indexOfAccount(root.__createdAccountId) >= 0) {169 // If the request comes from system settings, stop here
170 root.grantAccess(root.__createdAccountId)170 if (applicationInfo.id === "system-settings") {
171 root.__createdAccountId = 0171 root.allowed(root.__createdAccountId)
172 return
173 }
174
175 if (accountsModel.indexOfAccount(root.__createdAccountId) >= 0) {
176 root.grantAccess(root.__createdAccountId)
177 root.__createdAccountId = 0
178 }
172 }179 }
173 }180 }
174181
175182
=== added file 'online-accounts-ui/qml/SignOnUiPage.qml'
--- online-accounts-ui/qml/SignOnUiPage.qml 1970-01-01 00:00:00 +0000
+++ online-accounts-ui/qml/SignOnUiPage.qml 2014-08-18 13:33:35 +0000
@@ -0,0 +1,40 @@
1import QtQuick 2.0
2import Ubuntu.Components 0.1
3import Ubuntu.Components.ListItems 0.1 as ListItem
4import Ubuntu.OnlineAccounts.Plugin 1.0
5
6MainView {
7 id: root
8
9 property var signonRequest: request
10
11 width: units.gu(60)
12 height: units.gu(90)
13
14 Page {
15 WebView {
16 id: loader
17 signonRequest: root.signonRequest
18
19 anchors {
20 fill: parent
21 bottomMargin: Math.max(osk.height, cancelButton.height)
22 }
23 }
24
25 ListItem.SingleControl {
26 id: cancelButton
27 anchors.bottom: parent.bottom
28 showDivider: false
29 control: Button {
30 text: i18n.dtr("ubuntu-system-settings-online-accounts", "Cancel")
31 width: parent.width - units.gu(4)
32 onClicked: signonRequest.cancel()
33 }
34 }
35
36 KeyboardRectangle {
37 id: osk
38 }
39 }
40}
041
=== modified file 'online-accounts-ui/request-handler.cpp'
--- src/request-handler.cpp 2014-04-29 14:34:44 +0000
+++ online-accounts-ui/request-handler.cpp 2014-08-18 13:33:35 +0000
@@ -21,6 +21,7 @@
21#include "request-handler.h"21#include "request-handler.h"
2222
23#include "debug.h"23#include "debug.h"
24#include "ui-server.h"
2425
25#include <SignOn/uisessiondata_priv.h>26#include <SignOn/uisessiondata_priv.h>
26#include <QDBusArgument>27#include <QDBusArgument>
@@ -66,6 +67,11 @@
66 d_ptr(new RequestHandlerPrivate(this))67 d_ptr(new RequestHandlerPrivate(this))
67{68{
68 allRequestHandlers.append(this);69 allRequestHandlers.append(this);
70
71 OnlineAccountsUi::UiServer *server =
72 OnlineAccountsUi::UiServer::instance();
73 Q_ASSERT(server);
74 server->registerHandler(this);
69}75}
7076
71RequestHandler::~RequestHandler()77RequestHandler::~RequestHandler()
7278
=== modified file 'online-accounts-ui/request.cpp'
--- src/request.cpp 2014-05-30 08:09:02 +0000
+++ online-accounts-ui/request.cpp 2014-08-18 13:33:35 +0000
@@ -51,8 +51,9 @@
51 Q_DECLARE_PUBLIC(Request)51 Q_DECLARE_PUBLIC(Request)
5252
53public:53public:
54 RequestPrivate(const QDBusConnection &connection,54 RequestPrivate(const QString &interface,
55 const QDBusMessage &message,55 int id,
56 const QString &clientProfile,
56 const QVariantMap &parameters,57 const QVariantMap &parameters,
57 Request *request);58 Request *request);
58 ~RequestPrivate();59 ~RequestPrivate();
@@ -63,33 +64,36 @@
6364
64private:65private:
65 void setWindow(QWindow *window);66 void setWindow(QWindow *window);
66 QString findClientApparmorProfile();
6767
68private:68private:
69 mutable Request *q_ptr;69 mutable Request *q_ptr;
70 QDBusConnection m_connection;70 QString m_interface;
71 QDBusMessage m_message;71 int m_id;
72 QVariantMap m_parameters;72 QVariantMap m_parameters;
73 QString m_clientApparmorProfile;73 QString m_clientApparmorProfile;
74 bool m_inProgress;74 bool m_inProgress;
75 QPointer<QWindow> m_window;75 QPointer<QWindow> m_window;
76 QString m_errorName;
77 QString m_errorMessage;
78 QVariantMap m_result;
76};79};
7780
78} // namespace81} // namespace
7982
80RequestPrivate::RequestPrivate(const QDBusConnection &connection,83RequestPrivate::RequestPrivate(const QString &interface,
81 const QDBusMessage &message,84 int id,
85 const QString &clientProfile,
82 const QVariantMap &parameters,86 const QVariantMap &parameters,
83 Request *request):87 Request *request):
84 QObject(request),88 QObject(request),
85 q_ptr(request),89 q_ptr(request),
86 m_connection(connection),90 m_interface(interface),
87 m_message(message),91 m_id(id),
88 m_parameters(parameters),92 m_parameters(parameters),
93 m_clientApparmorProfile(clientProfile),
89 m_inProgress(false),94 m_inProgress(false),
90 m_window(0)95 m_window(0)
91{96{
92 m_clientApparmorProfile = findClientApparmorProfile();
93}97}
9498
95RequestPrivate::~RequestPrivate()99RequestPrivate::~RequestPrivate()
@@ -113,41 +117,14 @@
113 window->show();117 window->show();
114}118}
115119
116QString RequestPrivate::findClientApparmorProfile()
117{
118 QString uniqueConnectionId = m_message.service();
119 /* This is mainly for unit tests: real messages on the session bus always
120 * have a service name. */
121 if (uniqueConnectionId.isEmpty()) return QString();
122
123 QString appId;
124
125 QDBusMessage msg =
126 QDBusMessage::createMethodCall("org.freedesktop.DBus",
127 "/org/freedesktop/DBus",
128 "org.freedesktop.DBus",
129 "GetConnectionAppArmorSecurityContext");
130 QVariantList args;
131 args << uniqueConnectionId;
132 msg.setArguments(args);
133 QDBusMessage reply = QDBusConnection::sessionBus().call(msg, QDBus::Block);
134 if (reply.type() == QDBusMessage::ReplyMessage) {
135 appId = reply.arguments().value(0, QString()).toString();
136 DEBUG() << "App ID:" << appId;
137 } else {
138 qWarning() << "Error getting app ID:" << reply.errorName() <<
139 reply.errorMessage();
140 }
141 return appId;
142}
143
144/* Some unit tests might need to provide a different implementation for the120/* Some unit tests might need to provide a different implementation for the
145 * Request::newRequest() factory method; for this reason, we allow the method121 * Request::newRequest() factory method; for this reason, we allow the method
146 * to be excluded from compilation.122 * to be excluded from compilation.
147 */123 */
148#ifndef NO_REQUEST_FACTORY124#ifndef NO_REQUEST_FACTORY
149Request *Request::newRequest(const QDBusConnection &connection,125Request *Request::newRequest(const QString &interface,
150 const QDBusMessage &message,126 int id,
127 const QString &clientProfile,
151 const QVariantMap &parameters,128 const QVariantMap &parameters,
152 QObject *parent)129 QObject *parent)
153{130{
@@ -155,26 +132,29 @@
155 * different subclasses for handling them, and in this method we examine132 * different subclasses for handling them, and in this method we examine
156 * the @parameters argument to figure out which subclass is the most apt to133 * the @parameters argument to figure out which subclass is the most apt to
157 * handle the request. */134 * handle the request. */
158 if (message.interface() == OAU_INTERFACE) {135 if (interface == OAU_INTERFACE) {
159 if (parameters.contains(OAU_KEY_PROVIDER)) {136 if (parameters.contains(OAU_KEY_PROVIDER)) {
160 return new ProviderRequest(connection, message, parameters, parent);137 return new ProviderRequest(interface, id, clientProfile,
138 parameters, parent);
161 } else {139 } else {
162 return new PanelRequest(connection, message, parameters, parent);140 return new PanelRequest(interface, id, clientProfile,
141 parameters, parent);
163 }142 }
164 } else {143 } else {
165 Q_ASSERT(message.interface() == SIGNONUI_INTERFACE);144 Q_ASSERT(interface == SIGNONUI_INTERFACE);
166 return SignOnUi::Request::newRequest(connection, message,145 return SignOnUi::Request::newRequest(id, clientProfile,
167 parameters, parent);146 parameters, parent);
168 }147 }
169}148}
170#endif149#endif
171150
172Request::Request(const QDBusConnection &connection,151Request::Request(const QString &interface,
173 const QDBusMessage &message,152 int id,
153 const QString &clientProfile,
174 const QVariantMap &parameters,154 const QVariantMap &parameters,
175 QObject *parent):155 QObject *parent):
176 QObject(parent),156 QObject(parent),
177 d_ptr(new RequestPrivate(connection, message, parameters, this))157 d_ptr(new RequestPrivate(interface, id, clientProfile, parameters, this))
178{158{
179 allRequests.append(this);159 allRequests.append(this);
180}160}
@@ -195,6 +175,18 @@
195 return 0;175 return 0;
196}176}
197177
178QString Request::interface() const
179{
180 Q_D(const Request);
181 return d->m_interface;
182}
183
184int Request::id() const
185{
186 Q_D(const Request);
187 return d->m_id;
188}
189
198void Request::setWindow(QWindow *window)190void Request::setWindow(QWindow *window)
199{191{
200 Q_D(Request);192 Q_D(Request);
@@ -231,6 +223,24 @@
231 return d->m_window;223 return d->m_window;
232}224}
233225
226QVariantMap Request::result() const
227{
228 Q_D(const Request);
229 return d->m_result;
230}
231
232QString Request::errorName() const
233{
234 Q_D(const Request);
235 return d->m_errorName;
236}
237
238QString Request::errorMessage() const
239{
240 Q_D(const Request);
241 return d->m_errorMessage;
242}
243
234void Request::start()244void Request::start()
235{245{
236 Q_D(Request);246 Q_D(Request);
@@ -249,8 +259,11 @@
249void Request::fail(const QString &name, const QString &message)259void Request::fail(const QString &name, const QString &message)
250{260{
251 Q_D(Request);261 Q_D(Request);
252 QDBusMessage reply = d->m_message.createErrorReply(name, message);262
253 d->m_connection.send(reply);263 DEBUG() << name << message;
264
265 d->m_errorName = name;
266 d->m_errorMessage = message;
254267
255 Q_EMIT completed();268 Q_EMIT completed();
256}269}
@@ -268,8 +281,8 @@
268{281{
269 Q_D(Request);282 Q_D(Request);
270 if (d->m_inProgress) {283 if (d->m_inProgress) {
271 QDBusMessage reply = d->m_message.createReply(result);284 DEBUG() << result;
272 d->m_connection.send(reply);285 d->m_result = result;
273286
274 Q_EMIT completed();287 Q_EMIT completed();
275 d->m_inProgress = false;288 d->m_inProgress = false;
276289
=== modified file 'online-accounts-ui/request.h'
--- src/request.h 2014-05-30 08:09:02 +0000
+++ online-accounts-ui/request.h 2014-08-18 13:33:35 +0000
@@ -21,8 +21,6 @@
21#ifndef OAU_REQUEST_H21#ifndef OAU_REQUEST_H
22#define OAU_REQUEST_H22#define OAU_REQUEST_H
2323
24#include <QDBusConnection>
25#include <QDBusMessage>
26#include <QObject>24#include <QObject>
27#include <QVariantMap>25#include <QVariantMap>
28#include <QWindow>26#include <QWindow>
@@ -35,20 +33,27 @@
35 Q_OBJECT33 Q_OBJECT
3634
37public:35public:
38 static Request *newRequest(const QDBusConnection &connection,36 static Request *newRequest(const QString &interface,
39 const QDBusMessage &message,37 int id,
38 const QString &clientProfile,
40 const QVariantMap &parameters,39 const QVariantMap &parameters,
41 QObject *parent = 0);40 QObject *parent = 0);
42 ~Request();41 ~Request();
4342
44 static Request *find(const QVariantMap &match);43 static Request *find(const QVariantMap &match);
4544
45 QString interface() const;
46 int id() const;
46 WId windowId() const;47 WId windowId() const;
47 bool isInProgress() const;48 bool isInProgress() const;
48 const QVariantMap &parameters() const;49 const QVariantMap &parameters() const;
49 QString clientApparmorProfile() const;50 QString clientApparmorProfile() const;
50 QWindow *window() const;51 QWindow *window() const;
5152
53 QVariantMap result() const;
54 QString errorName() const;
55 QString errorMessage() const;
56
52public Q_SLOTS:57public Q_SLOTS:
53 virtual void start();58 virtual void start();
54 void cancel();59 void cancel();
@@ -57,8 +62,9 @@
57 void completed();62 void completed();
5863
59protected:64protected:
60 explicit Request(const QDBusConnection &connection,65 explicit Request(const QString &interface,
61 const QDBusMessage &message,66 int id,
67 const QString &clientProfile,
62 const QVariantMap &parameters,68 const QVariantMap &parameters,
63 QObject *parent = 0);69 QObject *parent = 0);
64 virtual void setWindow(QWindow *window);70 virtual void setWindow(QWindow *window);
6571
=== modified file 'online-accounts-ui/signonui-request.cpp'
--- src/signonui-request.cpp 2014-06-05 13:28:30 +0000
+++ online-accounts-ui/signonui-request.cpp 2014-08-18 13:33:35 +0000
@@ -1,7 +1,7 @@
1/*1/*
2 * This file is part of online-accounts-ui2 * This file is part of online-accounts-ui
3 *3 *
4 * Copyright (C) 2011 Canonical Ltd.4 * Copyright (C) 2011-2014 Canonical Ltd.
5 *5 *
6 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>6 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
7 *7 *
@@ -20,14 +20,19 @@
2020
21#include "signonui-request.h"21#include "signonui-request.h"
2222
23#include "account-manager.h"
24#include "application-manager.h"
23#include "browser-request.h"25#include "browser-request.h"
24#include "debug.h"26#include "debug.h"
25#include "globals.h"27#include "globals.h"
26#include "indicator-service.h"28#include "notification.h"
29#include "request-handler.h"
2730
28#include <Accounts/Account>31#include <Accounts/Account>
29#include <Accounts/Manager>32#include <Accounts/Application>
33#include <Accounts/Provider>
30#include <QDBusArgument>34#include <QDBusArgument>
35#include <QPointer>
31#include <SignOn/uisessiondata.h>36#include <SignOn/uisessiondata.h>
32#include <SignOn/uisessiondata_priv.h>37#include <SignOn/uisessiondata_priv.h>
3338
@@ -45,16 +50,19 @@
45 ~RequestPrivate();50 ~RequestPrivate();
4651
47private:52private:
48 bool setWindow(QWindow *window);53 void setWindow(QWindow *window);
49 Accounts::Account *findAccount();54 Accounts::Account *findAccount();
50 bool dispatchToIndicator();55
56private Q_SLOTS:
57 void onActionInvoked(const QString &action);
58 void onNotificationClosed();
5159
52private:60private:
53 mutable Request *q_ptr;61 mutable Request *q_ptr;
54 QVariantMap m_clientData;62 QVariantMap m_clientData;
55 bool m_inProgress;63 QPointer<RequestHandler> m_handler;
56 RequestHandler *m_handler;64 OnlineAccountsUi::Notification *m_notification;
57 Accounts::Manager *m_accountManager;65 QWindow *m_window;
58};66};
5967
60} // namespace68} // namespace
@@ -62,9 +70,9 @@
62RequestPrivate::RequestPrivate(Request *request):70RequestPrivate::RequestPrivate(Request *request):
63 QObject(request),71 QObject(request),
64 q_ptr(request),72 q_ptr(request),
65 m_inProgress(false),
66 m_handler(0),73 m_handler(0),
67 m_accountManager(0)74 m_notification(0),
75 m_window(0)
68{76{
69 const QVariantMap &parameters = request->parameters();77 const QVariantMap &parameters = request->parameters();
70 if (parameters.contains(SSOUI_KEY_CLIENT_DATA)) {78 if (parameters.contains(SSOUI_KEY_CLIENT_DATA)) {
@@ -77,20 +85,51 @@
7785
78RequestPrivate::~RequestPrivate()86RequestPrivate::~RequestPrivate()
79{87{
88 delete m_notification;
89 m_notification = 0;
80}90}
8191
82bool RequestPrivate::setWindow(QWindow *window)92void RequestPrivate::setWindow(QWindow *window)
83{93{
84 Q_Q(Request);94 Q_Q(Request);
85 Q_UNUSED(window);
8695
87 /* If the window has no parent and the webcredentials indicator service is96 /* Don't show the window yet: the user must be presented with a
88 * up, dispatch the request to it. */97 * snap-decision, and we'll show the window only if he decides to
89 if (q->windowId() == 0 && dispatchToIndicator()) {98 * authenticate. */
90 return true;99 Accounts::Account *account = findAccount();
100 if (Q_UNLIKELY(!account)) {
101 QVariantMap result;
102 result[SSOUI_KEY_ERROR] = SignOn::QUERY_ERROR_FORBIDDEN;
103 q->setResult(result);
104 return;
91 }105 }
92106
93 return false;107 OnlineAccountsUi::ApplicationManager *appManager =
108 OnlineAccountsUi::ApplicationManager::instance();
109 Accounts::Application application =
110 appManager->applicationFromProfile(q->clientApparmorProfile());
111
112 OnlineAccountsUi::AccountManager *accountManager =
113 OnlineAccountsUi::AccountManager::instance();
114 Accounts::Provider provider =
115 accountManager->provider(account->providerName());
116
117 QString summary =
118 QString("Please authorize %1 to access your %2 account %3").
119 arg(application.isValid() ? application.displayName() : "Ubuntu").
120 arg(provider.displayName()).
121 arg(account->displayName());
122 m_notification =
123 new OnlineAccountsUi::Notification("Authentication request", summary);
124 m_notification->addAction("cancel", "Cancel");
125 m_notification->addAction("continue", "Authorize...");
126 m_notification->setSnapDecision(true);
127 QObject::connect(m_notification, SIGNAL(actionInvoked(const QString &)),
128 this, SLOT(onActionInvoked(const QString &)));
129 QObject::connect(m_notification, SIGNAL(closed()),
130 this, SLOT(onNotificationClosed()));
131 m_notification->show();
132 m_window = window;
94}133}
95134
96Accounts::Account *RequestPrivate::findAccount()135Accounts::Account *RequestPrivate::findAccount()
@@ -104,11 +143,10 @@
104 /* Find the account using this identity.143 /* Find the account using this identity.
105 * FIXME: there might be more than one!144 * FIXME: there might be more than one!
106 */145 */
107 if (m_accountManager == 0) {146 OnlineAccountsUi::AccountManager *manager =
108 m_accountManager = new Accounts::Manager(this);147 OnlineAccountsUi::AccountManager::instance();
109 }148 Q_FOREACH(Accounts::AccountId accountId, manager->accountList()) {
110 Q_FOREACH(Accounts::AccountId accountId, m_accountManager->accountList()) {149 Accounts::Account *account = manager->account(accountId);
111 Accounts::Account *account = m_accountManager->account(accountId);
112 if (account == 0) continue;150 if (account == 0) continue;
113151
114 QVariant value(QVariant::UInt);152 QVariant value(QVariant::UInt);
@@ -122,52 +160,60 @@
122 return 0;160 return 0;
123}161}
124162
125bool RequestPrivate::dispatchToIndicator()163void RequestPrivate::onActionInvoked(const QString &action)
126{164{
127 Q_Q(Request);165 Q_Q(Request);
128166
129 Accounts::Account *account = findAccount();167 DEBUG() << action;
130 if (account == 0) {168
131 return false;169 QObject::disconnect(m_notification, 0, this, 0);
170 m_notification->deleteLater();
171 m_notification = 0;
172
173 if (action == QStringLiteral("continue")) {
174 q->setWindow(m_window);
175 } else {
176 q->cancel();
132 }177 }
133178}
134 QVariantMap notification;179
135 notification["DisplayName"] = account->displayName();180void RequestPrivate::onNotificationClosed()
136 notification["ClientData"] = m_clientData;181{
137 notification["Identity"] = q->identity();182 Q_Q(Request);
138 notification["Method"] = q->method();183
139 notification["Mechanism"] = q->mechanism();184 DEBUG();
140185
141 IndicatorService *indicator = IndicatorService::instance();186 /* setResult() should have been called by onActionInvoked(), but calling it
142 indicator->reportFailure(account->id(), notification);187 * twice won't harm because only the first invocation counts. */
143
144 /* the account has been reported as failing. We can now close this
145 * request, and tell the application that UI interaction is forbidden.
146 */
147 QVariantMap result;188 QVariantMap result;
148 result[SSOUI_KEY_ERROR] = SignOn::QUERY_ERROR_FORBIDDEN;189 result[SSOUI_KEY_ERROR] = SignOn::QUERY_ERROR_FORBIDDEN;
149 q->setResult(result);190 q->setResult(result);
150 return true;191
192 m_notification->deleteLater();
193 m_notification = 0;
151}194}
152195
153Request *Request::newRequest(const QDBusConnection &connection,196#ifndef NO_REQUEST_FACTORY
154 const QDBusMessage &message,197Request *Request::newRequest(int id,
198 const QString &clientProfile,
155 const QVariantMap &parameters,199 const QVariantMap &parameters,
156 QObject *parent)200 QObject *parent)
157{201{
158 if (parameters.contains(SSOUI_KEY_OPENURL)) {202 if (parameters.contains(SSOUI_KEY_OPENURL)) {
159 return new SignOnUi::BrowserRequest(connection, message,203 return new SignOnUi::BrowserRequest(id, clientProfile,
160 parameters, parent);204 parameters, parent);
161 } else {205 } else {
162 return 0; // TODO new DialogRequest(connection, message, parameters, parent);206 return 0; // TODO new DialogRequest(connection, message, parameters, parent);
163 }207 }
164}208}
209#endif
165210
166Request::Request(const QDBusConnection &connection,211Request::Request(int id,
167 const QDBusMessage &message,212 const QString &clientProfile,
168 const QVariantMap &parameters,213 const QVariantMap &parameters,
169 QObject *parent):214 QObject *parent):
170 OnlineAccountsUi::Request(connection, message, parameters, parent),215 OnlineAccountsUi::Request(SIGNONUI_INTERFACE, id, clientProfile,
216 parameters, parent),
171 d_ptr(new RequestPrivate(this))217 d_ptr(new RequestPrivate(this))
172{218{
173}219}
@@ -176,21 +222,35 @@
176{222{
177}223}
178224
179QString Request::id(const QVariantMap &parameters)225QString Request::ssoId(const QVariantMap &parameters)
180{226{
181 return parameters[SSOUI_KEY_REQUESTID].toString();227 return parameters[SSOUI_KEY_REQUESTID].toString();
182}228}
183229
184QString Request::id() const230QString Request::ssoId() const
185{231{
186 return Request::id(parameters());232 return Request::ssoId(parameters());
187}233}
188234
189void Request::setWindow(QWindow *window)235void Request::setWindow(QWindow *window)
190{236{
191 Q_D(Request);237 Q_D(Request);
192 if (!d->setWindow(window))238
239 /* While a notification is shown, ignore any further calls to
240 * setWindow(). */
241 if (d->m_notification) return;
242
243 /* The first time that this method is called, we handle it by presenting a
244 * snap decision to the user.
245 * Then, if this is called again with the same QWindow, it means that the
246 * snap decision was accepted, and we show the window.
247 */
248 if (window == d->m_window) {
193 OnlineAccountsUi::Request::setWindow(window);249 OnlineAccountsUi::Request::setWindow(window);
250 d->m_window = 0;
251 } else {
252 d->setWindow(window);
253 }
194}254}
195255
196uint Request::identity() const256uint Request::identity() const
@@ -232,12 +292,10 @@
232292
233void Request::setCanceled()293void Request::setCanceled()
234{294{
235 if (isInProgress()) {295 QVariantMap result;
236 QVariantMap result;296 result[SSOUI_KEY_ERROR] = SignOn::QUERY_ERROR_CANCELED;
237 result[SSOUI_KEY_ERROR] = SignOn::QUERY_ERROR_CANCELED;
238297
239 setResult(result);298 setResult(result);
240 }
241}299}
242300
243#include "signonui-request.moc"301#include "signonui-request.moc"
244302
=== modified file 'online-accounts-ui/signonui-request.h'
--- src/signonui-request.h 2014-04-29 14:34:44 +0000
+++ online-accounts-ui/signonui-request.h 2014-08-18 13:33:35 +0000
@@ -33,14 +33,14 @@
33 Q_OBJECT33 Q_OBJECT
3434
35public:35public:
36 static Request *newRequest(const QDBusConnection &connection,36 static Request *newRequest(int id,
37 const QDBusMessage &message,37 const QString &clientProfile,
38 const QVariantMap &parameters,38 const QVariantMap &parameters,
39 QObject *parent = 0);39 QObject *parent = 0);
40 ~Request();40 ~Request();
4141
42 static QString id(const QVariantMap &parameters);42 static QString ssoId(const QVariantMap &parameters);
43 QString id() const;43 QString ssoId() const;
4444
45 uint identity() const;45 uint identity() const;
46 QString method() const;46 QString method() const;
@@ -53,8 +53,8 @@
53 bool hasHandler() const { return handler() != 0; }53 bool hasHandler() const { return handler() != 0; }
5454
55protected:55protected:
56 explicit Request(const QDBusConnection &connection,56 explicit Request(int id,
57 const QDBusMessage &message,57 const QString &clientProfile,
58 const QVariantMap &parameters,58 const QVariantMap &parameters,
59 QObject *parent = 0);59 QObject *parent = 0);
60 virtual void setWindow(QWindow *window) Q_DECL_OVERRIDE;60 virtual void setWindow(QWindow *window) Q_DECL_OVERRIDE;
6161
=== added file 'online-accounts-ui/ui-server.cpp'
--- online-accounts-ui/ui-server.cpp 1970-01-01 00:00:00 +0000
+++ online-accounts-ui/ui-server.cpp 2014-08-18 13:33:35 +0000
@@ -0,0 +1,199 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "debug.h"
22#include "ipc.h"
23#include "request.h"
24#include "request-handler.h"
25#include "signonui-request.h"
26#include "ui-server.h"
27
28#include <QLocalSocket>
29#include <QtQml>
30#include <SignOn/uisessiondata_priv.h>
31
32using namespace OnlineAccountsUi;
33
34static UiServer *m_instance = 0;
35
36namespace OnlineAccountsUi {
37
38class UiServerPrivate: public QObject
39{
40 Q_OBJECT
41 Q_DECLARE_PUBLIC(UiServer)
42
43public:
44 inline UiServerPrivate(const QString &address, UiServer *pluginServer);
45 inline ~UiServerPrivate();
46
47 bool setupSocket();
48 bool init();
49 void sendOperation(const QVariantMap &data);
50
51private Q_SLOTS:
52 void onDataReady(QByteArray &data);
53 void onRequestCompleted();
54
55private:
56 QLocalSocket m_socket;
57 OnlineAccountsUi::Ipc m_ipc;
58 mutable UiServer *q_ptr;
59};
60
61} // namespace
62
63UiServerPrivate::UiServerPrivate(const QString &address,
64 UiServer *pluginServer):
65 QObject(pluginServer),
66 q_ptr(pluginServer)
67{
68 QObject::connect(&m_ipc, SIGNAL(dataReady(QByteArray &)),
69 this, SLOT(onDataReady(QByteArray &)));
70 QObject::connect(&m_socket, SIGNAL(disconnected()),
71 q_ptr, SIGNAL(finished()));
72 m_socket.connectToServer(address);
73}
74
75UiServerPrivate::~UiServerPrivate()
76{
77 DEBUG();
78}
79
80void UiServerPrivate::sendOperation(const QVariantMap &data)
81{
82 QByteArray ba;
83 QDataStream stream(&ba, QIODevice::WriteOnly);
84 stream << data;
85 m_ipc.write(ba);
86}
87
88void UiServerPrivate::onDataReady(QByteArray &data)
89{
90 Q_Q(UiServer);
91
92 QVariantMap map;
93 QDataStream stream(&data, QIODevice::ReadOnly);
94 stream >> map;
95
96 DEBUG() << map;
97
98 QString code = map.value(OAU_OPERATION_CODE).toString();
99 if (code == OAU_OPERATION_CODE_PROCESS) {
100 QVariantMap parameters = map[OAU_OPERATION_DATA].toMap();
101 Request *request =
102 Request::newRequest(map[OAU_OPERATION_INTERFACE].toString(),
103 map[OAU_OPERATION_ID].toInt(),
104 map[OAU_OPERATION_CLIENT_PROFILE].toString(),
105 parameters,
106 this);
107 QObject::connect(request, SIGNAL(completed()),
108 this, SLOT(onRequestCompleted()));
109
110 /* Check if a RequestHandler has been setup to handle this request. If
111 * so, bing the request object to the handler and start the request
112 * immediately. */
113 SignOnUi::Request *signonRequest =
114 qobject_cast<SignOnUi::Request*>(request);
115 if (signonRequest) {
116 SignOnUi::RequestHandler *handler =
117 SignOnUi::RequestHandler::findMatching(parameters);
118 if (handler) {
119 signonRequest->setHandler(handler);
120 }
121 }
122 request->start();
123 } else {
124 qWarning() << "Invalid operation code: " << code;
125 }
126}
127
128void UiServerPrivate::onRequestCompleted()
129{
130 Request *request = qobject_cast<Request*>(sender());
131 request->disconnect(this);
132 request->deleteLater();
133
134 if (request->errorName().isEmpty()) {
135 QVariantMap operation;
136 operation.insert(OAU_OPERATION_CODE,
137 OAU_OPERATION_CODE_REQUEST_FINISHED);
138 operation.insert(OAU_OPERATION_ID, request->id());
139 operation.insert(OAU_OPERATION_DATA, request->result());
140 operation.insert(OAU_OPERATION_INTERFACE, request->interface());
141 sendOperation(operation);
142 } else {
143 QVariantMap operation;
144 operation.insert(OAU_OPERATION_CODE,
145 OAU_OPERATION_CODE_REQUEST_FAILED);
146 operation.insert(OAU_OPERATION_ID, request->id());
147 operation.insert(OAU_OPERATION_INTERFACE, request->interface());
148 operation.insert(OAU_OPERATION_ERROR_NAME, request->errorName());
149 operation.insert(OAU_OPERATION_ERROR_MESSAGE, request->errorMessage());
150 sendOperation(operation);
151 }
152}
153
154bool UiServerPrivate::init()
155{
156 if (Q_UNLIKELY(!m_socket.waitForConnected())) return false;
157
158 m_ipc.setChannels(&m_socket, &m_socket);
159 return true;
160}
161
162UiServer::UiServer(const QString &address, QObject *parent):
163 QObject(parent),
164 d_ptr(new UiServerPrivate(address, this))
165{
166 m_instance = this;
167
168 qmlRegisterType<SignOnUi::RequestHandler>("Ubuntu.OnlineAccounts.Plugin",
169 1, 0, "RequestHandler");
170}
171
172UiServer::~UiServer()
173{
174 m_instance = 0;
175}
176
177UiServer *UiServer::instance()
178{
179 return m_instance;
180}
181
182bool UiServer::init()
183{
184 Q_D(UiServer);
185 return d->init();
186}
187
188void UiServer::registerHandler(SignOnUi::RequestHandler *handler)
189{
190 Q_D(UiServer);
191
192 QVariantMap operation;
193 operation.insert(OAU_OPERATION_CODE,
194 OAU_OPERATION_CODE_REGISTER_HANDLER);
195 operation.insert(OAU_OPERATION_HANDLER_ID, handler->matchId());
196 d->sendOperation(operation);
197}
198
199#include "ui-server.moc"
0200
=== added file 'online-accounts-ui/ui-server.h'
--- online-accounts-ui/ui-server.h 1970-01-01 00:00:00 +0000
+++ online-accounts-ui/ui-server.h 2014-08-18 13:33:35 +0000
@@ -0,0 +1,57 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef OAU_UI_SERVER_H
22#define OAU_UI_SERVER_H
23
24#include <QObject>
25#include <QVariantMap>
26
27namespace SignOnUi {
28class RequestHandler;
29}
30
31namespace OnlineAccountsUi {
32
33class UiServerPrivate;
34class UiServer: public QObject
35{
36 Q_OBJECT
37
38public:
39 explicit UiServer(const QString &address, QObject *parent = 0);
40 ~UiServer();
41
42 static UiServer *instance();
43
44 bool init();
45 void registerHandler(SignOnUi::RequestHandler *handler);
46
47Q_SIGNALS:
48 void finished();
49
50private:
51 UiServerPrivate *d_ptr;
52 Q_DECLARE_PRIVATE(UiServer)
53};
54
55} // namespace
56
57#endif // OAU_UI_SERVER_H
058
=== modified file 'online-accounts-ui/ui.qrc'
--- src/ui.qrc 2014-03-19 12:14:14 +0000
+++ online-accounts-ui/ui.qrc 2014-08-18 13:33:35 +0000
@@ -1,17 +1,8 @@
1<!DOCTYPE RCC><RCC version="1.0">1<!DOCTYPE RCC><RCC version="1.0">
2<qresource>2<qresource>
3 <file>qml/AccountCreationPage.qml</file>3 <file>qml/AccountCreationPage.qml</file>
4 <file>qml/AccountEditPage.qml</file>
5 <file>qml/AccountItem.qml</file>
6 <file>qml/AccountsPage.qml</file>
7 <file>qml/AddAccountLabel.qml</file>
8 <file>qml/AuthorizationPage.qml</file>4 <file>qml/AuthorizationPage.qml</file>
9 <file>qml/MainPage.qml</file>
10 <file>qml/NewAccountPage.qml</file>
11 <file>qml/NoAccountsPage.qml</file>
12 <file>qml/NormalStartupPage.qml</file>
13 <file>qml/ProviderPluginList.qml</file>
14 <file>qml/ProviderRequest.qml</file>5 <file>qml/ProviderRequest.qml</file>
15 <file>qml/ProvidersList.qml</file>6 <file>qml/SignOnUiPage.qml</file>
16</qresource>7</qresource>
17</RCC>8</RCC>
189
=== renamed file 'src/qml/AccountEditPage.qml' => 'system-settings-plugin/AccountEditPage.qml'
--- src/qml/AccountEditPage.qml 2014-03-19 12:14:14 +0000
+++ system-settings-plugin/AccountEditPage.qml 2014-08-18 13:33:35 +0000
@@ -19,6 +19,7 @@
19import QtQuick 2.019import QtQuick 2.0
20import Ubuntu.Components 0.120import Ubuntu.Components 0.1
21import Ubuntu.OnlineAccounts 0.121import Ubuntu.OnlineAccounts 0.1
22import Ubuntu.OnlineAccounts.Plugin 1.0
2223
23Page {24Page {
24 id: root25 id: root
@@ -34,26 +35,9 @@
34 objectHandle: accountHandle35 objectHandle: accountHandle
35 }36 }
3637
37 Loader {38 Options {
38 id: loader39 onFinished: {
39 property var account: account40 root.finished()
40
41 anchors.fill: parent
42 source: localQmlPluginPath + account.provider.id + "/Main.qml"
43
44 onStatusChanged: {
45 if (loader.status == Loader.Error) {
46 loader.source = systemQmlPluginPath + account.provider.id + "/Main.qml"
47 }
48 }
49
50
51 Connections {
52 target: loader.item
53 onFinished: {
54 console.log("====== PLUGIN FINISHED ======")
55 root.finished()
56 }
57 }41 }
58 }42 }
59}43}
6044
=== renamed file 'src/qml/AccountItem.qml' => 'system-settings-plugin/AccountItem.qml'
=== renamed file 'src/qml/AccountsPage.qml' => 'system-settings-plugin/AccountsPage.qml'
=== renamed file 'src/qml/AddAccountLabel.qml' => 'system-settings-plugin/AddAccountLabel.qml'
=== renamed file 'src/qml/MainPage.qml' => 'system-settings-plugin/MainPage.qml'
--- src/qml/MainPage.qml 2014-05-29 21:14:11 +0000
+++ system-settings-plugin/MainPage.qml 2014-08-18 13:33:35 +0000
@@ -17,52 +17,36 @@
17 */17 */
1818
19import QtQuick 2.019import QtQuick 2.0
20import SystemSettings 1.0
20import Ubuntu.Components 0.121import Ubuntu.Components 0.1
22import Ubuntu.Components.ListItems 0.1 as ListItem
21import Ubuntu.OnlineAccounts 0.123import Ubuntu.OnlineAccounts 0.1
2224
23MainView {25ItemPage {
24 id: root26 id: root
25 width: units.gu(48)27 objectName: "accountsPage"
26 height: units.gu(60)28
27 useDeprecatedToolbar: false29 title: i18n.tr("Accounts")
2830
29 Component.onCompleted: {31 property Item flickable: accountsPage.visible ? accountsPage : noAccountsPage
30 i18n.domain = "ubuntu-system-settings-online-accounts"32
31 pageStack.push(mainPage)33 AccountServiceModel {
32 }34 id: accountsModel
3335 service: "global"
34 PageStack {36 includeDisabled: true
35 id: pageStack37 }
3638
37 Page {39 AccountsPage {
38 id: mainPage40 id: accountsPage
39 title: i18n.tr("Accounts")41 anchors.fill: parent
40 tools: ToolbarItems {42 accountsModel: accountsModel
41 back: ActionItem {43 visible: accountsModel.count > 0
42 action: Action {44 }
43 iconName: "back"45
44 onTriggered: mainWindow.close()46 NoAccountsPage {
45 }47 id: noAccountsPage
46 }48 anchors.fill: parent
47 }49 accountsModel: accountsModel
4850 visible:!accountsPage.visible
49 Loader {51 }
50 id: loader52}
51 anchors.fill: parent
52 sourceComponent: pluginOptions.provider ? accountCreationPage : normalStartupPage
53 }
54 }
55 }
56
57 Component {
58 id: normalStartupPage
59 NormalStartupPage {}
60 }
61
62 Component {
63 id: accountCreationPage
64 AccountCreationPage {
65 providerId: pluginOptions.provider
66 }
67 }
68}
69\ No newline at end of file53\ No newline at end of file
7054
=== renamed file 'src/qml/NewAccountPage.qml' => 'system-settings-plugin/NewAccountPage.qml'
--- src/qml/NewAccountPage.qml 2013-10-17 11:08:57 +0000
+++ system-settings-plugin/NewAccountPage.qml 2014-08-18 13:33:35 +0000
@@ -29,8 +29,6 @@
2929
30 ProviderPluginList {30 ProviderPluginList {
31 onCreationFinished: {31 onCreationFinished: {
32 // pop the creation page and this page (go back to parent page)
33 pageStack.pop()
34 pageStack.pop()32 pageStack.pop()
35 }33 }
36 }34 }
3735
=== renamed file 'src/qml/NoAccountsPage.qml' => 'system-settings-plugin/NoAccountsPage.qml'
=== renamed file 'src/qml/NormalStartupPage.qml' => 'system-settings-plugin/NormalStartupPage.qml'
=== renamed file 'src/qml/ProviderPluginList.qml' => 'system-settings-plugin/ProviderPluginList.qml'
--- src/qml/ProviderPluginList.qml 2013-10-17 11:08:57 +0000
+++ system-settings-plugin/ProviderPluginList.qml 2014-08-18 13:33:35 +0000
@@ -18,25 +18,29 @@
1818
19import QtQuick 2.019import QtQuick 2.0
20import Ubuntu.Components 0.120import Ubuntu.Components 0.1
21import Ubuntu.OnlineAccounts.Client 0.1
2122
22ProvidersList {23ProvidersList {
23 id: root24 id: root
2425
25 property variant __creationPage: null26 property bool __processing: false
2627
27 signal creationFinished28 signal creationFinished
2829
30 Setup {
31 id: setup
32 applicationId: "system-settings"
33 onFinished: {
34 __processing = false
35 creationFinished()
36 }
37 }
38
29 onProviderClicked: {39 onProviderClicked: {
30 __creationPage = accountCreationPage.createObject(null, {40 if (!__processing) {
31 "providerId": providerId })41 __processing = true
32 __creationPage.finished.connect(__onCreationFinished)42 setup.providerId = providerId
33 pageStack.push(__creationPage)43 setup.exec()
34 }44 }
35
36 function __onCreationFinished() {
37 __creationPage.destroy(1000)
38 __creationPage.finished.disconnect(__onCreationFinished)
39 __creationPage = null
40 creationFinished()
41 }45 }
42}46}
4347
=== renamed file 'src/qml/ProvidersList.qml' => 'system-settings-plugin/ProvidersList.qml'
=== modified file 'system-settings-plugin/online-accounts.settings'
--- system-settings-plugin/online-accounts.settings 2013-09-09 10:56:53 +0000
+++ system-settings-plugin/online-accounts.settings 2014-08-18 13:33:35 +0000
@@ -11,5 +11,5 @@
11 ],11 ],
12 "has-dynamic-keywords": true,12 "has-dynamic-keywords": true,
13 "has-dynamic-visibility": false,13 "has-dynamic-visibility": false,
14 "plugin": "online-accounts"14 "page-component": "MainPage.qml"
15}15}
1616
=== removed file 'system-settings-plugin/plugin.cpp'
--- system-settings-plugin/plugin.cpp 2014-05-30 08:55:40 +0000
+++ system-settings-plugin/plugin.cpp 1970-01-01 00:00:00 +0000
@@ -1,89 +0,0 @@
1/*
2 * Copyright (C) 2013 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 3, as published
8 * by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranties of
12 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "plugin.h"
20
21#include <OnlineAccountsClient/Setup>
22#include <QDebug>
23#include <QStringList>
24#include <SystemSettings/ItemBase>
25
26using namespace SystemSettings;
27
28class Item: public ItemBase
29{
30 Q_OBJECT
31
32public:
33 Item(const QVariantMap &staticData, QObject *parent = 0);
34 ~Item();
35
36 QQmlComponent *pageComponent(QQmlEngine *engine,
37 QObject *parent = 0) Q_DECL_OVERRIDE;
38
39private Q_SLOTS:
40 void onFinished();
41
42private:
43 OnlineAccountsClient::Setup m_setup;
44 bool m_isOpen;
45};
46
47Item::Item(const QVariantMap &staticData, QObject *parent):
48 ItemBase(staticData, parent),
49 m_isOpen(false)
50{
51 QObject::connect(&m_setup, SIGNAL(finished()),
52 this, SLOT(onFinished()));
53}
54
55Item::~Item()
56{
57}
58
59QQmlComponent *Item::pageComponent(QQmlEngine *engine,
60 QObject *parent)
61{
62 Q_UNUSED(engine);
63 Q_UNUSED(parent);
64
65 if (!m_isOpen) {
66 qDebug() << "Opening Online Accounts";
67 m_isOpen = true;
68 m_setup.exec();
69 }
70 return 0;
71}
72
73void Item::onFinished()
74{
75 m_isOpen = false;
76}
77
78Plugin::Plugin():
79 QObject()
80{
81}
82
83ItemBase *Plugin::createItem(const QVariantMap &staticData,
84 QObject *parent)
85{
86 return new Item(staticData, parent);
87}
88
89#include "plugin.moc"
900
=== removed file 'system-settings-plugin/plugin.h'
--- system-settings-plugin/plugin.h 2013-09-09 10:56:53 +0000
+++ system-settings-plugin/plugin.h 1970-01-01 00:00:00 +0000
@@ -1,38 +0,0 @@
1/*
2 * Copyright (C) 2013 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 3, as published
8 * by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranties of
12 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef ONLINE_ACCOUNTS_SYSTEM_SETTINGS_PLUGIN_H
20#define ONLINE_ACCOUNTS_SYSTEM_SETTINGS_PLUGIN_H
21
22#include <QObject>
23#include <SystemSettings/PluginInterface>
24
25class Plugin: public QObject, public SystemSettings::PluginInterface
26{
27 Q_OBJECT
28 Q_PLUGIN_METADATA(IID "com.ubuntu.SystemSettings.PluginInterface")
29 Q_INTERFACES(SystemSettings::PluginInterface)
30
31public:
32 Plugin();
33
34 SystemSettings::ItemBase *createItem(const QVariantMap &staticData,
35 QObject *parent = 0);
36};
37
38#endif // ONLINE_ACCOUNTS_SYSTEM_SETTINGS_PLUGIN_H
390
=== modified file 'system-settings-plugin/system-settings-plugin.pro'
--- system-settings-plugin/system-settings-plugin.pro 2013-09-09 10:56:53 +0000
+++ system-settings-plugin/system-settings-plugin.pro 2014-08-18 13:33:35 +0000
@@ -1,41 +1,28 @@
1include(../common-project-config.pri)1include(../common-project-config.pri)
2include($${TOP_SRC_DIR}/common-vars.pri)2include($${TOP_SRC_DIR}/common-vars.pri)
33
4TEMPLATE = lib4TEMPLATE=aux
5TARGET = online-accounts5
66QML_SOURCES = \
7CONFIG += \7 AccountEditPage.qml \
8 link_pkgconfig \8 AccountItem.qml \
9 plugin \9 AccountsPage.qml \
10 qt10 AddAccountLabel.qml \
1111 MainPage.qml \
12QT += \12 NewAccountPage.qml \
13 core \13 NoAccountsPage.qml \
14 qml14 NormalStartupPage.qml \
1515 ProviderPluginList.qml \
16PKGCONFIG += \16 ProvidersList.qml
17 SystemSettings
18
19LIBS += -lonline-accounts-client
20QMAKE_LIBDIR += $${TOP_BUILD_DIR}/client/OnlineAccountsClient
21INCLUDEPATH += \
22 $${TOP_SRC_DIR}/client \
23 /usr/include
24
25SOURCES += \
26 plugin.cpp
27
28HEADERS += \
29 plugin.h
3017
31settings.files = online-accounts.settings18settings.files = online-accounts.settings
32settings.path = $${PLUGIN_MANIFEST_DIR}19settings.path = $${PLUGIN_MANIFEST_DIR}
33INSTALLS += settings20INSTALLS += settings
3421
35target.path = $${PLUGIN_MODULE_DIR}
36INSTALLS += target
37
38image.files = settings-accounts.svg22image.files = settings-accounts.svg
39image.path = $${PLUGIN_MANIFEST_DIR}/icons23image.path = $${PLUGIN_MANIFEST_DIR}/icons
40INSTALLS += image24INSTALLS += image
4125
26qml.files = $${QML_SOURCES}
27qml.path = $${PLUGIN_QML_DIR}/online-accounts
28INSTALLS += qml
4229
=== modified file 'tests/client/tst_client.cpp'
--- tests/client/tst_client.cpp 2014-03-19 12:14:14 +0000
+++ tests/client/tst_client.cpp 2014-08-18 13:33:35 +0000
@@ -20,7 +20,7 @@
20 * <http://www.gnu.org/licenses/>.20 * <http://www.gnu.org/licenses/>.
21 */21 */
2222
23#include "src/globals.h"23#include "online-accounts-ui/globals.h"
2424
25#include <OnlineAccountsClient/Setup>25#include <OnlineAccountsClient/Setup>
26#include <QDBusConnection>26#include <QDBusConnection>
2727
=== modified file 'tests/client/tst_qml_client.cpp'
--- tests/client/tst_qml_client.cpp 2014-03-19 12:14:14 +0000
+++ tests/client/tst_qml_client.cpp 2014-08-18 13:33:35 +0000
@@ -20,7 +20,7 @@
20 * <http://www.gnu.org/licenses/>.20 * <http://www.gnu.org/licenses/>.
21 */21 */
2222
23#include "src/globals.h"23#include "online-accounts-ui/globals.h"
2424
25#include <QDBusConnection>25#include <QDBusConnection>
26#include <QDebug>26#include <QDebug>
2727
=== added directory 'tests/online-accounts-service'
=== added file 'tests/online-accounts-service/online-accounts-service.pro'
--- tests/online-accounts-service/online-accounts-service.pro 1970-01-01 00:00:00 +0000
+++ tests/online-accounts-service/online-accounts-service.pro 2014-08-18 13:33:35 +0000
@@ -0,0 +1,4 @@
1TEMPLATE = subdirs
2SUBDIRS = \
3 tst_inactivity_timer.pro \
4 tst_service.pro
05
=== renamed file 'tests/online-accounts-ui/tst_inactivity_timer.cpp' => 'tests/online-accounts-service/tst_inactivity_timer.cpp'
=== renamed file 'tests/online-accounts-ui/tst_inactivity_timer.pro' => 'tests/online-accounts-service/tst_inactivity_timer.pro'
--- tests/online-accounts-ui/tst_inactivity_timer.pro 2014-03-07 07:44:07 +0000
+++ tests/online-accounts-service/tst_inactivity_timer.pro 2014-08-18 13:33:35 +0000
@@ -9,15 +9,19 @@
9 core \9 core \
10 testlib10 testlib
1111
12ONLINE_ACCOUNTS_SERVICE_DIR = $${TOP_SRC_DIR}/online-accounts-service
13COMMON_SRC_DIR = $${TOP_SRC_DIR}/online-accounts-ui
14
12SOURCES += \15SOURCES += \
13 $${TOP_SRC_DIR}/src/inactivity-timer.cpp \16 $${ONLINE_ACCOUNTS_SERVICE_DIR}/inactivity-timer.cpp \
14 tst_inactivity_timer.cpp17 tst_inactivity_timer.cpp
1518
16HEADERS += \19HEADERS += \
17 $${TOP_SRC_DIR}/src/inactivity-timer.h20 $${ONLINE_ACCOUNTS_SERVICE_DIR}/inactivity-timer.h
1821
19INCLUDEPATH += \22INCLUDEPATH += \
20 $${TOP_SRC_DIR}/src23 $${COMMON_SRC_DIR} \
24 $${ONLINE_ACCOUNTS_SERVICE_DIR}
2125
22check.commands = "xvfb-run -s '-screen 0 640x480x24' -a ./$${TARGET}"26check.commands = "xvfb-run -s '-screen 0 640x480x24' -a ./$${TARGET}"
23check.depends = $${TARGET}27check.depends = $${TARGET}
2428
=== renamed file 'tests/online-accounts-ui/tst_service.cpp' => 'tests/online-accounts-service/tst_service.cpp'
--- tests/online-accounts-ui/tst_service.cpp 2014-04-29 12:11:55 +0000
+++ tests/online-accounts-service/tst_service.cpp 2014-08-18 13:33:35 +0000
@@ -22,7 +22,7 @@
22#include "request.h"22#include "request.h"
23#include "request-manager.h"23#include "request-manager.h"
24#include "service.h"24#include "service.h"
25#include "window-watcher.h"25#include "ui-proxy.h"
2626
27#include <QDBusArgument>27#include <QDBusArgument>
28#include <QDBusConnection>28#include <QDBusConnection>
@@ -38,58 +38,12 @@
3838
39using namespace OnlineAccountsUi;39using namespace OnlineAccountsUi;
4040
41static const QString keyTimeout(QStringLiteral("timeout"));
42static const QString keyFail(QStringLiteral("fail"));
43
44#define P2P_SOCKET "unix:path=/tmp/tst_service_%1"41#define P2P_SOCKET "unix:path=/tmp/tst_service_%1"
45#define TEST_SERVICE_NAME \42#define TEST_SERVICE_NAME \
46 QStringLiteral("com.ubuntu.OnlineAccountsUi.Test")43 QStringLiteral("com.ubuntu.OnlineAccountsUi.Test")
47#define TEST_OBJECT_PATH QStringLiteral("/")44#define TEST_OBJECT_PATH QStringLiteral("/")
4845
49class TestRequest: public Request46QList<UiProxyPrivate *> m_uiProxies;
50{
51 Q_OBJECT
52
53public:
54 TestRequest(const QDBusConnection &connection,
55 const QDBusMessage &message,
56 const QVariantMap &parameters,
57 QObject *parent = 0):
58 Request(connection, message, parameters, parent)
59 {
60 m_timer.setSingleShot(true);
61 m_timer.setInterval(parameters.value(keyTimeout).toInt());
62 QObject::connect(&m_timer, SIGNAL(timeout()),
63 this, SLOT(onTimeout()));
64 }
65
66 void start() Q_DECL_OVERRIDE {
67 Request::start();
68 QWindow *window = new QWindow;
69 setWindow(window);
70 m_timer.start();
71 }
72
73private Q_SLOTS:
74 void onTimeout() {
75 if (parameters().contains(keyFail)) {
76 fail(parameters().value(keyFail).toString(), "Request failed");
77 } else {
78 setResult(parameters());
79 }
80 }
81
82private:
83 QTimer m_timer;
84};
85
86Request *Request::newRequest(const QDBusConnection &connection,
87 const QDBusMessage &message,
88 const QVariantMap &parameters,
89 QObject *parent)
90{
91 return new TestRequest(connection, message, parameters, parent);
92}
9347
94class RequestReply: public QDBusPendingCallWatcher48class RequestReply: public QDBusPendingCallWatcher
95{49{
@@ -107,6 +61,7 @@
107 bool isError() const { return m_isError; }61 bool isError() const { return m_isError; }
108 QVariantMap reply() const { return m_reply; }62 QVariantMap reply() const { return m_reply; }
109 QString errorName() const { return m_errorName; }63 QString errorName() const { return m_errorName; }
64 QString errorMessage() const { return m_errorMessage; }
11065
111private Q_SLOTS:66private Q_SLOTS:
112 void onFinished() {67 void onFinished() {
@@ -114,6 +69,7 @@
114 if (reply.isError()) {69 if (reply.isError()) {
115 m_isError = true;70 m_isError = true;
116 m_errorName = reply.error().name();71 m_errorName = reply.error().name();
72 m_errorMessage = reply.error().message();
117 } else {73 } else {
118 m_reply = qdbus_cast<QVariantMap>(reply.argumentAt(0).74 m_reply = qdbus_cast<QVariantMap>(reply.argumentAt(0).
119 value<QDBusArgument>());75 value<QDBusArgument>());
@@ -128,6 +84,7 @@
128 bool m_isError;84 bool m_isError;
129 QVariantMap m_reply;85 QVariantMap m_reply;
130 QString m_errorName;86 QString m_errorName;
87 QString m_errorMessage;
131};88};
13289
133class ServiceTest: public QObject90class ServiceTest: public QObject
@@ -154,8 +111,6 @@
154 void testResults();111 void testResults();
155 void testFailure();112 void testFailure();
156 void testIdle();113 void testIdle();
157 void testWindow();
158 void testWindowTransiency();
159114
160protected Q_SLOTS:115protected Q_SLOTS:
161 void onNewConnection(const QDBusConnection &connection);116 void onNewConnection(const QDBusConnection &connection);
@@ -166,6 +121,73 @@
166 QDBusConnection m_connection;121 QDBusConnection m_connection;
167};122};
168123
124/* Mocking UiProxy { */
125namespace OnlineAccountsUi {
126
127class UiProxyPrivate: public QObject
128{
129 Q_OBJECT
130 Q_DECLARE_PUBLIC(UiProxy)
131
132public:
133 UiProxyPrivate(UiProxy *uiProxy):
134 QObject(uiProxy),
135 m_initCount(0),
136 m_initReply(true),
137 q_ptr(uiProxy)
138 {
139 }
140 ~UiProxyPrivate() {};
141
142 void emitFinished() { Q_EMIT q_ptr->finished(); }
143
144Q_SIGNALS:
145 void handleRequestCalled();
146
147public:
148 int m_initCount;
149 bool m_initReply;
150 QList<Request*> m_requests;
151 QVariantMap m_expectedHasHandlerFor;
152 mutable UiProxy *q_ptr;
153};
154
155} // namespace
156
157UiProxy::UiProxy(pid_t, QObject *parent):
158 QObject(parent),
159 d_ptr(new UiProxyPrivate(this))
160{
161 m_uiProxies.append(d_ptr);
162}
163
164UiProxy::~UiProxy()
165{
166 m_uiProxies.removeOne(d_ptr);
167}
168
169bool UiProxy::init()
170{
171 Q_D(UiProxy);
172 d->m_initCount++;
173 return d->m_initReply;
174}
175
176void UiProxy::handleRequest(Request *request)
177{
178 Q_D(UiProxy);
179 d->m_requests.append(request);
180 Q_EMIT d->handleRequestCalled();
181}
182
183bool UiProxy::hasHandlerFor(const QVariantMap &parameters)
184{
185 Q_D(UiProxy);
186 return parameters == d->m_expectedHasHandlerFor;
187}
188
189/* } mocking UiProxy */
190
169ServiceTest::ServiceTest():191ServiceTest::ServiceTest():
170 QObject(0),192 QObject(0),
171 m_connection(QStringLiteral("uninitialized"))193 m_connection(QStringLiteral("uninitialized"))
@@ -205,30 +227,60 @@
205void ServiceTest::testResults()227void ServiceTest::testResults()
206{228{
207 QVariantMap parameters;229 QVariantMap parameters;
208 parameters.insert(keyTimeout, 10);
209 parameters.insert("hello", QString("world"));230 parameters.insert("hello", QString("world"));
210 RequestReply *call = sendRequest(parameters);231 RequestReply *call = sendRequest(parameters);
211 QSignalSpy callFinished(call, SIGNAL(finished()));232 QSignalSpy callFinished(call, SIGNAL(finished()));
212233
234 QTRY_COMPARE(m_uiProxies.count(), 1);
235
236 UiProxyPrivate *proxy = m_uiProxies[0];
237 QCOMPARE(proxy->m_initCount, 1);
238 QCOMPARE(proxy->m_requests.count(), 1);
239
240 Request *request = proxy->m_requests.last();
241 QCOMPARE(request->parameters(), parameters);
242
243 request->setInProgress(true);
244 request->setResult(parameters);
245
213 QVERIFY(callFinished.wait());246 QVERIFY(callFinished.wait());
214 QCOMPARE(call->isError(), false);247 QCOMPARE(call->isError(), false);
215 QCOMPARE(call->reply(), parameters);248 QCOMPARE(call->reply(), parameters);
216 delete call;249 delete call;
250
251 proxy->emitFinished();
252 QTRY_COMPARE(m_uiProxies.count(), 0);
217}253}
218254
219void ServiceTest::testFailure()255void ServiceTest::testFailure()
220{256{
257 QVariantMap parameters;
258 parameters.insert("hi", "there");
259 RequestReply *call = sendRequest(parameters);
260 QSignalSpy callFinished(call, SIGNAL(finished()));
261
262 QTRY_COMPARE(m_uiProxies.count(), 1);
263
264 UiProxyPrivate *proxy = m_uiProxies[0];
265 QCOMPARE(proxy->m_initCount, 1);
266 QCOMPARE(proxy->m_requests.count(), 1);
267
268 Request *request = proxy->m_requests.last();
269 QCOMPARE(request->parameters(), parameters);
270
271 request->setInProgress(true);
221 QString errorName("com.ubuntu.OnlineAccountsUi.BadLuck");272 QString errorName("com.ubuntu.OnlineAccountsUi.BadLuck");
222 QVariantMap parameters;273 QString errorMessage("really unlucky");
223 parameters.insert(keyTimeout, 10);274 request->fail(errorName, errorMessage);
224 parameters.insert("fail", errorName);
225 RequestReply *call = sendRequest(parameters);
226 QSignalSpy callFinished(call, SIGNAL(finished()));
227275
228 QVERIFY(callFinished.wait());276 QVERIFY(callFinished.wait());
229 QCOMPARE(call->isError(), true);277 QCOMPARE(call->isError(), true);
230 QCOMPARE(call->errorName(), errorName);278 QCOMPARE(call->errorName(), errorName);
279 QCOMPARE(call->errorMessage(), errorMessage);
231 delete call;280 delete call;
281
282 proxy->emitFinished();
283 QTRY_COMPARE(m_uiProxies.count(), 0);
232}284}
233285
234void ServiceTest::testIdle()286void ServiceTest::testIdle()
@@ -238,65 +290,37 @@
238 QSignalSpy isIdleChanged(&m_requestManager, SIGNAL(isIdleChanged()));290 QSignalSpy isIdleChanged(&m_requestManager, SIGNAL(isIdleChanged()));
239291
240 QVariantMap parameters;292 QVariantMap parameters;
241 parameters.insert(keyTimeout, 10);293 parameters.insert("time", "out");
242 RequestReply *call = sendRequest(parameters);294 RequestReply *call = sendRequest(parameters);
243 QSignalSpy callFinished(call, SIGNAL(finished()));295 QSignalSpy callFinished(call, SIGNAL(finished()));
244296
245 QVERIFY(isIdleChanged.wait());297 QVERIFY(isIdleChanged.wait());
246 QCOMPARE(m_requestManager.isIdle(), false);298 QCOMPARE(m_requestManager.isIdle(), false);
247299 isIdleChanged.clear();
248 /* the request will terminate after 10 milliseconds, so expect the service300
301 QTRY_COMPARE(m_uiProxies.count(), 1);
302
303 UiProxyPrivate *proxy = m_uiProxies[0];
304 QCOMPARE(proxy->m_initCount, 1);
305 QCOMPARE(proxy->m_requests.count(), 1);
306
307 Request *request = proxy->m_requests.last();
308 QCOMPARE(request->parameters(), parameters);
309
310 request->setInProgress(true);
311 request->setResult(parameters);
312
313 /* the request will terminate, so expect the service
249 * to be idle again */314 * to be idle again */
250 QVERIFY(isIdleChanged.wait());315 QTRY_COMPARE(isIdleChanged.count(), 1);
251 QCOMPARE(m_requestManager.isIdle(), true);316 QCOMPARE(m_requestManager.isIdle(), true);
252317
253 QVERIFY(callFinished.wait());318 QVERIFY(callFinished.wait());
254 QCOMPARE(call->isError(), false);319 QCOMPARE(call->isError(), false);
255 delete call;320 delete call;
256}321
257322 proxy->emitFinished();
258void ServiceTest::testWindow()323 QTRY_COMPARE(m_uiProxies.count(), 0);
259{
260 QVariantMap parameters;
261 parameters.insert(keyTimeout, 10);
262 RequestReply *call = sendRequest(parameters);
263 QSignalSpy callFinished(call, SIGNAL(finished()));
264 QSignalSpy windowShown(WindowWatcher::instance(),
265 SIGNAL(windowShown(QObject*)));
266
267 QVERIFY(windowShown.wait());
268 QWindow *window =
269 qobject_cast<QWindow*>(windowShown.at(0).at(0).value<QObject*>());
270 QVERIFY(window->property("transientParent").isNull());
271 QVERIFY(callFinished.wait());
272 QCOMPARE(call->isError(), false);
273 delete call;
274
275 QCOMPARE(windowShown.count(), 1);
276}
277
278void ServiceTest::testWindowTransiency()
279{
280 QVariantMap parameters;
281 parameters.insert(keyTimeout, 10);
282 parameters.insert(OAU_KEY_WINDOW_ID, 371);
283 RequestReply *call = sendRequest(parameters);
284 QSignalSpy callFinished(call, SIGNAL(finished()));
285 QSignalSpy windowShown(WindowWatcher::instance(),
286 SIGNAL(windowShown(QObject*)));
287
288 QVERIFY(windowShown.wait());
289 QWindow *window =
290 qobject_cast<QWindow*>(windowShown.at(0).at(0).value<QObject*>());
291 QObject *transientParentObject =
292 window->property("transientParent").value<QObject*>();
293 QWindow *transientParent = qobject_cast<QWindow*>(transientParentObject);
294 QCOMPARE(transientParent->property("winId").toUInt(), uint(371));
295 QVERIFY(callFinished.wait());
296 QCOMPARE(call->isError(), false);
297 delete call;
298
299 QCOMPARE(windowShown.count(), 1);
300}324}
301325
302QTEST_MAIN(ServiceTest);326QTEST_MAIN(ServiceTest);
303327
=== renamed file 'tests/online-accounts-ui/tst_service.pro' => 'tests/online-accounts-service/tst_service.pro'
--- tests/online-accounts-ui/tst_service.pro 2014-04-29 12:11:55 +0000
+++ tests/online-accounts-service/tst_service.pro 2014-08-18 13:33:35 +0000
@@ -13,23 +13,26 @@
13DEFINES += \13DEFINES += \
14 NO_REQUEST_FACTORY14 NO_REQUEST_FACTORY
1515
16ONLINE_ACCOUNTS_SERVICE_DIR = $${TOP_SRC_DIR}/online-accounts-service
17COMMON_SRC_DIR = $${TOP_SRC_DIR}/online-accounts-ui
18
16SOURCES += \19SOURCES += \
17 $${TOP_BUILD_DIR}/src/onlineaccountsui_adaptor.cpp \20 $${TOP_BUILD_DIR}/online-accounts-service/onlineaccountsui_adaptor.cpp \
18 $${TOP_SRC_DIR}/src/request.cpp \21 $${ONLINE_ACCOUNTS_SERVICE_DIR}/request.cpp \
19 $${TOP_SRC_DIR}/src/request-manager.cpp \22 $${ONLINE_ACCOUNTS_SERVICE_DIR}/request-manager.cpp \
20 $${TOP_SRC_DIR}/src/service.cpp \23 $${ONLINE_ACCOUNTS_SERVICE_DIR}/service.cpp \
21 mock/qwindow.cpp \
22 tst_service.cpp24 tst_service.cpp
2325
24HEADERS += \26HEADERS += \
25 $${TOP_BUILD_DIR}/src/onlineaccountsui_adaptor.h \27 $${TOP_BUILD_DIR}/online-accounts-service/onlineaccountsui_adaptor.h \
26 $${TOP_SRC_DIR}/src/request.h \28 $${ONLINE_ACCOUNTS_SERVICE_DIR}/request.h \
27 $${TOP_SRC_DIR}/src/request-manager.h \29 $${ONLINE_ACCOUNTS_SERVICE_DIR}/request-manager.h \
28 $${TOP_SRC_DIR}/src/service.h \30 $${ONLINE_ACCOUNTS_SERVICE_DIR}/service.h \
29 window-watcher.h31 $${ONLINE_ACCOUNTS_SERVICE_DIR}/ui-proxy.h \
3032
31INCLUDEPATH += \33INCLUDEPATH += \
32 $${TOP_SRC_DIR}/src34 $${ONLINE_ACCOUNTS_SERVICE_DIR} \
35 $${COMMON_SRC_DIR}
3336
34check.commands = "xvfb-run -s '-screen 0 640x480x24' -a dbus-test-runner -t ./$${TARGET}"37check.commands = "xvfb-run -s '-screen 0 640x480x24' -a dbus-test-runner -t ./$${TARGET}"
35check.depends = $${TARGET}38check.depends = $${TARGET}
3639
=== added file 'tests/online-accounts-ui/data/com.ubuntu.tests_application.application'
--- tests/online-accounts-ui/data/com.ubuntu.tests_application.application 1970-01-01 00:00:00 +0000
+++ tests/online-accounts-ui/data/com.ubuntu.tests_application.application 2014-08-18 13:33:35 +0000
@@ -0,0 +1,19 @@
1<?xml version="1.0" encoding="UTF-8" ?>
2<application id="com.ubuntu.tests_application">
3 <description>Mailer</description>
4 <translations>mailer-catalog</translations>
5 <desktop-entry>mailer.desktop</desktop-entry>
6
7 <service-types>
8 <service-type id="e-mail">
9 <description>Mailer can retrieve your e-mails</description>
10 </service-type>
11 </service-types>
12
13 <services>
14 <service id="coolshare">
15 <description>Mailer can even share stuff on CoolShare</description>
16 </service>
17 </services>
18 <profile>com.ubuntu.tests_application_0.3</profile>
19</application>
020
=== added file 'tests/online-accounts-ui/mock/notification-mock.cpp'
--- tests/online-accounts-ui/mock/notification-mock.cpp 1970-01-01 00:00:00 +0000
+++ tests/online-accounts-ui/mock/notification-mock.cpp 2014-08-18 13:33:35 +0000
@@ -0,0 +1,81 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "notification-mock.h"
22
23#include <QByteArray>
24#include <QDebug>
25#include <QString>
26
27using namespace OnlineAccountsUi;
28
29QList<Notification*> NotificationPrivate::allNotifications;
30
31NotificationPrivate::NotificationPrivate(const QString &summary,
32 const QString &body,
33 Notification *notification):
34 QObject(notification),
35 m_summary(summary),
36 m_body(body),
37 q_ptr(notification)
38{
39 allNotifications.append(notification);
40}
41
42NotificationPrivate::~NotificationPrivate()
43{
44 allNotifications.removeAll(q_ptr);
45}
46
47void NotificationPrivate::invokeAction(const QString &action)
48{
49 Q_Q(Notification);
50 Q_EMIT q->actionInvoked(action);
51}
52
53Notification::Notification(const QString &summary,
54 const QString &body,
55 QObject *parent):
56 QObject(parent),
57 d_ptr(new NotificationPrivate(summary, body, this))
58{
59}
60
61Notification::~Notification()
62{
63}
64
65void Notification::addAction(const QString &action, const QString &label)
66{
67 Q_D(Notification);
68 d->m_actions.append(ActionPair(action, label));
69}
70
71void Notification::setSnapDecision(bool snapDecision)
72{
73 Q_D(Notification);
74 d->m_isSnapDecision = snapDecision;
75}
76
77void Notification::show()
78{
79 Q_D(Notification);
80 Q_EMIT d->showCalled();
81}
082
=== added file 'tests/online-accounts-ui/mock/notification-mock.h'
--- tests/online-accounts-ui/mock/notification-mock.h 1970-01-01 00:00:00 +0000
+++ tests/online-accounts-ui/mock/notification-mock.h 2014-08-18 13:33:35 +0000
@@ -0,0 +1,66 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef MOCK_NOTIFICATiON_H
22#define MOCK_NOTIFICATiON_H
23
24#include "notification.h"
25
26#include <QByteArray>
27#include <QList>
28#include <QPair>
29#include <QString>
30
31using namespace OnlineAccountsUi;
32
33namespace OnlineAccountsUi {
34
35typedef QPair<QString,QString> ActionPair;
36
37class NotificationPrivate: public QObject
38{
39 Q_OBJECT
40 Q_DECLARE_PUBLIC(Notification)
41
42public:
43 NotificationPrivate(const QString &summary,
44 const QString &body,
45 Notification *notification);
46 ~NotificationPrivate();
47 static NotificationPrivate *mocked(Notification *n) { return n->d_ptr; }
48
49 static QList<Notification *> allNotifications;
50
51 void invokeAction(const QString &action);
52
53Q_SIGNALS:
54 void showCalled();
55
56public:
57 QString m_summary;
58 QString m_body;
59 QList<ActionPair> m_actions;
60 bool m_isSnapDecision;
61 mutable Notification *q_ptr;
62};
63
64} // namespace
65
66#endif // MOCK_NOTIFICATiON_H
067
=== added file 'tests/online-accounts-ui/mock/request-mock.cpp'
--- tests/online-accounts-ui/mock/request-mock.cpp 1970-01-01 00:00:00 +0000
+++ tests/online-accounts-ui/mock/request-mock.cpp 2014-08-18 13:33:35 +0000
@@ -0,0 +1,139 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "globals.h"
22#include "request-mock.h"
23
24#include <QDebug>
25
26using namespace OnlineAccountsUi;
27
28RequestPrivate::RequestPrivate(const QString &interface,
29 int id,
30 const QString &clientProfile,
31 const QVariantMap &parameters,
32 Request *request):
33 QObject(request),
34 q_ptr(request),
35 m_parameters(parameters),
36 m_clientApparmorProfile(clientProfile),
37 m_window(0),
38 m_inProgress(false)
39{
40 Q_UNUSED(interface);
41 Q_UNUSED(id);
42}
43
44RequestPrivate::~RequestPrivate()
45{
46}
47
48Request::Request(const QString &interface,
49 int id,
50 const QString &clientProfile,
51 const QVariantMap &parameters,
52 QObject *parent):
53 QObject(parent),
54 d_ptr(new RequestPrivate(interface, id, clientProfile, parameters, this))
55{
56}
57
58Request::~Request()
59{
60}
61
62void Request::setWindow(QWindow *window)
63{
64 Q_D(Request);
65 Q_EMIT d->setWindowCalled(window);
66}
67
68WId Request::windowId() const
69{
70 Q_D(const Request);
71 return d->m_parameters[OAU_KEY_WINDOW_ID].toUInt();
72}
73
74bool Request::isInProgress() const
75{
76 Q_D(const Request);
77 return d->m_inProgress;
78}
79
80const QVariantMap &Request::parameters() const
81{
82 Q_D(const Request);
83 return d->m_parameters;
84}
85
86QString Request::clientApparmorProfile() const
87{
88 Q_D(const Request);
89 return d->m_clientApparmorProfile;
90}
91
92QWindow *Request::window() const
93{
94 Q_D(const Request);
95 return d->m_window;
96}
97
98void Request::start()
99{
100 Q_D(Request);
101 if (d->m_inProgress) {
102 qWarning() << "Request already started!";
103 return;
104 }
105 d->m_inProgress = true;
106}
107
108void Request::cancel()
109{
110 setCanceled();
111}
112
113void Request::fail(const QString &name, const QString &message)
114{
115 Q_D(Request);
116 Q_EMIT d->failCalled(name, message);
117
118 Q_EMIT completed();
119}
120
121void Request::setCanceled()
122{
123 Q_D(Request);
124 if (d->m_inProgress) {
125 fail(OAU_ERROR_USER_CANCELED, QStringLiteral("Canceled"));
126 d->m_inProgress = false;
127 }
128}
129
130void Request::setResult(const QVariantMap &result)
131{
132 Q_D(Request);
133 if (d->m_inProgress) {
134 Q_EMIT d->setResultCalled(result);
135
136 Q_EMIT completed();
137 d->m_inProgress = false;
138 }
139}
0140
=== added file 'tests/online-accounts-ui/mock/request-mock.h'
--- tests/online-accounts-ui/mock/request-mock.h 1970-01-01 00:00:00 +0000
+++ tests/online-accounts-ui/mock/request-mock.h 2014-08-18 13:33:35 +0000
@@ -0,0 +1,61 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef MOCK_REQUEST_H
22#define MOCK_REQUEST_H
23
24#include "request.h"
25
26#include <QObject>
27#include <QString>
28#include <QVariantMap>
29
30namespace OnlineAccountsUi {
31
32class RequestPrivate: public QObject
33{
34 Q_OBJECT
35 Q_DECLARE_PUBLIC(Request)
36
37public:
38 RequestPrivate(const QString &interface,
39 int id,
40 const QString &clientProfile,
41 const QVariantMap &parameters,
42 Request *request);
43 ~RequestPrivate();
44 static RequestPrivate *mocked(Request *r) { return r->d_ptr; }
45
46Q_SIGNALS:
47 void setWindowCalled(QWindow *);
48 void failCalled(const QString &name, const QString &message);
49 void setResultCalled(const QVariantMap &result);
50
51private:
52 mutable Request *q_ptr;
53 QVariantMap m_parameters;
54 QString m_clientApparmorProfile;
55 QWindow *m_window;
56 bool m_inProgress;
57};
58
59} // namespace
60
61#endif // MOCK_REQUEST_H
062
=== added file 'tests/online-accounts-ui/mock/ui-server-mock.cpp'
--- tests/online-accounts-ui/mock/ui-server-mock.cpp 1970-01-01 00:00:00 +0000
+++ tests/online-accounts-ui/mock/ui-server-mock.cpp 2014-08-18 13:33:35 +0000
@@ -0,0 +1,68 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "ui-server-mock.h"
22
23#include <QDebug>
24
25using namespace OnlineAccountsUi;
26
27static UiServer *m_instance = 0;
28
29UiServerPrivate::UiServerPrivate(const QString &address,
30 UiServer *server):
31 QObject(server),
32 q_ptr(server),
33 m_address(address)
34{
35}
36
37UiServerPrivate::~UiServerPrivate()
38{
39}
40
41UiServer::UiServer(const QString &address,
42 QObject *parent):
43 QObject(parent),
44 d_ptr(new UiServerPrivate(address, this))
45{
46 m_instance = this;
47}
48
49UiServer::~UiServer()
50{
51 m_instance = 0;
52}
53
54UiServer *UiServer::instance()
55{
56 return m_instance;
57}
58
59bool UiServer::init()
60{
61 return true;
62}
63
64void UiServer::registerHandler(SignOnUi::RequestHandler *handler)
65{
66 Q_D(UiServer);
67 Q_EMIT d->registerHandlerCalled(handler);
68}
069
=== added file 'tests/online-accounts-ui/mock/ui-server-mock.h'
--- tests/online-accounts-ui/mock/ui-server-mock.h 1970-01-01 00:00:00 +0000
+++ tests/online-accounts-ui/mock/ui-server-mock.h 2014-08-18 13:33:35 +0000
@@ -0,0 +1,53 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
5 *
6 * This file is part of online-accounts-ui
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 3, as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranties of
14 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef MOCK_UI_SERVER_H
22#define MOCK_UI_SERVER_H
23
24#include "ui-server.h"
25
26#include <QObject>
27#include <QString>
28
29namespace OnlineAccountsUi {
30
31class UiServerPrivate: public QObject
32{
33 Q_OBJECT
34 Q_DECLARE_PUBLIC(UiServer)
35
36public:
37 UiServerPrivate(const QString &address, UiServer *pluginServer);
38 ~UiServerPrivate();
39 static UiServerPrivate *mocked(UiServer *r) { return r->d_ptr; }
40
41 void emitFinished() { Q_EMIT q_ptr->finished(); }
42
43Q_SIGNALS:
44 void registerHandlerCalled(SignOnUi::RequestHandler *handler);
45
46public:
47 mutable UiServer *q_ptr;
48 QString m_address;
49};
50
51} // namespace
52
53#endif // MOCK_UI_SERVER_H
054
=== added file 'tests/online-accounts-ui/online-accounts-ui.pri'
--- tests/online-accounts-ui/online-accounts-ui.pri 1970-01-01 00:00:00 +0000
+++ tests/online-accounts-ui/online-accounts-ui.pri 2014-08-18 13:33:35 +0000
@@ -0,0 +1,18 @@
1include(../../common-project-config.pri)
2
3CONFIG += \
4 debug
5
6QT += \
7 core \
8 testlib
9
10DEFINES += \
11 DEBUG_ENABLED
12
13ONLINE_ACCOUNTS_UI_DIR = $${TOP_SRC_DIR}/online-accounts-ui
14COMMON_SRC_DIR = $${TOP_SRC_DIR}/online-accounts-ui
15
16INCLUDEPATH += \
17 $${ONLINE_ACCOUNTS_SERVICE_DIR} \
18 $${COMMON_SRC_DIR}
019
=== modified file 'tests/online-accounts-ui/online-accounts-ui.pro'
--- tests/online-accounts-ui/online-accounts-ui.pro 2014-06-05 13:28:30 +0000
+++ tests/online-accounts-ui/online-accounts-ui.pro 2014-08-18 13:33:35 +0000
@@ -3,6 +3,5 @@
3 qml \3 qml \
4 tst_access_model.pro \4 tst_access_model.pro \
5 tst_application_manager.pro \5 tst_application_manager.pro \
6 tst_inactivity_timer.pro \
7 tst_notification.pro \6 tst_notification.pro \
8 tst_service.pro7 tst_signonui_request.pro
98
=== modified file 'tests/online-accounts-ui/qml/Source/qmldir'
--- tests/online-accounts-ui/qml/Source/qmldir 2013-09-18 08:35:43 +0000
+++ tests/online-accounts-ui/qml/Source/qmldir 2014-08-18 13:33:35 +0000
@@ -1,2 +1,2 @@
1module Source1module Source
2AccountCreationPage 1.0 ../../../../src/qml/AccountCreationPage.qml2AccountCreationPage 1.0 ../../../../online-accounts-ui/qml/AccountCreationPage.qml
33
=== modified file 'tests/online-accounts-ui/tst_access_model.pro'
--- tests/online-accounts-ui/tst_access_model.pro 2014-02-03 10:27:39 +0000
+++ tests/online-accounts-ui/tst_access_model.pro 2014-08-18 13:33:35 +0000
@@ -1,37 +1,30 @@
1include(../../common-project-config.pri)1include(online-accounts-ui.pri)
22
3TARGET = tst_access_model3TARGET = tst_access_model
44
5CONFIG += \5CONFIG += \
6 debug \
7 link_pkgconfig6 link_pkgconfig
87
9QT += \8QT += \
10 core \
11 dbus \9 dbus \
12 qml \10 qml
13 testlib
1411
15PKGCONFIG += \12PKGCONFIG += \
16 accounts-qt513 accounts-qt5
1714
18DEFINES += \15DEFINES += \
19 DEBUG_ENABLED \
20 TEST_DATA_DIR=\\\"$${PWD}/data\\\"16 TEST_DATA_DIR=\\\"$${PWD}/data\\\"
2117
22SOURCES += \18SOURCES += \
23 $${TOP_SRC_DIR}/src/access-model.cpp \19 $${ONLINE_ACCOUNTS_UI_DIR}/access-model.cpp \
24 $${TOP_SRC_DIR}/src/account-manager.cpp \20 $${ONLINE_ACCOUNTS_UI_DIR}/account-manager.cpp \
25 $${TOP_SRC_DIR}/src/debug.cpp \21 $${ONLINE_ACCOUNTS_UI_DIR}/debug.cpp \
26 tst_access_model.cpp22 tst_access_model.cpp
2723
28HEADERS += \24HEADERS += \
29 $${TOP_SRC_DIR}/src/access-model.h \25 $${ONLINE_ACCOUNTS_UI_DIR}/access-model.h \
30 $${TOP_SRC_DIR}/src/account-manager.h \26 $${ONLINE_ACCOUNTS_UI_DIR}/account-manager.h \
31 $${TOP_SRC_DIR}/src/debug.h27 $${ONLINE_ACCOUNTS_UI_DIR}/debug.h
32
33INCLUDEPATH += \
34 $${TOP_SRC_DIR}/src
3528
36check.commands = "xvfb-run -a dbus-test-runner -t ./$${TARGET}"29check.commands = "xvfb-run -a dbus-test-runner -t ./$${TARGET}"
37check.depends = $${TARGET}30check.depends = $${TARGET}
3831
=== modified file 'tests/online-accounts-ui/tst_application_manager.pro'
--- tests/online-accounts-ui/tst_application_manager.pro 2014-05-14 13:31:42 +0000
+++ tests/online-accounts-ui/tst_application_manager.pro 2014-08-18 13:33:35 +0000
@@ -1,37 +1,30 @@
1include(../../common-project-config.pri)1include(online-accounts-ui.pri)
22
3TARGET = tst_application_manager3TARGET = tst_application_manager
44
5CONFIG += \5CONFIG += \
6 debug \
7 link_pkgconfig6 link_pkgconfig
87
9QT += \8QT += \
10 core \
11 dbus \9 dbus \
12 qml \10 qml
13 testlib
1411
15PKGCONFIG += \12PKGCONFIG += \
16 accounts-qt513 accounts-qt5
1714
18DEFINES += \15DEFINES += \
19 DEBUG_ENABLED \
20 TEST_DATA_DIR=\\\"$${PWD}/data\\\"16 TEST_DATA_DIR=\\\"$${PWD}/data\\\"
2117
22SOURCES += \18SOURCES += \
23 $${TOP_SRC_DIR}/src/application-manager.cpp \19 $${ONLINE_ACCOUNTS_UI_DIR}/application-manager.cpp \
24 $${TOP_SRC_DIR}/src/account-manager.cpp \20 $${ONLINE_ACCOUNTS_UI_DIR}/account-manager.cpp \
25 $${TOP_SRC_DIR}/src/debug.cpp \21 $${ONLINE_ACCOUNTS_UI_DIR}/debug.cpp \
26 tst_application_manager.cpp22 tst_application_manager.cpp
2723
28HEADERS += \24HEADERS += \
29 $${TOP_SRC_DIR}/src/application-manager.h \25 $${ONLINE_ACCOUNTS_UI_DIR}/application-manager.h \
30 $${TOP_SRC_DIR}/src/account-manager.h \26 $${ONLINE_ACCOUNTS_UI_DIR}/account-manager.h \
31 $${TOP_SRC_DIR}/src/debug.h27 $${ONLINE_ACCOUNTS_UI_DIR}/debug.h
32
33INCLUDEPATH += \
34 $${TOP_SRC_DIR}/src
3528
36check.commands = "xvfb-run -a dbus-test-runner -t ./$${TARGET}"29check.commands = "xvfb-run -a dbus-test-runner -t ./$${TARGET}"
37check.depends = $${TARGET}30check.depends = $${TARGET}
3831
=== modified file 'tests/online-accounts-ui/tst_notification.cpp'
--- tests/online-accounts-ui/tst_notification.cpp 2014-06-05 13:28:30 +0000
+++ tests/online-accounts-ui/tst_notification.cpp 2014-08-18 13:33:35 +0000
@@ -26,6 +26,7 @@
26#include <QPair>26#include <QPair>
27#include <QSignalSpy>27#include <QSignalSpy>
28#include <QTest>28#include <QTest>
29#include <QVariantMap>
29#include <libnotify/notification.h>30#include <libnotify/notification.h>
30#include <libnotify/notify.h>31#include <libnotify/notify.h>
3132
@@ -52,6 +53,7 @@
52 QString summary;53 QString summary;
53 QString body;54 QString body;
54 QList<ActionPair> actions;55 QList<ActionPair> actions;
56 QVariantMap hints;
55 bool visible;57 bool visible;
5658
57 MockNotification();59 MockNotification();
@@ -167,6 +169,22 @@
167 callbackData.userData = user_data;169 callbackData.userData = user_data;
168}170}
169171
172void notify_notification_set_hint(NotifyNotification *notification,
173 const char *key,
174 GVariant *value)
175{
176 MockNotification *mock =
177 reinterpret_cast<MockNotification*>(notification);
178 QVariant variant;
179 if (g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
180 variant = bool(g_variant_get_boolean(value));
181 } else {
182 /* Add support for any needed types */
183 qWarning() << "Unsupported variant type";
184 }
185 mock->hints.insert(QString::fromUtf8(key), variant);
186}
187
170/* End of mock code */188/* End of mock code */
171189
172class NotificationTest: public QObject190class NotificationTest: public QObject
@@ -180,6 +198,7 @@
180 void testInitialization();198 void testInitialization();
181 void testDestruction();199 void testDestruction();
182 void testContents();200 void testContents();
201 void testSnapDecision();
183 void testVisibility();202 void testVisibility();
184 void testClosing();203 void testClosing();
185 void testActions();204 void testActions();
@@ -220,6 +239,20 @@
220 MockNotification *mock = *(notifications.begin());239 MockNotification *mock = *(notifications.begin());
221 QCOMPARE(mock->summary, QString("Summary"));240 QCOMPARE(mock->summary, QString("Summary"));
222 QCOMPARE(mock->body, QString("Body"));241 QCOMPARE(mock->body, QString("Body"));
242 QVERIFY(mock->hints.isEmpty());
243}
244
245void NotificationTest::testSnapDecision()
246{
247 Notification first("Summary", "Body");
248 MockNotification *mock = *(notifications.begin());
249 QVERIFY(mock->hints.isEmpty());
250
251 first.setSnapDecision(true);
252 QCOMPARE(mock->hints["x-canonical-snap-decisions"].toBool(), true);
253
254 first.setSnapDecision(false);
255 QCOMPARE(mock->hints["x-canonical-snap-decisions"].toBool(), false);
223}256}
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches