Merge lp:~michihenning/storage-framework/merge-devel into lp:storage-framework

Proposed by Michi Henning
Status: Merged
Approved by: James Henstridge
Approved revision: no longer in the source branch.
Merged at revision: 15
Proposed branch: lp:~michihenning/storage-framework/merge-devel
Merge into: lp:storage-framework
Diff against target: 3789 lines (+1688/-685)
66 files modified
CMakeLists.txt (+2/-1)
data/registry.xml (+21/-24)
debian/changelog (+9/-0)
debian/control (+5/-90)
debian/control.in (+15/-2)
debian/storage-framework-registry.install (+2/-0)
demo/demo.qml (+1/-1)
demo/provider_test/provider-test.cpp (+1/-1)
include/unity/storage/internal/AccountDetails.h (+60/-0)
include/unity/storage/internal/ActivityNotifier.h (+57/-0)
include/unity/storage/internal/EnvVars.h (+51/-0)
include/unity/storage/internal/InactivityTimer.h (+60/-0)
include/unity/storage/internal/TraceMessageHandler.h (+3/-0)
include/unity/storage/qt/Account.h (+4/-1)
include/unity/storage/qt/AccountsJob.h (+2/-5)
include/unity/storage/qt/Runtime.h (+3/-3)
include/unity/storage/qt/internal/AccountImpl.h (+6/-19)
include/unity/storage/qt/internal/AccountsJobImpl.h (+18/-10)
include/unity/storage/qt/internal/Handler.h (+2/-2)
include/unity/storage/qt/internal/RuntimeImpl.h (+7/-8)
include/unity/storage/registry/Registry.h (+35/-0)
include/unity/storage/registry/internal/ListAccountsHandler.h (+70/-0)
include/unity/storage/registry/internal/RegistryAdaptor.h (+71/-0)
include/unity/storage/registry/internal/qdbus-last-error-msg.h (+41/-0)
src/CMakeLists.txt (+1/-0)
src/internal/AccountDetails.cpp (+108/-0)
src/internal/CMakeLists.txt (+8/-0)
src/internal/EnvVars.cpp (+81/-0)
src/internal/InactivityTimer.cpp (+82/-0)
src/internal/TraceMessageHandler.cpp (+20/-3)
src/qt/Account.cpp (+10/-0)
src/qt/AccountsJob.cpp (+2/-8)
src/qt/CMakeLists.txt (+10/-3)
src/qt/Runtime.cpp (+4/-4)
src/qt/client/internal/remote_client/RuntimeImpl.cpp (+1/-1)
src/qt/internal/AccountImpl.cpp (+27/-49)
src/qt/internal/AccountsJobImpl.cpp (+50/-69)
src/qt/internal/ItemImpl.cpp (+10/-8)
src/qt/internal/ItemListJobImpl.cpp (+4/-6)
src/qt/internal/MultiItemListJobImpl.cpp (+1/-4)
src/qt/internal/RuntimeImpl.cpp (+24/-22)
src/qt/internal/validate.cpp (+75/-63)
src/registry/CMakeLists.txt (+47/-0)
src/registry/com.canonical.StorageFramework.Registry.service.in (+3/-0)
src/registry/internal/ListAccountsHandler.cpp (+127/-0)
src/registry/internal/RegistryAdaptor.cpp (+55/-0)
src/registry/internal/qdbus-last-error-msg.cpp (+49/-0)
src/registry/main.cpp (+95/-0)
tests/CMakeLists.txt (+1/-6)
tests/copyright/check_copyright.sh (+13/-7)
tests/headers/CMakeLists.txt (+2/-2)
tests/headers/compile_headers.py (+11/-8)
tests/local-client/local-client_test.cpp (+4/-0)
tests/provider-AccountData/AccountData_test.cpp (+4/-0)
tests/provider-DBusPeerCache/DBusPeerCache_test.cpp (+4/-0)
tests/provider-ProviderInterface/TestProvider.cpp (+5/-5)
tests/registry/CMakeLists.txt (+20/-0)
tests/registry/registry_test.cpp (+27/-0)
tests/remote-client-v1/remote-client-v1_test.cpp (+4/-4)
tests/remote-client/CMakeLists.txt (+1/-1)
tests/remote-client/remote-client_test.cpp (+131/-81)
tests/utils/DBusEnvironment.cpp (+9/-0)
tests/utils/DBusEnvironment.h (+1/-0)
tests/utils/ProviderFixture.h (+4/-0)
tests/utils/com.ubuntu.OnlineAccounts.Manager.xml (+0/-153)
tests/utils/fake-online-accounts-daemon.py (+7/-11)
To merge this branch: bzr merge lp:~michihenning/storage-framework/merge-devel
Reviewer Review Type Date Requested Status
James Henstridge Approve
Review via email: mp+312873@code.launchpad.net

Commit message

Merge devel at r99. Updated changelog.

Description of the change

Merged devel at r99. Updated changelog.

To post a comment you must log in.
15. By CI Train Bot Account

* Fix for lp:1644577, fail list job if metadata for any item is incorrect.
* Always emit itemsReady(), even if list is empty.
* Improvements to error logging and detail in error messages: lp:1644577
* Added separate registry service.

Revision history for this message
James Henstridge (jamesh) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2016-10-31 09:03:32 +0000
+++ CMakeLists.txt 2016-12-12 02:53:43 +0000
@@ -104,7 +104,7 @@
104include(CTest)104include(CTest)
105enable_testing()105enable_testing()
106106
107include(EnableCoverageReport)107find_package(CoverageReport)
108108
109include(GNUInstallDirs)109include(GNUInstallDirs)
110110
@@ -138,6 +138,7 @@
138 storage-framework-qt-local-client138 storage-framework-qt-local-client
139 sf-provider-objects139 sf-provider-objects
140 storage-framework-provider140 storage-framework-provider
141 storage-framework-registry
141 FILTER142 FILTER
142 ${CMAKE_SOURCE_DIR}/tests/*143 ${CMAKE_SOURCE_DIR}/tests/*
143 ${CMAKE_BINARY_DIR}/*144 ${CMAKE_BINARY_DIR}/*
144145
=== modified file 'data/registry.xml'
--- data/registry.xml 2016-05-04 14:32:07 +0000
+++ data/registry.xml 2016-12-12 02:53:43 +0000
@@ -3,33 +3,30 @@
3<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">3<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
4 <!--4 <!--
5 com.canonical.StorageFramework.Registry:5 com.canonical.StorageFramework.Registry:
6 @short_description: Interface to query the backend registry6 @short_description: Interface to retrieve providers that are configured in online accounts
7
8 Inteface to query the repository of backends that are
9 available.
10 -->7 -->
11 <interface name="com.canonical.StorageFramework.Registry">8 <interface name="com.canonical.StorageFramework.Registry">
12
13 <!--9 <!--
14 GetBackend:10 List:
15 @short_description: request access to a storage account11 @short_description: Get the list of accounts
16 @service_id: if not empty, restrict results to accounts12 @accounts: Returned list of accounts.
17 matching this service ID.13
18 @bus_name: the bus name of the storage provider14 Returns the list of provider accounts that are available
19 @path: the object path of the storage account at the provider15 in online accounts. In essence, this method is a proxy
2016 for the OnlineAccounts::Manager::availableAccounts() method.
21 Interactively prompt the user to pick a storage account for17
22 use by the application, and return the D-Bus endpoint that can18 The returned values are structs with the following members:
23 be used to communicate with the associated provider.19 - bus name (e.g. "com.canonical.StorageFramework.Provider.OwnCloud")
2420 - object path (e.g. "/provider/7")
25 As this involves user interaction, the caller should use a21 - ID (e.g. 7, used for object path)
26 relatively long time out for this method call.22 - service ID (e.g. "storage-provider-owncloud")
27 -->23 - display name (e.g. "michi.henning@canonical.com")
28 <method name="GetProvider">24 - translated provider name (e.g. "OwnCloud")
29 <arg type="s" name="service_id" direction="in" />25 - icon name
3026 -->
31 <arg type="s" name="bus_name" direction="out" />27 <method name="ListAccounts">
32 <arg type="o" name="path" direction="out" />28 <arg type="a(soussss)" name="accounts" direction="out"/>
29 <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QList&lt;unity::storage::internal::AccountDetails&gt;"/>
33 </method>30 </method>
34 </interface>31 </interface>
35</node>32</node>
3633
=== modified file 'debian/changelog'
--- debian/changelog 2016-11-04 12:22:33 +0000
+++ debian/changelog 2016-12-12 02:53:43 +0000
@@ -1,3 +1,12 @@
1storage-framework (0.2+17.04.20161104-0ubuntu2) UNRELEASED; urgency=medium
2
3 * Fix for lp:1644577, fail list job if metadata for any item is incorrect.
4 * Always emit itemsReady(), even if list is empty.
5 * Improvements to error logging and detail in error messages: lp:1644577
6 * Added separate registry service.
7
8 -- Michi Henning <michi.henning@canonical.com> Fri, 09 Dec 2016 11:35:17 +1000
9
1storage-framework (0.2+17.04.20161104-0ubuntu1) zesty; urgency=medium10storage-framework (0.2+17.04.20161104-0ubuntu1) zesty; urgency=medium
211
3 [ Michi Henning ]12 [ Michi Henning ]
413
=== modified file 'debian/control'
--- debian/control 2016-11-04 12:22:33 +0000
+++ debian/control 2016-12-12 02:53:43 +0000
@@ -1,98 +1,13 @@
1# This file is autogenerated. DO NOT EDIT!1# This file is autogenerated. DO NOT EDIT!
2#2#
3# Modifications should be made to ./debian/control.in instead.3# Modifications should be made to ./debian/control.in instead.
4# This file is regenerated automatically in the clean target.4# This file is regenerated automatically by bileto.
5#5#
6Source: storage-framework6Source: storage-framework
7Section: libs7
8Priority: optional8# DO NOT EDIT THIS FILE. WE REALLY MEAN IT!
9Maintainer: Ubuntu Core Developers <ubuntu-devel-discuss@lists.ubuntu.com>
10Standards-Version: 3.9.6
11Build-Depends: cmake,
12 cmake-extras (>= 0.4),
13 debhelper (>= 9),
14 devscripts,
15 doxygen,
16 google-mock,
17 libapparmor-dev,
18 libboost-filesystem-dev (>= 1.58) | libboost-filesystem1.58-dev,
19 libboost-system-dev (>= 1.58) | libboost-system1.58-dev,
20 libboost-thread-dev (>= 1.58) | libboost-thread1.58-dev,
21 libglib2.0-dev,
22 libgtest-dev,
23 libonline-accounts-qt-dev,
24 libqtdbustest1-dev,
25 libunity-api-dev,
26 lsb-release,
27 python3-dbus,
28 python3-gi,
29 qtbase5-dev,
30 qtbase5-dev-tools,
31 qtdeclarative5-dev,
32Homepage: https://launchpad.net/storage-framework
33# if you don't have have commit access to this branch but would like to upload
34# directly to Ubuntu, don't worry: your changes will be merged back into the
35# upstream branch
36Vcs-Bzr: lp:storage-framework
379
38Package: libstorage-framework-provider-1-510Package: libstorage-framework-provider-1-5
39Architecture: any11Architecture: any
40Multi-Arch: same12Description: DO NOT EDIT THIS FILE, IT IS GENERATED FROM control.in
41Pre-Depends: ${misc:Pre-Depends},13 DO NOT EDIT THIS FILE
42Depends: ${misc:Depends},
43 ${shlibs:Depends},
44Description: Library for Storage Framework providers
45 Server-side runtime support for provider implementations.
46
47Package: libstorage-framework-qt-client-1-0
48Architecture: any
49Multi-Arch: same
50Pre-Depends: ${misc:Pre-Depends},
51Depends: ${misc:Depends},
52 ${shlibs:Depends},
53Description: Client library for the Storage Framework (API v1, soon to be removed)
54 Runtime support for storage framework clients.
55
56Package: libstorage-framework-qt-client-2-0
57Architecture: any
58Multi-Arch: same
59Pre-Depends: ${misc:Pre-Depends},
60Depends: ${misc:Depends},
61 ${shlibs:Depends},
62Description: Client library for the Storage Framework
63 Runtime support for storage framework clients.
64
65Package: libstorage-framework-qt-local-client-1-0
66Architecture: any
67Multi-Arch: same
68Pre-Depends: ${misc:Pre-Depends},
69Depends: ${misc:Depends},
70 ${shlibs:Depends},
71Description: Client library for the Storage Framework backed by the local file system
72 A version of the client-side API that implements a local
73 file system provider. This is intended mainly for testing;
74 it allows application code to use the storage framework
75 API without requiring use of DBus and cloud service account.
76
77Package: storage-framework-client-dev
78Section: libdevel
79Architecture: any
80Multi-Arch: same
81Pre-Depends: ${misc:Pre-Depends},
82Depends: libstorage-framework-qt-client-1-0 (= ${binary:Version}),
83 libstorage-framework-qt-local-client-1-0 (= ${binary:Version}),
84 qtbase5-dev,
85 ${misc:Depends},
86Description: Header files for the Storage Framework client libraries
87 Development C++ headers for the client side API.
88
89Package: storage-framework-provider-dev
90Section: libdevel
91Architecture: any
92Multi-Arch: same
93Pre-Depends: ${misc:Pre-Depends},
94Depends: libstorage-framework-provider-1-5 (= ${binary:Version}),
95 libboost-thread-dev (>= 1.58) | libboost-thread1.58-dev,
96 ${misc:Depends},
97Description: Header files for the Storage Framework provider library
98 Development C++ headers for the provider API.
9914
=== modified file 'debian/control.in'
--- debian/control.in 2016-09-30 01:47:57 +0000
+++ debian/control.in 2016-12-12 02:53:43 +0000
@@ -4,9 +4,8 @@
4Maintainer: Ubuntu Core Developers <ubuntu-devel-discuss@lists.ubuntu.com>4Maintainer: Ubuntu Core Developers <ubuntu-devel-discuss@lists.ubuntu.com>
5Standards-Version: 3.9.65Standards-Version: 3.9.6
6Build-Depends: cmake,6Build-Depends: cmake,
7 cmake-extras (>= 0.4),7 cmake-extras (>= 0.10),
8 debhelper (>= 9),8 debhelper (>= 9),
9 devscripts,
10 doxygen,9 doxygen,
11 google-mock,10 google-mock,
12 libapparmor-dev,11 libapparmor-dev,
@@ -18,6 +17,7 @@
18 libonline-accounts-qt-dev,17 libonline-accounts-qt-dev,
19 libqtdbustest1-dev,18 libqtdbustest1-dev,
20 libunity-api-dev,19 libunity-api-dev,
20 licensecheck | devscripts (<< 2.16.6),
21 lsb-release,21 lsb-release,
22 python3-dbus,22 python3-dbus,
23 python3-gi,23 python3-gi,
@@ -48,12 +48,24 @@
48Description: Client library for the Storage Framework (API v1, soon to be removed)48Description: Client library for the Storage Framework (API v1, soon to be removed)
49 Runtime support for storage framework clients.49 Runtime support for storage framework clients.
5050
51Package: storage-framework-registry
52Architecture: any
53Multi-Arch: foreign
54Pre-Depends: ${misc:Pre-Depends},
55Depends: ${misc:Depends},
56 ${shlibs:Depends},
57# TODO: should be removed once online accounts is fixed: lp:1643421
58 online-accounts-daemon,
59Description: Registry for the Storage Framework
60 DBus service that provides access to provider account information.
61
51Package: libstorage-framework-qt-client-2-062Package: libstorage-framework-qt-client-2-0
52Architecture: any63Architecture: any
53Multi-Arch: same64Multi-Arch: same
54Pre-Depends: ${misc:Pre-Depends},65Pre-Depends: ${misc:Pre-Depends},
55Depends: ${misc:Depends},66Depends: ${misc:Depends},
56 ${shlibs:Depends},67 ${shlibs:Depends},
68 storage-framework-registry
57Description: Client library for the Storage Framework69Description: Client library for the Storage Framework
58 Runtime support for storage framework clients.70 Runtime support for storage framework clients.
5971
@@ -76,6 +88,7 @@
76Pre-Depends: ${misc:Pre-Depends},88Pre-Depends: ${misc:Pre-Depends},
77Depends: libstorage-framework-qt-client-1-0 (= ${binary:Version}),89Depends: libstorage-framework-qt-client-1-0 (= ${binary:Version}),
78 libstorage-framework-qt-local-client-1-0 (= ${binary:Version}),90 libstorage-framework-qt-local-client-1-0 (= ${binary:Version}),
91 libstorage-framework-qt-client-2-0 (= ${binary:Version}),
79 qtbase5-dev,92 qtbase5-dev,
80 ${misc:Depends},93 ${misc:Depends},
81Description: Header files for the Storage Framework client libraries94Description: Header files for the Storage Framework client libraries
8295
=== added file 'debian/storage-framework-registry.install'
--- debian/storage-framework-registry.install 1970-01-01 00:00:00 +0000
+++ debian/storage-framework-registry.install 2016-12-12 02:53:43 +0000
@@ -0,0 +1,2 @@
1usr/lib/*/*/storage-framework-registry
2usr/share/dbus-1/services/com.canonical.StorageFramework.Registry.service
03
=== modified file 'demo/demo.qml'
--- demo/demo.qml 2016-11-04 10:52:10 +0000
+++ demo/demo.qml 2016-12-12 02:53:43 +0000
@@ -48,7 +48,7 @@
48 for (var i = 0; i < accounts.length; i++) {48 for (var i = 0; i < accounts.length; i++) {
49 console.log("Account " + i + ": busName = " + accounts[i].busName());49 console.log("Account " + i + ": busName = " + accounts[i].busName());
50 console.log("Account " + i + ": objectPath = " + accounts[i].objectPath());50 console.log("Account " + i + ": objectPath = " + accounts[i].objectPath());
51 console.log("Account " + i + ": displayName = " + accounts[i].displayName);51 console.log("Account " + i + ": name = " + accounts[i].name);
52 }52 }
53 }53 }
54 }54 }
5555
=== modified file 'demo/provider_test/provider-test.cpp'
--- demo/provider_test/provider-test.cpp 2016-11-03 02:43:43 +0000
+++ demo/provider_test/provider-test.cpp 2016-12-12 02:53:43 +0000
@@ -314,7 +314,7 @@
314int main(int argc, char **argv)314int main(int argc, char **argv)
315{315{
316 const std::string bus_name = "com.canonical.StorageFramework.Provider.ProviderTest";316 const std::string bus_name = "com.canonical.StorageFramework.Provider.ProviderTest";
317 std::string account_service_id = "google-drive-scope";317 std::string account_service_id = "storage-provider-test";
318 if (argc > 1)318 if (argc > 1)
319 {319 {
320 account_service_id = argv[1];320 account_service_id = argv[1];
321321
=== added file 'include/unity/storage/internal/AccountDetails.h'
--- include/unity/storage/internal/AccountDetails.h 1970-01-01 00:00:00 +0000
+++ include/unity/storage/internal/AccountDetails.h 2016-12-12 02:53:43 +0000
@@ -0,0 +1,60 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#pragma once
20
21#pragma GCC diagnostic push
22#pragma GCC diagnostic ignored "-Wcast-align"
23#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
24#pragma GCC diagnostic ignored "-Wswitch-default"
25#include <QDBusArgument>
26#pragma GCC diagnostic pop
27
28namespace unity
29{
30namespace storage
31{
32namespace internal
33{
34
35struct AccountDetails
36{
37 QString busName;
38 QDBusObjectPath objectPath;
39 quint32 id;
40 QString serviceId;
41 QString displayName;
42 QString providerName;
43 QString iconName;
44};
45
46bool operator==(AccountDetails const& lhs, AccountDetails const& rhs);
47bool operator!=(AccountDetails const& lhs, AccountDetails const& rhs);
48bool operator<(AccountDetails const& lhs, AccountDetails const& rhs);
49bool operator<=(AccountDetails const& lhs, AccountDetails const& rhs);
50bool operator>(AccountDetails const& lhs, AccountDetails const& rhs);
51bool operator>=(AccountDetails const& lhs, AccountDetails const& rhs);
52
53QDBusArgument& operator<<(QDBusArgument& argument, storage::internal::AccountDetails const& account);
54QDBusArgument const& operator>>(QDBusArgument const& argument, storage::internal::AccountDetails& account);
55
56} // namespace internal
57} // namespace storage
58} // namespace unity
59
60Q_DECLARE_METATYPE(unity::storage::internal::AccountDetails)
061
=== added file 'include/unity/storage/internal/ActivityNotifier.h'
--- include/unity/storage/internal/ActivityNotifier.h 1970-01-01 00:00:00 +0000
+++ include/unity/storage/internal/ActivityNotifier.h 2016-12-12 02:53:43 +0000
@@ -0,0 +1,57 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#pragma once
20
21#include <unity/storage/internal/InactivityTimer.h>
22
23#include <cassert>
24#include <memory>
25
26namespace unity
27{
28namespace storage
29{
30namespace internal
31{
32
33class InactivityTimer;
34
35class ActivityNotifier
36{
37public:
38 ActivityNotifier(std::shared_ptr<InactivityTimer> const& timer)
39 : timer_(timer)
40 {
41 assert(timer);
42
43 timer_->request_started();
44 }
45
46 ~ActivityNotifier()
47 {
48 timer_->request_finished();
49 }
50
51private:
52 std::shared_ptr<InactivityTimer> timer_;
53};
54
55} // namespace internal
56} // namespace storage
57} // namespace unity
058
=== added file 'include/unity/storage/internal/EnvVars.h'
--- include/unity/storage/internal/EnvVars.h 1970-01-01 00:00:00 +0000
+++ include/unity/storage/internal/EnvVars.h 2016-12-12 02:53:43 +0000
@@ -0,0 +1,51 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#pragma once
20
21#include <unity/storage/registry/Registry.h>
22
23#include <string>
24
25namespace unity
26{
27namespace storage
28{
29namespace internal
30{
31
32constexpr char const* REGISTRY_IDLE_TIMEOUT = "SF_REGISTRY_IDLE_TIMEOUT"; // Seconds, 0 means "never"
33constexpr int REGISTRY_IDLE_TIMEOUT_DFLT = 30;
34
35// Helper class to make retrieval of environment variables type-safe and
36// to sanity check the setting, if applicable. Also returns a default
37// setting, if applicable.
38
39class EnvVars
40{
41public:
42 static int registry_timeout_ms();
43
44 // Returns value of var_name in the environment, if set, and an empty string otherwise.
45 // Can be used for any environment variable, not just the ones defined above.
46 static std::string get(char const* var_name);
47};
48
49} // namespace internal
50} // namespace storage
51} // namespace unity
052
=== added file 'include/unity/storage/internal/InactivityTimer.h'
--- include/unity/storage/internal/InactivityTimer.h 1970-01-01 00:00:00 +0000
+++ include/unity/storage/internal/InactivityTimer.h 2016-12-12 02:53:43 +0000
@@ -0,0 +1,60 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#pragma once
20
21#pragma GCC diagnostic push
22#pragma GCC diagnostic ignored "-Wcast-align"
23#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
24#pragma GCC diagnostic ignored "-Wswitch-default"
25#include <QTimer>
26#pragma GCC diagnostic pop
27
28#include <functional>
29
30namespace unity
31{
32namespace storage
33{
34namespace internal
35{
36
37class InactivityTimer : public QObject
38{
39 Q_OBJECT
40
41public:
42 InactivityTimer(int timeout_ms, std::function<void()> timeout_func);
43 ~InactivityTimer();
44
45 void request_started();
46 void request_finished();
47
48private Q_SLOTS:
49 void timeout();
50
51private:
52 int timeout_ms_;
53 std::function<void()> timeout_func_;
54 QTimer timer_;
55 int32_t num_requests_;
56};
57
58} // namespace internal
59} // namespace storage
60} // namespace unity
061
=== modified file 'include/unity/storage/internal/TraceMessageHandler.h'
--- include/unity/storage/internal/TraceMessageHandler.h 2016-08-25 05:18:37 +0000
+++ include/unity/storage/internal/TraceMessageHandler.h 2016-12-12 02:53:43 +0000
@@ -35,7 +35,10 @@
35class TraceMessageHandler final35class TraceMessageHandler final
36{36{
37public:37public:
38 TraceMessageHandler();
38 TraceMessageHandler(std::string const& prog_name);39 TraceMessageHandler(std::string const& prog_name);
40 TraceMessageHandler(QString const& prog_name);
41 TraceMessageHandler(char const* prog_name);
39 ~TraceMessageHandler();42 ~TraceMessageHandler();
4043
41private:44private:
4245
=== modified file 'include/unity/storage/qt/Account.h'
--- include/unity/storage/qt/Account.h 2016-11-03 06:41:00 +0000
+++ include/unity/storage/qt/Account.h 2016-12-12 02:53:43 +0000
@@ -47,6 +47,8 @@
47 Q_PROPERTY(QString busName READ busName FINAL)47 Q_PROPERTY(QString busName READ busName FINAL)
48 Q_PROPERTY(QString objectPath READ objectPath FINAL)48 Q_PROPERTY(QString objectPath READ objectPath FINAL)
49 Q_PROPERTY(QString displayName READ displayName FINAL)49 Q_PROPERTY(QString displayName READ displayName FINAL)
50 Q_PROPERTY(QString providerName READ providerName FINAL)
51 Q_PROPERTY(QString iconName READ iconName FINAL)
5052
51public:53public:
52 Account();54 Account();
@@ -60,7 +62,8 @@
60 QString busName() const;62 QString busName() const;
61 QString objectPath() const;63 QString objectPath() const;
62 QString displayName() const;64 QString displayName() const;
63 // TODO: add more methods to retrieve additional info, such as description, icon ID, and service name.65 QString providerName() const;
66 QString iconName() const;
6467
65 Q_INVOKABLE unity::storage::qt::ItemListJob* roots(QStringList const& keys = QStringList()) const;68 Q_INVOKABLE unity::storage::qt::ItemListJob* roots(QStringList const& keys = QStringList()) const;
66 Q_INVOKABLE unity::storage::qt::ItemJob* get(QString const& itemId, QStringList const& keys = QStringList()) const;69 Q_INVOKABLE unity::storage::qt::ItemJob* get(QString const& itemId, QStringList const& keys = QStringList()) const;
6770
=== modified file 'include/unity/storage/qt/AccountsJob.h'
--- include/unity/storage/qt/AccountsJob.h 2016-11-02 02:54:48 +0000
+++ include/unity/storage/qt/AccountsJob.h 2016-12-12 02:53:43 +0000
@@ -34,12 +34,10 @@
34{34{
3535
36class AccountsJobImpl;36class AccountsJobImpl;
37class RuntimeImpl;
3837
39} // namespace internal38} // namespace internal
4039
41class Account;40class Account;
42class Runtime;
43class StorageError;41class StorageError;
4442
45class Q_DECL_EXPORT AccountsJob final : public QObject43class Q_DECL_EXPORT AccountsJob final : public QObject
@@ -65,14 +63,13 @@
65 void statusChanged(unity::storage::qt::AccountsJob::Status status) const;63 void statusChanged(unity::storage::qt::AccountsJob::Status status) const;
6664
67private:65private:
68 AccountsJob(std::shared_ptr<internal::RuntimeImpl> const& runtime);66 AccountsJob(std::unique_ptr<internal::AccountsJobImpl> accounts_job_impl);
69 AccountsJob(StorageError const& error);
7067
71 QVariantList accountsAsVariantList() const;68 QVariantList accountsAsVariantList() const;
7269
73 std::unique_ptr<internal::AccountsJobImpl> const p_;70 std::unique_ptr<internal::AccountsJobImpl> const p_;
7471
75 friend class internal::RuntimeImpl;72 friend class internal::AccountsJobImpl;
76};73};
7774
78} // namespace qt75} // namespace qt
7976
=== modified file 'include/unity/storage/qt/Runtime.h'
--- include/unity/storage/qt/Runtime.h 2016-11-02 02:54:48 +0000
+++ include/unity/storage/qt/Runtime.h 2016-12-12 02:53:43 +0000
@@ -66,9 +66,9 @@
6666
67 Account make_test_account(QString const& bus_name,67 Account make_test_account(QString const& bus_name,
68 QString const& object_path,68 QString const& object_path,
69 QString const& id = "",69 quint32 id = 999,
70 QString const& serviceId = "",70 QString const& service_id = "",
71 QString const& displayName = "") const;71 QString const& name = "") const;
7272
73private:73private:
74 std::shared_ptr<internal::RuntimeImpl> p_;74 std::shared_ptr<internal::RuntimeImpl> p_;
7575
=== modified file 'include/unity/storage/qt/internal/AccountImpl.h'
--- include/unity/storage/qt/internal/AccountImpl.h 2016-11-03 06:41:00 +0000
+++ include/unity/storage/qt/internal/AccountImpl.h 2016-12-12 02:53:43 +0000
@@ -19,10 +19,7 @@
19#pragma once19#pragma once
2020
21#include <unity/storage/qt/Item.h>21#include <unity/storage/qt/Item.h>
2222#include <unity/storage/internal/AccountDetails.h>
23#include <QString>
24
25#include <memory>
2623
27class ProviderInterface;24class ProviderInterface;
2825
@@ -50,6 +47,8 @@
50 QString busName() const;47 QString busName() const;
51 QString objectPath() const;48 QString objectPath() const;
52 QString displayName() const;49 QString displayName() const;
50 QString providerName() const;
51 QString iconName() const;
5352
54 ItemListJob* roots(QStringList const& keys) const;53 ItemListJob* roots(QStringList const& keys) const;
55 ItemJob* get(QString const& itemId, QStringList const& keys) const;54 ItemJob* get(QString const& itemId, QStringList const& keys) const;
@@ -67,26 +66,14 @@
67 std::shared_ptr<ProviderInterface> provider() const;66 std::shared_ptr<ProviderInterface> provider() const;
6867
69 static Account make_account(std::shared_ptr<RuntimeImpl> const& runtime_impl,68 static Account make_account(std::shared_ptr<RuntimeImpl> const& runtime_impl,
70 QString const& bus_name,69 storage::internal::AccountDetails const& details);
71 QString const& object_path,
72 QString const& id,
73 QString const& service_id,
74 QString const& display_name);
7570
76private:71private:
77 AccountImpl(std::shared_ptr<RuntimeImpl> const& runtime_impl,72 AccountImpl(std::shared_ptr<RuntimeImpl> const& runtime_impl,
78 QString const& bus_name,73 storage::internal::AccountDetails const& details);
79 QString const& object_path,
80 QString const& id,
81 QString const& service_id,
82 QString const& display_name);
8374
84 bool is_valid_;75 bool is_valid_;
85 QString bus_name_;76 storage::internal::AccountDetails details_;
86 QString object_path_;
87 QString id_;
88 QString service_id_;
89 QString display_name_;
90 std::weak_ptr<RuntimeImpl> runtime_impl_;77 std::weak_ptr<RuntimeImpl> runtime_impl_;
91 std::shared_ptr<ProviderInterface> provider_;78 std::shared_ptr<ProviderInterface> provider_;
9279
9380
=== modified file 'include/unity/storage/qt/internal/AccountsJobImpl.h'
--- include/unity/storage/qt/internal/AccountsJobImpl.h 2016-11-02 02:54:48 +0000
+++ include/unity/storage/qt/internal/AccountsJobImpl.h 2016-12-12 02:53:43 +0000
@@ -18,9 +18,14 @@
1818
19#pragma once19#pragma once
2020
21#include <unity/storage/internal/AccountDetails.h>
21#include <unity/storage/qt/AccountsJob.h>22#include <unity/storage/qt/AccountsJob.h>
2223
23#include <QTimer>24#pragma GCC diagnostic push
25#pragma GCC diagnostic ignored "-Wcast-align"
26#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
27#include <QDBusPendingReply>
28#pragma GCC diagnostic pop
2429
25namespace unity30namespace unity
26{31{
@@ -31,12 +36,16 @@
31namespace internal36namespace internal
32{37{
3338
39class RuntimeImpl;
40
34class AccountsJobImpl : public QObject41class AccountsJobImpl : public QObject
35{42{
36 Q_OBJECT43 Q_OBJECT
37public:44public:
38 AccountsJobImpl(AccountsJob* public_instance, std::shared_ptr<RuntimeImpl> const& runtime_impl);45 AccountsJobImpl(std::shared_ptr<RuntimeImpl> const& runtime_impl,
39 AccountsJobImpl(AccountsJob* public_instance, StorageError const& error);46 QString const& method,
47 QDBusPendingReply<QList<storage::internal::AccountDetails>>& reply);
48 AccountsJobImpl(StorageError const& error);
40 virtual ~AccountsJobImpl() = default;49 virtual ~AccountsJobImpl() = default;
4150
42 bool isValid() const;51 bool isValid() const;
@@ -45,21 +54,20 @@
45 QList<Account> accounts() const;54 QList<Account> accounts() const;
46 QVariantList accountsAsVariantList() const;55 QVariantList accountsAsVariantList() const;
4756
48private Q_SLOTS:57 static AccountsJob* make_job(std::shared_ptr<RuntimeImpl> const& runtime_impl,
49 void manager_ready();58 QString const& method,
50 void timeout();59 QDBusPendingReply<QList<storage::internal::AccountDetails>>& reply);
60 static AccountsJob* make_job(StorageError const& e);
5161
52private:62private:
53 std::shared_ptr<RuntimeImpl> get_runtime_impl(QString const& method) const;63 std::shared_ptr<RuntimeImpl> get_runtime_impl(QString const& method) const;
54 void initialize_accounts();
55 AccountsJob::Status emit_status_changed(AccountsJob::Status new_status) const;64 AccountsJob::Status emit_status_changed(AccountsJob::Status new_status) const;
5665
57 AccountsJob* const public_instance_;66 AccountsJob* public_instance_;
58 AccountsJob::Status status_;67 AccountsJob::Status status_;
59 StorageError error_;68 StorageError error_;
60 QList<unity::storage::qt::Account> accounts_;
61 std::weak_ptr<RuntimeImpl> const runtime_impl_;69 std::weak_ptr<RuntimeImpl> const runtime_impl_;
62 QTimer timer_;70 QList<Account> accounts_;
6371
64 friend class unity::storage::qt::AccountsJob;72 friend class unity::storage::qt::AccountsJob;
65};73};
6674
=== modified file 'include/unity/storage/qt/internal/Handler.h'
--- include/unity/storage/qt/internal/Handler.h 2016-11-04 04:13:45 +0000
+++ include/unity/storage/qt/internal/Handler.h 2016-12-12 02:53:43 +0000
@@ -71,7 +71,7 @@
71 case StorageError::Type::NoError:71 case StorageError::Type::NoError:
72 {72 {
73 // LCOV_EXCL_START73 // LCOV_EXCL_START
74 QString msg = "impossible provider exception: " + e.errorString();74 QString msg = "impossible service exception: " + e.errorString();
75 qCritical().noquote() << msg;75 qCritical().noquote() << msg;
76 e = StorageErrorImpl::local_comms_error(msg);76 e = StorageErrorImpl::local_comms_error(msg);
77 break;77 break;
@@ -82,7 +82,7 @@
82 case StorageError::Type::ResourceError:82 case StorageError::Type::ResourceError:
83 {83 {
84 // Log these errors because they are unexpected.84 // Log these errors because they are unexpected.
85 QString msg = "provider exception: " + e.errorString();85 QString msg = "service exception: " + e.errorString();
86 qCritical().noquote() << msg;86 qCritical().noquote() << msg;
87 break;87 break;
88 }88 }
8989
=== modified file 'include/unity/storage/qt/internal/RuntimeImpl.h'
--- include/unity/storage/qt/internal/RuntimeImpl.h 2016-09-22 01:52:20 +0000
+++ include/unity/storage/qt/internal/RuntimeImpl.h 2016-12-12 02:53:43 +0000
@@ -24,10 +24,11 @@
24#pragma GCC diagnostic push24#pragma GCC diagnostic push
25#pragma GCC diagnostic ignored "-Wcast-align"25#pragma GCC diagnostic ignored "-Wcast-align"
26#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"26#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
27#include <OnlineAccounts/Manager>
28#include <QDBusConnection>27#include <QDBusConnection>
29#pragma GCC diagnostic pop28#pragma GCC diagnostic pop
3029
30class RegistryInterface;
31
31namespace unity32namespace unity
32{33{
33namespace storage34namespace storage
@@ -45,7 +46,7 @@
45{46{
46public:47public:
47 RuntimeImpl();48 RuntimeImpl();
48 RuntimeImpl(QDBusConnection const& bus);49 RuntimeImpl(QDBusConnection const& conn);
49 RuntimeImpl(RuntimeImpl const&) = delete;50 RuntimeImpl(RuntimeImpl const&) = delete;
50 RuntimeImpl(RuntimeImpl&&) = delete;51 RuntimeImpl(RuntimeImpl&&) = delete;
51 ~RuntimeImpl();52 ~RuntimeImpl();
@@ -58,19 +59,17 @@
58 AccountsJob* accounts() const;59 AccountsJob* accounts() const;
59 StorageError shutdown();60 StorageError shutdown();
6061
61 std::shared_ptr<OnlineAccounts::Manager> accounts_manager() const;
62
63 Account make_test_account(QString const& bus_name,62 Account make_test_account(QString const& bus_name,
64 QString const& object_path,63 QString const& object_path,
65 QString const& owner_id,64 quint32 id,
66 QString const& owner,65 QString const& service_id,
67 QString const& description);66 QString const& display_name);
6867
69private:68private:
70 bool is_valid_;69 bool is_valid_;
71 StorageError error_;70 StorageError error_;
72 QDBusConnection conn_;71 QDBusConnection conn_;
73 std::shared_ptr<OnlineAccounts::Manager> accounts_manager_;72 std::unique_ptr<RegistryInterface> registry_;
7473
75 friend class unity::storage::qt::Runtime;74 friend class unity::storage::qt::Runtime;
76};75};
7776
=== added directory 'include/unity/storage/registry'
=== added file 'include/unity/storage/registry/Registry.h'
--- include/unity/storage/registry/Registry.h 1970-01-01 00:00:00 +0000
+++ include/unity/storage/registry/Registry.h 2016-12-12 02:53:43 +0000
@@ -0,0 +1,35 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#pragma once
20
21#include <QString>
22
23namespace unity
24{
25namespace storage
26{
27namespace registry
28{
29
30static QString const BUS_NAME(QStringLiteral("com.canonical.StorageFramework.Registry"));
31static QString const OBJECT_PATH(QStringLiteral("/com/canonical/StorageFramework/Registry"));
32
33} // namespace registry
34} // namespace storage
35} // namespace unity
036
=== added directory 'include/unity/storage/registry/internal'
=== added file 'include/unity/storage/registry/internal/ListAccountsHandler.h'
--- include/unity/storage/registry/internal/ListAccountsHandler.h 1970-01-01 00:00:00 +0000
+++ include/unity/storage/registry/internal/ListAccountsHandler.h 2016-12-12 02:53:43 +0000
@@ -0,0 +1,70 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#pragma once
20
21#include <unity/storage/internal/ActivityNotifier.h>
22
23#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-Wcast-align"
25#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
26#include <OnlineAccounts/Manager>
27#include <QDBusConnection>
28#include <QDBusMessage>
29#include <QTimer>
30#pragma GCC diagnostic pop
31
32namespace unity
33{
34namespace storage
35{
36namespace registry
37{
38namespace internal
39{
40
41class ListAccountsHandler : public QObject
42{
43 Q_OBJECT
44
45public:
46 ListAccountsHandler(QDBusConnection const& conn,
47 QDBusMessage const& msg,
48 std::shared_ptr<storage::internal::InactivityTimer> const& timer);
49 ~ListAccountsHandler();
50
51private Q_SLOTS:
52 void manager_ready();
53 void timeout();
54
55private:
56 void initialize_manager();
57
58 QDBusConnection const conn_;
59 QDBusMessage const msg_;
60 OnlineAccounts::Manager manager_;
61 QTimer timer_;
62 storage::internal::ActivityNotifier activity_notifier_; // RAII guard variable
63
64 Q_DISABLE_COPY(ListAccountsHandler)
65};
66
67} // namespace internal
68} // namespace registry
69} // namespace storage
70} // namespace unity
071
=== added file 'include/unity/storage/registry/internal/RegistryAdaptor.h'
--- include/unity/storage/registry/internal/RegistryAdaptor.h 1970-01-01 00:00:00 +0000
+++ include/unity/storage/registry/internal/RegistryAdaptor.h 2016-12-12 02:53:43 +0000
@@ -0,0 +1,71 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#pragma once
20
21#include <unity/storage/internal/AccountDetails.h>
22
23#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-Wcast-align"
25#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
26#include <QDBusConnection>
27#include <QDBusContext>
28#pragma GCC diagnostic pop
29
30#include <memory>
31
32namespace unity
33{
34namespace storage
35{
36namespace internal
37{
38
39class InactivityTimer;
40
41} // namespace internal
42
43namespace registry
44{
45namespace internal
46{
47
48class RegistryAdaptor : public QObject, protected QDBusContext
49{
50 Q_OBJECT
51
52public:
53 RegistryAdaptor(QDBusConnection const& conn,
54 std::shared_ptr<storage::internal::InactivityTimer> const& timer,
55 QObject* parent = nullptr);
56 ~RegistryAdaptor();
57
58public Q_SLOTS:
59 QList<unity::storage::internal::AccountDetails> ListAccounts();
60
61private:
62 QDBusConnection conn_;
63 std::shared_ptr<storage::internal::InactivityTimer> timer_;
64
65 Q_DISABLE_COPY(RegistryAdaptor)
66};
67
68} // namespace internal
69} // namespace registry
70} // namespace storage
71} // namespace unity
072
=== added file 'include/unity/storage/registry/internal/qdbus-last-error-msg.h'
--- include/unity/storage/registry/internal/qdbus-last-error-msg.h 1970-01-01 00:00:00 +0000
+++ include/unity/storage/registry/internal/qdbus-last-error-msg.h 2016-12-12 02:53:43 +0000
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#pragma once
20
21#pragma GCC diagnostic push
22#pragma GCC diagnostic ignored "-Wcast-align"
23#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
24#include <QDBusConnection>
25#pragma GCC diagnostic pop
26
27namespace unity
28{
29namespace storage
30{
31namespace registry
32{
33namespace internal
34{
35
36QString last_error_msg(QDBusConnection const& conn);
37
38} // namespace internal
39} // namespace registry
40} // namespace storage
41} // namespace unity
042
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2016-07-06 00:59:42 +0000
+++ src/CMakeLists.txt 2016-12-12 02:53:43 +0000
@@ -1,3 +1,4 @@
1add_subdirectory(internal)1add_subdirectory(internal)
2add_subdirectory(provider)2add_subdirectory(provider)
3add_subdirectory(qt)3add_subdirectory(qt)
4add_subdirectory(registry)
45
=== added file 'src/internal/AccountDetails.cpp'
--- src/internal/AccountDetails.cpp 1970-01-01 00:00:00 +0000
+++ src/internal/AccountDetails.cpp 2016-12-12 02:53:43 +0000
@@ -0,0 +1,108 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#include <unity/storage/internal/AccountDetails.h>
20
21using namespace unity::storage::internal;
22
23namespace unity
24{
25namespace storage
26{
27namespace internal
28{
29
30bool operator==(AccountDetails const& lhs, AccountDetails const& rhs)
31{
32 return lhs.id == rhs.id
33 && lhs.serviceId == rhs.serviceId
34 && lhs.displayName == rhs.displayName;
35}
36
37bool operator!=(AccountDetails const& lhs, AccountDetails const& rhs)
38{
39 return !(lhs == rhs);
40}
41
42bool operator<(AccountDetails const& lhs, AccountDetails const& rhs)
43{
44 if (lhs.id < rhs.id)
45 {
46 return true;
47 }
48 if (lhs.id > rhs.id)
49 {
50 return false;
51 }
52 if (lhs.serviceId < rhs.serviceId)
53 {
54 return true;
55 }
56 if (lhs.serviceId > rhs.serviceId)
57 {
58 return false;
59 }
60 return lhs.displayName < rhs.displayName;
61}
62
63bool operator<=(AccountDetails const& lhs, AccountDetails const& rhs)
64{
65 return lhs < rhs || lhs == rhs;
66}
67
68bool operator>(AccountDetails const& lhs, AccountDetails const& rhs)
69{
70 return !(lhs <= rhs);
71}
72
73bool operator>=(AccountDetails const& lhs, AccountDetails const& rhs)
74{
75 return !(lhs < rhs);
76}
77
78QDBusArgument& operator<<(QDBusArgument& argument, storage::internal::AccountDetails const& account)
79{
80 argument.beginStructure();
81 argument << account.busName;
82 argument << account.objectPath;
83 argument << account.id;
84 argument << account.serviceId;
85 argument << account.displayName;
86 argument << account.providerName;
87 argument << account.iconName;
88 argument.endStructure();
89 return argument;
90}
91
92QDBusArgument const& operator>>(QDBusArgument const& argument, storage::internal::AccountDetails& account)
93{
94 argument.beginStructure();
95 argument >> account.busName;
96 argument >> account.objectPath;
97 argument >> account.id;
98 argument >> account.serviceId;
99 argument >> account.displayName;
100 argument >> account.providerName;
101 argument >> account.iconName;
102 argument.endStructure();
103 return argument;
104}
105
106} // namespace internal
107} // namespace storage
108} // namespace unity
0109
=== modified file 'src/internal/CMakeLists.txt'
--- src/internal/CMakeLists.txt 2016-08-12 06:19:22 +0000
+++ src/internal/CMakeLists.txt 2016-12-12 02:53:43 +0000
@@ -1,10 +1,18 @@
1set(src1set(src
2 AccountDetails.cpp
2 dbusmarshal.cpp3 dbusmarshal.cpp
4 EnvVars.cpp
5 InactivityTimer.cpp
3 safe_strerror.cpp6 safe_strerror.cpp
4 TraceMessageHandler.cpp7 TraceMessageHandler.cpp
8 ${CMAKE_SOURCE_DIR}/include/unity/storage/internal/InactivityTimer.h
5)9)
610
11
7add_library(storage-framework-common-internal STATIC ${src})12add_library(storage-framework-common-internal STATIC ${src})
13
14set_target_properties(storage-framework-common-internal PROPERTIES AUTOMOC TRUE)
15
8target_link_libraries(storage-framework-common-internal16target_link_libraries(storage-framework-common-internal
9 Qt5::DBus17 Qt5::DBus
10)18)
1119
=== added file 'src/internal/EnvVars.cpp'
--- src/internal/EnvVars.cpp 1970-01-01 00:00:00 +0000
+++ src/internal/EnvVars.cpp 2016-12-12 02:53:43 +0000
@@ -0,0 +1,81 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#include <unity/storage/internal/EnvVars.h>
20
21#include <cassert>
22#include <QDebug>
23
24#include <stdlib.h>
25
26using namespace std;
27
28namespace unity
29{
30namespace storage
31{
32namespace internal
33{
34
35int EnvVars::registry_timeout_ms()
36{
37 int const dflt_val = REGISTRY_IDLE_TIMEOUT_DFLT * 1000;
38
39 auto const val = get(REGISTRY_IDLE_TIMEOUT);
40 if (val.empty())
41 {
42 return dflt_val;
43 }
44 try
45 {
46 size_t pos;
47 auto int_val = stoi(val, &pos);
48 if (pos != val.size())
49 {
50 throw invalid_argument("unexpected trailing character(s)");
51 }
52 if (int_val < 0)
53 {
54 throw invalid_argument("value must be >= 0");
55 }
56 return int_val;
57 }
58 catch (std::exception const& e)
59 {
60 qWarning().noquote().nospace() << "Invalid setting of env var " << QString::fromStdString(REGISTRY_IDLE_TIMEOUT)
61 << " (\"" << QString::fromStdString(val) << "\"): " << e.what();
62 qWarning().nospace() << "Using default value of " << REGISTRY_IDLE_TIMEOUT_DFLT;
63 }
64 return dflt_val;
65}
66
67string EnvVars::get(char const* var_name)
68{
69 assert(var_name != nullptr);
70
71 auto p = getenv(var_name);
72 if (!p)
73 {
74 return string();
75 }
76 return string(p);
77}
78
79} // namespace internal
80} // namespace storage
81} // namespace unity
082
=== added file 'src/internal/InactivityTimer.cpp'
--- src/internal/InactivityTimer.cpp 1970-01-01 00:00:00 +0000
+++ src/internal/InactivityTimer.cpp 2016-12-12 02:53:43 +0000
@@ -0,0 +1,82 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#include <unity/storage/internal/InactivityTimer.h>
20
21#include <QDebug>
22
23#include <cassert>
24
25namespace unity
26{
27namespace storage
28{
29namespace internal
30{
31
32InactivityTimer::InactivityTimer(int timeout_ms, std::function<void()> timeout_func)
33 : timeout_ms_(timeout_ms)
34 , timeout_func_(timeout_func)
35 , num_requests_(0)
36{
37 assert(timeout_ms_ >= 0);
38 assert(timeout_func);
39
40 connect(&timer_, &QTimer::timeout, this, &InactivityTimer::timeout);
41}
42
43InactivityTimer::~InactivityTimer() = default;
44
45void InactivityTimer::request_started()
46{
47 assert(num_requests_ >= 0);
48
49 if (num_requests_++ == 0)
50 {
51 timer_.stop();
52 }
53}
54
55void InactivityTimer::request_finished()
56{
57 assert(num_requests_ > 0);
58
59 if (--num_requests_ == 0)
60 {
61 timer_.start(timeout_ms_);
62 }
63}
64
65void InactivityTimer::timeout()
66{
67 timer_.stop();
68 disconnect(this);
69 try
70 {
71 timeout_func_();
72 }
73 catch (std::exception const& e)
74 {
75 auto msg = QString("InactivityTimer::timeout(): exception from timeout callback: ") + e.what();
76 qWarning().nospace() << msg;
77 }
78}
79
80} // namespace internal
81} // namespace storage
82} // namespace unity
083
=== modified file 'src/internal/TraceMessageHandler.cpp'
--- src/internal/TraceMessageHandler.cpp 2016-08-12 06:19:22 +0000
+++ src/internal/TraceMessageHandler.cpp 2016-12-12 02:53:43 +0000
@@ -80,10 +80,27 @@
8080
81} // namespace81} // namespace
8282
83TraceMessageHandler::TraceMessageHandler()
84 : old_message_handler_(qInstallMessageHandler(trace_message_handler))
85{
86}
87
83TraceMessageHandler::TraceMessageHandler(string const& prog_name)88TraceMessageHandler::TraceMessageHandler(string const& prog_name)
84{89 : TraceMessageHandler()
85 prefix = prog_name;90{
86 old_message_handler_ = qInstallMessageHandler(trace_message_handler);91 prefix = prog_name;
92}
93
94TraceMessageHandler::TraceMessageHandler(QString const& prog_name)
95 : TraceMessageHandler()
96{
97 prefix = prog_name.toStdString();
98}
99
100TraceMessageHandler::TraceMessageHandler(char const* prog_name)
101 : TraceMessageHandler()
102{
103 prefix = prog_name;
87}104}
88105
89TraceMessageHandler::~TraceMessageHandler()106TraceMessageHandler::~TraceMessageHandler()
90107
=== modified file 'src/qt/Account.cpp'
--- src/qt/Account.cpp 2016-11-03 06:41:00 +0000
+++ src/qt/Account.cpp 2016-12-12 02:53:43 +0000
@@ -93,6 +93,16 @@
93 return p_->displayName();93 return p_->displayName();
94}94}
9595
96QString Account::providerName() const
97{
98 return p_->providerName();
99}
100
101QString Account::iconName() const
102{
103 return p_->iconName();
104}
105
96ItemListJob* Account::roots(QStringList const& keys) const106ItemListJob* Account::roots(QStringList const& keys) const
97{107{
98 return p_->roots(keys);108 return p_->roots(keys);
99109
=== modified file 'src/qt/AccountsJob.cpp'
--- src/qt/AccountsJob.cpp 2016-11-02 02:54:48 +0000
+++ src/qt/AccountsJob.cpp 2016-12-12 02:53:43 +0000
@@ -18,7 +18,6 @@
1818
19#include <unity/storage/qt/AccountsJob.h>19#include <unity/storage/qt/AccountsJob.h>
2020
21#include <unity/storage/qt/Account.h>
22#include <unity/storage/qt/internal/AccountsJobImpl.h>21#include <unity/storage/qt/internal/AccountsJobImpl.h>
2322
24#include <QVariant>23#include <QVariant>
@@ -33,13 +32,8 @@
33namespace qt32namespace qt
34{33{
3534
36AccountsJob::AccountsJob(shared_ptr<internal::RuntimeImpl> const& runtime)35AccountsJob::AccountsJob(unique_ptr<internal::AccountsJobImpl> accounts_job_impl)
37 : p_(new internal::AccountsJobImpl(this, runtime))36 : p_(move(accounts_job_impl))
38{
39}
40
41AccountsJob::AccountsJob(StorageError const& error)
42 : p_(new internal::AccountsJobImpl(this, error))
43{37{
44}38}
4539
4640
=== modified file 'src/qt/CMakeLists.txt'
--- src/qt/CMakeLists.txt 2016-10-12 08:08:48 +0000
+++ src/qt/CMakeLists.txt 2016-12-12 02:53:43 +0000
@@ -4,11 +4,20 @@
4 CLASSNAME ProviderInterface4 CLASSNAME ProviderInterface
5 INCLUDE unity/storage/internal/dbusmarshal.h5 INCLUDE unity/storage/internal/dbusmarshal.h
6)6)
7
8qt5_add_dbus_interface(generated_files7qt5_add_dbus_interface(generated_files
9 ${CMAKE_SOURCE_DIR}/data/provider.xml8 ${CMAKE_SOURCE_DIR}/data/provider.xml
10 ProviderInterface9 ProviderInterface
11)10)
11
12set_source_files_properties(${CMAKE_SOURCE_DIR}/data/registry.xml PROPERTIES
13 CLASSNAME RegistryInterface
14 INCLUDE unity/storage/internal/AccountDetails.h
15)
16qt5_add_dbus_interface(generated_files
17 ${CMAKE_SOURCE_DIR}/data/registry.xml
18 RegistryInterface
19)
20
12set_source_files_properties(${generated_files} dbusmarshal.cpp PROPERTIES21set_source_files_properties(${generated_files} dbusmarshal.cpp PROPERTIES
13 COMPILE_FLAGS "-Wno-ctor-dtor-privacy -Wno-missing-field-initializers"22 COMPILE_FLAGS "-Wno-ctor-dtor-privacy -Wno-missing-field-initializers"
14 GENERATED TRUE23 GENERATED TRUE
@@ -71,7 +80,6 @@
71target_include_directories(storage-framework-qt-client-v2 PRIVATE80target_include_directories(storage-framework-qt-client-v2 PRIVATE
72 ${Qt5DBus_INCLUDE_DIRS}81 ${Qt5DBus_INCLUDE_DIRS}
73 ${Qt5Network_INCLUDE_DIRS}82 ${Qt5Network_INCLUDE_DIRS}
74 ${ONLINEACCOUNTS_DEPS_INCLUDE_DIRS}
75)83)
76set_target_properties(storage-framework-qt-client-v2 PROPERTIES84set_target_properties(storage-framework-qt-client-v2 PROPERTIES
77 AUTOMOC TRUE85 AUTOMOC TRUE
@@ -85,7 +93,6 @@
85 Qt5::Core93 Qt5::Core
86 Qt5::DBus94 Qt5::DBus
87 Qt5::Network95 Qt5::Network
88 ${ONLINEACCOUNTS_DEPS_LDFLAGS}
89)96)
90install(97install(
91 TARGETS storage-framework-qt-client-v298 TARGETS storage-framework-qt-client-v2
9299
=== modified file 'src/qt/Runtime.cpp'
--- src/qt/Runtime.cpp 2016-09-22 01:52:20 +0000
+++ src/qt/Runtime.cpp 2016-12-12 02:53:43 +0000
@@ -70,11 +70,11 @@
7070
71Account Runtime::make_test_account(QString const& bus_name,71Account Runtime::make_test_account(QString const& bus_name,
72 QString const& object_path,72 QString const& object_path,
73 QString const& owner_id,73 quint32 id,
74 QString const& owner,74 QString const& service_id,
75 QString const& description) const75 QString const& display_name) const
76{76{
77 return p_->make_test_account(bus_name, object_path, owner_id, owner, description);77 return p_->make_test_account(bus_name, object_path, id, service_id, display_name);
78}78}
7979
80} // namespace qt80} // namespace qt
8181
=== modified file 'src/qt/client/internal/remote_client/RuntimeImpl.cpp'
--- src/qt/client/internal/remote_client/RuntimeImpl.cpp 2016-11-02 09:32:53 +0000
+++ src/qt/client/internal/remote_client/RuntimeImpl.cpp 2016-12-12 02:53:43 +0000
@@ -47,7 +47,7 @@
4747
48static const map<QString, QString> BUS_NAMES =48static const map<QString, QString> BUS_NAMES =
49{49{
50 { "google-drive-scope", "com.canonical.StorageFramework.Provider.ProviderTest" },50 { "storage-provider-test", "com.canonical.StorageFramework.Provider.ProviderTest" },
51 { "com.canonical.scopes.mcloud_mcloud_mcloud", "com.canonical.StorageFramework.Provider.McloudProvider" },51 { "com.canonical.scopes.mcloud_mcloud_mcloud", "com.canonical.StorageFramework.Provider.McloudProvider" },
52 { "storage-provider-owncloud", "com.canonical.StorageFramework.Provider.OwnCloud" },52 { "storage-provider-owncloud", "com.canonical.StorageFramework.Provider.OwnCloud" },
53 { "storage-provider-onedrive", "com.canonical.StorageFramework.Provider.OnedriveProvider" },53 { "storage-provider-onedrive", "com.canonical.StorageFramework.Provider.OnedriveProvider" },
5454
=== modified file 'src/qt/internal/AccountImpl.cpp'
--- src/qt/internal/AccountImpl.cpp 2016-11-03 06:41:00 +0000
+++ src/qt/internal/AccountImpl.cpp 2016-12-12 02:53:43 +0000
@@ -48,37 +48,39 @@
48}48}
4949
50AccountImpl::AccountImpl(shared_ptr<RuntimeImpl> const& runtime_impl,50AccountImpl::AccountImpl(shared_ptr<RuntimeImpl> const& runtime_impl,
51 QString const& bus_name,51 storage::internal::AccountDetails const& details)
52 QString const& object_path,
53 QString const& id,
54 QString const& service_id,
55 QString const& display_name)
56 : is_valid_(true)52 : is_valid_(true)
57 , bus_name_(bus_name)53 , details_(details)
58 , object_path_(object_path)
59 , id_(id)
60 , service_id_(service_id)
61 , display_name_(display_name)
62 , runtime_impl_(runtime_impl)54 , runtime_impl_(runtime_impl)
63 , provider_(new ProviderInterface(bus_name, object_path, runtime_impl->connection()))55 , provider_(new ProviderInterface(details.busName, details.objectPath.path(), runtime_impl->connection()))
64{56{
65 assert(!bus_name.isEmpty());57 assert(!details.busName.isEmpty());
66 assert(!object_path.isEmpty());58 assert(!details.objectPath.path().isEmpty());
67}59}
6860
69QString AccountImpl::busName() const61QString AccountImpl::busName() const
70{62{
71 return is_valid_ ? bus_name_ : "";63 return is_valid_ ? details_.busName : "";
72}64}
7365
74QString AccountImpl::objectPath() const66QString AccountImpl::objectPath() const
75{67{
76 return is_valid_ ? object_path_ : "";68 return is_valid_ ? details_.objectPath.path() : QDBusObjectPath().path();
77}69}
7870
79QString AccountImpl::displayName() const71QString AccountImpl::displayName() const
80{72{
81 return is_valid_ ? display_name_ : "";73 return is_valid_ ? details_.displayName : "";
74}
75
76QString AccountImpl::providerName() const
77{
78 return is_valid_ ? details_.providerName : "";
79}
80
81QString AccountImpl::iconName() const
82{
83 return is_valid_ ? details_.iconName : "";
82}84}
8385
84ItemListJob* AccountImpl::roots(QStringList const& keys) const86ItemListJob* AccountImpl::roots(QStringList const& keys) const
@@ -101,7 +103,8 @@
101 {103 {
102 if (md.type != ItemType::root)104 if (md.type != ItemType::root)
103 {105 {
104 QString msg = method + ": provider returned non-root item type: " + QString::number(int(md.type));106 QString msg = method + ": provider returned non-root item type: " + QString::number(int(md.type)) +
107 " (id = " + md.item_id + ")";
105 qCritical().noquote() << msg;108 qCritical().noquote() << msg;
106 throw StorageErrorImpl::local_comms_error(msg);109 throw StorageErrorImpl::local_comms_error(msg);
107 }110 }
@@ -141,10 +144,7 @@
141{144{
142 if (is_valid_)145 if (is_valid_)
143 {146 {
144 return other.is_valid_147 return other.is_valid_ && details_ == other.details_;
145 && id_ == other.id_
146 && service_id_ == other.service_id_
147 && display_name_ == other.display_name_;
148 }148 }
149 return !other.is_valid_;149 return !other.is_valid_;
150}150}
@@ -164,24 +164,7 @@
164 {164 {
165 return false;165 return false;
166 }166 }
167 assert(is_valid_ && other.is_valid_);167 return details_ < other.details_;
168 if (id_ < other.id_)
169 {
170 return true;
171 }
172 if (id_ > other.id_)
173 {
174 return false;
175 }
176 if (service_id_ < other.service_id_)
177 {
178 return true;
179 }
180 if (service_id_ > other.service_id_)
181 {
182 return false;
183 }
184 return display_name_ < other.display_name_;
185}168}
186169
187bool AccountImpl::operator<=(AccountImpl const& other) const170bool AccountImpl::operator<=(AccountImpl const& other) const
@@ -215,21 +198,16 @@
215 {198 {
216 return 0;199 return 0;
217 }200 }
218 size_t hash = 0;201 size_t hash = details_.id;
219 boost::hash_combine(hash, qHash(service_id_));202 boost::hash_combine(hash, qHash(details_.serviceId));
220 boost::hash_combine(hash, qHash(id_));203 boost::hash_combine(hash, qHash(details_.displayName));
221 boost::hash_combine(hash, qHash(display_name_));
222 return hash;204 return hash;
223}205}
224206
225Account AccountImpl::make_account(shared_ptr<RuntimeImpl> const& runtime,207Account AccountImpl::make_account(shared_ptr<RuntimeImpl> const& runtime,
226 QString const& bus_name,208 storage::internal::AccountDetails const& details)
227 QString const& object_path,
228 QString const& id,
229 QString const& service_id,
230 QString const& display_name)
231{209{
232 shared_ptr<AccountImpl> p(new AccountImpl(runtime, bus_name, object_path, id, service_id, display_name));210 shared_ptr<AccountImpl> p(new AccountImpl(runtime, details));
233 return Account(p);211 return Account(p);
234}212}
235213
236214
=== modified file 'src/qt/internal/AccountsJobImpl.cpp'
--- src/qt/internal/AccountsJobImpl.cpp 2016-11-03 07:33:40 +0000
+++ src/qt/internal/AccountsJobImpl.cpp 2016-12-12 02:53:43 +0000
@@ -18,12 +18,12 @@
1818
19#include <unity/storage/qt/internal/AccountsJobImpl.h>19#include <unity/storage/qt/internal/AccountsJobImpl.h>
2020
21#include "RegistryInterface.h"
21#include <unity/storage/qt/internal/AccountImpl.h>22#include <unity/storage/qt/internal/AccountImpl.h>
23#include <unity/storage/qt/internal/Handler.h>
22#include <unity/storage/qt/internal/RuntimeImpl.h>24#include <unity/storage/qt/internal/RuntimeImpl.h>
23#include <unity/storage/qt/internal/StorageErrorImpl.h>25#include <unity/storage/qt/internal/StorageErrorImpl.h>
2426
25#include <OnlineAccounts/Account>
26
27#include <cassert>27#include <cassert>
2828
29using namespace std;29using namespace std;
@@ -37,38 +37,45 @@
37namespace internal37namespace internal
38{38{
3939
40namespace40AccountsJobImpl::AccountsJobImpl(shared_ptr<RuntimeImpl> const& runtime_impl,
41{41 QString const& method,
4242 QDBusPendingReply<QList<storage::internal::AccountDetails>>& reply)
43// TODO: We retrieve the accounts directly from online accounts until we have a working registry.43 : status_(AccountsJob::Status::Loading)
44
45static map<QString, QString> const BUS_NAMES =
46{
47 { "google-drive-scope", "com.canonical.StorageFramework.Provider.ProviderTest" },
48 { "com.canonical.scopes.mcloud_mcloud_mcloud", "com.canonical.StorageFramework.Provider.McloudProvider" },
49 { "storage-provider-owncloud", "com.canonical.StorageFramework.Provider.OwnCloud" },
50 { "storage-provider-onedrive", "com.canonical.StorageFramework.Provider.OnedriveProvider" },
51};
52
53} // namespace
54
55AccountsJobImpl::AccountsJobImpl(AccountsJob* public_instance, shared_ptr<RuntimeImpl> const& runtime_impl)
56 : public_instance_(public_instance)
57 , status_(AccountsJob::Status::Loading)
58 , runtime_impl_(runtime_impl)44 , runtime_impl_(runtime_impl)
59{45{
60 assert(public_instance);
61 assert(runtime_impl);46 assert(runtime_impl);
6247
63 initialize_accounts();48 auto process_reply = [this, method](decltype(reply)& r)
49 {
50 auto runtime = get_runtime_impl(method);
51 if (!runtime || !runtime->isValid())
52 {
53 return;
54 }
55
56 for (auto const& ad : r.value())
57 {
58 auto a = AccountImpl::make_account(runtime, ad);
59 accounts_.append(a);
60 }
61 status_ = AccountsJob::Status::Finished;
62 Q_EMIT public_instance_->statusChanged(status_);
63 };
64
65 auto process_error = [this](StorageError const& error)
66 {
67 error_ = error;
68 status_ = AccountsJob::Status::Error;
69 Q_EMIT public_instance_->statusChanged(status_);
70 };
71
72 new Handler<QList<storage::internal::AccountDetails>>(this, reply, process_reply, process_error);
64}73}
6574
66AccountsJobImpl::AccountsJobImpl(AccountsJob* public_instance, StorageError const& error)75AccountsJobImpl::AccountsJobImpl(StorageError const& error)
67 : public_instance_(public_instance)76 : status_(AccountsJob::Status::Error)
68 , status_(AccountsJob::Status::Loading)
69 , error_(error)77 , error_(error)
70{78{
71 assert(public_instance);
72 assert(error.type() != StorageError::Type::NoError);79 assert(error.type() != StorageError::Type::NoError);
7380
74 status_ = emit_status_changed(AccountsJob::Status::Error);81 status_ = emit_status_changed(AccountsJob::Status::Error);
@@ -113,21 +120,27 @@
113 return account_list;120 return account_list;
114}121}
115122
116void AccountsJobImpl::manager_ready()123AccountsJob* AccountsJobImpl::make_job(shared_ptr<RuntimeImpl> const& runtime,
124 QString const& method,
125 QDBusPendingReply<QList<storage::internal::AccountDetails>>& reply)
117{126{
118 timer_.stop();127 unique_ptr<AccountsJobImpl> impl(new AccountsJobImpl(runtime, method, reply));
119 disconnect(this);128 auto job = new AccountsJob(move(impl));
120 initialize_accounts();129 job->p_->public_instance_ = job;
130 return job;
121}131}
122132
123// LCOV_EXCL_START133AccountsJob* AccountsJobImpl::make_job(StorageError const& error)
124void AccountsJobImpl::timeout()
125{134{
126 disconnect(this);135 unique_ptr<AccountsJobImpl> impl(new AccountsJobImpl(error));
127 error_ = StorageErrorImpl::local_comms_error("AccountsJob(): timeout retrieving Online accounts");136 auto job = new AccountsJob(move(impl));
128 status_ = emit_status_changed(AccountsJob::Status::Error);137 job->p_->public_instance_ = job;
138 QMetaObject::invokeMethod(job,
139 "statusChanged",
140 Qt::QueuedConnection,
141 Q_ARG(unity::storage::qt::AccountsJob::Status, job->p_->status_));
142 return job;
129}143}
130// LCOV_EXCL_STOP
131144
132AccountsJob::Status AccountsJobImpl::emit_status_changed(AccountsJob::Status new_status) const145AccountsJob::Status AccountsJobImpl::emit_status_changed(AccountsJob::Status new_status) const
133{146{
@@ -152,43 +165,11 @@
152 auto This = const_cast<AccountsJobImpl*>(this);165 auto This = const_cast<AccountsJobImpl*>(this);
153 This->error_ = StorageErrorImpl::runtime_destroyed_error(msg);166 This->error_ = StorageErrorImpl::runtime_destroyed_error(msg);
154 This->status_ = emit_status_changed(AccountsJob::Status::Error);167 This->status_ = emit_status_changed(AccountsJob::Status::Error);
168 return nullptr;
155 }169 }
156 return runtime;170 return runtime;
157}171}
158172
159void AccountsJobImpl::initialize_accounts()
160{
161 auto runtime = get_runtime_impl("AccountsJob()");
162 assert(runtime);
163
164 auto manager = runtime->accounts_manager();
165 if (!manager->isReady())
166 {
167 connect(manager.get(), &OnlineAccounts::Manager::ready, this, &AccountsJobImpl::manager_ready);
168 connect(&timer_, &QTimer::timeout, this, &AccountsJobImpl::timeout);
169 timer_.setSingleShot(true);
170 timer_.start(30000); // TODO: Need config for this eventually.
171 return;
172 }
173
174 for (auto const map_entry : BUS_NAMES)
175 {
176 auto service_id = map_entry.first;
177 for (auto const& a : manager->availableAccounts(service_id))
178 {
179 auto object_path = QStringLiteral("/provider/%1").arg(a->id());
180 auto bus_name = map_entry.second;
181 accounts_.append(AccountImpl::make_account(runtime,
182 bus_name,
183 object_path,
184 QString::number(a->id()),
185 a->serviceId(),
186 a->displayName()));
187 }
188 }
189 status_ = emit_status_changed(AccountsJob::Status::Finished);
190}
191
192} // namespace internal173} // namespace internal
193} // namespace qt174} // namespace qt
194} // namespace storage175} // namespace storage
195176
=== modified file 'src/qt/internal/ItemImpl.cpp'
--- src/qt/internal/ItemImpl.cpp 2016-11-03 03:41:24 +0000
+++ src/qt/internal/ItemImpl.cpp 2016-12-12 02:53:43 +0000
@@ -153,7 +153,7 @@
153 {153 {
154 if (md.type == ItemType::file)154 if (md.type == ItemType::file)
155 {155 {
156 QString msg = method + ": provider returned a file as a parent";156 QString msg = method + ": provider returned a file as a parent (id = " + md.item_id + ")";
157 qCritical().noquote() << msg;157 qCritical().noquote() << msg;
158 throw StorageErrorImpl::local_comms_error(msg);158 throw StorageErrorImpl::local_comms_error(msg);
159 }159 }
@@ -178,7 +178,8 @@
178 ||178 ||
179 (md_.type != ItemType::file && md.type == ItemType::file))179 (md_.type != ItemType::file && md.type == ItemType::file))
180 {180 {
181 QString msg = method + ": source and target item type differ";181 QString msg = method + "provider error: source and target item type differ (source id = " +
182 md_.item_id + ", target id = " + md.item_id + ")";
182 qCritical().noquote() << msg;183 qCritical().noquote() << msg;
183 throw StorageErrorImpl::local_comms_error(msg);184 throw StorageErrorImpl::local_comms_error(msg);
184 }185 }
@@ -203,7 +204,7 @@
203 {204 {
204 if (md.type == ItemType::root)205 if (md.type == ItemType::root)
205 {206 {
206 QString msg = method + ": impossible root item returned by provider";207 QString msg = method + ": impossible root item returned by provider (id = " + md.item_id + ")";
207 qCritical().noquote() << msg;208 qCritical().noquote() << msg;
208 throw StorageErrorImpl::local_comms_error(msg);209 throw StorageErrorImpl::local_comms_error(msg);
209 }210 }
@@ -211,7 +212,8 @@
211 ||212 ||
212 (md_.type != ItemType::file && md.type == ItemType::file))213 (md_.type != ItemType::file && md.type == ItemType::file))
213 {214 {
214 QString msg = method + ": provider error: source and target item type differ";215 QString msg = method + ": provider error: source and target item type differ (source id = " +
216 md_.item_id + ", target id = " + md.item_id + ")";
215 qCritical().noquote() << msg;217 qCritical().noquote() << msg;
216 throw StorageErrorImpl::local_comms_error(msg);218 throw StorageErrorImpl::local_comms_error(msg);
217 }219 }
@@ -266,7 +268,7 @@
266 {268 {
267 if (md.type != storage::ItemType::file)269 if (md.type != storage::ItemType::file)
268 {270 {
269 QString msg = method + ": impossible folder item returned by provider";271 QString msg = method + ": impossible folder item returned by provider (id = " + md.item_id + ")";
270 qCritical().noquote() << msg;272 qCritical().noquote() << msg;
271 throw StorageErrorImpl::local_comms_error(msg);273 throw StorageErrorImpl::local_comms_error(msg);
272 }274 }
@@ -318,7 +320,7 @@
318 {320 {
319 if (md.type == storage::ItemType::root)321 if (md.type == storage::ItemType::root)
320 {322 {
321 QString msg = method + ": impossible root item returned by provider";323 QString msg = method + ": impossible root item returned by provider (id = " + md.item_id + ")";
322 qCritical().noquote() << msg;324 qCritical().noquote() << msg;
323 throw StorageErrorImpl::local_comms_error(msg);325 throw StorageErrorImpl::local_comms_error(msg);
324 }326 }
@@ -379,7 +381,7 @@
379 {381 {
380 return;382 return;
381 }383 }
382 QString msg = method + ": impossible file item returned by provider";384 QString msg = method + ": impossible file item returned by provider (id = " + md.item_id + ")";
383 qCritical().noquote() << msg;385 qCritical().noquote() << msg;
384 throw StorageErrorImpl::local_comms_error(msg);386 throw StorageErrorImpl::local_comms_error(msg);
385 };387 };
@@ -423,7 +425,7 @@
423 {425 {
424 if (md.type != storage::ItemType::file)426 if (md.type != storage::ItemType::file)
425 {427 {
426 QString msg = method + ": impossible folder item returned by provider";428 QString msg = method + ": impossible folder item returned by provider (id = " + md.item_id + ")";
427 qCritical().noquote() << msg;429 qCritical().noquote() << msg;
428 throw StorageErrorImpl::local_comms_error(msg);430 throw StorageErrorImpl::local_comms_error(msg);
429 }431 }
430432
=== modified file 'src/qt/internal/ItemListJobImpl.cpp'
--- src/qt/internal/ItemListJobImpl.cpp 2016-10-12 07:23:15 +0000
+++ src/qt/internal/ItemListJobImpl.cpp 2016-12-12 02:53:43 +0000
@@ -62,16 +62,14 @@
62 auto item = ItemImpl::make_item(method_, md, account_impl_);62 auto item = ItemImpl::make_item(method_, md, account_impl_);
63 items.append(item);63 items.append(item);
64 }64 }
65 catch (StorageError const&)65 catch (StorageError const& e)
66 {66 {
67 // Bad metadata received from provider, validate_() or make_item() have logged it.67 // Bad metadata received from provider, validate_() or make_item() have logged it.
68 error_ = e;
68 }69 }
69 }70 }
70 status_ = ItemListJob::Status::Finished;71 status_ = error_.type() == StorageError::NoError ? ItemListJob::Finished : ItemListJob::Error;
71 if (!items.isEmpty())72 Q_EMIT public_instance_->itemsReady(items);
72 {
73 Q_EMIT public_instance_->itemsReady(items);
74 }
75 Q_EMIT public_instance_->statusChanged(status_);73 Q_EMIT public_instance_->statusChanged(status_);
76 };74 };
7775
7876
=== modified file 'src/qt/internal/MultiItemListJobImpl.cpp'
--- src/qt/internal/MultiItemListJobImpl.cpp 2016-10-12 07:23:15 +0000
+++ src/qt/internal/MultiItemListJobImpl.cpp 2016-12-12 02:53:43 +0000
@@ -86,10 +86,7 @@
86 {86 {
87 status_ = ItemListJob::Status::Finished;87 status_ = ItemListJob::Status::Finished;
88 }88 }
89 if (!items.isEmpty())89 Q_EMIT public_instance_->itemsReady(items);
90 {
91 Q_EMIT public_instance_->itemsReady(items);
92 }
93 if (token.isEmpty())90 if (token.isEmpty())
94 {91 {
95 Q_EMIT public_instance_->statusChanged(status_);92 Q_EMIT public_instance_->statusChanged(status_);
9693
=== modified file 'src/qt/internal/RuntimeImpl.cpp'
--- src/qt/internal/RuntimeImpl.cpp 2016-10-10 05:24:16 +0000
+++ src/qt/internal/RuntimeImpl.cpp 2016-12-12 02:53:43 +0000
@@ -18,15 +18,17 @@
1818
19#include <unity/storage/qt/internal/RuntimeImpl.h>19#include <unity/storage/qt/internal/RuntimeImpl.h>
2020
21#include "RegistryInterface.h"
21#include <unity/storage/internal/dbusmarshal.h>22#include <unity/storage/internal/dbusmarshal.h>
22#include <unity/storage/qt/AccountsJob.h>23#include <unity/storage/internal/EnvVars.h>
23#include <unity/storage/qt/internal/AccountImpl.h>24#include <unity/storage/qt/internal/AccountImpl.h>
25#include <unity/storage/qt/internal/AccountsJobImpl.h>
24#include <unity/storage/qt/internal/StorageErrorImpl.h>26#include <unity/storage/qt/internal/StorageErrorImpl.h>
25#include <unity/storage/qt/Item.h>
26#include <unity/storage/qt/ItemJob.h>27#include <unity/storage/qt/ItemJob.h>
27#include <unity/storage/qt/ItemListJob.h>28#include <unity/storage/qt/ItemListJob.h>
28#include <unity/storage/qt/Runtime.h>29#include <unity/storage/qt/Runtime.h>
29#include <unity/storage/qt/VoidJob.h>30#include <unity/storage/qt/VoidJob.h>
31#include <unity/storage/registry/Registry.h>
3032
31#include <QDBusError>33#include <QDBusError>
32#include <QDBusMetaType>34#include <QDBusMetaType>
@@ -57,6 +59,9 @@
5759
58 qDBusRegisterMetaType<unity::storage::internal::ItemMetadata>();60 qDBusRegisterMetaType<unity::storage::internal::ItemMetadata>();
59 qDBusRegisterMetaType<QList<unity::storage::internal::ItemMetadata>>();61 qDBusRegisterMetaType<QList<unity::storage::internal::ItemMetadata>>();
62
63 qDBusRegisterMetaType<unity::storage::internal::AccountDetails>();
64 qDBusRegisterMetaType<QList<unity::storage::internal::AccountDetails>>();
60}65}
6166
62}67}
@@ -66,10 +71,12 @@
66{71{
67}72}
6873
69RuntimeImpl::RuntimeImpl(QDBusConnection const& bus)74RuntimeImpl::RuntimeImpl(QDBusConnection const& conn)
70 : is_valid_(true)75 : is_valid_(true)
71 , conn_(bus)76 , conn_(conn)
72 , accounts_manager_(new OnlineAccounts::Manager("", conn_))77 , registry_(new RegistryInterface(storage::registry::BUS_NAME,
78 storage::registry::OBJECT_PATH,
79 conn_))
73{80{
74 register_meta_types();81 register_meta_types();
75}82}
@@ -96,13 +103,17 @@
96103
97AccountsJob* RuntimeImpl::accounts() const104AccountsJob* RuntimeImpl::accounts() const
98{105{
106 QString const method = "Runtime::accounts()";
107
99 if (!is_valid_)108 if (!is_valid_)
100 {109 {
101 QString msg = "Runtime::accounts(): Runtime was destroyed previously";110 QString msg = "Runtime::accounts(): Runtime was destroyed previously";
102 return new AccountsJob(StorageErrorImpl::runtime_destroyed_error(msg));111 return AccountsJobImpl::make_job(StorageErrorImpl::runtime_destroyed_error(msg));
103 }112 }
104 auto This = const_cast<RuntimeImpl*>(this);113
105 return new AccountsJob(This->shared_from_this());114 auto reply = registry_->ListAccounts();
115 auto This = const_pointer_cast<RuntimeImpl>(shared_from_this());
116 return AccountsJobImpl::make_job(This, method, reply);
106}117}
107118
108StorageError RuntimeImpl::shutdown()119StorageError RuntimeImpl::shutdown()
@@ -116,23 +127,14 @@
116 return error_;127 return error_;
117}128}
118129
119shared_ptr<OnlineAccounts::Manager> RuntimeImpl::accounts_manager() const
120{
121 return accounts_manager_;
122}
123
124Account RuntimeImpl::make_test_account(QString const& bus_name,130Account RuntimeImpl::make_test_account(QString const& bus_name,
125 QString const& object_path,131 QString const& object_path,
126 QString const& owner_id,132 quint32 id,
127 QString const& owner,133 QString const& service_id,
128 QString const& description)134 QString const& name)
129{135{
130 return AccountImpl::make_account(shared_from_this(),136 storage::internal::AccountDetails ad{bus_name, QDBusObjectPath(object_path), id, service_id, name, "", ""};
131 bus_name,137 return AccountImpl::make_account(shared_from_this(), ad);
132 object_path,
133 owner_id,
134 owner,
135 description);
136}138}
137139
138} // namespace internal140} // namespace internal
139141
=== modified file 'src/qt/internal/validate.cpp'
--- src/qt/internal/validate.cpp 2016-11-02 06:06:32 +0000
+++ src/qt/internal/validate.cpp 2016-12-12 02:53:43 +0000
@@ -110,69 +110,81 @@
110{110{
111 using namespace unity::storage::metadata;111 using namespace unity::storage::metadata;
112112
113 QString prefix = method + ": received invalid metadata from provider: ";113 QString prefix = method + ": received invalid metadata from provider";
114114 if (!md.item_id.isEmpty())
115 // Basic sanity checks for mandatory fields.115 {
116 if (md.item_id.isEmpty())116 prefix += " (id = " + md.item_id + ")";
117 {117 }
118 throw StorageErrorImpl::local_comms_error(prefix + "item_id cannot be empty");118 prefix += ": ";
119 }119
120 if (md.type != ItemType::root)120 try
121 {121 {
122 if (md.parent_ids.isEmpty())122 // Basic sanity checks for mandatory fields.
123 {123 if (md.item_id.isEmpty())
124 throw StorageErrorImpl::local_comms_error(prefix + "file or folder must have at least one parent ID");124 {
125 }125 throw StorageErrorImpl::local_comms_error(prefix + "item_id cannot be empty");
126 for (int i = 0; i < md.parent_ids.size(); ++i)126 }
127 {127 if (md.type != ItemType::root)
128 if (md.parent_ids.at(i).isEmpty())128 {
129 {129 if (md.parent_ids.isEmpty())
130 throw StorageErrorImpl::local_comms_error(prefix + "parent_id of file or folder cannot be empty");130 {
131 }131 throw StorageErrorImpl::local_comms_error(prefix + "file or folder must have at least one parent ID");
132 }132 }
133 }133 for (int i = 0; i < md.parent_ids.size(); ++i)
134 if (md.type == ItemType::root && !md.parent_ids.isEmpty())134 {
135 {135 if (md.parent_ids.at(i).isEmpty())
136 throw StorageErrorImpl::local_comms_error(prefix + "parent_ids of root must be empty");136 {
137 }137 throw StorageErrorImpl::local_comms_error(prefix + "parent_id of file or folder cannot be empty");
138 if (md.type != ItemType::root) // Dropbox does not support metadata for roots.138 }
139 {139 }
140 if (md.name.isEmpty())140 }
141 {141 if (md.type == ItemType::root && !md.parent_ids.isEmpty())
142 throw StorageErrorImpl::local_comms_error(prefix + "name cannot be empty");142 {
143 }143 throw StorageErrorImpl::local_comms_error(prefix + "parent_ids of root must be empty");
144 }144 }
145 if (md.type == ItemType::file && md.etag.isEmpty()) // WebDav doesn't do etag for folders.145 if (md.type != ItemType::root) // Dropbox does not support metadata for roots.
146 {146 {
147 throw StorageErrorImpl::local_comms_error(prefix + "etag of a file cannot be empty");147 if (md.name.isEmpty())
148 }148 {
149149 throw StorageErrorImpl::local_comms_error(prefix + "name cannot be empty");
150 // Sanity check metadata to make sure only known metadata keys appear.150 }
151 QMapIterator<QString, QVariant> actual(md.metadata);151 }
152 while (actual.hasNext())152 if (md.type == ItemType::file && md.etag.isEmpty()) // WebDav doesn't do etag for folders.
153 {153 {
154 actual.next();154 throw StorageErrorImpl::local_comms_error(prefix + "etag of a file cannot be empty");
155 auto known = known_metadata.find(actual.key().toStdString());155 }
156 if (known == known_metadata.end())156
157 {157 // Sanity check metadata to make sure only known metadata keys appear.
158 qWarning().noquote().nospace() << prefix << "unknown metadata key: \"" << actual.key() << "\"";158 QMapIterator<QString, QVariant> actual(md.metadata);
159 }159 while (actual.hasNext())
160 else160 {
161 {161 actual.next();
162 validate_type_and_value(prefix, actual, known);162 auto known = known_metadata.find(actual.key().toStdString());
163 }163 if (known == known_metadata.end())
164 }164 {
165165 qWarning().noquote().nospace() << prefix << "unknown metadata key: \"" << actual.key() << "\"";
166 // Sanity check metadata to make sure that mandatory fields are present.166 }
167 if (md.type == ItemType::file)167 else
168 {168 {
169 if (!md.metadata.contains(metadata::SIZE_IN_BYTES) ||169 validate_type_and_value(prefix, actual, known);
170 !md.metadata.contains(metadata::LAST_MODIFIED_TIME))170 }
171 {171 }
172 QString msg = prefix + "missing key \"" + metadata::SIZE_IN_BYTES + "\" "172
173 "in metadata for \"" + md.item_id + "\"";173 // Sanity check metadata to make sure that mandatory fields are present.
174 throw StorageErrorImpl::local_comms_error(msg);174 if (md.type == ItemType::file)
175 }175 {
176 if (!md.metadata.contains(metadata::SIZE_IN_BYTES) ||
177 !md.metadata.contains(metadata::LAST_MODIFIED_TIME))
178 {
179 QString msg = prefix + "missing key \"" + metadata::SIZE_IN_BYTES + "\" in metadata";
180 throw StorageErrorImpl::local_comms_error(msg);
181 }
182 }
183 }
184 catch (StorageError const& e)
185 {
186 qCritical().noquote() << e.errorString();
187 throw;
176 }188 }
177}189}
178190
179191
=== added directory 'src/registry'
=== added file 'src/registry/CMakeLists.txt'
--- src/registry/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ src/registry/CMakeLists.txt 2016-12-12 02:53:43 +0000
@@ -0,0 +1,47 @@
1include_directories(
2 ${CMAKE_CURRENT_BINARY_DIR}
3 ${ONLINEACCOUNTS_DEPS_INCLUDE_DIRS}
4)
5
6set(TARGET "storage-framework-registry")
7
8qt5_add_dbus_adaptor(adaptor_files
9 ${CMAKE_SOURCE_DIR}/data/registry.xml
10 unity/storage/registry/internal/RegistryAdaptor.h
11 unity::storage::registry::internal::RegistryAdaptor
12)
13
14set_source_files_properties(${adaptor_files} PROPERTIES
15 COMPILE_FLAGS "-Wno-ctor-dtor-privacy -Wno-missing-field-initializers"
16 GENERATED TRUE
17)
18
19add_executable(${TARGET}
20 internal/ListAccountsHandler.cpp
21 internal/qdbus-last-error-msg.cpp
22 internal/RegistryAdaptor.cpp
23 main.cpp
24 ${CMAKE_SOURCE_DIR}/include/unity/storage/registry/internal/ListAccountsHandler.h
25 ${CMAKE_SOURCE_DIR}/include/unity/storage/registry/internal/RegistryAdaptor.h
26 ${adaptor_files})
27
28set_target_properties(${TARGET} PROPERTIES AUTOMOC TRUE)
29
30target_link_libraries(${TARGET}
31 storage-framework-common-internal
32 Qt5::Core
33 Qt5::DBus
34 ${ONLINEACCOUNTS_DEPS_LDFLAGS}
35)
36
37install(
38 TARGETS ${TARGET}
39 RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}
40)
41
42configure_file(com.canonical.StorageFramework.Registry.service.in com.canonical.StorageFramework.Registry.service)
43
44install(
45 FILES ${CMAKE_CURRENT_BINARY_DIR}/com.canonical.StorageFramework.Registry.service
46 DESTINATION ${CMAKE_INSTALL_DATADIR}/dbus-1/services
47)
048
=== added file 'src/registry/com.canonical.StorageFramework.Registry.service.in'
--- src/registry/com.canonical.StorageFramework.Registry.service.in 1970-01-01 00:00:00 +0000
+++ src/registry/com.canonical.StorageFramework.Registry.service.in 2016-12-12 02:53:43 +0000
@@ -0,0 +1,3 @@
1[D-BUS Service]
2Name=com.canonical.StorageFramework.Registry
3Exec=@CMAKE_INSTALL_FULL_LIBDIR@/@PROJECT_NAME@/storage-framework-registry
04
=== added directory 'src/registry/internal'
=== added file 'src/registry/internal/ListAccountsHandler.cpp'
--- src/registry/internal/ListAccountsHandler.cpp 1970-01-01 00:00:00 +0000
+++ src/registry/internal/ListAccountsHandler.cpp 2016-12-12 02:53:43 +0000
@@ -0,0 +1,127 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#include <unity/storage/registry/internal/ListAccountsHandler.h>
20
21#include <unity/storage/internal/AccountDetails.h>
22#include <unity/storage/registry/internal/qdbus-last-error-msg.h>
23
24#include <OnlineAccounts/Account>
25#include <QDebug>
26
27using namespace std;
28
29namespace unity
30{
31namespace storage
32{
33namespace registry
34{
35namespace internal
36{
37
38ListAccountsHandler::ListAccountsHandler(QDBusConnection const& conn,
39 QDBusMessage const& msg,
40 shared_ptr<storage::internal::InactivityTimer> const& timer)
41 : conn_(conn)
42 , msg_(msg)
43 , manager_("", conn)
44 , activity_notifier_(timer)
45{
46 connect(&manager_, &OnlineAccounts::Manager::ready, this, &ListAccountsHandler::manager_ready);
47 connect(&timer_, &QTimer::timeout, this, &ListAccountsHandler::timeout);
48 timer_.setSingleShot(true);
49 timer_.start(25000); // TODO: Need config for this eventually.
50}
51
52ListAccountsHandler::~ListAccountsHandler() = default;
53
54namespace
55{
56
57// TODO: This is a hack until Online Accounts is updated to give us the provider ID, provider name, and icon name.
58
59struct ProviderDetails
60{
61 char const* bus_name;
62 char const* provider_name;
63};
64
65static map<QString, ProviderDetails> const BUS_NAMES =
66{
67 { "storage-provider-test", { "com.canonical.StorageFramework.Provider.ProviderTest", "Test Provider" } },
68 { "com.canonical.scopes.mcloud_mcloud_mcloud", { "com.canonical.StorageFramework.Provider.McloudProvider", "mcloud" } },
69 { "storage-provider-owncloud", { "com.canonical.StorageFramework.Provider.OwnCloud", "ownCloud" } },
70 { "storage-provider-onedrive", { "com.canonical.StorageFramework.Provider.OnedriveProvider", "OneDrive" } },
71};
72
73} // namespace
74
75void ListAccountsHandler::manager_ready()
76{
77 timer_.stop();
78 disconnect(this);
79 deleteLater();
80
81 QList<storage::internal::AccountDetails> accounts;
82 for (auto const& acct : manager_.availableAccounts())
83 {
84 auto const it = BUS_NAMES.find(acct->serviceId());
85 if (it == BUS_NAMES.end())
86 {
87 continue;
88 }
89
90 storage::internal::AccountDetails ad;
91 ad.busName = it->second.bus_name;
92 ad.objectPath = QDBusObjectPath(QStringLiteral("/provider/%1").arg(acct->id()));
93 ad.id = acct->id();
94 ad.serviceId = acct->serviceId();
95 ad.displayName = acct->displayName();
96 ad.providerName = it->second.provider_name;
97 ad.iconName = "";
98
99 accounts.append(ad);
100 }
101
102 if (!conn_.send(msg_.createReply(QVariant::fromValue(accounts))))
103 {
104 auto msg = last_error_msg(conn_);
105 qCritical().noquote() << "ListAccounts(): could not send DBus reply" + msg;
106 }
107}
108
109void ListAccountsHandler::timeout()
110{
111 disconnect(this);
112 deleteLater();
113
114 QString err = QString("cannot contact Online Accounts: request timed out after ") +
115 QString::number(timer_.interval()) + " ms";
116 qCritical().noquote() << err;
117 if (!conn_.send(msg_.createErrorReply(QDBusError::Other, err)))
118 {
119 auto msg = last_error_msg(conn_);
120 qCritical().noquote() << "ListAccounts(): could not send DBus error reply" + msg;
121 }
122}
123
124} // namespace internal
125} // namespace registry
126} // namespace storage
127} // namespace unity
0128
=== added file 'src/registry/internal/RegistryAdaptor.cpp'
--- src/registry/internal/RegistryAdaptor.cpp 1970-01-01 00:00:00 +0000
+++ src/registry/internal/RegistryAdaptor.cpp 2016-12-12 02:53:43 +0000
@@ -0,0 +1,55 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#include <unity/storage/registry/internal/RegistryAdaptor.h>
20
21#include <unity/storage/registry/internal/ListAccountsHandler.h>
22
23using namespace std;
24
25namespace unity
26{
27namespace storage
28{
29namespace registry
30{
31namespace internal
32{
33
34RegistryAdaptor::RegistryAdaptor(QDBusConnection const& conn,
35 shared_ptr<storage::internal::InactivityTimer> const& timer,
36 QObject* parent)
37 : QObject(parent)
38 , conn_(conn)
39 , timer_(timer)
40{
41}
42
43RegistryAdaptor::~RegistryAdaptor() = default;
44
45QList<unity::storage::internal::AccountDetails> RegistryAdaptor::ListAccounts()
46{
47 new ListAccountsHandler(conn_, message(), timer_); // Handler deletes itself once done.
48 setDelayedReply(true);
49 return QList<unity::storage::internal::AccountDetails>();
50}
51
52} // namespace internal
53} // namespace registry
54} // namespace storage
55} // namespace unity
056
=== added file 'src/registry/internal/qdbus-last-error-msg.cpp'
--- src/registry/internal/qdbus-last-error-msg.cpp 1970-01-01 00:00:00 +0000
+++ src/registry/internal/qdbus-last-error-msg.cpp 2016-12-12 02:53:43 +0000
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#include <unity/storage/registry/internal/qdbus-last-error-msg.h>
20
21#pragma GCC diagnostic push
22#pragma GCC diagnostic ignored "-Wcast-align"
23#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
24#include <QDBusError>
25#pragma GCC diagnostic pop
26
27namespace unity
28{
29namespace storage
30{
31namespace registry
32{
33namespace internal
34{
35
36QString last_error_msg(QDBusConnection const& conn)
37{
38 auto msg = conn.lastError().message();
39 if (!msg.isEmpty())
40 {
41 msg = ": " + msg;
42 }
43 return msg;
44}
45
46} // namespace internal
47} // namespace registry
48} // namespace storage
49} // namespace unity
050
=== added file 'src/registry/main.cpp'
--- src/registry/main.cpp 1970-01-01 00:00:00 +0000
+++ src/registry/main.cpp 2016-12-12 02:53:43 +0000
@@ -0,0 +1,95 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#include "registryadaptor.h"
20#include <unity/storage/internal/EnvVars.h>
21#include <unity/storage/internal/InactivityTimer.h>
22#include <unity/storage/internal/TraceMessageHandler.h>
23#include <unity/storage/registry/internal/qdbus-last-error-msg.h>
24#include <unity/storage/registry/internal/RegistryAdaptor.h>
25#include <unity/storage/registry/Registry.h>
26
27#pragma GCC diagnostic push
28#pragma GCC diagnostic ignored "-Wcast-align"
29#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
30#include <QCoreApplication>
31#include <QDBusArgument>
32#include <QDBusError>
33#include <QFileInfo>
34#pragma GCC diagnostic pop
35
36using namespace unity::storage;
37using namespace unity::storage::registry::internal;
38using namespace std;
39
40int main(int argc, char* argv[])
41{
42 auto const prog_name = QFileInfo(argv[0]).fileName();
43 internal::TraceMessageHandler message_handler(prog_name);
44
45 int rc = 1;
46 try
47 {
48 QCoreApplication app(argc, argv);
49
50 auto conn = QDBusConnection::sessionBus();
51
52 int const timeout_ms = internal::EnvVars::registry_timeout_ms();
53 auto timeout_func = [&app, timeout_ms]
54 {
55 qInfo().noquote().nospace() << "Exiting after " << QString::number(timeout_ms) << " ms of idle time";
56 app.quit();
57 };
58 auto inactivity_timer = make_shared<unity::storage::internal::InactivityTimer>(timeout_ms, timeout_func);
59
60 registry::internal::RegistryAdaptor registry_adaptor(conn, inactivity_timer);
61 new ::RegistryAdaptor(&registry_adaptor);
62
63 auto const& object_path = registry::OBJECT_PATH;
64 if (!conn.registerObject(object_path, &registry_adaptor))
65 {
66 auto msg = last_error_msg(conn);
67 throw runtime_error(string("Could not register object path ") +
68 object_path.toStdString() + msg.toStdString());
69 }
70
71 qDBusRegisterMetaType<unity::storage::internal::AccountDetails>();
72 qDBusRegisterMetaType<QList<unity::storage::internal::AccountDetails>>();
73
74 auto const& bus_name = registry::BUS_NAME;
75 if (!conn.registerService(bus_name))
76 {
77 auto msg = last_error_msg(conn);
78 throw runtime_error(string("Could not acquire DBus name ") + bus_name.toStdString() + msg.toStdString());
79 }
80
81 rc = app.exec();
82
83 if (!conn.unregisterService(bus_name))
84 {
85 auto msg = last_error_msg(conn);
86 throw runtime_error(string("Could not release DBus name ") + bus_name.toStdString() + msg.toStdString());
87 }
88 }
89 catch (std::exception const& e)
90 {
91 qCritical().noquote() << e.what();
92 }
93
94 return rc;
95}
096
=== modified file 'tests/CMakeLists.txt'
--- tests/CMakeLists.txt 2016-09-08 08:33:59 +0000
+++ tests/CMakeLists.txt 2016-12-12 02:53:43 +0000
@@ -1,10 +1,4 @@
1# We add -g so we get debug info for the gtest stack frames with gdb.
2# The warnings are suppressed so we get a noise-free build for gtest and gmock.
3
4set(old_cxx_flags ${CMAKE_CXX_FLAGS})
5set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wno-old-style-cast -Wno-missing-field-initializers")
6find_package(GMock)1find_package(GMock)
7set(CMAKE_CXX_FLAGS ${old_cxx_flags})
82
9configure_file(testsetup.h.in testsetup.h @ONLY)3configure_file(testsetup.h.in testsetup.h @ONLY)
10include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})4include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
@@ -12,6 +6,7 @@
12add_subdirectory(utils)6add_subdirectory(utils)
137
14set(unit_test_dirs8set(unit_test_dirs
9 registry
15 local-client10 local-client
16 remote-client11 remote-client
17 remote-client-v112 remote-client-v1
1813
=== modified file 'tests/copyright/check_copyright.sh'
--- tests/copyright/check_copyright.sh 2016-11-04 10:52:10 +0000
+++ tests/copyright/check_copyright.sh 2016-12-12 02:53:43 +0000
@@ -22,6 +22,8 @@
22# Check that we have acceptable license information in our source files.22# Check that we have acceptable license information in our source files.
23#23#
2424
25set -eu
26
25usage()27usage()
26{28{
27 echo "usage: check_copyright dir [ignore_dir]" >&229 echo "usage: check_copyright dir [ignore_dir]" >&2
@@ -31,6 +33,9 @@
31[ $# -lt 1 ] && usage33[ $# -lt 1 ] && usage
32[ $# -gt 2 ] && usage34[ $# -gt 2 ] && usage
3335
36source_dir="$1"
37ignore_dir="${2:-}"
38
34ignore_pat="\\.sci$|\\.swp$|\\.bzr|debian|qmldir|HACKING|ubsan-suppress|valgrind-suppress|\\.txt$|\\.xml$|\\.in$|\\.dox$|\\.yaml$"39ignore_pat="\\.sci$|\\.swp$|\\.bzr|debian|qmldir|HACKING|ubsan-suppress|valgrind-suppress|\\.txt$|\\.xml$|\\.in$|\\.dox$|\\.yaml$"
3540
36#41#
@@ -39,15 +44,16 @@
39# the output with grep -F, so we don't get false positives from licensecheck.44# the output with grep -F, so we don't get false positives from licensecheck.
40#45#
4146
42[ $# -eq 2 ] && ignore_dir="$2"47licensecheck -i "$ignore_pat" -r "$source_dir" > licensecheck.log
4348if [ -n "$ignore_dir" ]; then
44if [ -n "$ignore_dir" ]49 cat licensecheck.log | grep -v -F "$ignore_dir" | grep "No copyright" > filtered.log || :
45then
46 licensecheck -i "$ignore_pat" -r "$1" | grep -F "$ignore_dir" -v | grep 'No copyright'
47else50else
48 licensecheck -i "$ignore_pat" -r "$1" | grep 'No copyright'51 cat licensecheck.log | grep "No copyright" > filtered.log || :
49fi52fi
5053
51[ $? -eq 0 ] && exit 154if [ -s filtered.log ]; then
55 cat filtered.log
56 exit 1
57fi
5258
53exit 059exit 0
5460
=== modified file 'tests/headers/CMakeLists.txt'
--- tests/headers/CMakeLists.txt 2016-09-08 08:33:59 +0000
+++ tests/headers/CMakeLists.txt 2016-12-12 02:53:43 +0000
@@ -41,14 +41,14 @@
41 add_test(stand-alone-${location}-headers41 add_test(stand-alone-${location}-headers
42 ${CMAKE_CURRENT_SOURCE_DIR}/compile_headers.py42 ${CMAKE_CURRENT_SOURCE_DIR}/compile_headers.py
43 ${extra_defines}43 ${extra_defines}
44 ${public_inc_dir} ${CMAKE_CXX_COMPILER} "${CMAKE_CXX_COMPILER_ARG1} -fPIC -fsyntax-only -I${root_inc_dir} -I${public_inc_dir} ${other_inc_dirs} ${CMAKE_CXX_FLAGS} ${extra_inc_dirs}")44 ${public_inc_dir} ${CMAKE_CXX_COMPILER} "${CMAKE_CXX_COMPILER_ARG1} -fPIC -I${root_inc_dir} -I${public_inc_dir} ${other_inc_dirs} ${CMAKE_CXX_FLAGS} ${extra_inc_dirs}")
4545
46 # Test that each internal header compiles stand-alone.46 # Test that each internal header compiles stand-alone.
47 if (IS_DIRECTORY ${internal_inc_dir})47 if (IS_DIRECTORY ${internal_inc_dir})
48 add_test(stand-alone-${location}-internal-headers48 add_test(stand-alone-${location}-internal-headers
49 ${CMAKE_CURRENT_SOURCE_DIR}/compile_headers.py49 ${CMAKE_CURRENT_SOURCE_DIR}/compile_headers.py
50 ${extra_defines}50 ${extra_defines}
51 ${internal_inc_dir} ${CMAKE_CXX_COMPILER} "${CMAKE_CXX_COMPILER_ARG1} -fPIC -fsyntax-only -I${root_inc_dir} -I${internal_inc_dir} ${other_inc_dirs} ${CMAKE_CXX_FLAGS} ${extra_inc_dirs}")51 ${internal_inc_dir} ${CMAKE_CXX_COMPILER} "${CMAKE_CXX_COMPILER_ARG1} -fPIC -I${root_inc_dir} -I${internal_inc_dir} ${other_inc_dirs} ${CMAKE_CXX_FLAGS} ${extra_inc_dirs}")
52 endif()52 endif()
5353
54 if (NOT ${public_inc_dir} MATCHES "/internal/")54 if (NOT ${public_inc_dir} MATCHES "/internal/")
5555
=== modified file 'tests/headers/compile_headers.py'
--- tests/headers/compile_headers.py 2016-08-22 04:35:33 +0000
+++ tests/headers/compile_headers.py 2016-12-12 02:53:43 +0000
@@ -52,7 +52,6 @@
52import shlex52import shlex
53import subprocess53import subprocess
54import sys54import sys
55import tempfile
56import concurrent.futures, multiprocessing55import concurrent.futures, multiprocessing
5756
58#57#
@@ -74,16 +73,20 @@
74#73#
75def run_compiler(hdr, compiler, copts, define, verbose, hdr_dir):74def run_compiler(hdr, compiler, copts, define, verbose, hdr_dir):
76 try:75 try:
77 src = tempfile.NamedTemporaryFile(suffix='.cpp', dir='.')76 compile_dir = "./.header_tests"
77 os.makedirs(compile_dir, exist_ok=True)
78 src_name = os.path.join(compile_dir, hdr) + ".cpp"
79
80 if not os.path.exists(src_name):
81 src_fd = os.open(src_name, os.O_WRONLY | os.O_CREAT)
82 src = os.fdopen(src_fd, 'w')
83 src.write("#include <" + hdr + ">" + "\n")
84 src.write("#include <" + hdr + ">" + "\n") # To test that double-inclusion is safe
7885
79 # Add any extra defines to the command line.86 # Add any extra defines to the command line.
80 for flag in define:87 for flag in define:
81 copts = "-D" + flag + " " + copts88 copts = "-D" + flag + " " + copts
8289
83 src.write(bytes("#include <" + hdr + ">" + "\n", 'UTF-8'))
84 src.flush() # Need this to make the file visible
85 src_name = os.path.join('.', src.name)
86
87 if verbose:90 if verbose:
88 print(compiler + " -c " + src_name + " " + copts)91 print(compiler + " -c " + src_name + " " + copts)
8992
@@ -91,13 +94,13 @@
91 if status != 0:94 if status != 0:
92 message("cannot compile \"" + hdr + "\"") # Yes, write to stdout because this is expected output95 message("cannot compile \"" + hdr + "\"") # Yes, write to stdout because this is expected output
9396
94 obj = os.path.splitext(src_name)[0] + ".o"97 obj = hdr + ".o"
95 try:98 try:
96 os.unlink(obj)99 os.unlink(obj)
97 except:100 except:
98 pass101 pass
99102
100 gcov = os.path.splitext(src_name)[0] + ".gcno"103 gcov = hdr + ".gcno"
101 try:104 try:
102 os.unlink(gcov)105 os.unlink(gcov)
103 except:106 except:
104107
=== modified file 'tests/local-client/local-client_test.cpp'
--- tests/local-client/local-client_test.cpp 2016-08-26 04:45:56 +0000
+++ tests/local-client/local-client_test.cpp 2016-12-12 02:53:43 +0000
@@ -21,7 +21,11 @@
21#include <unity/storage/qt/client/internal/local_client/boost_filesystem.h>21#include <unity/storage/qt/client/internal/local_client/boost_filesystem.h>
22#include <unity/storage/qt/client/internal/local_client/tmpfile_prefix.h>22#include <unity/storage/qt/client/internal/local_client/tmpfile_prefix.h>
2323
24#pragma GCC diagnostic push
25#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
24#include <gtest/gtest.h>26#include <gtest/gtest.h>
27#pragma GCC diagnostic pop
28
25#include <QCoreApplication>29#include <QCoreApplication>
26#include <QFile>30#include <QFile>
27#include <QFutureWatcher>31#include <QFutureWatcher>
2832
=== modified file 'tests/provider-AccountData/AccountData_test.cpp'
--- tests/provider-AccountData/AccountData_test.cpp 2016-09-28 11:58:35 +0000
+++ tests/provider-AccountData/AccountData_test.cpp 2016-12-12 02:53:43 +0000
@@ -22,7 +22,11 @@
2222
23#include <utils/DBusEnvironment.h>23#include <utils/DBusEnvironment.h>
2424
25#pragma GCC diagnostic push
26#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
25#include <gtest/gtest.h>27#include <gtest/gtest.h>
28#pragma GCC diagnostic pop
29
26#include <OnlineAccounts/Account>30#include <OnlineAccounts/Account>
27#include <OnlineAccounts/Manager>31#include <OnlineAccounts/Manager>
28#include <QCoreApplication>32#include <QCoreApplication>
2933
=== modified file 'tests/provider-DBusPeerCache/DBusPeerCache_test.cpp'
--- tests/provider-DBusPeerCache/DBusPeerCache_test.cpp 2016-07-28 03:10:57 +0000
+++ tests/provider-DBusPeerCache/DBusPeerCache_test.cpp 2016-12-12 02:53:43 +0000
@@ -20,7 +20,11 @@
2020
21#include <utils/DBusEnvironment.h>21#include <utils/DBusEnvironment.h>
2222
23#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
23#include <gtest/gtest.h>25#include <gtest/gtest.h>
26#pragma GCC diagnostic pop
27
24#include <OnlineAccounts/Account>28#include <OnlineAccounts/Account>
25#include <OnlineAccounts/Manager>29#include <OnlineAccounts/Manager>
26#include <QCoreApplication>30#include <QCoreApplication>
2731
=== modified file 'tests/provider-ProviderInterface/TestProvider.cpp'
--- tests/provider-ProviderInterface/TestProvider.cpp 2016-11-03 02:43:43 +0000
+++ tests/provider-ProviderInterface/TestProvider.cpp 2016-12-12 02:53:43 +0000
@@ -87,7 +87,7 @@
87boost::future<Item> TestUploadJob::finish()87boost::future<Item> TestUploadJob::finish()
88{88{
89 boost::promise<Item> p;89 boost::promise<Item> p;
90 printf("TestUploadJob::finish(): %d read of expected %d\n", (int) bytes_read_, (int) size_);90 printf("TestUploadJob::finish(): %d read of expected %d\n", int(bytes_read_), int(size_));
91 notifier_.setEnabled(false);91 notifier_.setEnabled(false);
92 drain();92 drain();
93 if (bytes_read_ == size_)93 if (bytes_read_ == size_)
@@ -139,7 +139,7 @@
139139
140void TestUploadJob::read_some()140void TestUploadJob::read_some()
141{141{
142 printf("TestUploadJob::read_some(): %d read of expected %d\n", (int) bytes_read_, (int) size_);142 printf("TestUploadJob::read_some(): %d read of expected %d\n", int(bytes_read_), int(size_));
143143
144 char buf[5];144 char buf[5];
145 ssize_t n_read = read(read_socket(), buf, sizeof(buf));145 ssize_t n_read = read(read_socket(), buf, sizeof(buf));
@@ -248,7 +248,7 @@
248boost::future<void> TestDownloadJob::finish()248boost::future<void> TestDownloadJob::finish()
249{249{
250 boost::promise<void> p;250 boost::promise<void> p;
251 if (bytes_written_ < (ssize_t)data_.size())251 if (bytes_written_ < ssize_t(data_.size()))
252 {252 {
253 p.set_exception(LogicException("Not all data read"));253 p.set_exception(LogicException("Not all data read"));
254 }254 }
@@ -261,14 +261,14 @@
261261
262void TestDownloadJob::write_some()262void TestDownloadJob::write_some()
263{263{
264 if (bytes_written_ >= (ssize_t)data_.size()) {264 if (bytes_written_ >= ssize_t(data_.size())) {
265 report_complete();265 report_complete();
266 timer_.stop();266 timer_.stop();
267 return;267 return;
268 }268 }
269269
270 ssize_t n_written = write(write_socket(), data_.data() + bytes_written_,270 ssize_t n_written = write(write_socket(), data_.data() + bytes_written_,
271 min(data_.size() - bytes_written_, (size_t)2));271 min(data_.size() - bytes_written_, size_t(2)));
272 if (n_written < 0)272 if (n_written < 0)
273 {273 {
274 int error_code = errno;274 int error_code = errno;
275275
=== added directory 'tests/registry'
=== added file 'tests/registry/CMakeLists.txt'
--- tests/registry/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ tests/registry/CMakeLists.txt 2016-12-12 02:53:43 +0000
@@ -0,0 +1,20 @@
1add_executable(registry_test registry_test.cpp)
2#set_target_properties(remote-client_test PROPERTIES AUTOMOC TRUE)
3
4#add_definitions(-DTEST_DIR="${CMAKE_CURRENT_BINARY_DIR}" -DBOOST_THREAD_VERSION=4)
5#include_directories(${GLIB_DEPS_INCLUDE_DIRS})
6
7#target_link_libraries(remote-client_test
8# storage-framework-provider
9# storage-framework-qt-client-v2
10# Qt5::Network
11# Qt5::Test
12# ${Boost_LIBRARIES}
13# ${GLIB_DEPS_LIBRARIES}
14# testutils
15# gtest
16#)
17add_test(registry registry_test)
18#add_dependencies(remote-client_test qt-client-all-headers provider-test)
19
20#set(UNIT_TEST_TARGETS ${UNIT_TEST_TARGETS} PARENT_SCOPE)
021
=== added file 'tests/registry/registry_test.cpp'
--- tests/registry/registry_test.cpp 1970-01-01 00:00:00 +0000
+++ tests/registry/registry_test.cpp 2016-12-12 02:53:43 +0000
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2016 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 version 3 as
6 * published by the Free Software Foundation.
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 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19int main(int argc, char** argv)
20{
21#if 0
22 QCoreApplication app(argc, argv);
23
24 ::testing::InitGoogleTest(&argc, argv);
25 return RUN_ALL_TESTS();
26#endif
27}
028
=== modified file 'tests/remote-client-v1/remote-client-v1_test.cpp'
--- tests/remote-client-v1/remote-client-v1_test.cpp 2016-09-26 02:37:03 +0000
+++ tests/remote-client-v1/remote-client-v1_test.cpp 2016-12-12 02:53:43 +0000
@@ -56,7 +56,7 @@
56 void SetUp() override56 void SetUp() override
57 {57 {
58 dbus_.reset(new DBusEnvironment);58 dbus_.reset(new DBusEnvironment);
59 dbus_->add_demo_provider("google-drive-scope");59 dbus_->add_demo_provider("storage-provider-test");
60 dbus_->start_services();60 dbus_->start_services();
61 }61 }
6262
@@ -150,7 +150,7 @@
150 }150 }
151 for (auto acc : accounts)151 for (auto acc : accounts)
152 {152 {
153 if (acc->owner_id() == "google-drive-scope")153 if (acc->owner_id() == "storage-provider-test")
154 {154 {
155 return acc;155 return acc;
156 }156 }
@@ -198,8 +198,8 @@
198 auto acc = get_account(runtime);198 auto acc = get_account(runtime);
199 EXPECT_EQ(runtime, acc->runtime());199 EXPECT_EQ(runtime, acc->runtime());
200 EXPECT_EQ("", acc->owner());200 EXPECT_EQ("", acc->owner());
201 EXPECT_EQ("google-drive-scope", acc->owner_id());201 EXPECT_EQ("storage-provider-test", acc->owner_id());
202 EXPECT_EQ("Fake google account", acc->description());202 EXPECT_EQ("Fake test account", acc->description());
203}203}
204204
205TEST_F(RuntimeTest, roots)205TEST_F(RuntimeTest, roots)
206206
=== modified file 'tests/remote-client/CMakeLists.txt'
--- tests/remote-client/CMakeLists.txt 2016-09-08 08:33:59 +0000
+++ tests/remote-client/CMakeLists.txt 2016-12-12 02:53:43 +0000
@@ -15,6 +15,6 @@
15 gtest15 gtest
16)16)
17add_test(remote-client remote-client_test)17add_test(remote-client remote-client_test)
18add_dependencies(remote-client_test qt-client-all-headers provider-test)18add_dependencies(remote-client_test qt-client-all-headers storage-framework-registry)
1919
20set(UNIT_TEST_TARGETS ${UNIT_TEST_TARGETS} PARENT_SCOPE)20set(UNIT_TEST_TARGETS ${UNIT_TEST_TARGETS} PARENT_SCOPE)
2121
=== modified file 'tests/remote-client/remote-client_test.cpp'
--- tests/remote-client/remote-client_test.cpp 2016-11-04 07:33:07 +0000
+++ tests/remote-client/remote-client_test.cpp 2016-12-12 02:53:43 +0000
@@ -22,7 +22,11 @@
22#include <utils/gtest_printer.h>22#include <utils/gtest_printer.h>
23#include <utils/ProviderFixture.h>23#include <utils/ProviderFixture.h>
2424
25#pragma GCC diagnostic push
26#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
25#include <gtest/gtest.h>27#include <gtest/gtest.h>
28#pragma GCC diagnostic pop
29
26#include <QSignalSpy>30#include <QSignalSpy>
2731
28#include <unordered_set>32#include <unordered_set>
@@ -121,77 +125,77 @@
121125
122 {126 {
123 auto acc = runtime_->make_test_account(service_connection_->baseService(), object_path(),127 auto acc = runtime_->make_test_account(service_connection_->baseService(), object_path(),
124 "id", "sid", "displayName");128 99, "sid", "name");
125 EXPECT_TRUE(acc.isValid());129 EXPECT_TRUE(acc.isValid());
126 EXPECT_EQ(service_connection_->baseService(), acc.busName());130 EXPECT_EQ(service_connection_->baseService(), acc.busName());
127 EXPECT_EQ(object_path(), acc.objectPath());131 EXPECT_EQ(object_path(), acc.objectPath());
128 EXPECT_EQ("displayName", acc.displayName());132 EXPECT_EQ("name", acc.displayName());
129133
130 // Copy constructor134 // Copy constructor
131 Account a2(acc);135 Account a2(acc);
132 EXPECT_TRUE(a2.isValid());136 EXPECT_TRUE(a2.isValid());
133 EXPECT_EQ(service_connection_->baseService(), a2.busName());137 EXPECT_EQ(service_connection_->baseService(), a2.busName());
134 EXPECT_EQ(object_path(), a2.objectPath());138 EXPECT_EQ(object_path(), a2.objectPath());
135 EXPECT_EQ("displayName", a2.displayName());139 EXPECT_EQ("name", a2.displayName());
136140
137 // Move constructor141 // Move constructor
138 Account a3(move(a2));142 Account a3(move(a2));
139 EXPECT_TRUE(a3.isValid());143 EXPECT_TRUE(a3.isValid());
140 EXPECT_EQ(service_connection_->baseService(), a3.busName());144 EXPECT_EQ(service_connection_->baseService(), a3.busName());
141 EXPECT_EQ(object_path(), a3.objectPath());145 EXPECT_EQ(object_path(), a3.objectPath());
142 EXPECT_EQ("displayName", a3.displayName());146 EXPECT_EQ("name", a3.displayName());
143147
144 // Moved-from object must be invalid148 // Moved-from object must be invalid
145 EXPECT_FALSE(a2.isValid());149 EXPECT_FALSE(a2.isValid());
146150
147 // Moved-from object must be assignable151 // Moved-from object must be assignable
148 auto a4 = runtime_->make_test_account(service_connection_->baseService(), object_path(),152 auto a4 = runtime_->make_test_account(service_connection_->baseService(), object_path(),
149 "id4", "sid4", "displayName4");153 99, "sid4", "name4");
150 a2 = a4;154 a2 = a4;
151 EXPECT_TRUE(a2.isValid());155 EXPECT_TRUE(a2.isValid());
152 EXPECT_EQ(service_connection_->baseService(), a2.busName());156 EXPECT_EQ(service_connection_->baseService(), a2.busName());
153 EXPECT_EQ(object_path(), a2.objectPath());157 EXPECT_EQ(object_path(), a2.objectPath());
154 EXPECT_EQ("displayName4", a2.displayName());158 EXPECT_EQ("name4", a2.displayName());
155 }159 }
156160
157 {161 {
158 auto a1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "id", "sid", "dn");162 auto a1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 99, "sid", "dn");
159 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "id2", "sid2", "dn2");163 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 100, "sid2", "n2");
160164
161 // Copy assignment165 // Copy assignment
162 a1 = a2;166 a1 = a2;
163 EXPECT_TRUE(a2.isValid());167 EXPECT_TRUE(a2.isValid());
164 EXPECT_EQ(service_connection_->baseService(), a1.busName());168 EXPECT_EQ(service_connection_->baseService(), a1.busName());
165 EXPECT_EQ(object_path(), a1.objectPath());169 EXPECT_EQ(object_path(), a1.objectPath());
166 EXPECT_EQ("dn2", a1.displayName());170 EXPECT_EQ("n2", a1.displayName());
167171
168 // Self-assignment172 // Self-assignment
169 a2 = a2;173 a2 = a2;
170 EXPECT_TRUE(a2.isValid());174 EXPECT_TRUE(a2.isValid());
171 EXPECT_EQ(service_connection_->baseService(), a1.busName());175 EXPECT_EQ(service_connection_->baseService(), a1.busName());
172 EXPECT_EQ(object_path(), a1.objectPath());176 EXPECT_EQ(object_path(), a1.objectPath());
173 EXPECT_EQ("dn2", a1.displayName());177 EXPECT_EQ("n2", a1.displayName());
174178
175 // Move assignment179 // Move assignment
176 auto a3 = runtime_->make_test_account(service_connection_->baseService(), object_path(),180 auto a3 = runtime_->make_test_account(service_connection_->baseService(), object_path(),
177 "id3", "sid3", "dn3");181 101, "sid3", "n3");
178 a1 = move(a3);182 a1 = move(a3);
179 EXPECT_TRUE(a1.isValid());183 EXPECT_TRUE(a1.isValid());
180 EXPECT_EQ(service_connection_->baseService(), a1.busName());184 EXPECT_EQ(service_connection_->baseService(), a1.busName());
181 EXPECT_EQ(object_path(), a1.objectPath());185 EXPECT_EQ(object_path(), a1.objectPath());
182 EXPECT_EQ("dn3", a1.displayName());186 EXPECT_EQ("n3", a1.displayName());
183187
184 // Moved-from object must be invalid188 // Moved-from object must be invalid
185 EXPECT_FALSE(a3.isValid());189 EXPECT_FALSE(a3.isValid());
186190
187 // Moved-from object must be assignable191 // Moved-from object must be assignable
188 auto a4 = runtime_->make_test_account(service_connection_->baseService(), object_path(),192 auto a4 = runtime_->make_test_account(service_connection_->baseService(), object_path(),
189 "id4", "sid4", "dn4");193 102, "sid4", "n4");
190 a2 = a4;194 a2 = a4;
191 EXPECT_TRUE(a2.isValid());195 EXPECT_TRUE(a2.isValid());
192 EXPECT_EQ(service_connection_->baseService(), a2.busName());196 EXPECT_EQ(service_connection_->baseService(), a2.busName());
193 EXPECT_EQ(object_path(), a2.objectPath());197 EXPECT_EQ(object_path(), a2.objectPath());
194 EXPECT_EQ("dn4", a2.displayName());198 EXPECT_EQ("n4", a2.displayName());
195 }199 }
196}200}
197201
@@ -231,8 +235,8 @@
231235
232 {236 {
233 // a1 < a2 for ID237 // a1 < a2 for ID
234 auto a1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "a", "x", "x");238 auto a1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 1, "x", "x");
235 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "b", "x", "x");239 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 2, "x", "x");
236240
237 EXPECT_FALSE(a1 == a2);241 EXPECT_FALSE(a1 == a2);
238 EXPECT_TRUE(a1 != a2);242 EXPECT_TRUE(a1 != a2);
@@ -252,8 +256,8 @@
252256
253 {257 {
254 // a1 < a2 for service ID258 // a1 < a2 for service ID
255 auto a1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "a", "a", "x");259 auto a1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 1, "a", "x");
256 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "a", "b", "x");260 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 1, "b", "x");
257261
258 EXPECT_FALSE(a1 == a2);262 EXPECT_FALSE(a1 == a2);
259 EXPECT_TRUE(a1 != a2);263 EXPECT_TRUE(a1 != a2);
@@ -273,8 +277,8 @@
273277
274 {278 {
275 // a1 < a2 for display name279 // a1 < a2 for display name
276 auto a1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "a", "a", "a");280 auto a1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 1, "a", "a");
277 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "a", "a", "b");281 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 1, "a", "b");
278282
279 EXPECT_FALSE(a1 == a2);283 EXPECT_FALSE(a1 == a2);
280 EXPECT_TRUE(a1 != a2);284 EXPECT_TRUE(a1 != a2);
@@ -294,8 +298,8 @@
294298
295 {299 {
296 // a1 == a2300 // a1 == a2
297 auto a1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "a", "a", "a");301 auto a1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 1, "a", "a");
298 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "a", "a", "a");302 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 1, "a", "a");
299303
300 EXPECT_TRUE(a1 == a2);304 EXPECT_TRUE(a1 == a2);
301 EXPECT_FALSE(a1 != a2);305 EXPECT_FALSE(a1 != a2);
@@ -319,14 +323,14 @@
319 unordered_set<Account>(); // Just to show that this works.323 unordered_set<Account>(); // Just to show that this works.
320324
321 Account a1;325 Account a1;
322 EXPECT_EQ(0, hash<Account>()(a1));326 EXPECT_EQ(0u, hash<Account>()(a1));
323 EXPECT_EQ(0, a1.hash());327 EXPECT_EQ(0u, a1.hash());
324 EXPECT_EQ(0, qHash(a1));328 EXPECT_EQ(0u, qHash(a1));
325329
326 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "a", "a", "a");330 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 1, "a", "a");
327 // Due to different return types (size_t vs uint), hash() and qHash() do not return the same value.331 // Due to different return types (size_t vs uint), hash() and qHash() do not return the same value.
328 EXPECT_NE(0, a2.hash());332 EXPECT_NE(0u, a2.hash());
329 EXPECT_NE(0, qHash(a2));333 EXPECT_NE(0u, qHash(a2));
330}334}
331335
332TEST_F(AccountTest, accounts)336TEST_F(AccountTest, accounts)
@@ -347,17 +351,29 @@
347 EXPECT_EQ(AccountsJob::Status::Finished, j->status());351 EXPECT_EQ(AccountsJob::Status::Finished, j->status());
348 EXPECT_EQ(StorageError::Type::NoError, j->error().type());352 EXPECT_EQ(StorageError::Type::NoError, j->error().type());
349353
350 EXPECT_TRUE(runtime_->connection().isConnected()); // Just for coverage.
351
352 auto accounts = j->accounts();354 auto accounts = j->accounts();
355 EXPECT_GT(accounts.size(), 0);
353356
354 // We don't check the contents of accounts here because we are using the real online accounts manager357 // The fake online accounts service includes a "com.canonical.StorageFramework.Provider.ProviderTest" account.
355 // in this test. This means that the number and kind of accounts that are returned depends358 bool found = false;
356 // on what provider accounts the test user has configured.359 for (auto const& a : accounts)
360 {
361 qDebug() << a.busName();
362 if (a.busName() == "com.canonical.StorageFramework.Provider.ProviderTest")
363 {
364 found = true;
365 EXPECT_EQ("Test Provider", a.providerName());
366 // TODO: add tests for the other account properties.
367 break;
368 }
369 }
370 EXPECT_TRUE(found);
357}371}
358372
359TEST_F(AccountTest, runtime_destroyed)373TEST_F(AccountTest, runtime_destroyed)
360{374{
375 EXPECT_TRUE(runtime_->connection().isConnected()); // Just for coverage.
376
361 EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime.377 EXPECT_EQ(StorageError::Type::NoError, runtime_->shutdown().type()); // Destroy runtime.
362378
363 AccountsJob* j = runtime_->accounts();379 AccountsJob* j = runtime_->accounts();
@@ -504,11 +520,23 @@
504 QSignalSpy ready_spy(j.get(), &ItemListJob::itemsReady);520 QSignalSpy ready_spy(j.get(), &ItemListJob::itemsReady);
505 QSignalSpy status_spy(j.get(), &ItemListJob::statusChanged);521 QSignalSpy status_spy(j.get(), &ItemListJob::statusChanged);
506 status_spy.wait(SIGNAL_WAIT_TIME);522 status_spy.wait(SIGNAL_WAIT_TIME);
507 auto arg = status_spy.takeFirst();523 {
508524 auto arg = status_spy.takeFirst();
509 // Bad metadata is ignored, so status is finished, and itemsReady was never called.525 EXPECT_EQ(ItemListJob::Status::Error, qvariant_cast<ItemListJob::Status>(arg.at(0)));
510 EXPECT_EQ(ItemListJob::Status::Finished, qvariant_cast<ItemListJob::Status>(arg.at(0)));526 }
511 EXPECT_EQ(0, status_spy.count());527
528 if (ready_spy.count() != 1)
529 {
530 ready_spy.wait(SIGNAL_WAIT_TIME);
531 }
532 auto arg = ready_spy.takeFirst();
533 auto items = qvariant_cast<QList<Item>>(arg.at(0));
534 EXPECT_EQ(0, items.size());
535
536 EXPECT_EQ(ItemListJob::Status::Error, j->status());
537 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());
538 EXPECT_EQ("LocalCommsError: Account::roots(): provider returned non-root item type: 0 (id = root_id)",
539 j->error().errorString());
512}540}
513541
514TEST_F(GetTest, basic)542TEST_F(GetTest, basic)
@@ -679,8 +707,9 @@
679 spy.wait(SIGNAL_WAIT_TIME);707 spy.wait(SIGNAL_WAIT_TIME);
680708
681 EXPECT_EQ(ItemJob::Status::Error, j->status());709 EXPECT_EQ(ItemJob::Status::Error, j->status());
682 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "710 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
683 "file or folder must have at least one parent ID", j->error().errorString());711 "file or folder must have at least one parent ID"
712 , j->error().errorString());
684}713}
685714
686TEST_F(MetadataTest, empty_parent)715TEST_F(MetadataTest, empty_parent)
@@ -693,8 +722,9 @@
693 spy.wait(SIGNAL_WAIT_TIME);722 spy.wait(SIGNAL_WAIT_TIME);
694723
695 EXPECT_EQ(ItemJob::Status::Error, j->status());724 EXPECT_EQ(ItemJob::Status::Error, j->status());
696 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "725 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
697 "parent_id of file or folder cannot be empty", j->error().errorString());726 "parent_id of file or folder cannot be empty",
727 j->error().errorString());
698}728}
699729
700TEST_F(MetadataTest, root_with_parent)730TEST_F(MetadataTest, root_with_parent)
@@ -707,8 +737,9 @@
707 spy.wait(SIGNAL_WAIT_TIME);737 spy.wait(SIGNAL_WAIT_TIME);
708738
709 EXPECT_EQ(ItemJob::Status::Error, j->status());739 EXPECT_EQ(ItemJob::Status::Error, j->status());
710 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "740 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = root_id): "
711 "parent_ids of root must be empty", j->error().errorString());741 "parent_ids of root must be empty",
742 j->error().errorString());
712}743}
713744
714TEST_F(MetadataTest, empty_name)745TEST_F(MetadataTest, empty_name)
@@ -721,8 +752,9 @@
721 spy.wait(SIGNAL_WAIT_TIME);752 spy.wait(SIGNAL_WAIT_TIME);
722753
723 EXPECT_EQ(ItemJob::Status::Error, j->status());754 EXPECT_EQ(ItemJob::Status::Error, j->status());
724 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "755 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
725 "name cannot be empty", j->error().errorString());756 "name cannot be empty",
757 j->error().errorString());
726}758}
727759
728TEST_F(MetadataTest, empty_etag)760TEST_F(MetadataTest, empty_etag)
@@ -735,8 +767,9 @@
735 spy.wait(SIGNAL_WAIT_TIME);767 spy.wait(SIGNAL_WAIT_TIME);
736768
737 EXPECT_EQ(ItemJob::Status::Error, j->status());769 EXPECT_EQ(ItemJob::Status::Error, j->status());
738 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "770 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
739 "etag of a file cannot be empty", j->error().errorString());771 "etag of a file cannot be empty",
772 j->error().errorString());
740}773}
741774
742TEST_F(MetadataTest, unknown_key)775TEST_F(MetadataTest, unknown_key)
@@ -762,8 +795,9 @@
762 spy.wait(SIGNAL_WAIT_TIME);795 spy.wait(SIGNAL_WAIT_TIME);
763796
764 EXPECT_EQ(ItemJob::Status::Error, j->status());797 EXPECT_EQ(ItemJob::Status::Error, j->status());
765 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "798 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
766 "missing key \"size_in_bytes\" in metadata for \"child_id\"", j->error().errorString());799 "missing key \"size_in_bytes\" in metadata",
800 j->error().errorString());
767}801}
768802
769TEST_F(MetadataTest, wrong_type_for_time)803TEST_F(MetadataTest, wrong_type_for_time)
@@ -776,8 +810,9 @@
776 spy.wait(SIGNAL_WAIT_TIME);810 spy.wait(SIGNAL_WAIT_TIME);
777811
778 EXPECT_EQ(ItemJob::Status::Error, j->status());812 EXPECT_EQ(ItemJob::Status::Error, j->status());
779 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: last_modified_time: "813 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
780 "expected value of type QString, but received value of type qlonglong", j->error().errorString());814 "last_modified_time: expected value of type QString, but received value of type qlonglong",
815 j->error().errorString());
781}816}
782817
783TEST_F(MetadataTest, bad_parse_for_time)818TEST_F(MetadataTest, bad_parse_for_time)
@@ -790,8 +825,9 @@
790 spy.wait(SIGNAL_WAIT_TIME);825 spy.wait(SIGNAL_WAIT_TIME);
791826
792 EXPECT_EQ(ItemJob::Status::Error, j->status());827 EXPECT_EQ(ItemJob::Status::Error, j->status());
793 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: last_modified_time: "828 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
794 "value \"xyz\" does not parse as ISO-8601 date", j->error().errorString());829 "last_modified_time: value \"xyz\" does not parse as ISO-8601 date",
830 j->error().errorString());
795}831}
796832
797TEST_F(MetadataTest, missing_timezone)833TEST_F(MetadataTest, missing_timezone)
@@ -804,8 +840,9 @@
804 spy.wait(SIGNAL_WAIT_TIME);840 spy.wait(SIGNAL_WAIT_TIME);
805841
806 EXPECT_EQ(ItemJob::Status::Error, j->status());842 EXPECT_EQ(ItemJob::Status::Error, j->status());
807 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: last_modified_time: "843 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
808 "value \"2007-04-05T14:30\" lacks a time zone specification", j->error().errorString());844 "last_modified_time: value \"2007-04-05T14:30\" lacks a time zone specification",
845 j->error().errorString());
809}846}
810847
811TEST_F(MetadataTest, wrong_type_for_size)848TEST_F(MetadataTest, wrong_type_for_size)
@@ -818,8 +855,9 @@
818 spy.wait(SIGNAL_WAIT_TIME);855 spy.wait(SIGNAL_WAIT_TIME);
819856
820 EXPECT_EQ(ItemJob::Status::Error, j->status());857 EXPECT_EQ(ItemJob::Status::Error, j->status());
821 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: size_in_bytes: "858 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
822 "expected value of type qlonglong, but received value of type QString", j->error().errorString());859 "size_in_bytes: expected value of type qlonglong, but received value of type QString",
860 j->error().errorString());
823}861}
824862
825TEST_F(MetadataTest, negative_size)863TEST_F(MetadataTest, negative_size)
@@ -832,8 +870,9 @@
832 spy.wait(SIGNAL_WAIT_TIME);870 spy.wait(SIGNAL_WAIT_TIME);
833871
834 EXPECT_EQ(ItemJob::Status::Error, j->status());872 EXPECT_EQ(ItemJob::Status::Error, j->status());
835 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: size_in_bytes: "873 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider (id = child_id): "
836 "expected value >= 0, but received -1", j->error().errorString());874 "size_in_bytes: expected value >= 0, but received -1",
875 j->error().errorString());
837}876}
838877
839TEST_F(DeleteTest, basic)878TEST_F(DeleteTest, basic)
@@ -1121,9 +1160,9 @@
11211160
1122 unordered_set<Item>(); // Just to show that this works.1161 unordered_set<Item>(); // Just to show that this works.
11231162
1124 EXPECT_EQ(0, hash<Item>()(i1));1163 EXPECT_EQ(0u, hash<Item>()(i1));
1125 EXPECT_EQ(0, i1.hash());1164 EXPECT_EQ(0u, i1.hash());
1126 EXPECT_EQ(0, qHash(i1));1165 EXPECT_EQ(0u, qHash(i1));
1127 }1166 }
11281167
1129 {1168 {
@@ -1155,15 +1194,15 @@
1155 EXPECT_FALSE(i2 > i1);1194 EXPECT_FALSE(i2 > i1);
1156 EXPECT_FALSE(i2 >= i1);1195 EXPECT_FALSE(i2 >= i1);
11571196
1158 EXPECT_NE(0, i1.hash());1197 EXPECT_NE(0u, i1.hash());
1159 EXPECT_NE(0, qHash(i1));1198 EXPECT_NE(0u, qHash(i1));
1160 }1199 }
11611200
1162 {1201 {
1163 // Both items valid with identical metadata, but different accounts (a1 < a2).1202 // Both items valid with identical metadata, but different accounts (a1 < a2).
11641203
1165 auto a1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "a", "x", "x");1204 auto a1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 1, "x", "x");
1166 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), "b", "x", "x");1205 auto a2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 2, "x", "x");
11671206
1168 Item i1;1207 Item i1;
1169 Item i2;1208 Item i2;
@@ -1485,7 +1524,7 @@
1485 auto arg = spy.takeFirst();1524 auto arg = spy.takeFirst();
1486 EXPECT_EQ(ItemListJob::Status::Error, qvariant_cast<ItemListJob::Status>(arg.at(0)));1525 EXPECT_EQ(ItemListJob::Status::Error, qvariant_cast<ItemListJob::Status>(arg.at(0)));
14871526
1488 EXPECT_EQ("Item::parents(): provider returned a file as a parent", j->error().message());1527 EXPECT_EQ("Item::parents(): provider returned a file as a parent (id = root_id)", j->error().message());
1489 }1528 }
1490}1529}
14911530
@@ -1639,11 +1678,12 @@
1639{1678{
1640 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));1679 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
16411680
1642 auto test_account = runtime_->make_test_account(service_connection_->baseService(), object_path(), "test_account");1681 auto acc1 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 1);
1682 auto acc2 = runtime_->make_test_account(service_connection_->baseService(), object_path(), 2);
16431683
1644 Item root1;1684 Item root1;
1645 {1685 {
1646 unique_ptr<ItemJob> j(test_account.get("root_id"));1686 unique_ptr<ItemJob> j(acc1.get("root_id"));
1647 QSignalSpy spy(j.get(), &ItemJob::statusChanged);1687 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
1648 spy.wait(SIGNAL_WAIT_TIME);1688 spy.wait(SIGNAL_WAIT_TIME);
1649 root1 = j->item();1689 root1 = j->item();
@@ -1652,7 +1692,7 @@
16521692
1653 Item root2;1693 Item root2;
1654 {1694 {
1655 unique_ptr<ItemJob> j(acc_.get("root_id"));1695 unique_ptr<ItemJob> j(acc2.get("root_id"));
1656 QSignalSpy spy(j.get(), &ItemJob::statusChanged);1696 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
1657 spy.wait(SIGNAL_WAIT_TIME);1697 spy.wait(SIGNAL_WAIT_TIME);
1658 root2 = j->item();1698 root2 = j->item();
@@ -1661,7 +1701,7 @@
16611701
1662 Item child;1702 Item child;
1663 {1703 {
1664 unique_ptr<ItemJob> j(acc_.get("child_id"));1704 unique_ptr<ItemJob> j(acc2.get("child_id"));
1665 QSignalSpy spy(j.get(), &ItemJob::statusChanged);1705 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
1666 spy.wait(SIGNAL_WAIT_TIME);1706 spy.wait(SIGNAL_WAIT_TIME);
1667 child = j->item();1707 child = j->item();
@@ -1751,7 +1791,9 @@
1751 EXPECT_FALSE(j->isValid());1791 EXPECT_FALSE(j->isValid());
1752 EXPECT_EQ(ItemJob::Status::Error, j->status());1792 EXPECT_EQ(ItemJob::Status::Error, j->status());
1753 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());1793 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());
1754 EXPECT_EQ("LocalCommsError: Item::copy(): source and target item type differ", j->error().errorString());1794 EXPECT_EQ("LocalCommsError: Item::copy()provider error: source and target item type differ "
1795 "(source id = child_id, target id = new_item_id)",
1796 j->error().errorString());
1755}1797}
17561798
1757TEST_F(MoveTest, basic)1799TEST_F(MoveTest, basic)
@@ -1863,7 +1905,8 @@
1863 EXPECT_EQ(ItemJob::Status::Error, j->status());1905 EXPECT_EQ(ItemJob::Status::Error, j->status());
1864 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());1906 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());
1865 EXPECT_EQ("LocalCommsError", j->error().name());1907 EXPECT_EQ("LocalCommsError", j->error().name());
1866 EXPECT_EQ("LocalCommsError: Item::move(): impossible root item returned by provider", j->error().errorString());1908 EXPECT_EQ("LocalCommsError: Item::move(): impossible root item returned by provider (id = root_id)",
1909 j->error().errorString());
1867}1910}
18681911
1869TEST_F(MoveTest, type_mismatch)1912TEST_F(MoveTest, type_mismatch)
@@ -1899,7 +1942,8 @@
1899 EXPECT_FALSE(j->isValid());1942 EXPECT_FALSE(j->isValid());
1900 EXPECT_EQ(ItemJob::Status::Error, j->status());1943 EXPECT_EQ(ItemJob::Status::Error, j->status());
1901 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());1944 EXPECT_EQ(StorageError::Type::LocalCommsError, j->error().type());
1902 EXPECT_EQ("LocalCommsError: Item::move(): provider error: source and target item type differ",1945 EXPECT_EQ("LocalCommsError: Item::move(): provider error: source and target item type differ "
1946 "(source id = child_id, target id = child_id)",
1903 j->error().errorString());1947 j->error().errorString());
1904}1948}
19051949
@@ -2094,7 +2138,7 @@
2094 auto status = qvariant_cast<ItemJob::Status>(arg.at(0));2138 auto status = qvariant_cast<ItemJob::Status>(arg.at(0));
2095 EXPECT_EQ(ItemJob::Status::Error, status);2139 EXPECT_EQ(ItemJob::Status::Error, status);
20962140
2097 EXPECT_EQ("LocalCommsError: Item::createFolder(): impossible file item returned by provider",2141 EXPECT_EQ("LocalCommsError: Item::createFolder(): impossible file item returned by provider (id = new_folder_id)",
2098 j->error().errorString());2142 j->error().errorString());
2099}2143}
21002144
@@ -2157,7 +2201,10 @@
2157 QSignalSpy ready_spy(j.get(), &ItemListJob::itemsReady);2201 QSignalSpy ready_spy(j.get(), &ItemListJob::itemsReady);
2158 QSignalSpy status_spy(j.get(), &ItemListJob::statusChanged);2202 QSignalSpy status_spy(j.get(), &ItemListJob::statusChanged);
2159 status_spy.wait(SIGNAL_WAIT_TIME);2203 status_spy.wait(SIGNAL_WAIT_TIME);
2160 ASSERT_EQ(0, ready_spy.count());2204 if (ready_spy.count() == 0)
2205 {
2206 ASSERT_TRUE(ready_spy.wait(SIGNAL_WAIT_TIME));
2207 }
21612208
2162 EXPECT_EQ(ItemListJob::Status::Finished, j->status());2209 EXPECT_EQ(ItemListJob::Status::Finished, j->status());
21632210
@@ -2303,7 +2350,8 @@
2303 auto arg = spy.takeFirst();2350 auto arg = spy.takeFirst();
2304 EXPECT_EQ(ItemListJob::Status::Error, qvariant_cast<ItemListJob::Status>(arg.at(0)));2351 EXPECT_EQ(ItemListJob::Status::Error, qvariant_cast<ItemListJob::Status>(arg.at(0)));
23052352
2306 EXPECT_EQ("LocalCommsError: Item::list(): impossible root item returned by provider", j->error().errorString());2353 EXPECT_EQ("LocalCommsError: Item::list(): impossible root item returned by provider (id = child_id)",
2354 j->error().errorString());
2307}2355}
23082356
2309TEST_F(ListTest, runtime_destroyed_while_item_list_job_running)2357TEST_F(ListTest, runtime_destroyed_while_item_list_job_running)
@@ -3026,7 +3074,7 @@
30263074
3027 unique_ptr<Uploader> uploader(child.createUploader(Item::ConflictPolicy::IgnoreConflict, 20));3075 unique_ptr<Uploader> uploader(child.createUploader(Item::ConflictPolicy::IgnoreConflict, 20));
3028 EXPECT_FALSE(uploader->isValid());3076 EXPECT_FALSE(uploader->isValid());
3029 EXPECT_EQ(Downloader::Status::Error, uploader->status());3077 EXPECT_EQ(Uploader::Status::Error, uploader->status());
3030 EXPECT_EQ(StorageError::RuntimeDestroyed, uploader->error().type());3078 EXPECT_EQ(StorageError::RuntimeDestroyed, uploader->error().type());
3031 EXPECT_EQ("RuntimeDestroyed: Item::createUploader(): Runtime was destroyed previously",3079 EXPECT_EQ("RuntimeDestroyed: Item::createUploader(): Runtime was destroyed previously",
3032 uploader->error().errorString());3080 uploader->error().errorString());
@@ -3370,7 +3418,8 @@
33703418
3371 EXPECT_EQ(Uploader::Status::Error, uploader->status());3419 EXPECT_EQ(Uploader::Status::Error, uploader->status());
3372 EXPECT_EQ(StorageError::Type::LocalCommsError, uploader->error().type());3420 EXPECT_EQ(StorageError::Type::LocalCommsError, uploader->error().type());
3373 EXPECT_EQ("Item::createUploader(): impossible folder item returned by provider", uploader->error().message());3421 EXPECT_EQ("Item::createUploader(): impossible folder item returned by provider (id = some_id)",
3422 uploader->error().message());
3374}3423}
33753424
3376TEST_F(UploadTest, cancel_success)3425TEST_F(UploadTest, cancel_success)
@@ -3702,7 +3751,8 @@
3702 EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));3751 EXPECT_EQ(Uploader::Status::Error, qvariant_cast<Uploader::Status>(arg.at(0)));
37033752
3704 EXPECT_EQ(StorageError::Type::LocalCommsError, uploader->error().type());3753 EXPECT_EQ(StorageError::Type::LocalCommsError, uploader->error().type());
3705 EXPECT_EQ("Item::createFile(): impossible folder item returned by provider", uploader->error().message());3754 EXPECT_EQ("Item::createFile(): impossible folder item returned by provider (id = some_id)",
3755 uploader->error().message());
3706}3756}
37073757
3708TEST_F(CreateFileTest, exists)3758TEST_F(CreateFileTest, exists)
37093759
=== modified file 'tests/utils/DBusEnvironment.cpp'
--- tests/utils/DBusEnvironment.cpp 2016-08-04 10:12:01 +0000
+++ tests/utils/DBusEnvironment.cpp 2016-12-12 02:53:43 +0000
@@ -17,6 +17,7 @@
17 */17 */
1818
19#include "DBusEnvironment.h"19#include "DBusEnvironment.h"
20#include <unity/storage/registry/Registry.h>
2021
21#include <testsetup.h>22#include <testsetup.h>
2223
@@ -27,6 +28,9 @@
27char const ACCOUNTS_BUS_NAME[] = "com.ubuntu.OnlineAccounts.Manager";28char const ACCOUNTS_BUS_NAME[] = "com.ubuntu.OnlineAccounts.Manager";
28char const FAKE_ACCOUNTS_SERVICE[] = TEST_SRC_DIR "/utils/fake-online-accounts-daemon.py";29char const FAKE_ACCOUNTS_SERVICE[] = TEST_SRC_DIR "/utils/fake-online-accounts-daemon.py";
2930
31char const REGISTRY_TEST_BUS_NAME[] = "com.ubuntu.StorageFramework.TestRegistry";
32char const REGISTRY_SERVICE[] = TEST_BIN_DIR "/../src/registry/storage-framework-registry";
33
30char const DEMO_PROVIDER_BUS_NAME[] = "com.canonical.StorageFramework.Provider.ProviderTest";34char const DEMO_PROVIDER_BUS_NAME[] = "com.canonical.StorageFramework.Provider.ProviderTest";
31char const DEMO_PROVIDER_SERVICE[] = TEST_BIN_DIR "/../demo/provider_test/provider-test";35char const DEMO_PROVIDER_SERVICE[] = TEST_BIN_DIR "/../demo/provider_test/provider-test";
32}36}
@@ -38,6 +42,11 @@
38 ACCOUNTS_BUS_NAME, QDBusConnection::SessionBus,42 ACCOUNTS_BUS_NAME, QDBusConnection::SessionBus,
39 FAKE_ACCOUNTS_SERVICE, {}));43 FAKE_ACCOUNTS_SERVICE, {}));
40 runner_->registerService(accounts_service_);44 runner_->registerService(accounts_service_);
45
46 registry_service_.reset(new QtDBusTest::QProcessDBusService(
47 unity::storage::registry::BUS_NAME, QDBusConnection::SessionBus,
48 REGISTRY_SERVICE, {}));
49 runner_->registerService(registry_service_);
41}50}
4251
43DBusEnvironment::~DBusEnvironment()52DBusEnvironment::~DBusEnvironment()
4453
=== modified file 'tests/utils/DBusEnvironment.h'
--- tests/utils/DBusEnvironment.h 2016-08-04 10:12:01 +0000
+++ tests/utils/DBusEnvironment.h 2016-12-12 02:53:43 +0000
@@ -45,5 +45,6 @@
45private:45private:
46 std::unique_ptr<QtDBusTest::DBusTestRunner> runner_;46 std::unique_ptr<QtDBusTest::DBusTestRunner> runner_;
47 QSharedPointer<QtDBusTest::QProcessDBusService> accounts_service_;47 QSharedPointer<QtDBusTest::QProcessDBusService> accounts_service_;
48 QSharedPointer<QtDBusTest::QProcessDBusService> registry_service_;
48 QSharedPointer<QtDBusTest::QProcessDBusService> demo_provider_;49 QSharedPointer<QtDBusTest::QProcessDBusService> demo_provider_;
49};50};
5051
=== modified file 'tests/utils/ProviderFixture.h'
--- tests/utils/ProviderFixture.h 2016-09-26 02:37:03 +0000
+++ tests/utils/ProviderFixture.h 2016-12-12 02:53:43 +0000
@@ -23,7 +23,11 @@
23#include <utils/DBusEnvironment.h>23#include <utils/DBusEnvironment.h>
24#include <utils/ProviderClient.h>24#include <utils/ProviderClient.h>
2525
26#pragma GCC diagnostic push
27#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
26#include <gtest/gtest.h>28#include <gtest/gtest.h>
29#pragma GCC diagnostic pop
30
27#include <OnlineAccounts/Account>31#include <OnlineAccounts/Account>
28#include <OnlineAccounts/Manager>32#include <OnlineAccounts/Manager>
29#include <QDBusConnection>33#include <QDBusConnection>
3034
=== removed file 'tests/utils/com.ubuntu.OnlineAccounts.Manager.xml'
--- tests/utils/com.ubuntu.OnlineAccounts.Manager.xml 2016-07-12 02:25:26 +0000
+++ tests/utils/com.ubuntu.OnlineAccounts.Manager.xml 1970-01-01 00:00:00 +0000
@@ -1,153 +0,0 @@
1<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
2"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
3
4<node name="/com/ubuntu/OnlineAccounts/Manager">
5 <interface name="com.ubuntu.OnlineAccounts.Manager">
6
7 <!--
8 Global concepts:
9
10 Clients are identified by their "applicationId", which is the
11 "<package>_<app>" of the client.
12
13 The "serviceId" is an application-specific name for an account provider.
14 That is, the "serviceId" contains the information about the application
15 which will use it, and the account provider (e.g. "google", "facebook").
16 "serviceId"s are backed by files shipped with the application, which can
17 contain application/account-provider specific information, such as the
18 ClientId and ClientSecret to be used when authentication with OAuth 2.0.
19 An application can ship more than one "serviceId", if they refer to
20 different account providers; that is, one application can have a
21 serviceId for Google and one for Facebook, but the same application
22 cannot have one for GMail and another for Picasa.
23 -->
24
25 <!--
26 GetAccounts: returns a list of account IDs that satisfy the given
27 filters.
28
29 Allowed keys for the "filters" parameter (any combination is allowed,
30 though not all combinations might make sense):
31
32 - "applicationId" ("s"): the "<package>_<app>" of the client. An
33 unconfined application can specify this in order to restrict the set
34 of results to only those accounts that the application has been
35 authorized to use. For confined apps, OA will deduce the
36 applicationId from the apparmor label of the caller.
37
38 - "serviceId" ("s"): if the application wants to list only those
39 accounts coming from a specific provider (e.g., "Facebook").
40
41 - "accountId" ("u"): the ID of an account.
42
43 In any case, an application will receive only those accounts which the
44 user has authorized the application to use. See
45 http://wiki.ubuntu.com/OnlineAccounts
46 for an overview of the UI experience.
47
48 Disabled accounts will not be returned.
49 -->
50 <method name="GetAccounts">
51 <arg name="filters" type="a{sv}" direction="in" />
52 <!--
53 The return value is a list of account IDs paired with a dictionary of account data.
54 This will always include:
55 - "serviceId" (s)
56 - "displayName" (s)
57 Other settings stored on the account will also be included, such as the
58 server address and port of an owncloud or IMAP account, but we haven't
59 defined exactly how. Possibly, all account-specific keys will be
60 prefixed by "settings/", in order not to clash with the keys defined at
61 the framework level.
62 -->
63 <arg name="accounts" type="a(ua{sv})" direction="out" />
64 <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
65 <annotation name="org.qtproject.QtDBus.QtTypeName.Out0"
66 value="QList&lt;AccountInfo&gt;"/>
67 </method>
68
69 <!--
70 Authenticate: request authentication credentials for the given
71 account ID in the context of a particular service.
72
73 If "interactive" is false, an error will be returned if
74 user interaction would be required to retrieve the
75 credentials.
76
77 If "invalidate" is true, any stored credentials will be
78 ignored and new credentials will be requested from the account
79 provider.
80 -->
81 <method name="Authenticate">
82 <arg name="accountId" type="u" direction="in" />
83 <arg name="serviceId" type="s" direction="in" />
84 <arg name="interactive" type="b" direction="in" />
85 <arg name="invalidate" type="b" direction="in" />
86 <!--
87 This dictionary can be used to specify OAuth client keys or permission
88 scopes. While it's possible to statically define them a the "serviceId"
89 level, some apps might want to change this information at runtime.
90 Possible use cases:
91 1) OAuth keys are retrieved from a server (so that they can be updated
92 when the old ones are revoked).
93 2) An app might want to use different keys when talking to GMail and
94 Picasa.
95 3) The scope list can also be dynamic, and depending on how the user is
96 using the app.
97 4) SASL: the parameters would contain the latest challenge got from the
98 server.
99 -->
100 <arg name="parameters" type="a{sv}" direction="in" />
101 <arg name="credentials" type="a{sv}" direction="out" />
102 <annotation name="org.qtproject.QtDBus.QtTypeName.In4" value="QVariantMap"/>
103 <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
104 </method>
105
106 <!--
107 RequestAccess: register a new account for use with the given
108 service.
109 This method also performs the authentication, since that's what apps
110 would do as soon as they get the account.
111 -->
112 <method name="RequestAccess">
113 <arg name="serviceId" type="s" direction="in" />
114 <arg name="parameters" type="a{sv}" direction="in" />
115 <arg name="account" type="(ua{sv})" direction="out" />
116 <arg name="credentials" type="a{sv}" direction="out" />
117 <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
118 <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="AccountInfo"/>
119 <annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="QVariantMap"/>
120 </method>
121
122 <!--
123 AccountChanged: emitted when account details are changed.
124
125 The apparmor policy will NOT ALLOW confined applications to receive
126 this signal on the account manager object path (which might be
127 /com/ubuntu/OnlineAccounts/Manager). Only unconfined applications will
128 be able to listen to this signal from that object path.
129
130 Confined apps will have to catch this signal from a different object path:
131 /com/ubuntu/OnlineAccounts/Manager/@{APP_PKGNAME_DBUS}, which will
132 deliver the signal only for those accounts which the app has been
133 authorized to use.
134 -->
135 <signal name="AccountChanged">
136 <!--
137 The serviceId will also be included in the "account" dictionary. The
138 reason for having it also here is to allow clients to filter D-Bus
139 messages by arg0. This can be important for unconfined clients, which
140 would otherwise be woken up by any account change, even those not
141 relevant to them.
142 -->
143 <arg name="serviceId" type="s" />
144 <!--
145 The dictionary contains a changeType key, type "u", whose value is
146 enum { enabled, disabled, changed }
147 -->
148 <arg name="account" type="(ua{sv})" />
149 <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="AccountInfo"/>
150 </signal>
151
152 </interface>
153</node>
1540
=== modified file 'tests/utils/fake-online-accounts-daemon.py'
--- tests/utils/fake-online-accounts-daemon.py 2016-11-01 03:36:29 +0000
+++ tests/utils/fake-online-accounts-daemon.py 2016-12-12 02:53:43 +0000
@@ -17,7 +17,6 @@
1717
18"""A fake version of the OnlineAccounts D-Bus service."""18"""A fake version of the OnlineAccounts D-Bus service."""
1919
20import os
21import sys20import sys
2221
23import dbus.service22import dbus.service
@@ -28,9 +27,6 @@
28OBJECT_PATH = "/com/ubuntu/OnlineAccounts/Manager"27OBJECT_PATH = "/com/ubuntu/OnlineAccounts/Manager"
29OA_IFACE = "com.ubuntu.OnlineAccounts.Manager"28OA_IFACE = "com.ubuntu.OnlineAccounts.Manager"
3029
31INTERFACE_XML = os.path.join(os.path.dirname(__file__),
32 "com.ubuntu.OnlineAccounts.Manager.xml")
33
34AUTH_OAUTH1 = 130AUTH_OAUTH1 = 1
35AUTH_OAUTH2 = 231AUTH_OAUTH2 = 2
36AUTH_PASSWORD = 332AUTH_PASSWORD = 3
@@ -90,16 +86,16 @@
90 }, signature="sv")86 }, signature="sv")
9187
92class Account:88class Account:
93 def __init__(self, account_id, display_name, service_id, credentials, settings=None):89 def __init__(self, account_id, name, service_id, credentials, settings=None):
94 self.account_id = account_id90 self.account_id = account_id
95 self.display_name = display_name91 self.name = name
96 self.service_id = service_id92 self.service_id = service_id
97 self.credentials = credentials93 self.credentials = credentials
98 self.settings = settings94 self.settings = settings
9995
100 def serialise(self):96 def serialise(self):
101 account_info = dbus.Dictionary({97 account_info = dbus.Dictionary({
102 "displayName": dbus.String(self.display_name),98 "displayName": dbus.String(self.name),
103 "serviceId": dbus.String(self.service_id),99 "serviceId": dbus.String(self.service_id),
104 "authMethod": dbus.Int32(self.credentials.method),100 "authMethod": dbus.Int32(self.credentials.method),
105 }, signature="sv")101 }, signature="sv")
@@ -114,12 +110,12 @@
114 self.accounts = accounts110 self.accounts = accounts
115111
116 @dbus.service.method(dbus_interface=OA_IFACE,112 @dbus.service.method(dbus_interface=OA_IFACE,
117 in_signature="a{sv}", out_signature="a(ua{sv})")113 in_signature="a{sv}", out_signature="a(ua{sv})aa{sv}")
118 def GetAccounts(self, filters):114 def GetAccounts(self, filters):
119 #print("GetAccounts %r" % filters)115 #print("GetAccounts %r" % filters)
120 sys.stdout.flush()116 sys.stdout.flush()
121 return dbus.Array([a.serialise() for a in self.accounts],117 return dbus.Array([a.serialise() for a in self.accounts],
122 signature="a(ua{sv})")118 signature="a(ua{sv})"), dbus.Array(signature="a{sv}")
123119
124 @dbus.service.method(dbus_interface=OA_IFACE,120 @dbus.service.method(dbus_interface=OA_IFACE,
125 in_signature="usbba{sv}", out_signature="a{sv}")121 in_signature="usbba{sv}", out_signature="a{sv}")
@@ -178,8 +174,8 @@
178 Account(4, "Password host account", "password-host-service",174 Account(4, "Password host account", "password-host-service",
179 Password_Bug1628473("joe", "secret"),175 Password_Bug1628473("joe", "secret"),
180 {"host": "http://www.example.com/"}),176 {"host": "http://www.example.com/"}),
181 Account(42, "Fake google account", "google-drive-scope",177 Account(42, "Fake test account", "storage-provider-test",
182 OAuth2("fake-google-access-token", 0, [])),178 OAuth2("fake-test-access-token", 0, [])),
183 Account(99, "Fake mcloud account", "com.canonical.scopes.mcloud_mcloud_mcloud",179 Account(99, "Fake mcloud account", "com.canonical.scopes.mcloud_mcloud_mcloud",
184 OAuth2("fake-mcloud-access-token", 0, [])),180 OAuth2("fake-mcloud-access-token", 0, [])),
185 ]181 ]

Subscribers

People subscribed via source and target branches

to all changes: