Merge lp:~zsombi/ubuntu-ui-toolkit/rtm-to-staging into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Merged
Approved by: Zsombor Egri
Approved revision: 1407
Merged at revision: 1407
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/rtm-to-staging
Merge into: lp:ubuntu-ui-toolkit/staging
Diff against target: 2582 lines (+352/-1002)
19 files modified
components.api (+78/-0)
debian/changelog (+28/-0)
modules/Ubuntu/Components/11/Haptics.qml (+181/-0)
modules/Ubuntu/Components/AbstractButton.qml (+6/-12)
modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qml (+1/-6)
modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp (+0/-226)
modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h (+0/-55)
modules/Ubuntu/Components/plugin/plugin.pro (+2/-2)
modules/Ubuntu/Components/plugin/ucserviceproperties.cpp (+0/-317)
modules/Ubuntu/Components/plugin/ucserviceproperties.h (+0/-83)
modules/Ubuntu/Components/plugin/ucserviceproperties_p.h (+0/-53)
modules/Ubuntu/Components/qmldir (+3/-0)
tests/unit/runtest.sh (+1/-0)
tests/unit/tst_components/tst_haptics.qml (+52/-0)
tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml (+0/-31)
tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml (+0/-31)
tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml (+0/-32)
tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp (+0/-146)
tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro (+0/-8)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/rtm-to-staging
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Zoltan Balogh Approve
Review via email: mp+249220@code.launchpad.net

Commit message

RTM branch diff merge.

Description of the change

RTM branch diff merge.

To post a comment you must log in.
Revision history for this message
Zoltan Balogh (bzoltan) wrote :

Looks good

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'components.api'
--- components.api 2015-02-06 11:49:35 +0000
+++ components.api 2015-02-11 08:57:32 +0000
@@ -62,6 +62,11 @@
62 property string fadeStyle62 property string fadeStyle
63 readonly property bool running63 readonly property bool running
64 readonly property int status64 readonly property int status
65Haptics 0.1 1.0
66Object
67 readonly property bool enabled
68 property HapticsEffect effect
69 function play(customEffect)
65Header 0.1 1.070Header 0.1 1.0
66AppHeader71AppHeader
67 property string _for_autopilot72 property string _for_autopilot
@@ -693,6 +698,64 @@
693 name: "QAbstractProxyModel"698 name: "QAbstractProxyModel"
694 prototype: "QAbstractItemModel"699 prototype: "QAbstractItemModel"
695 Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }700 Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true }
701 name: "QDeclarativeFeedbackActuator"
702 prototype: "QObject"
703 exports: ["QtFeedback/Actuator 5.0"]
704 name: "Capability"
705 name: "State"
706 Property { name: "actuatorId"; type: "int"; isReadonly: true }
707 Property { name: "name"; type: "string"; isReadonly: true }
708 Property { name: "state"; type: "State"; isReadonly: true }
709 Property { name: "valid"; type: "bool"; isReadonly: true }
710 Property { name: "enabled"; type: "bool" }
711 Method {
712 name: "isCapabilitySupported"
713 Parameter { name: "capability"; type: "Capability" }
714 name: "QDeclarativeFeedbackEffect"
715 prototype: "QObject"
716 exports: ["QtFeedback/Feedback 5.0", "QtFeedback/FeedbackEffect 5.0"]
717 name: "Duration"
718 name: "State"
719 name: "ErrorType"
720 Property { name: "running"; type: "bool" }
721 Property { name: "paused"; type: "bool" }
722 Property { name: "duration"; type: "int" }
723 Property { name: "state"; type: "State" }
724 Property { name: "error"; type: "ErrorType"; isReadonly: true }
725 Method { name: "updateState" }
726 Method { name: "start" }
727 Method { name: "stop" }
728 Method { name: "pause" }
729 name: "QDeclarativeFileEffect"
730 prototype: "QDeclarativeFeedbackEffect"
731 exports: ["QtFeedback/FileEffect 5.0"]
732 Property { name: "loaded"; type: "bool" }
733 Property { name: "source"; type: "QUrl" }
734 Property { name: "supportedMimeTypes"; type: "QStringList"; isReadonly: true }
735 Method { name: "load" }
736 Method { name: "unload" }
737 name: "QDeclarativeHapticsEffect"
738 prototype: "QDeclarativeFeedbackEffect"
739 exports: ["QtFeedback/HapticsEffect 5.0"]
740 Property {
741 name: "availableActuators"
742 Property { name: "intensity"; type: "double" }
743 Property { name: "attackTime"; type: "int" }
744 Property { name: "attackIntensity"; type: "double" }
745 Property { name: "fadeTime"; type: "int" }
746 Property { name: "fadeIntensity"; type: "double" }
747 Property { name: "period"; type: "int" }
748 Property { name: "actuator"; type: "QDeclarativeFeedbackActuator"; isPointer: true }
749 name: "QDeclarativeThemeEffect"
750 prototype: "QObject"
751 exports: ["QtFeedback/EffectPlayer 5.0", "QtFeedback/ThemeEffect 5.0"]
752 name: "Effect"
753 Property { name: "supported"; type: "bool"; isReadonly: true }
754 Property { name: "effect"; type: "Effect" }
755 Method { name: "play" }
756 Method {
757 name: "play"
758 Parameter { name: "effect"; type: "Effect" }
696 name: "QSortFilterProxyModel"759 name: "QSortFilterProxyModel"
697 prototype: "QAbstractProxyModel"760 prototype: "QAbstractProxyModel"
698 Property { name: "filterRegExp"; type: "QRegExp" }761 Property { name: "filterRegExp"; type: "QRegExp" }
@@ -1056,6 +1119,21 @@
1056 name: "tag"1119 name: "tag"
1057 Parameter { name: "context"; type: "string" }1120 Parameter { name: "context"; type: "string" }
1058 Parameter { name: "text"; type: "string" }1121 Parameter { name: "text"; type: "string" }
1122 prototype: "QObject"
1123 name: "Haptics"
1124 exports: ["Haptics -1.-1"]
1125 Property { name: "enabled"; type: "bool"; isReadonly: true }
1126 Property { name: "effect"; type: "QDeclarativeHapticsEffect"; isReadonly: true; isPointer: true }
1127 Method {
1128 name: "play"
1129 Parameter { name: "customEffect"; type: "QVariant" }
1130 Property { name: "__defaultPropertyFix"; type: "QObject"; isList: true; isReadonly: true }
1131 Property { name: "children"; type: "QObject"; isList: true; isReadonly: true }
1132 prototype: "QObject"
1133 name: "Object"
1134 exports: ["Object -1.-1"]
1135 Property { name: "__defaultPropertyFix"; type: "QObject"; isList: true; isReadonly: true }
1136 Property { name: "children"; type: "QObject"; isList: true; isReadonly: true }
1059 name: "ULConditionalLayout"1137 name: "ULConditionalLayout"
1060 prototype: "QObject"1138 prototype: "QObject"
1061 exports: ["ConditionalLayout 0.1", "ConditionalLayout 1.0"]1139 exports: ["ConditionalLayout 0.1", "ConditionalLayout 1.0"]
10621140
=== modified file 'debian/changelog'
--- debian/changelog 2015-01-14 13:51:28 +0000
+++ debian/changelog 2015-02-11 08:57:32 +0000
@@ -227,6 +227,34 @@
227227
228 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Sun, 02 Nov 2014 13:01:56 +0000228 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Sun, 02 Nov 2014 13:01:56 +0000
229229
230ubuntu-ui-toolkit (1.1.1298+15.04.20150209~rtm-0ubuntu1) 14.09; urgency=medium
231
232 [ Zsombor Egri ]
233 * isHapticsFeedbackEnabled context property exposed to drive
234 HapticsFeedback in AbstractButton. (LP: #1391877)
235 * Haptics singleton component to provide toolkit wide default and
236 custom feedback functionaity controlled by system settings. (LP:
237 #1391877)
238
239 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 09 Feb 2015 13:10:45 +0000
240
241ubuntu-ui-toolkit (1.1.1298+15.04.20150202~rtm-0ubuntu1) 14.09; urgency=medium
242
243 [ Tim Peeters ]
244 * Port "In Progress" translation fix from staging to rtm. (LP:
245 #1391617, #1081607)
246
247 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 02 Feb 2015 09:11:21 +0000
248
249ubuntu-ui-toolkit (1.1.1298+15.04.20150116~rtm-0ubuntu1) 14.09; urgency=low
250
251 [ Florian Boucault ]
252 * ActivityIndicator: make its animation rely solely on the rendering
253 thread so that it does not stop spinning if the main thread is
254 blocked. (LP: #1411376)
255
256 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 16 Jan 2015 10:17:50 +0000
257
230ubuntu-ui-toolkit (1.1.1298+15.04.20141111.2~rtm-0ubuntu1) 14.09; urgency=low258ubuntu-ui-toolkit (1.1.1298+15.04.20141111.2~rtm-0ubuntu1) 14.09; urgency=low
231259
232 [ Ubuntu daily release ]260 [ Ubuntu daily release ]
233261
=== added file 'modules/Ubuntu/Components/11/Haptics.qml'
--- modules/Ubuntu/Components/11/Haptics.qml 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/11/Haptics.qml 2015-02-11 08:57:32 +0000
@@ -0,0 +1,181 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17pragma Singleton
18import QtQuick 2.0
19import QtFeedback 5.0
20import Ubuntu.Components 1.1
21
22/*!
23 \qmltype Haptics
24 \inqmlmodule Ubuntu.Components 1.1
25 \ingroup ubuntu-services
26 \brief Singleton defining the haptics feedback used in components, where execution
27 of the feedback is controlled by the system settings.
28
29 Supports global feedback as well as custom feedback. Global feedback can be
30 configured through its properties, and \l play function will play the default
31 configuration, or a custom one if parameter is given.
32
33 Example of using Haptics:
34 \qml
35 import QtQuick 2.3
36 import Ubuntu.Components 1.1
37
38 Item {
39 implicitWidth: units.gu(20)
40 implicitHeight: units.gu(5)
41
42 Label {
43 text: "Press me"
44 anchors.fill: parent
45 horizontalAlignment: Text.AlignHCenter
46 verticalAlignment: Text.AlignVCenter
47 }
48 MouseArea {
49 anchors.fill: parent
50 onClicked: Haptics.play()
51 }
52 }
53 \endqml
54
55 Custom effects can be played as follows:
56 \qml
57 import QtQuick 2.3
58 import Ubuntu.Components 1.1
59
60 Item {
61 implicitWidth: units.gu(20)
62 implicitHeight: units.gu(5)
63
64 Label {
65 text: "Press me"
66 anchors.fill: parent
67 horizontalAlignment: Text.AlignHCenter
68 verticalAlignment: Text.AlignVCenter
69 }
70 MouseArea {
71 anchors.fill: parent
72 onClicked: Haptics.play({duration: 25, attackIntensity: 0.7})
73 }
74 }
75 \endqml
76
77 \note Though the \l effect property exposes \c start, \c stop and \c pause
78 functions, use those only if you want to have feedback independent on what the
79 system setting is.
80 */
81Object {
82
83 /*!
84 \qmlproperty bool enabled
85 \readonly
86 The property specifies whether the haptics feedback is enabled or not by the system.
87 */
88 readonly property alias enabled: vibra.otherVibrate
89
90 /*!
91 \qmlproperty HapticsEffect effect
92 The property defines the settings of the haptics effect used by the component.
93 The default setting is a haptics effect with a duration of 10 milliseconds
94 with an intensity of 1.0, having fading time of 50 millisecods and fading
95 intensity 0.0, and attack time of 50 milliseconds and with an intensity of
96 0.0.
97 */
98 property alias effect: effect
99
100 /*!
101 \qmlmethod play([customEffect])
102 The function plays the feedback with the configuration specified in \l effect
103 if no parameter is given. Custom effect can be played by specifying the effect
104 properties in a JSON object in \c customEffect.
105
106 The function will exit unconditionaly if playing the effects is blocked by
107 system settings.
108
109 The function will not stop any ongoing haptics effect played, if that one
110 was a default haptics effect. In case of custom effects, the previous effect
111 will be stopped, and settings will be restored before the new haptics will
112 be played. The custom settings properties (the ones which are required to
113 be different from the ones defined in the \l effect) must be specified in
114 the parameter in a JSON object.
115 */
116 function play(customEffect) {
117 if (!vibra.otherVibrate) {
118 return;
119 }
120 if (effectData.data) {
121 // we have a custom effect playing, stop it
122 effect.stop();
123 }
124 if (effect.running) {
125 // this is a global effect, leave
126 return;
127 }
128 if (customEffect) {
129 effectData.backup(customEffect);
130 }
131 effect.start();
132 }
133
134 QtObject {
135 id: effectData
136 property var data
137
138 function backup(customEffect) {
139 data = customEffect;
140 for (var p in data) {
141 var value = data[p];
142 data[p] = effect[p];
143 effect[p] = value;
144 }
145 }
146 function restore() {
147 for (var p in data) {
148 effect[p] = data[p];
149 }
150 data = undefined;
151 }
152 }
153
154 // local feedback component used to play feedback
155 HapticsEffect {
156 id: effect
157 attackIntensity: 0.0
158 attackTime: 50
159 intensity: 1.0
160 duration: 10
161 fadeTime: 50
162 fadeIntensity: 0.0
163
164 onStateChanged: {
165 if (state == HapticsEffect.Stopped) {
166 effectData.restore();
167 }
168 }
169 }
170
171 // watch system settings for otherVibrate
172 ServiceProperties {
173 objectName: "system_effect_settings"
174 id: vibra
175 service: "org.freedesktop.Accounts"
176 serviceInterface: "org.freedesktop.Accounts"
177 path: "/org/freedesktop/Accounts"
178 adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
179 property bool otherVibrate: true
180 }
181}
0182
=== modified file 'modules/Ubuntu/Components/AbstractButton.qml'
--- modules/Ubuntu/Components/AbstractButton.qml 2014-12-03 14:43:27 +0000
+++ modules/Ubuntu/Components/AbstractButton.qml 2015-02-11 08:57:32 +0000
@@ -15,7 +15,6 @@
15 */15 */
1616
17import QtQuick 2.017import QtQuick 2.0
18import QtFeedback 5.0
19import Ubuntu.Components 1.118import Ubuntu.Components 1.1
2019
21/*!20/*!
@@ -83,16 +82,6 @@
8382
84 activeFocusOnPress: true83 activeFocusOnPress: true
8584
86 HapticsEffect {
87 id: pressEffect
88 attackIntensity: 0.0
89 attackTime: 50
90 intensity: 1.0
91 duration: 10
92 fadeTime: 50
93 fadeIntensity: 0.0
94 }
95
96 MouseArea {85 MouseArea {
97 id: mouseArea86 id: mouseArea
98 anchors.fill: parent87 anchors.fill: parent
@@ -100,9 +89,14 @@
100 // as it might occlude the newly assigned mouse area.89 // as it might occlude the newly assigned mouse area.
101 hoverEnabled: true90 hoverEnabled: true
10291
92 // invoke Haptics singleton earlier than we press the button,
93 // so we give some time for the singleton to sync settings with the service
94 property bool hapticsEnabled: Haptics.enabled
95
103 onClicked: {96 onClicked: {
104 if (button.__acceptEvents) {97 if (button.__acceptEvents) {
105 pressEffect.start()98 // FIXME (Vivid) call this in the style rather than from AbstractButton
99 Haptics.play();
106 button.clicked()100 button.clicked()
107 }101 }
108 }102 }
109103
=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qml'
--- modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qml 2014-07-08 10:59:01 +0000
+++ modules/Ubuntu/Components/Themes/Ambiance/ActivityIndicatorStyle.qml 2015-02-11 08:57:32 +0000
@@ -28,12 +28,7 @@
28 verticalAlignment: Image.AlignVCenter28 verticalAlignment: Image.AlignVCenter
29 source: "artwork/spinner.png"29 source: "artwork/spinner.png"
3030
31 /*31 RotationAnimator on rotation {
32 Changed from RotationAnimator to RotationAnimation to
33 work around bug: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1338602
34 "Activity Indicator crashes in QML/Widget mixed applications"
35 */
36 RotationAnimation on rotation {
37 running: styledItem.running32 running: styledItem.running
38 from: 033 from: 0
39 to: 36034 to: 360
4035
=== added file 'modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp'
--- modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp 2015-02-11 08:57:32 +0000
@@ -0,0 +1,226 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "dbuspropertywatcher_p.h"
18#include <QtDBus/QDBusReply>
19#include <unistd.h>
20#include <sys/types.h>
21#include "i18n.h"
22#include <QtQml/QQmlInfo>
23
24#define DYNAMIC_PROPERTY "__q_property"
25
26UCServicePropertiesPrivate *createServicePropertiesAdapter(UCServiceProperties *owner)
27{
28 return new DBusServiceProperties(owner);
29}
30
31DBusServiceProperties::DBusServiceProperties(UCServiceProperties *qq)
32 : UCServicePropertiesPrivate(qq)
33 , connection("")
34 , watcher(0)
35 , iface(0)
36{
37}
38
39bool DBusServiceProperties::init()
40{
41 // crear previous connections
42 setStatus(UCServiceProperties::Inactive);
43 delete iface;
44 iface = 0;
45 delete watcher;
46 watcher = 0;
47 setError(QString());
48
49 if (service.isEmpty() || path.isEmpty()) {
50 setStatus(UCServiceProperties::ConnectionError);
51 setError(UbuntuI18n::instance().tr("No service/path specified"));
52 return false;
53 }
54
55 switch (type) {
56 case UCServiceProperties::System:
57 {
58 connection = QDBusConnection::systemBus();
59 break;
60 }
61 case UCServiceProperties::Session:
62 {
63 connection = QDBusConnection::sessionBus();
64 break;
65 }
66 default:
67 {
68 setStatus(UCServiceProperties::ConnectionError);
69 setError(UbuntuI18n::instance().tr("Invalid bus type: %1.").arg(type));
70 return false;
71 }
72 }
73
74 Q_Q(UCServiceProperties);
75 // connect dbus watcher to catch OwnerChanged
76 watcher = new QDBusServiceWatcher(service, connection, QDBusServiceWatcher::WatchForOwnerChange, q);
77 // connect interface
78 iface = new QDBusInterface(service, path, interface, connection, q);
79 if (!iface->isValid()) {
80 setStatus(UCServiceProperties::ConnectionError);
81 setError(iface->lastError().message());
82 return false;
83 }
84 // connect watcher to get owner changes
85 QObject::connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
86 this, SLOT(changeServiceOwner(QString,QString,QString)));
87 return setupInterface();
88}
89
90/*
91 * Connect dbus signal identified by (service, path, iface, name) quaduple to a
92 * slot to receive property changes.
93 */
94bool DBusServiceProperties::setupInterface()
95{
96 QDBusReply<QDBusObjectPath> dbusObjectPath = iface->call("FindUserById", qlonglong(getuid()));
97 if (dbusObjectPath.isValid()) {
98 objectPath = dbusObjectPath.value().path();
99 iface->connection().connect(
100 service,
101 objectPath,
102 "org.freedesktop.DBus.Properties",
103 "PropertiesChanged",
104 this,
105 SLOT(updateProperties(QString,QVariantMap,QStringList)));
106 return true;
107 }
108
109 setStatus(UCServiceProperties::ConnectionError);
110 setError(dbusObjectPath.error().message());
111 return false;
112}
113
114bool DBusServiceProperties::fetchPropertyValues()
115{
116 scannedProperties = properties;
117 Q_FOREACH(QString property, properties) {
118 readProperty(property);
119 }
120 return true;
121}
122
123/*
124 * Reads a property value from the adaptorInterface asynchronously.
125 */
126bool DBusServiceProperties::readProperty(const QString &property)
127{
128 if ((status < UCServiceProperties::Synchronizing) || objectPath.isEmpty()) {
129 return false;
130 }
131 Q_Q(UCServiceProperties);
132 QDBusInterface readIFace(iface->interface(), objectPath, "org.freedesktop.DBus.Properties", connection);
133 if (!readIFace.isValid()) {
134 // report invalid interface only if the property's first letter was with capital one!
135 if (property[0].isUpper()) {
136 warning(readIFace.lastError().message());
137 }
138 return false;
139 }
140 QDBusPendingCall pending = readIFace.asyncCall("Get", adaptor, property);
141 if (pending.isError()) {
142 warning(pending.error().message());
143 return false;
144 }
145 QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(pending, q);
146 QObject::connect(callWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
147 this, SLOT(readFinished(QDBusPendingCallWatcher*)));
148
149 // set a dynamic property so we know which property are we reading
150 callWatcher->setProperty(DYNAMIC_PROPERTY, property);
151 return true;
152}
153
154/*
155 * Writes a property value to theadaptorInterface synchronously. It is for pure testing purposes.
156 */
157bool DBusServiceProperties::testProperty(const QString &property, const QVariant &value)
158{
159 if (objectPath.isEmpty()) {
160 return false;
161 }
162 QDBusInterface writeIFace(iface->interface(), objectPath, "org.freedesktop.DBus.Properties", connection);
163 if (!writeIFace.isValid()) {
164 // invalid interface
165 return false;
166 }
167 QDBusMessage msg = writeIFace.call("Set", adaptor, property, QVariant::fromValue(QDBusVariant(value)));
168 return msg.type() == QDBusMessage::ReplyMessage;
169}
170
171/*
172 * Slot called when the async read operation finishes.
173 */
174void DBusServiceProperties::readFinished(QDBusPendingCallWatcher *call)
175{
176 Q_Q(UCServiceProperties);
177 QDBusPendingReply<QVariant> reply = *call;
178 QString property = call->property(DYNAMIC_PROPERTY).toString();
179 scannedProperties.removeAll(property);
180 if (reply.isError()) {
181 // remove the property from being watched, as it has no property like that
182 properties.removeAll(property);
183 if (property[0].isUpper()) {
184 // report error!
185 warning(reply.error().message());
186 }
187 } else {
188 // update watched property value
189 // make sure we have lower case when the property value is updated
190 property[0] = property[0].toLower();
191 q->setProperty(property.toLocal8Bit().constData(), reply.value());
192 }
193
194 if ((status == UCServiceProperties::Synchronizing) && scannedProperties.isEmpty()) {
195 // set status to active
196 setStatus(UCServiceProperties::Active);
197 }
198
199 // delete watcher
200 call->deleteLater();
201}
202
203/*
204 * Slot called when service owner is changed.
205 */
206void DBusServiceProperties::changeServiceOwner(const QString &serviceName, const QString &oldOwner, const QString &newOwner)
207{
208 Q_UNUSED(oldOwner);
209 Q_UNUSED(newOwner);
210 if (serviceName != service) {
211 return;
212 }
213 setupInterface();
214}
215
216/*
217 * Slot called when the properties are changed in the service.
218 */
219void DBusServiceProperties::updateProperties(const QString &onInterface, const QVariantMap &map, const QStringList &invalidated)
220{
221 Q_UNUSED(onInterface);
222 Q_UNUSED(map);
223 Q_FOREACH(const QString &property, invalidated) {
224 readProperty(property);
225 }
226}
0227
=== removed file 'modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp'
--- modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp 2014-12-03 08:26:33 +0000
+++ modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.cpp 1970-01-01 00:00:00 +0000
@@ -1,226 +0,0 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "dbuspropertywatcher_p.h"
18#include <QtDBus/QDBusReply>
19#include <unistd.h>
20#include <sys/types.h>
21#include "i18n.h"
22#include <QtQml/QQmlInfo>
23
24#define DYNAMIC_PROPERTY "__q_property"
25
26UCServicePropertiesPrivate *createServicePropertiesAdapter(UCServiceProperties *owner)
27{
28 return new DBusServiceProperties(owner);
29}
30
31DBusServiceProperties::DBusServiceProperties(UCServiceProperties *qq)
32 : UCServicePropertiesPrivate(qq)
33 , connection("")
34 , watcher(0)
35 , iface(0)
36{
37}
38
39bool DBusServiceProperties::init()
40{
41 // crear previous connections
42 setStatus(UCServiceProperties::Inactive);
43 delete iface;
44 iface = 0;
45 delete watcher;
46 watcher = 0;
47 setError(QString());
48
49 if (service.isEmpty() || path.isEmpty()) {
50 setStatus(UCServiceProperties::ConnectionError);
51 setError(UbuntuI18n::instance().tr("No service/path specified"));
52 return false;
53 }
54
55 switch (type) {
56 case UCServiceProperties::System:
57 {
58 connection = QDBusConnection::systemBus();
59 break;
60 }
61 case UCServiceProperties::Session:
62 {
63 connection = QDBusConnection::sessionBus();
64 break;
65 }
66 default:
67 {
68 setStatus(UCServiceProperties::ConnectionError);
69 setError(UbuntuI18n::instance().tr("Invalid bus type: %1.").arg(type));
70 return false;
71 }
72 }
73
74 Q_Q(UCServiceProperties);
75 // connect dbus watcher to catch OwnerChanged
76 watcher = new QDBusServiceWatcher(service, connection, QDBusServiceWatcher::WatchForOwnerChange, q);
77 // connect interface
78 iface = new QDBusInterface(service, path, interface, connection, q);
79 if (!iface->isValid()) {
80 setStatus(UCServiceProperties::ConnectionError);
81 setError(iface->lastError().message());
82 return false;
83 }
84 // connect watcher to get owner changes
85 QObject::connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
86 this, SLOT(changeServiceOwner(QString,QString,QString)));
87 return setupInterface();
88}
89
90/*
91 * Connect dbus signal identified by (service, path, iface, name) quaduple to a
92 * slot to receive property changes.
93 */
94bool DBusServiceProperties::setupInterface()
95{
96 QDBusReply<QDBusObjectPath> dbusObjectPath = iface->call("FindUserById", qlonglong(getuid()));
97 if (dbusObjectPath.isValid()) {
98 objectPath = dbusObjectPath.value().path();
99 iface->connection().connect(
100 service,
101 objectPath,
102 "org.freedesktop.DBus.Properties",
103 "PropertiesChanged",
104 this,
105 SLOT(updateProperties(QString,QVariantMap,QStringList)));
106 return true;
107 }
108
109 setStatus(UCServiceProperties::ConnectionError);
110 setError(dbusObjectPath.error().message());
111 return false;
112}
113
114bool DBusServiceProperties::fetchPropertyValues()
115{
116 scannedProperties = properties;
117 Q_FOREACH(QString property, properties) {
118 readProperty(property);
119 }
120 return true;
121}
122
123/*
124 * Reads a property value from the adaptorInterface asynchronously.
125 */
126bool DBusServiceProperties::readProperty(const QString &property)
127{
128 if ((status < UCServiceProperties::Synchronizing) || objectPath.isEmpty()) {
129 return false;
130 }
131 Q_Q(UCServiceProperties);
132 QDBusInterface readIFace(iface->interface(), objectPath, "org.freedesktop.DBus.Properties", connection);
133 if (!readIFace.isValid()) {
134 // report invalid interface only if the property's first letter was with capital one!
135 if (property[0].isUpper()) {
136 qmlInfo(q) << readIFace.lastError().message();
137 }
138 return false;
139 }
140 QDBusPendingCall pending = readIFace.asyncCall("Get", adaptor, property);
141 if (pending.isError()) {
142 qmlInfo(q) << pending.error().message();
143 return false;
144 }
145 QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(pending, q);
146 QObject::connect(callWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
147 this, SLOT(readFinished(QDBusPendingCallWatcher*)));
148
149 // set a dynamic property so we know which property are we reading
150 callWatcher->setProperty(DYNAMIC_PROPERTY, property);
151 return true;
152}
153
154/*
155 * Writes a property value to theadaptorInterface synchronously. It is for pure testing purposes.
156 */
157bool DBusServiceProperties::testProperty(const QString &property, const QVariant &value)
158{
159 if (objectPath.isEmpty()) {
160 return false;
161 }
162 QDBusInterface writeIFace(iface->interface(), objectPath, "org.freedesktop.DBus.Properties", connection);
163 if (!writeIFace.isValid()) {
164 // invalid interface
165 return false;
166 }
167 QDBusMessage msg = writeIFace.call("Set", adaptor, property, QVariant::fromValue(QDBusVariant(value)));
168 return msg.type() == QDBusMessage::ReplyMessage;
169}
170
171/*
172 * Slot called when the async read operation finishes.
173 */
174void DBusServiceProperties::readFinished(QDBusPendingCallWatcher *call)
175{
176 Q_Q(UCServiceProperties);
177 QDBusPendingReply<QVariant> reply = *call;
178 QString property = call->property(DYNAMIC_PROPERTY).toString();
179 scannedProperties.removeAll(property);
180 if (reply.isError()) {
181 // remove the property from being watched, as it has no property like that
182 properties.removeAll(property);
183 if (property[0].isUpper()) {
184 // report error!
185 qmlInfo(q) << reply.error().message();
186 }
187 } else {
188 // update watched property value
189 // make sure we have lower case when the property value is updated
190 property[0] = property[0].toLower();
191 q->setProperty(property.toLocal8Bit().constData(), reply.value());
192 }
193
194 if ((status == UCServiceProperties::Synchronizing) && scannedProperties.isEmpty()) {
195 // set status to active
196 setStatus(UCServiceProperties::Active);
197 }
198
199 // delete watcher
200 call->deleteLater();
201}
202
203/*
204 * Slot called when service owner is changed.
205 */
206void DBusServiceProperties::changeServiceOwner(const QString &serviceName, const QString &oldOwner, const QString &newOwner)
207{
208 Q_UNUSED(oldOwner);
209 Q_UNUSED(newOwner);
210 if (serviceName != service) {
211 return;
212 }
213 setupInterface();
214}
215
216/*
217 * Slot called when the properties are changed in the service.
218 */
219void DBusServiceProperties::updateProperties(const QString &onInterface, const QVariantMap &map, const QStringList &invalidated)
220{
221 Q_UNUSED(onInterface);
222 Q_UNUSED(map);
223 Q_FOREACH(const QString &property, invalidated) {
224 readProperty(property);
225 }
226}
2270
=== added file 'modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h'
--- modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h 2015-02-11 08:57:32 +0000
@@ -0,0 +1,55 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef DBUSPROPERTYWATCHER_P_H
18#define DBUSPROPERTYWATCHER_P_H
19
20#include <QtCore/QObject>
21#include <QtDBus/QDBusConnection>
22#include <QtDBus/QDBusServiceWatcher>
23#include <QtDBus/QDBusInterface>
24
25#include "ucserviceproperties_p.h"
26
27class QDBusPendingCallWatcher;
28class DBusServiceProperties : public QObject, public UCServicePropertiesPrivate
29{
30 Q_OBJECT
31 Q_DECLARE_PUBLIC(UCServiceProperties)
32public:
33 DBusServiceProperties(UCServiceProperties *qq);
34
35 bool init();
36 bool fetchPropertyValues();
37 bool readProperty(const QString &property);
38 // for testing purposes only!!!
39 bool testProperty(const QString &property, const QVariant &value);
40
41 QStringList scannedProperties;
42 QDBusConnection connection;
43 QDBusServiceWatcher *watcher;
44 QDBusInterface *iface;
45 QString objectPath;
46
47 bool setupInterface();
48
49public Q_SLOTS:
50 void readFinished(QDBusPendingCallWatcher *watcher);
51 void changeServiceOwner(const QString &serviceName, const QString &oldOwner, const QString &newOwner);
52 void updateProperties(const QString &iface, const QVariantMap &map, const QStringList &invalidated);
53};
54
55#endif // DBUSPROPERTYWATCHER_P_H
056
=== removed file 'modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h'
--- modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h 2014-12-03 08:26:33 +0000
+++ modules/Ubuntu/Components/plugin/adapters/dbuspropertywatcher_p.h 1970-01-01 00:00:00 +0000
@@ -1,55 +0,0 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef DBUSPROPERTYWATCHER_P_H
18#define DBUSPROPERTYWATCHER_P_H
19
20#include <QtCore/QObject>
21#include <QtDBus/QDBusConnection>
22#include <QtDBus/QDBusServiceWatcher>
23#include <QtDBus/QDBusInterface>
24
25#include "ucserviceproperties_p.h"
26
27class QDBusPendingCallWatcher;
28class DBusServiceProperties : public QObject, public UCServicePropertiesPrivate
29{
30 Q_OBJECT
31 Q_DECLARE_PUBLIC(UCServiceProperties)
32public:
33 DBusServiceProperties(UCServiceProperties *qq);
34
35 bool init();
36 bool fetchPropertyValues();
37 bool readProperty(const QString &property);
38 // for testing purposes only!!!
39 bool testProperty(const QString &property, const QVariant &value);
40
41 QStringList scannedProperties;
42 QDBusConnection connection;
43 QDBusServiceWatcher *watcher;
44 QDBusInterface *iface;
45 QString objectPath;
46
47 bool setupInterface();
48
49public Q_SLOTS:
50 void readFinished(QDBusPendingCallWatcher *watcher);
51 void changeServiceOwner(const QString &serviceName, const QString &oldOwner, const QString &newOwner);
52 void updateProperties(const QString &iface, const QVariantMap &map, const QStringList &invalidated);
53};
54
55#endif // DBUSPROPERTYWATCHER_P_H
560
=== modified file 'modules/Ubuntu/Components/plugin/plugin.pro'
--- modules/Ubuntu/Components/plugin/plugin.pro 2015-01-22 06:26:27 +0000
+++ modules/Ubuntu/Components/plugin/plugin.pro 2015-02-11 08:57:32 +0000
@@ -67,13 +67,13 @@
67 ucactioncontext.h \67 ucactioncontext.h \
68 ucactionmanager.h \68 ucactionmanager.h \
69 adapters/actionsproxy_p.h \69 adapters/actionsproxy_p.h \
70 adapters/dbuspropertywatcher_p.h \
70 uclistitem.h \71 uclistitem.h \
71 uclistitem_p.h \72 uclistitem_p.h \
72 uclistitemactions.h \73 uclistitemactions.h \
73 uclistitemactions_p.h \74 uclistitemactions_p.h \
74 propertychange_p.h \75 propertychange_p.h \
75 uclistitemstyle.h \76 uclistitemstyle.h \
76 adapters\dbuspropertywatcher_p.h \
77 ucserviceproperties.h \77 ucserviceproperties.h \
78 ucserviceproperties_p.h78 ucserviceproperties_p.h
7979
@@ -112,6 +112,7 @@
112 ucactioncontext.cpp \112 ucactioncontext.cpp \
113 ucactionmanager.cpp \113 ucactionmanager.cpp \
114 adapters/actionsproxy_p.cpp \114 adapters/actionsproxy_p.cpp \
115 adapters/dbuspropertywatcher_p.cpp \
115 uclistitem.cpp \116 uclistitem.cpp \
116 uclistitemactions.cpp \117 uclistitemactions.cpp \
117 propertychange_p.cpp \118 propertychange_p.cpp \
@@ -119,7 +120,6 @@
119 ucviewitemsattached.cpp \120 ucviewitemsattached.cpp \
120 uclistitemattached.cpp \121 uclistitemattached.cpp \
121 ucactionpanel_p.cpp \122 ucactionpanel_p.cpp \
122 adapters\dbuspropertywatcher_p.cpp \
123 ucserviceproperties.cpp123 ucserviceproperties.cpp
124124
125# adapters125# adapters
126126
=== added file 'modules/Ubuntu/Components/plugin/ucserviceproperties.cpp'
--- modules/Ubuntu/Components/plugin/ucserviceproperties.cpp 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/ucserviceproperties.cpp 2015-02-11 08:57:32 +0000
@@ -0,0 +1,327 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "ucserviceproperties.h"
18#include "ucserviceproperties_p.h"
19#include "i18n.h"
20#include <QtQml/QQmlInfo>
21#include <QtCore/QMetaProperty>
22#include <QtQml/QQmlProperty>
23#include <QtQml/private/qqmlproperty_p.h>
24
25UCServicePropertiesPrivate::UCServicePropertiesPrivate(UCServiceProperties *qq)
26 : q_ptr(qq)
27 , ready(false)
28 , status(UCServiceProperties::Inactive)
29 , type(UCServiceProperties::System)
30{
31}
32
33UCServicePropertiesPrivate::~UCServicePropertiesPrivate()
34{
35}
36
37UCServicePropertiesPrivate *UCServicePropertiesPrivate::get(UCServiceProperties *service)
38{
39 return service->d_func();
40}
41
42void UCServicePropertiesPrivate::warning(const QString &message)
43{
44 QByteArray suppressWarnings = qgetenv("SUPPRESS_SERVICEPROPERTIES_WARNINGS");
45 if ((suppressWarnings == "yes") || (suppressWarnings == "1")) {
46 return;
47 }
48 qmlInfo(q_ptr) << message;
49}
50
51void UCServicePropertiesPrivate::setError(const QString &msg)
52{
53 if (error == msg) {
54 return;
55 }
56 error = msg;
57 Q_EMIT q_ptr->errorChanged();
58}
59
60void UCServicePropertiesPrivate::setStatus(UCServiceProperties::Status status)
61{
62 if (this->status == status) {
63 return;
64 }
65 this->status = status;
66 Q_EMIT q_ptr->statusChanged();
67}
68
69void printLocked(UCServiceProperties *owner)
70{
71 UCServicePropertiesPrivate::get(owner)->
72 warning(UbuntuI18n::instance().tr("Changing connection parameters forbidden."));
73}
74
75/*!
76 * \qmltype ServiceProperties
77 * \instantiates UCServiceProperties
78 * \inqmlmodule Ubuntu.Components 1.1
79 * \since Ubuntu.Components 1.1
80 * \ingroup ubuntu-services
81 * \brief The component enables accessing service properties from QML.
82 *
83 * The services accessed by the component are ones providing their interfaces
84 * through DBus. The component is specialized to read properties exposed by these
85 * services, andf to keep these property values up to date. It is not meant to
86 * access signals or slots exposed, nor to change the values of the properties
87 * watched.
88 *
89 * Properties watched should be declared within the body of the component like
90 * any other QML property, preferably defining a default value for them. The component
91 * will enumerate these properties and will ask the service to provide values for
92 * those. When enumerating properties, each property will be checked twice, with
93 * the case specified as well as with the first letter capitalized.
94 * \qml
95 * import QtQuick 2.3
96 * import Ubuntu.Components 1.1
97 *
98 * ServiceProperties {
99 * service: "org.freenode.AccountsService"
100 * path: "/org/freenode/AccountsService"
101 * serviceInterface: "org.freenode.AccountsService"
102 * adaptorInterface: "com.ubuntu.touch.Accounts.Sound"
103 * // listing properties to watch
104 * // each property name existence will be checked against the current case
105 * // as well as with first character capitalized
106 * property bool incomingCallVibrate: true
107 * }
108 * \endqml
109 *
110 * Note that there are few properties which must be set in order the component
111 * to work. These are \l service, \l path and \l adaptorInterface. Also, once
112 * specified, \l service, \l serviceInterface and \l adaptorInterface values
113 * should not be changed as it cannot be guaranteed that properties watched will
114 * be available on those service. Therefore any change on these properties after
115 * the component completion will be ignored. Property bindings on properties
116 * watched will be ignored as well, as service will report changes in these property
117 * values.
118 *
119 * The service is connected once the component gets completed (Component.onCompleted).
120 * The \l error property specifies any error occured during connection, and the
121 * \l status property notifies whether the connection to the service is active or not.
122 *
123 * \note Pay attention when chosing the service watched, and set your application's
124 * AppArmor rights to ensure a successful service connection.
125 */
126UCServiceProperties::UCServiceProperties(QObject *parent)
127 : QObject(parent)
128 , d_ptr(createServicePropertiesAdapter(this))
129{
130}
131UCServiceProperties::~UCServiceProperties()
132{
133 delete d_ptr;
134 d_ptr = 0;
135}
136
137void UCServiceProperties::classBegin()
138{
139}
140
141void UCServiceProperties::componentComplete()
142{
143 Q_D(UCServiceProperties);
144 d->ready = true;
145 // enumerate properties
146 const QMetaObject *mo = metaObject();
147 for (int i = mo->propertyOffset(); i < mo->propertyCount(); i++) {
148 const QMetaProperty prop = mo->property(i);
149 QString property(prop.name());
150
151 // check the binding on the property and warn if there is one.
152 QQmlProperty qmlProperty(this, property);
153 if (QQmlPropertyPrivate::binding(qmlProperty)) {
154 d->warning(UbuntuI18n::instance().
155 tr("Binding detected on property '%1' will be removed by the service updates.").
156 arg(property));
157 }
158 // insert both the declared and capitalized first character properties
159 d->properties << property;
160 property[0] = property[0].toUpper();
161 d->properties << property;
162 }
163 // initialize DBus
164 if (d->init()) {
165 d->setStatus(UCServiceProperties::Synchronizing);
166 d->fetchPropertyValues();
167 }
168}
169
170/*!
171 * \qmlproperty enum ServiceProperties::type
172 * Specifies the DBus connection session type. It can get the following values:
173 * \list
174 * \li - \e ServiceProperties.System when system bus is used (default)
175 * \li - \e ServiceProperties.Session when session bus is used
176 * \endlist
177 */
178UCServiceProperties::ServiceType UCServiceProperties::type() const
179{
180 Q_D(const UCServiceProperties);
181 return d->type;
182}
183void UCServiceProperties::setType(ServiceType type)
184{
185 Q_D(UCServiceProperties);
186 if (d->type == type) {
187 return;
188 }
189 if (d->ready) {
190 printLocked(this);
191 return;
192 }
193 d->type = type;
194 Q_EMIT typeChanged();
195}
196
197/*!
198 * \qmlproperty string ServiceProperties::service
199 * The proeprty specifies the DBus service URI. It is mandatory to be specified.
200 */
201QString UCServiceProperties::service() const
202{
203 Q_D(const UCServiceProperties);
204 return d->service;
205}
206void UCServiceProperties::setService(const QString &value)
207{
208 Q_D(UCServiceProperties);
209 if (d->service == value) {
210 return;
211 }
212 if (d->ready) {
213 printLocked(this);
214 return;
215 }
216 d->service = value;
217 Q_EMIT serviceChanged();
218}
219
220/*!
221 * \qmlproperty string ServiceProperties::path
222 * The property specifies the DBus service connection path. It is mandatory to be
223 * specified.
224 */
225QString UCServiceProperties::path() const
226{
227 Q_D(const UCServiceProperties);
228 return d->path;
229}
230void UCServiceProperties::setPath(const QString &value)
231{
232 Q_D(UCServiceProperties);
233 if (d->path == value) {
234 return;
235 }
236 d->path = value;
237 Q_EMIT pathChanged();
238 if (d->ready) {
239 // need to re-initialize connections
240 d->init();
241 }
242}
243
244/*!
245 * \qmlproperty string ServiceProperties::serviceInterface
246 * The property specifies the service intertface. If it is an empty string, the
247 * component will refer to the merging of all interfaces found in the service.
248 */
249QString UCServiceProperties::interface() const
250{
251 Q_D(const UCServiceProperties);
252 return d->interface;
253}
254void UCServiceProperties::setInterface(const QString &value)
255{
256 Q_D(UCServiceProperties);
257 if (d->interface == value) {
258 return;
259 }
260 if (d->ready) {
261 printLocked(this);
262 return;
263 }
264 d->interface = value;
265 Q_EMIT serviceInterfaceChanged();
266}
267/*!
268 * \qmlproperty string ServiceProperties::adaptorInterface
269 * The proeprty specifies the dbus adaptor interface which provides the properties
270 * watched. This can be a different interface that the one specified in \l serviceInterface,
271 * and in the same way, it can be empty, in which case all the properties from all
272 * interfaces of the service will be watched.
273 */
274QString UCServiceProperties::adaptor() const
275{
276 Q_D(const UCServiceProperties);
277 return d->adaptor;
278}
279void UCServiceProperties::setAdaptor(const QString &value)
280{
281 Q_D(UCServiceProperties);
282 if (d->adaptor == value) {
283 return;
284 }
285 if (d->ready) {
286 printLocked(this);
287 return;
288 }
289 d->adaptor = value;
290 Q_EMIT adaptorInterfaceChanged();
291}
292
293/*!
294 * \qmlproperty string ServiceProperties::error
295 * The property is set with a human readablestring each time an error occurrs
296 * during the service connection. Empty string means no error.
297 */
298QString UCServiceProperties::error()
299{
300 Q_D(UCServiceProperties);
301 return d->error;
302}
303
304/*!
305 * \qmlproperty enum ServiceProperties::status
306 * The property presents the status of the component.
307 * \list
308 * \li - \e ServiceProperties.Inactive - the component is inactive, initial state
309 * \li - \e ServiceProperties.ConnectionError - there was a connection error, the
310 * \l error contains the error string.
311 * \li - \e ServiceProperties.Synchronizing - the connection to the service succeeded,
312 * and the properties are being synchronized;
313 * \li - \e ServiceProperties.Active - the service watcher is active and initial
314 * property synchronization completed.
315 * \endlist
316 * \note While the status is set to \e Synchronizing, the properties are checked
317 * against their existence in the service. Each proeprty will be checked as declared
318 * as well with capital first letter. If neither of these exists in the service,
319 * it will be reported in the \l error property separately.
320 */
321UCServiceProperties::Status UCServiceProperties::status() const
322{
323 Q_D(const UCServiceProperties);
324 return d->status;
325}
326
327#include "moc_ucserviceproperties.cpp"
0328
=== removed file 'modules/Ubuntu/Components/plugin/ucserviceproperties.cpp'
--- modules/Ubuntu/Components/plugin/ucserviceproperties.cpp 2014-12-03 08:26:33 +0000
+++ modules/Ubuntu/Components/plugin/ucserviceproperties.cpp 1970-01-01 00:00:00 +0000
@@ -1,317 +0,0 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "ucserviceproperties.h"
18#include "ucserviceproperties_p.h"
19#include "i18n.h"
20#include <QtQml/QQmlInfo>
21#include <QtCore/QMetaProperty>
22#include <QtQml/QQmlProperty>
23#include <QtQml/private/qqmlproperty_p.h>
24
25UCServicePropertiesPrivate::UCServicePropertiesPrivate(UCServiceProperties *qq)
26 : q_ptr(qq)
27 , ready(false)
28 , status(UCServiceProperties::Inactive)
29 , type(UCServiceProperties::System)
30{
31}
32
33UCServicePropertiesPrivate::~UCServicePropertiesPrivate()
34{
35}
36
37UCServicePropertiesPrivate *UCServicePropertiesPrivate::get(UCServiceProperties *service)
38{
39 return service->d_func();
40}
41
42void UCServicePropertiesPrivate::setError(const QString &msg)
43{
44 if (error == msg) {
45 return;
46 }
47 error = msg;
48 Q_EMIT q_ptr->errorChanged();
49}
50
51void UCServicePropertiesPrivate::setStatus(UCServiceProperties::Status status)
52{
53 if (this->status == status) {
54 return;
55 }
56 this->status = status;
57 Q_EMIT q_ptr->statusChanged();
58}
59
60void printLocked(UCServiceProperties *owner)
61{
62 qmlInfo(owner) << UbuntuI18n::instance().tr("Changing connection parameters forbidden.");
63}
64
65/*!
66 * \qmltype ServiceProperties
67 * \instantiates UCServiceProperties
68 * \inqmlmodule Ubuntu.Components 1.1
69 * \since Ubuntu.Components 1.1
70 * \ingroup ubuntu-services
71 * \brief The component enables accessing service properties from QML.
72 *
73 * The services accessed by the component are ones providing their interfaces
74 * through DBus. The component is specialized to read properties exposed by these
75 * services, andf to keep these property values up to date. It is not meant to
76 * access signals or slots exposed, nor to change the values of the properties
77 * watched.
78 *
79 * Properties watched should be declared within the body of the component like
80 * any other QML property, preferably defining a default value for them. The component
81 * will enumerate these properties and will ask the service to provide values for
82 * those. When enumerating properties, each property will be checked twice, with
83 * the case specified as well as with the first letter capitalized.
84 * \qml
85 * import QtQuick 2.3
86 * import Ubuntu.Components 1.1
87 *
88 * ServiceProperties {
89 * service: "org.freenode.AccountsService"
90 * path: "/org/freenode/AccountsService"
91 * serviceInterface: "org.freenode.AccountsService"
92 * adaptorInterface: "com.ubuntu.touch.Accounts.Sound"
93 * // listing properties to watch
94 * // each property name existence will be checked against the current case
95 * // as well as with first character capitalized
96 * property bool incomingCallVibrate: true
97 * }
98 * \endqml
99 *
100 * Note that there are few properties which must be set in order the component
101 * to work. These are \l service, \l path and \l adaptorInterface. Also, once
102 * specified, \l service, \l serviceInterface and \l adaptorInterface values
103 * should not be changed as it cannot be guaranteed that properties watched will
104 * be available on those service. Therefore any change on these properties after
105 * the component completion will be ignored. Property bindings on properties
106 * watched will be ignored as well, as service will report changes in these property
107 * values.
108 *
109 * The service is connected once the component gets completed (Component.onCompleted).
110 * The \l error property specifies any error occured during connection, and the
111 * \l status property notifies whether the connection to the service is active or not.
112 *
113 * \note Pay attention when chosing the service watched, and set your application's
114 * AppArmor rights to ensure a successful service connection.
115 */
116UCServiceProperties::UCServiceProperties(QObject *parent)
117 : QObject(parent)
118 , d_ptr(createServicePropertiesAdapter(this))
119{
120}
121UCServiceProperties::~UCServiceProperties()
122{
123 delete d_ptr;
124 d_ptr = 0;
125}
126
127void UCServiceProperties::classBegin()
128{
129}
130
131void UCServiceProperties::componentComplete()
132{
133 Q_D(UCServiceProperties);
134 d->ready = true;
135 // enumerate properties
136 const QMetaObject *mo = metaObject();
137 for (int i = mo->propertyOffset(); i < mo->propertyCount(); i++) {
138 const QMetaProperty prop = mo->property(i);
139 QString property(prop.name());
140
141 // check the binding on the property and warn if there is one.
142 QQmlProperty qmlProperty(this, property);
143 if (QQmlPropertyPrivate::binding(qmlProperty)) {
144 qmlInfo(this) << UbuntuI18n::instance().
145 tr("Binding detected on property '%1' will be removed by the service updates.").
146 arg(property);
147 }
148 // insert both the declared and capitalized first character properties
149 d->properties << property;
150 property[0] = property[0].toUpper();
151 d->properties << property;
152 }
153 // initialize DBus
154 if (d->init()) {
155 d->setStatus(UCServiceProperties::Synchronizing);
156 d->fetchPropertyValues();
157 }
158}
159
160/*!
161 * \qmlproperty enum ServiceProperties::type
162 * Specifies the DBus connection session type. It can get the following values:
163 * \list
164 * \li - \e ServiceProperties.System when system bus is used (default)
165 * \li - \e ServiceProperties.Session when session bus is used
166 * \endlist
167 */
168UCServiceProperties::ServiceType UCServiceProperties::type() const
169{
170 Q_D(const UCServiceProperties);
171 return d->type;
172}
173void UCServiceProperties::setType(ServiceType type)
174{
175 Q_D(UCServiceProperties);
176 if (d->type == type) {
177 return;
178 }
179 if (d->ready) {
180 printLocked(this);
181 return;
182 }
183 d->type = type;
184 Q_EMIT typeChanged();
185}
186
187/*!
188 * \qmlproperty string ServiceProperties::service
189 * The proeprty specifies the DBus service URI. It is mandatory to be specified.
190 */
191QString UCServiceProperties::service() const
192{
193 Q_D(const UCServiceProperties);
194 return d->service;
195}
196void UCServiceProperties::setService(const QString &value)
197{
198 Q_D(UCServiceProperties);
199 if (d->service == value) {
200 return;
201 }
202 if (d->ready) {
203 printLocked(this);
204 return;
205 }
206 d->service = value;
207 Q_EMIT serviceChanged();
208}
209
210/*!
211 * \qmlproperty string ServiceProperties::path
212 * The property specifies the DBus service connection path. It is mandatory to be
213 * specified.
214 */
215QString UCServiceProperties::path() const
216{
217 Q_D(const UCServiceProperties);
218 return d->path;
219}
220void UCServiceProperties::setPath(const QString &value)
221{
222 Q_D(UCServiceProperties);
223 if (d->path == value) {
224 return;
225 }
226 d->path = value;
227 Q_EMIT pathChanged();
228 if (d->ready) {
229 // need to re-initialize connections
230 d->init();
231 }
232}
233
234/*!
235 * \qmlproperty string ServiceProperties::serviceInterface
236 * The property specifies the service intertface. If it is an empty string, the
237 * component will refer to the merging of all interfaces found in the service.
238 */
239QString UCServiceProperties::interface() const
240{
241 Q_D(const UCServiceProperties);
242 return d->interface;
243}
244void UCServiceProperties::setInterface(const QString &value)
245{
246 Q_D(UCServiceProperties);
247 if (d->interface == value) {
248 return;
249 }
250 if (d->ready) {
251 printLocked(this);
252 return;
253 }
254 d->interface = value;
255 Q_EMIT serviceInterfaceChanged();
256}
257/*!
258 * \qmlproperty string ServiceProperties::adaptorInterface
259 * The proeprty specifies the dbus adaptor interface which provides the properties
260 * watched. This can be a different interface that the one specified in \l serviceInterface,
261 * and in the same way, it can be empty, in which case all the properties from all
262 * interfaces of the service will be watched.
263 */
264QString UCServiceProperties::adaptor() const
265{
266 Q_D(const UCServiceProperties);
267 return d->adaptor;
268}
269void UCServiceProperties::setAdaptor(const QString &value)
270{
271 Q_D(UCServiceProperties);
272 if (d->adaptor == value) {
273 return;
274 }
275 if (d->ready) {
276 printLocked(this);
277 return;
278 }
279 d->adaptor = value;
280 Q_EMIT adaptorInterfaceChanged();
281}
282
283/*!
284 * \qmlproperty string ServiceProperties::error
285 * The property is set with a human readablestring each time an error occurrs
286 * during the service connection. Empty string means no error.
287 */
288QString UCServiceProperties::error()
289{
290 Q_D(UCServiceProperties);
291 return d->error;
292}
293
294/*!
295 * \qmlproperty enum ServiceProperties::status
296 * The property presents the status of the component.
297 * \list
298 * \li - \e ServiceProperties.Inactive - the component is inactive, initial state
299 * \li - \e ServiceProperties.ConnectionError - there was a connection error, the
300 * \l error contains the error string.
301 * \li - \e ServiceProperties.Synchronizing - the connection to the service succeeded,
302 * and the properties are being synchronized;
303 * \li - \e ServiceProperties.Active - the service watcher is active and initial
304 * property synchronization completed.
305 * \endlist
306 * \note While the status is set to \e Synchronizing, the properties are checked
307 * against their existence in the service. Each proeprty will be checked as declared
308 * as well with capital first letter. If neither of these exists in the service,
309 * it will be reported in the \l error property separately.
310 */
311UCServiceProperties::Status UCServiceProperties::status() const
312{
313 Q_D(const UCServiceProperties);
314 return d->status;
315}
316
317#include "moc_ucserviceproperties.cpp"
3180
=== added file 'modules/Ubuntu/Components/plugin/ucserviceproperties.h'
--- modules/Ubuntu/Components/plugin/ucserviceproperties.h 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/ucserviceproperties.h 2015-02-11 08:57:32 +0000
@@ -0,0 +1,83 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef UCSERVICEPROPERTIES_H
18#define UCSERVICEPROPERTIES_H
19
20#include <QtCore/QObject>
21#include <QtQml/QQmlParserStatus>
22
23class UCServicePropertiesPrivate;
24class UCServiceProperties : public QObject, public QQmlParserStatus
25{
26 Q_OBJECT
27 Q_INTERFACES(QQmlParserStatus)
28
29 Q_PROPERTY(ServiceType type READ type WRITE setType NOTIFY typeChanged REVISION 1)
30 Q_PROPERTY(QString service READ service WRITE setService NOTIFY serviceChanged REVISION 1)
31 Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged REVISION 1)
32 Q_PROPERTY(QString serviceInterface READ interface WRITE setInterface NOTIFY serviceInterfaceChanged REVISION 1)
33 Q_PROPERTY(QString adaptorInterface READ adaptor WRITE setAdaptor NOTIFY adaptorInterfaceChanged REVISION 1)
34 Q_PROPERTY(QString error READ error NOTIFY errorChanged REVISION 1)
35 Q_PROPERTY(Status status READ status NOTIFY statusChanged REVISION 1)
36
37 Q_ENUMS(ServiceType Status)
38public:
39 enum ServiceType {
40 Undefined,
41 System,
42 Session
43 };
44 enum Status {
45 Inactive,
46 ConnectionError,
47 Synchronizing,
48 Active
49 };
50
51 explicit UCServiceProperties(QObject *parent = 0);
52 ~UCServiceProperties();
53 void classBegin();
54 void componentComplete();
55
56 ServiceType type() const;
57 void setType(ServiceType type);
58 QString service() const;
59 void setService(const QString &value);
60 QString path() const;
61 void setPath(const QString &value);
62 QString interface() const;
63 void setInterface(const QString &value);
64 QString adaptor() const;
65 void setAdaptor(const QString &value);
66 QString error();
67 Status status() const;
68
69Q_SIGNALS:
70 void typeChanged();
71 void serviceChanged();
72 void pathChanged();
73 void serviceInterfaceChanged();
74 void adaptorInterfaceChanged();
75 void errorChanged();
76 void statusChanged();
77
78private:
79 UCServicePropertiesPrivate *d_ptr;
80 Q_DECLARE_PRIVATE_D(d_ptr, UCServiceProperties)
81};
82
83#endif // UCSERVICEPROPERTIES_H
084
=== removed file 'modules/Ubuntu/Components/plugin/ucserviceproperties.h'
--- modules/Ubuntu/Components/plugin/ucserviceproperties.h 2014-12-03 08:26:33 +0000
+++ modules/Ubuntu/Components/plugin/ucserviceproperties.h 1970-01-01 00:00:00 +0000
@@ -1,83 +0,0 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef UCSERVICEPROPERTIES_H
18#define UCSERVICEPROPERTIES_H
19
20#include <QtCore/QObject>
21#include <QtQml/QQmlParserStatus>
22
23class UCServicePropertiesPrivate;
24class UCServiceProperties : public QObject, public QQmlParserStatus
25{
26 Q_OBJECT
27 Q_INTERFACES(QQmlParserStatus)
28
29 Q_PROPERTY(ServiceType type READ type WRITE setType NOTIFY typeChanged REVISION 1)
30 Q_PROPERTY(QString service READ service WRITE setService NOTIFY serviceChanged REVISION 1)
31 Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged REVISION 1)
32 Q_PROPERTY(QString serviceInterface READ interface WRITE setInterface NOTIFY serviceInterfaceChanged REVISION 1)
33 Q_PROPERTY(QString adaptorInterface READ adaptor WRITE setAdaptor NOTIFY adaptorInterfaceChanged REVISION 1)
34 Q_PROPERTY(QString error READ error NOTIFY errorChanged REVISION 1)
35 Q_PROPERTY(Status status READ status NOTIFY statusChanged REVISION 1)
36
37 Q_ENUMS(ServiceType Status)
38public:
39 enum ServiceType {
40 Undefined,
41 System,
42 Session
43 };
44 enum Status {
45 Inactive,
46 ConnectionError,
47 Synchronizing,
48 Active
49 };
50
51 explicit UCServiceProperties(QObject *parent = 0);
52 ~UCServiceProperties();
53 void classBegin();
54 void componentComplete();
55
56 ServiceType type() const;
57 void setType(ServiceType type);
58 QString service() const;
59 void setService(const QString &value);
60 QString path() const;
61 void setPath(const QString &value);
62 QString interface() const;
63 void setInterface(const QString &value);
64 QString adaptor() const;
65 void setAdaptor(const QString &value);
66 QString error();
67 Status status() const;
68
69Q_SIGNALS:
70 void typeChanged();
71 void serviceChanged();
72 void pathChanged();
73 void serviceInterfaceChanged();
74 void adaptorInterfaceChanged();
75 void errorChanged();
76 void statusChanged();
77
78private:
79 UCServicePropertiesPrivate *d_ptr;
80 Q_DECLARE_PRIVATE_D(d_ptr, UCServiceProperties)
81};
82
83#endif // UCSERVICEPROPERTIES_H
840
=== added file 'modules/Ubuntu/Components/plugin/ucserviceproperties_p.h'
--- modules/Ubuntu/Components/plugin/ucserviceproperties_p.h 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/plugin/ucserviceproperties_p.h 2015-02-11 08:57:32 +0000
@@ -0,0 +1,54 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef UCSERVICEPROPERTIES_P_H
18#define UCSERVICEPROPERTIES_P_H
19
20#include "ucserviceproperties.h"
21#include <QtCore/QStringList>
22
23class UCServicePropertiesPrivate
24{
25public:
26 UCServicePropertiesPrivate(UCServiceProperties *qq);
27 virtual ~UCServicePropertiesPrivate();
28
29 static UCServicePropertiesPrivate *get(UCServiceProperties *service);
30 void warning(const QString &message);
31 void setError(const QString &msg);
32 void setStatus(UCServiceProperties::Status status);
33
34 virtual bool init() = 0;
35 virtual bool fetchPropertyValues() = 0;
36 virtual bool readProperty(const QString &property) = 0;
37 virtual bool testProperty(const QString &property, const QVariant &value) = 0;
38
39 // data
40 UCServiceProperties *q_ptr;
41 bool ready:1;
42 UCServiceProperties::Status status;
43 UCServiceProperties::ServiceType type;
44 QString service;
45 QString path;
46 QString interface;
47 QString adaptor;
48 QString error;
49 QStringList properties;
50};
51
52UCServicePropertiesPrivate *createServicePropertiesAdapter(UCServiceProperties *owner);
53
54#endif // UCSERVICEPROPERTIES_P_H
055
=== removed file 'modules/Ubuntu/Components/plugin/ucserviceproperties_p.h'
--- modules/Ubuntu/Components/plugin/ucserviceproperties_p.h 2014-12-03 08:26:33 +0000
+++ modules/Ubuntu/Components/plugin/ucserviceproperties_p.h 1970-01-01 00:00:00 +0000
@@ -1,53 +0,0 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef UCSERVICEPROPERTIES_P_H
18#define UCSERVICEPROPERTIES_P_H
19
20#include "ucserviceproperties.h"
21#include <QtCore/QStringList>
22
23class UCServicePropertiesPrivate
24{
25public:
26 UCServicePropertiesPrivate(UCServiceProperties *qq);
27 virtual ~UCServicePropertiesPrivate();
28
29 static UCServicePropertiesPrivate *get(UCServiceProperties *service);
30 void setError(const QString &msg);
31 void setStatus(UCServiceProperties::Status status);
32
33 virtual bool init() = 0;
34 virtual bool fetchPropertyValues() = 0;
35 virtual bool readProperty(const QString &property) = 0;
36 virtual bool testProperty(const QString &property, const QVariant &value) = 0;
37
38 // data
39 UCServiceProperties *q_ptr;
40 bool ready:1;
41 UCServiceProperties::Status status;
42 UCServiceProperties::ServiceType type;
43 QString service;
44 QString path;
45 QString interface;
46 QString adaptor;
47 QString error;
48 QStringList properties;
49};
50
51UCServicePropertiesPrivate *createServicePropertiesAdapter(UCServiceProperties *owner);
52
53#endif // UCSERVICEPROPERTIES_P_H
540
=== modified file 'modules/Ubuntu/Components/qmldir'
--- modules/Ubuntu/Components/qmldir 2015-01-26 17:01:21 +0000
+++ modules/Ubuntu/Components/qmldir 2015-02-11 08:57:32 +0000
@@ -105,3 +105,6 @@
105StyledItem 1.1 StyledItem.qml105StyledItem 1.1 StyledItem.qml
106singleton UbuntuColors 1.1 11/UbuntuColors.qml106singleton UbuntuColors 1.1 11/UbuntuColors.qml
107internal MainViewBase MainViewBase.qml107internal MainViewBase MainViewBase.qml
108
109singleton Haptics 0.1 11/Haptics.qml
110singleton Haptics 1.0 11/Haptics.qml
108111
=== modified file 'tests/unit/runtest.sh'
--- tests/unit/runtest.sh 2015-01-20 09:56:46 +0000
+++ tests/unit/runtest.sh 2015-02-11 08:57:32 +0000
@@ -63,6 +63,7 @@
63 63
64 QML2_IMPORT_PATH=${_IMPORT_PATH} UBUNTU_UI_TOOLKIT_THEMES_PATH=${_THEMES_PATH} \64 QML2_IMPORT_PATH=${_IMPORT_PATH} UBUNTU_UI_TOOLKIT_THEMES_PATH=${_THEMES_PATH} \
65 ALARM_BACKEND=memory \65 ALARM_BACKEND=memory \
66 SUPPRESS_SERVICEPROPERTIES_WARNINGS=yes \
66 $_CMD $_ARGS 2>&1 | grep -v 'QFontDatabase: Cannot find font directory'67 $_CMD $_ARGS 2>&1 | grep -v 'QFontDatabase: Cannot find font directory'
67 # Note: Get first command before the pipe, $? would be ambiguous68 # Note: Get first command before the pipe, $? would be ambiguous
68 RESULT=${PIPESTATUS[0]}69 RESULT=${PIPESTATUS[0]}
6970
=== added file 'tests/unit/tst_components/tst_haptics.qml'
--- tests/unit/tst_components/tst_haptics.qml 1970-01-01 00:00:00 +0000
+++ tests/unit/tst_components/tst_haptics.qml 2015-02-11 08:57:32 +0000
@@ -0,0 +1,52 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.3
18import QtTest 1.0
19import Ubuntu.Components 1.1
20import Ubuntu.Test 1.0
21import QtFeedback 5.0
22
23UbuntuTestCase {
24 name: "HapticsAPI"
25
26 function waitForHapticsCompleted() {
27 tryCompareFunction(function() { return Haptics.effect.state; }, HapticsEffect.Stopped, 1000);
28 }
29
30 function test_0_defaults() {
31 verify(Haptics.hasOwnProperty("enabled"), "missing property 'enabled'");
32 verify(Haptics.hasOwnProperty("effect"), "missing property 'effect'");
33 verify(Haptics.hasOwnProperty("play"), "missing function 'play'");
34 }
35
36 function test_play() {
37 Haptics.play();
38 if (Haptics.enabled) {
39 waitForHapticsCompleted();
40 }
41 }
42
43 function test_custom_play() {
44 Haptics.play({attackTime: 10, attackIntensity: 0.5, duration: 1200});
45 if (Haptics.enabled && Haptics.effect.running) {
46 compare(Haptics.effect.attackTime, 10, "attack time not modified");
47 compare(Haptics.effect.attackIntensity, 0.5, "attack intensity not modified");
48 compare(Haptics.effect.duration, 400, "duration not modified");
49 waitForHapticsCompleted();
50 }
51 }
52}
053
=== added directory 'tests/unit_x11/tst_serviceproperties'
=== removed directory 'tests/unit_x11/tst_serviceproperties'
=== added file 'tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml'
--- tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml 1970-01-01 00:00:00 +0000
+++ tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml 2015-02-11 08:57:32 +0000
@@ -0,0 +1,31 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.3
18import Ubuntu.Components 1.1
19
20Item {
21 property alias service: service
22 ServiceProperties {
23 id: service
24 service: "org.freedesktop.Accounts"
25 serviceInterface: "org.freedesktop.Accounts"
26 path: "/org/freedesktop/Accounts"
27 adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
28
29 property bool incomingCallVibrate: true
30 }
31}
032
=== removed file 'tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml'
--- tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml 2014-12-03 08:26:33 +0000
+++ tests/unit_x11/tst_serviceproperties/IncomingCallVibrateWatcher.qml 1970-01-01 00:00:00 +0000
@@ -1,31 +0,0 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.3
18import Ubuntu.Components 1.1
19
20Item {
21 property alias service: service
22 ServiceProperties {
23 id: service
24 service: "org.freedesktop.Accounts"
25 serviceInterface: "org.freedesktop.Accounts"
26 path: "/org/freedesktop/Accounts"
27 adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
28
29 property bool incomingCallVibrate: true
30 }
31}
320
=== added file 'tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml'
--- tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml 1970-01-01 00:00:00 +0000
+++ tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml 2015-02-11 08:57:32 +0000
@@ -0,0 +1,31 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.3
18import Ubuntu.Components 1.1
19
20Item {
21 property alias service: service
22 ServiceProperties {
23 id: service
24 service: "org.freedesktop.Accounts"
25 serviceInterface: "org.freedesktop.Accounts"
26 path: "/org/freedesktop/Accounts"
27 adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
28
29 property bool thisIsAnInvalidPropertyToWatch: true
30 }
31}
032
=== removed file 'tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml'
--- tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml 2014-12-03 08:26:33 +0000
+++ tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher.qml 1970-01-01 00:00:00 +0000
@@ -1,31 +0,0 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.3
18import Ubuntu.Components 1.1
19
20Item {
21 property alias service: service
22 ServiceProperties {
23 id: service
24 service: "org.freedesktop.Accounts"
25 serviceInterface: "org.freedesktop.Accounts"
26 path: "/org/freedesktop/Accounts"
27 adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
28
29 property bool thisIsAnInvalidPropertyToWatch: true
30 }
31}
320
=== added file 'tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml'
--- tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml 1970-01-01 00:00:00 +0000
+++ tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml 2015-02-11 08:57:32 +0000
@@ -0,0 +1,32 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.3
18import Ubuntu.Components 1.1
19
20Item {
21 property alias service: service
22 ServiceProperties {
23 id: service
24 service: "org.freedesktop.Accounts"
25 serviceInterface: "org.freedesktop.Accounts"
26 path: "/org/freedesktop/Accounts"
27 adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
28
29 property bool thisIsAnInvalidPropertyToWatch: true
30 property bool incomingCallVibrate: true
31 }
32}
033
=== removed file 'tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml'
--- tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml 2014-12-03 08:26:33 +0000
+++ tests/unit_x11/tst_serviceproperties/InvalidPropertyWatcher2.qml 1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.3
18import Ubuntu.Components 1.1
19
20Item {
21 property alias service: service
22 ServiceProperties {
23 id: service
24 service: "org.freedesktop.Accounts"
25 serviceInterface: "org.freedesktop.Accounts"
26 path: "/org/freedesktop/Accounts"
27 adaptorInterface: "com.ubuntu.touch.AccountsService.Sound"
28
29 property bool thisIsAnInvalidPropertyToWatch: true
30 property bool incomingCallVibrate: true
31 }
32}
330
=== added file 'tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp'
--- tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp 2015-02-11 08:57:32 +0000
@@ -0,0 +1,146 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "uctestcase.h"
18#include "ucserviceproperties.h"
19#include "ucserviceproperties_p.h"
20#include <QtCore/QString>
21#include <QtCore/QDebug>
22#include <QtTest/QTest>
23#include <QtTest/QSignalSpy>
24
25class tst_ServiceProperties : public QObject
26{
27 Q_OBJECT
28
29public:
30 tst_ServiceProperties() {}
31
32private:
33
34 QString error;
35
36 // FIXME use UbuntuTestCase::ignoreWaring in Vivid
37 void ignoreWarning(const QString& fileName, uint line, uint column, const QString& message, uint occurences=1)
38 {
39 for (uint i = 0; i < occurences; i++) {
40 QString url(QUrl::fromLocalFile(QFileInfo(fileName).absoluteFilePath()).toEncoded());
41 QString warning(QString("%1:%2:%3: %4").arg(url).arg(line).arg(column).arg(message));
42 QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
43 }
44 }
45
46
47private Q_SLOTS:
48
49 void initTestCase()
50 {
51 // check if the connection is possible, otherwise we must skip all tests
52 QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml"));
53 UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
54 QVERIFY(watcher);
55 if (watcher->status() == UCServiceProperties::Synchronizing ||
56 watcher->status() == UCServiceProperties::Inactive) {
57 QSignalSpy wait(watcher, SIGNAL(statusChanged()));
58 wait.wait();
59 }
60 if (watcher->status() == UCServiceProperties::ConnectionError) {
61 error = "Skip test: " + watcher->error();
62 }
63 }
64
65 void test_change_property()
66 {
67 if (!error.isEmpty()) {
68 QSKIP(qPrintable(error));
69 }
70 QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml"));
71 UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
72 QVERIFY(watcher);
73
74 bool backup = watcher->property("incomingCallVibrate").toBool();
75 UCServicePropertiesPrivate *pWatcher = UCServicePropertiesPrivate::get(watcher);
76 QSignalSpy spy(watcher, SIGNAL(incomingCallVibrateChanged()));
77 pWatcher->testProperty("IncomingCallVibrate", !backup);
78 spy.wait(400);
79 QCOMPARE(spy.count(), 1);
80 QCOMPARE(watcher->property("incomingCallVibrate").toBool(), !backup);
81
82 // restore value
83 spy.clear();
84 pWatcher->testProperty("IncomingCallVibrate", backup);
85 spy.wait(400);
86 }
87
88 void test_invalid_property()
89 {
90 if (!error.isEmpty()) {
91 QSKIP(qPrintable(error));
92 }
93 ignoreWarning("InvalidPropertyWatcher.qml", 22, 5, "QML ServiceProperties: No such property 'ThisIsAnInvalidPropertyToWatch'");
94 QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("InvalidPropertyWatcher.qml"));
95 UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
96 QVERIFY(watcher);
97 // error should not be set
98 QCOMPARE(watcher->property("error").toString(), QString());
99 }
100
101 void test_one_valid_one_invalid_property()
102 {
103 if (!error.isEmpty()) {
104 QSKIP(qPrintable(error));
105 }
106 ignoreWarning("InvalidPropertyWatcher2.qml", 22, 5, "QML ServiceProperties: No such property 'ThisIsAnInvalidPropertyToWatch'");
107 QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("InvalidPropertyWatcher2.qml"));
108 UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
109 QVERIFY(watcher);
110 // error should not be set
111 QCOMPARE(watcher->property("error").toString(), QString());
112 }
113
114 void test_change_connection_props_data()
115 {
116 QTest::addColumn<QString>("property");
117 QTest::addColumn<QString>("value");
118
119 QTest::newRow("Changing servcie") << "service" << "anything.else";
120 QTest::newRow("Changing interface") << "serviceInterface" << "anything.else";
121 QTest::newRow("Changing adaptor") << "adaptorInterface" << "anything.else";
122 }
123 void test_change_connection_props()
124 {
125 QFETCH(QString, property);
126 QFETCH(QString, value);
127
128 if (!error.isEmpty()) {
129 QSKIP(qPrintable(error));
130 }
131 ignoreWarning("IncomingCallVibrateWatcher.qml", 22, 5, "QML ServiceProperties: Changing connection parameters forbidden.");
132 QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml"));
133 UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
134 QVERIFY(watcher);
135
136 // try to change the property
137 watcher->setProperty(property.toLocal8Bit().constData(), value);
138 // no error should be reported
139 QCOMPARE(watcher->property("error").toString(), QString());
140 }
141
142};
143
144QTEST_MAIN(tst_ServiceProperties)
145
146#include "tst_serviceproperties.moc"
0147
=== removed file 'tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp'
--- tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp 2014-12-03 10:22:17 +0000
+++ tests/unit_x11/tst_serviceproperties/tst_serviceproperties.cpp 1970-01-01 00:00:00 +0000
@@ -1,146 +0,0 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "uctestcase.h"
18#include "ucserviceproperties.h"
19#include "ucserviceproperties_p.h"
20#include <QtCore/QString>
21#include <QtCore/QDebug>
22#include <QtTest/QTest>
23#include <QtTest/QSignalSpy>
24
25class tst_ServiceProperties : public QObject
26{
27 Q_OBJECT
28
29public:
30 tst_ServiceProperties() {}
31
32private:
33
34 QString error;
35
36 // FIXME use UbuntuTestCase::ignoreWaring in Vivid
37 void ignoreWarning(const QString& fileName, uint line, uint column, const QString& message, uint occurences=1)
38 {
39 for (uint i = 0; i < occurences; i++) {
40 QString url(QUrl::fromLocalFile(QFileInfo(fileName).absoluteFilePath()).toEncoded());
41 QString warning(QString("%1:%2:%3: %4").arg(url).arg(line).arg(column).arg(message));
42 QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
43 }
44 }
45
46
47private Q_SLOTS:
48
49 void initTestCase()
50 {
51 // check if the connection is possible, otherwise we must skip all tests
52 QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml"));
53 UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
54 QVERIFY(watcher);
55 if (watcher->status() == UCServiceProperties::Synchronizing ||
56 watcher->status() == UCServiceProperties::Inactive) {
57 QSignalSpy wait(watcher, SIGNAL(statusChanged()));
58 wait.wait();
59 }
60 if (watcher->status() == UCServiceProperties::ConnectionError) {
61 error = "Skip test: " + watcher->error();
62 }
63 }
64
65 void test_change_property()
66 {
67 if (!error.isEmpty()) {
68 QSKIP(qPrintable(error));
69 }
70 QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml"));
71 UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
72 QVERIFY(watcher);
73
74 bool backup = watcher->property("incomingCallVibrate").toBool();
75 UCServicePropertiesPrivate *pWatcher = UCServicePropertiesPrivate::get(watcher);
76 QSignalSpy spy(watcher, SIGNAL(incomingCallVibrateChanged()));
77 pWatcher->testProperty("IncomingCallVibrate", !backup);
78 spy.wait(400);
79 QCOMPARE(spy.count(), 1);
80 QCOMPARE(watcher->property("incomingCallVibrate").toBool(), !backup);
81
82 // restore value
83 spy.clear();
84 pWatcher->testProperty("IncomingCallVibrate", backup);
85 spy.wait(400);
86 }
87
88 void test_invalid_property()
89 {
90 if (!error.isEmpty()) {
91 QSKIP(qPrintable(error));
92 }
93 ignoreWarning("InvalidPropertyWatcher.qml", 22, 5, "QML ServiceProperties: No such property 'ThisIsAnInvalidPropertyToWatch'");
94 QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("InvalidPropertyWatcher.qml"));
95 UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
96 QVERIFY(watcher);
97 // error should not be set
98 QCOMPARE(watcher->property("error").toString(), QString());
99 }
100
101 void test_one_valid_one_invalid_property()
102 {
103 if (!error.isEmpty()) {
104 QSKIP(qPrintable(error));
105 }
106 ignoreWarning("InvalidPropertyWatcher2.qml", 22, 5, "QML ServiceProperties: No such property 'ThisIsAnInvalidPropertyToWatch'");
107 QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("InvalidPropertyWatcher2.qml"));
108 UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
109 QVERIFY(watcher);
110 // error should not be set
111 QCOMPARE(watcher->property("error").toString(), QString());
112 }
113
114 void test_change_connection_props_data()
115 {
116 QTest::addColumn<QString>("property");
117 QTest::addColumn<QString>("value");
118
119 QTest::newRow("Changing servcie") << "service" << "anything.else";
120 QTest::newRow("Changing interface") << "serviceInterface" << "anything.else";
121 QTest::newRow("Changing adaptor") << "adaptorInterface" << "anything.else";
122 }
123 void test_change_connection_props()
124 {
125 QFETCH(QString, property);
126 QFETCH(QString, value);
127
128 if (!error.isEmpty()) {
129 QSKIP(qPrintable(error));
130 }
131 ignoreWarning("IncomingCallVibrateWatcher.qml", 22, 5, "QML ServiceProperties: Changing connection parameters forbidden.");
132 QScopedPointer<UbuntuTestCase> test(new UbuntuTestCase("IncomingCallVibrateWatcher.qml"));
133 UCServiceProperties *watcher = static_cast<UCServiceProperties*>(test->rootObject()->property("service").value<QObject*>());
134 QVERIFY(watcher);
135
136 // try to change the property
137 watcher->setProperty(property.toLocal8Bit().constData(), value);
138 // no error should be reported
139 QCOMPARE(watcher->property("error").toString(), QString());
140 }
141
142};
143
144QTEST_MAIN(tst_ServiceProperties)
145
146#include "tst_serviceproperties.moc"
1470
=== added file 'tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro'
--- tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro 1970-01-01 00:00:00 +0000
+++ tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro 2015-02-11 08:57:32 +0000
@@ -0,0 +1,8 @@
1include(../test-include.pri)
2SOURCES += \
3 tst_serviceproperties.cpp
4
5OTHER_FILES += \
6 IncomingCallVibrateWatcher.qml \
7 InvalidPropertyWatcher.qml \
8 InvalidPropertyWatcher2.qml
09
=== removed file 'tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro'
--- tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro 2014-12-03 08:26:33 +0000
+++ tests/unit_x11/tst_serviceproperties/tst_serviceproperties.pro 1970-01-01 00:00:00 +0000
@@ -1,8 +0,0 @@
1include(../test-include.pri)
2SOURCES += \
3 tst_serviceproperties.cpp
4
5OTHER_FILES += \
6 IncomingCallVibrateWatcher.qml \
7 InvalidPropertyWatcher.qml \
8 InvalidPropertyWatcher2.qml

Subscribers

People subscribed via source and target branches